From 36d8593ec74dc04d3bd7c1c897a7b7cfbd0b0dc6 Mon Sep 17 00:00:00 2001 From: Russell King - ARM Linux Date: Sat, 19 Feb 2011 15:34:50 +0000 Subject: Make clocksource name const As nothing should be writing to the clocksource name string, make the clocksource name pointer const. Build-tested on ARM Versatile Express. Signed-off-by: Russell King Signed-off-by: John Stultz --- include/linux/clocksource.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h index c37b21ad5a3b..94c1f38e922a 100644 --- a/include/linux/clocksource.h +++ b/include/linux/clocksource.h @@ -161,7 +161,7 @@ struct clocksource { /* * First part of structure is read mostly */ - char *name; + const char *name; struct list_head list; int rating; cycle_t (*read)(struct clocksource *cs); -- cgit From 78b7280cce23293f7570ad52c1ffe1485c6d9669 Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 11 Mar 2011 17:57:23 +0000 Subject: KEYS: Improve /proc/keys Improve /proc/keys by: (1) Don't attempt to summarise the payload of a negated key. It won't have one. To this end, a helper function - key_is_instantiated() has been added that allows the caller to find out whether the key is positively instantiated (as opposed to being uninstantiated or negatively instantiated). (2) Do show keys that are negative, expired or revoked rather than hiding them. This requires an override flag (no_state_check) to be passed to search_my_process_keyrings() and keyring_search_aux() to suppress this check. Without this, keys that are possessed by the caller, but only grant permissions to the caller if possessed are skipped as the possession check fails. Keys that are visible due to user, group or other checks are visible with or without this patch. Signed-off-by: David Howells Signed-off-by: James Morris --- include/linux/key.h | 13 +++++++++++++ net/dns_resolver/dns_key.c | 10 ++++++---- security/keys/internal.h | 4 +++- security/keys/keyring.c | 37 ++++++++++++++++++++++++------------- security/keys/proc.c | 2 +- security/keys/process_keys.c | 12 +++++++----- security/keys/request_key.c | 3 +-- security/keys/request_key_auth.c | 3 ++- security/keys/user_defined.c | 4 ++-- 9 files changed, 59 insertions(+), 29 deletions(-) (limited to 'include/linux') diff --git a/include/linux/key.h b/include/linux/key.h index b2bb01719561..ef19b99aff98 100644 --- a/include/linux/key.h +++ b/include/linux/key.h @@ -276,6 +276,19 @@ static inline key_serial_t key_serial(struct key *key) return key ? key->serial : 0; } +/** + * key_is_instantiated - Determine if a key has been positively instantiated + * @key: The key to check. + * + * Return true if the specified key has been positively instantiated, false + * otherwise. + */ +static inline bool key_is_instantiated(const struct key *key) +{ + return test_bit(KEY_FLAG_INSTANTIATED, &key->flags) && + !test_bit(KEY_FLAG_NEGATIVE, &key->flags); +} + #define rcu_dereference_key(KEY) \ (rcu_dereference_protected((KEY)->payload.rcudata, \ rwsem_is_locked(&((struct key *)(KEY))->sem))) diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c index cfa7a5e1c5c9..fa000d26dc60 100644 --- a/net/dns_resolver/dns_key.c +++ b/net/dns_resolver/dns_key.c @@ -212,10 +212,12 @@ static void dns_resolver_describe(const struct key *key, struct seq_file *m) int err = key->type_data.x[0]; seq_puts(m, key->description); - if (err) - seq_printf(m, ": %d", err); - else - seq_printf(m, ": %u", key->datalen); + if (key_is_instantiated(key)) { + if (err) + seq_printf(m, ": %d", err); + else + seq_printf(m, ": %u", key->datalen); + } } /* diff --git a/security/keys/internal.h b/security/keys/internal.h index 07a025f81902..f375152a2500 100644 --- a/security/keys/internal.h +++ b/security/keys/internal.h @@ -109,11 +109,13 @@ extern key_ref_t keyring_search_aux(key_ref_t keyring_ref, const struct cred *cred, struct key_type *type, const void *description, - key_match_func_t match); + key_match_func_t match, + bool no_state_check); extern key_ref_t search_my_process_keyrings(struct key_type *type, const void *description, key_match_func_t match, + bool no_state_check, const struct cred *cred); extern key_ref_t search_process_keyrings(struct key_type *type, const void *description, diff --git a/security/keys/keyring.c b/security/keys/keyring.c index cdd2f3f88c88..a06ffab38568 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c @@ -176,13 +176,15 @@ static void keyring_describe(const struct key *keyring, struct seq_file *m) else seq_puts(m, "[anon]"); - rcu_read_lock(); - klist = rcu_dereference(keyring->payload.subscriptions); - if (klist) - seq_printf(m, ": %u/%u", klist->nkeys, klist->maxkeys); - else - seq_puts(m, ": empty"); - rcu_read_unlock(); + if (key_is_instantiated(keyring)) { + rcu_read_lock(); + klist = rcu_dereference(keyring->payload.subscriptions); + if (klist) + seq_printf(m, ": %u/%u", klist->nkeys, klist->maxkeys); + else + seq_puts(m, ": empty"); + rcu_read_unlock(); + } } /* @@ -271,6 +273,7 @@ struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid, * @type: The type of key to search for. * @description: Parameter for @match. * @match: Function to rule on whether or not a key is the one required. + * @no_state_check: Don't check if a matching key is bad * * Search the supplied keyring tree for a key that matches the criteria given. * The root keyring and any linked keyrings must grant Search permission to the @@ -303,7 +306,8 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref, const struct cred *cred, struct key_type *type, const void *description, - key_match_func_t match) + key_match_func_t match, + bool no_state_check) { struct { struct keyring_list *keylist; @@ -345,6 +349,8 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref, kflags = keyring->flags; if (keyring->type == type && match(keyring, description)) { key = keyring; + if (no_state_check) + goto found; /* check it isn't negative and hasn't expired or been * revoked */ @@ -384,11 +390,13 @@ descend: continue; /* skip revoked keys and expired keys */ - if (kflags & (1 << KEY_FLAG_REVOKED)) - continue; + if (!no_state_check) { + if (kflags & (1 << KEY_FLAG_REVOKED)) + continue; - if (key->expiry && now.tv_sec >= key->expiry) - continue; + if (key->expiry && now.tv_sec >= key->expiry) + continue; + } /* keys that don't match */ if (!match(key, description)) @@ -399,6 +407,9 @@ descend: cred, KEY_SEARCH) < 0) continue; + if (no_state_check) + goto found; + /* we set a different error code if we pass a negative key */ if (kflags & (1 << KEY_FLAG_NEGATIVE)) { err = key->type_data.reject_error; @@ -478,7 +489,7 @@ key_ref_t keyring_search(key_ref_t keyring, return ERR_PTR(-ENOKEY); return keyring_search_aux(keyring, current->cred, - type, description, type->match); + type, description, type->match, false); } EXPORT_SYMBOL(keyring_search); diff --git a/security/keys/proc.c b/security/keys/proc.c index 525cf8a29cdd..49bbc97943ad 100644 --- a/security/keys/proc.c +++ b/security/keys/proc.c @@ -199,7 +199,7 @@ static int proc_keys_show(struct seq_file *m, void *v) if (key->perm & KEY_POS_VIEW) { skey_ref = search_my_process_keyrings(key->type, key, lookup_user_key_possessed, - cred); + true, cred); if (!IS_ERR(skey_ref)) { key_ref_put(skey_ref); key_ref = make_key_ref(key, 1); diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c index 930634e45149..6c0480db8885 100644 --- a/security/keys/process_keys.c +++ b/security/keys/process_keys.c @@ -331,6 +331,7 @@ void key_fsgid_changed(struct task_struct *tsk) key_ref_t search_my_process_keyrings(struct key_type *type, const void *description, key_match_func_t match, + bool no_state_check, const struct cred *cred) { key_ref_t key_ref, ret, err; @@ -350,7 +351,7 @@ key_ref_t search_my_process_keyrings(struct key_type *type, if (cred->thread_keyring) { key_ref = keyring_search_aux( make_key_ref(cred->thread_keyring, 1), - cred, type, description, match); + cred, type, description, match, no_state_check); if (!IS_ERR(key_ref)) goto found; @@ -371,7 +372,7 @@ key_ref_t search_my_process_keyrings(struct key_type *type, if (cred->tgcred->process_keyring) { key_ref = keyring_search_aux( make_key_ref(cred->tgcred->process_keyring, 1), - cred, type, description, match); + cred, type, description, match, no_state_check); if (!IS_ERR(key_ref)) goto found; @@ -395,7 +396,7 @@ key_ref_t search_my_process_keyrings(struct key_type *type, make_key_ref(rcu_dereference( cred->tgcred->session_keyring), 1), - cred, type, description, match); + cred, type, description, match, no_state_check); rcu_read_unlock(); if (!IS_ERR(key_ref)) @@ -417,7 +418,7 @@ key_ref_t search_my_process_keyrings(struct key_type *type, else if (cred->user->session_keyring) { key_ref = keyring_search_aux( make_key_ref(cred->user->session_keyring, 1), - cred, type, description, match); + cred, type, description, match, no_state_check); if (!IS_ERR(key_ref)) goto found; @@ -459,7 +460,8 @@ key_ref_t search_process_keyrings(struct key_type *type, might_sleep(); - key_ref = search_my_process_keyrings(type, description, match, cred); + key_ref = search_my_process_keyrings(type, description, match, + false, cred); if (!IS_ERR(key_ref)) goto found; err = key_ref; diff --git a/security/keys/request_key.c b/security/keys/request_key.c index df3c0417ee40..b18a71745901 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c @@ -530,8 +530,7 @@ struct key *request_key_and_link(struct key_type *type, dest_keyring, flags); /* search all the process keyrings for a key */ - key_ref = search_process_keyrings(type, description, type->match, - cred); + key_ref = search_process_keyrings(type, description, type->match, cred); if (!IS_ERR(key_ref)) { key = key_ref_to_ptr(key_ref); diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c index 68164031a74e..f6337c9082eb 100644 --- a/security/keys/request_key_auth.c +++ b/security/keys/request_key_auth.c @@ -59,7 +59,8 @@ static void request_key_auth_describe(const struct key *key, seq_puts(m, "key:"); seq_puts(m, key->description); - seq_printf(m, " pid:%d ci:%zu", rka->pid, rka->callout_len); + if (key_is_instantiated(key)) + seq_printf(m, " pid:%d ci:%zu", rka->pid, rka->callout_len); } /* diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c index c6ca8662a468..63bb1aaffc0a 100644 --- a/security/keys/user_defined.c +++ b/security/keys/user_defined.c @@ -169,8 +169,8 @@ EXPORT_SYMBOL_GPL(user_destroy); void user_describe(const struct key *key, struct seq_file *m) { seq_puts(m, key->description); - - seq_printf(m, ": %u", key->datalen); + if (key_is_instantiated(key)) + seq_printf(m, ": %u", key->datalen); } EXPORT_SYMBOL_GPL(user_describe); -- cgit From 09e10d7fe509408d15818db6a0299f563668a7ba Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 16 Mar 2011 22:57:47 +0000 Subject: ASoC: Add WM8958 VSS support With appropriate firmware the WM8958 can support Virtual Surround Sound or VSS, widening the stereo audio image for improved user experience. Enable support for this mode of operation when the appropriate firmware can be loaded at runtime. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- include/linux/mfd/wm8994/pdata.h | 34 ++++ sound/soc/codecs/wm8958-dsp2.c | 363 ++++++++++++++++++++++++++++++++++++++- sound/soc/codecs/wm8994.c | 2 + sound/soc/codecs/wm8994.h | 14 ++ 4 files changed, 405 insertions(+), 8 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h index 466b1c777aff..c72174aff1fe 100644 --- a/include/linux/mfd/wm8994/pdata.h +++ b/include/linux/mfd/wm8994/pdata.h @@ -32,6 +32,9 @@ struct wm8994_ldo_pdata { #define WM8994_EQ_REGS 20 #define WM8958_MBC_CUTOFF_REGS 20 #define WM8958_MBC_COEFF_REGS 48 +#define WM8958_MBC_COMBINED_REGS 56 +#define WM8958_VSS_HPF_REGS 2 +#define WM8958_VSS_REGS 148 /** * DRC configurations are specified with a label and a set of register @@ -71,6 +74,31 @@ struct wm8958_mbc_cfg { const char *name; u16 cutoff_regs[WM8958_MBC_CUTOFF_REGS]; u16 coeff_regs[WM8958_MBC_COEFF_REGS]; + + /* Coefficient layout when using MBC+VSS firmware */ + u16 combined_regs[WM8958_MBC_COMBINED_REGS]; +}; + +/** + * VSS HPF configurations are specified with a label and two values to + * write. Configurations are expected to be generated using the + * multiband compressor configuration panel in WISCE - see + * http://www.wolfsonmicro.com/wisce/ + */ +struct wm8958_vss_hpf_cfg { + const char *name; + u16 regs[WM8958_VSS_HPF_REGS]; +}; + +/** + * VSS configurations are specified with a label and array of values + * to write. Configurations are expected to be generated using the + * multiband compressor configuration panel in WISCE - see + * http://www.wolfsonmicro.com/wisce/ + */ +struct wm8958_vss_cfg { + const char *name; + u16 regs[WM8958_VSS_REGS]; }; struct wm8994_pdata { @@ -95,6 +123,12 @@ struct wm8994_pdata { int num_mbc_cfgs; struct wm8958_mbc_cfg *mbc_cfgs; + int num_vss_cfgs; + struct wm8958_vss_cfg *vss_cfgs; + + int num_vss_hpf_cfgs; + struct wm8958_vss_hpf_cfg *vss_hpf_cfgs; + /* LINEOUT can be differential or single ended */ unsigned int lineout1_diff:1; unsigned int lineout2_diff:1; diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c index 9c1cbe5b61ae..d0e257315d97 100644 --- a/sound/soc/codecs/wm8958-dsp2.c +++ b/sound/soc/codecs/wm8958-dsp2.c @@ -233,6 +233,68 @@ static void wm8958_dsp_start_mbc(struct snd_soc_codec *codec, int path) WM8958_MBC_ENA); } +static void wm8958_dsp_start_vss(struct snd_soc_codec *codec, int path) +{ + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + struct wm8994_pdata *pdata = wm8994->pdata; + int i, ena; + + if (wm8994->mbc_vss) + wm8958_dsp2_fw(codec, "MBC+VSS", wm8994->mbc_vss, false); + + snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM, + WM8958_DSP2_ENA, WM8958_DSP2_ENA); + + /* If we've got user supplied settings use them */ + if (pdata && pdata->num_mbc_cfgs) { + struct wm8958_mbc_cfg *cfg + = &pdata->mbc_cfgs[wm8994->mbc_cfg]; + + for (i = 0; i < ARRAY_SIZE(cfg->combined_regs); i++) + snd_soc_write(codec, i + 0x2800, + cfg->combined_regs[i]); + } + + if (pdata && pdata->num_vss_cfgs) { + struct wm8958_vss_cfg *cfg + = &pdata->vss_cfgs[wm8994->vss_cfg]; + + for (i = 0; i < ARRAY_SIZE(cfg->regs); i++) + snd_soc_write(codec, i + 0x2600, cfg->regs[i]); + } + + if (pdata && pdata->num_vss_hpf_cfgs) { + struct wm8958_vss_hpf_cfg *cfg + = &pdata->vss_hpf_cfgs[wm8994->vss_hpf_cfg]; + + for (i = 0; i < ARRAY_SIZE(cfg->regs); i++) + snd_soc_write(codec, i + 0x2400, cfg->regs[i]); + } + + /* Run the DSP */ + snd_soc_write(codec, WM8958_DSP2_EXECCONTROL, + WM8958_DSP2_RUNR); + + /* Enable the algorithms we've selected */ + ena = 0; + if (wm8994->mbc_ena[path]) + ena |= 0x8; + if (wm8994->hpf2_ena[path]) + ena |= 0x4; + if (wm8994->hpf1_ena[path]) + ena |= 0x2; + if (wm8994->vss_ena[path]) + ena |= 0x1; + + snd_soc_write(codec, 0x2201, ena); + + /* Switch the DSP into the data path */ + snd_soc_update_bits(codec, WM8958_DSP2_CONFIG, + WM8958_MBC_SEL_MASK | WM8958_MBC_ENA, + path << WM8958_MBC_SEL_SHIFT | WM8958_MBC_ENA); +} + + static void wm8958_dsp_apply(struct snd_soc_codec *codec, int path, int start) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); @@ -258,7 +320,8 @@ static void wm8958_dsp_apply(struct snd_soc_codec *codec, int path, int start) } /* Do we have both an active AIF and an active algorithm? */ - ena = wm8994->mbc_ena[path]; + ena = wm8994->mbc_ena[path] || wm8994->vss_ena[path] || + wm8994->hpf1_ena[path] || wm8994->hpf2_ena[path]; if (!pwr_reg) ena = 0; @@ -281,11 +344,18 @@ static void wm8958_dsp_apply(struct snd_soc_codec *codec, int path, int start) aif << WM8958_DSP2CLK_SRC_SHIFT | WM8958_DSP2CLK_ENA); - if (wm8994->mbc_ena[path]) + if (wm8994->vss_ena[path] || wm8994->hpf1_ena[path] || + wm8994->hpf2_ena[path]) + wm8958_dsp_start_vss(codec, path); + else if (wm8994->mbc_ena[path]) wm8958_dsp_start_mbc(codec, path); - dev_dbg(codec->dev, "DSP running\n"); - } else { + wm8994->dsp_active = path; + + dev_dbg(codec->dev, "DSP running in path %d\n", path); + } + + if (!start && wm8994->dsp_active == path) { /* If the DSP is already stopped then noop */ if (!(reg & WM8958_DSP2_ENA)) return; @@ -335,7 +405,8 @@ static int wm8958_dsp2_busy(struct wm8994_priv *wm8994, int aif) for (i = 0; i < ARRAY_SIZE(wm8994->mbc_ena); i++) { if (i == aif) continue; - if (wm8994->mbc_ena[i]) + if (wm8994->mbc_ena[i] || wm8994->vss_ena[i] || + wm8994->hpf1_ena[i] || wm8994->hpf2_ena[i]) return 1; } @@ -426,22 +497,239 @@ static int wm8958_mbc_put(struct snd_kcontrol *kcontrol, .get = wm8958_mbc_get, .put = wm8958_mbc_put, \ .private_value = xval } +static int wm8958_put_vss_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + struct wm8994_pdata *pdata = wm8994->pdata; + int value = ucontrol->value.integer.value[0]; + int reg; + + /* Don't allow on the fly reconfiguration */ + reg = snd_soc_read(codec, WM8994_CLOCKING_1); + if (reg < 0 || reg & WM8958_DSP2CLK_ENA) + return -EBUSY; + + if (value >= pdata->num_vss_cfgs) + return -EINVAL; + + wm8994->vss_cfg = value; + + return 0; +} + +static int wm8958_get_vss_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.enumerated.item[0] = wm8994->vss_cfg; + + return 0; +} + +static int wm8958_put_vss_hpf_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + struct wm8994_pdata *pdata = wm8994->pdata; + int value = ucontrol->value.integer.value[0]; + int reg; + + /* Don't allow on the fly reconfiguration */ + reg = snd_soc_read(codec, WM8994_CLOCKING_1); + if (reg < 0 || reg & WM8958_DSP2CLK_ENA) + return -EBUSY; + + if (value >= pdata->num_vss_hpf_cfgs) + return -EINVAL; + + wm8994->vss_hpf_cfg = value; + + return 0; +} + +static int wm8958_get_vss_hpf_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.enumerated.item[0] = wm8994->vss_hpf_cfg; + + return 0; +} + +static int wm8958_vss_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + return 0; +} + +static int wm8958_vss_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int vss = kcontrol->private_value; + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = wm8994->vss_ena[vss]; + + return 0; +} + +static int wm8958_vss_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int vss = kcontrol->private_value; + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + if (ucontrol->value.integer.value[0] > 1) + return -EINVAL; + + if (!wm8994->mbc_vss) + return -ENODEV; + + if (wm8958_dsp2_busy(wm8994, vss)) { + dev_dbg(codec->dev, "DSP2 active on %d already\n", vss); + return -EBUSY; + } + + wm8994->vss_ena[vss] = ucontrol->value.integer.value[0]; + + wm8958_dsp_apply(codec, vss, wm8994->vss_ena[vss]); + + return 0; +} + + +#define WM8958_VSS_SWITCH(xname, xval) {\ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\ + .info = wm8958_vss_info, \ + .get = wm8958_vss_get, .put = wm8958_vss_put, \ + .private_value = xval } + +static int wm8958_hpf_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + return 0; +} + +static int wm8958_hpf_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int hpf = kcontrol->private_value; + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + if (hpf < 3) + ucontrol->value.integer.value[0] = wm8994->hpf1_ena[hpf % 3]; + else + ucontrol->value.integer.value[0] = wm8994->hpf2_ena[hpf % 3]; + + return 0; +} + +static int wm8958_hpf_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int hpf = kcontrol->private_value; + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + if (ucontrol->value.integer.value[0] > 1) + return -EINVAL; + + if (!wm8994->mbc_vss) + return -ENODEV; + + if (wm8958_dsp2_busy(wm8994, hpf % 3)) { + dev_dbg(codec->dev, "DSP2 active on %d already\n", hpf); + return -EBUSY; + } + + if (wm8994->eq[hpf % 3]) + return -EBUSY; + + if (hpf < 3) + wm8994->hpf1_ena[hpf % 3] = ucontrol->value.integer.value[0]; + else + wm8994->hpf2_ena[hpf % 3] = ucontrol->value.integer.value[0]; + + wm8958_dsp_apply(codec, hpf % 3, ucontrol->value.integer.value[0]); + + return 0; +} + +#define WM8958_HPF_SWITCH(xname, xval) {\ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\ + .info = wm8958_hpf_info, \ + .get = wm8958_hpf_get, .put = wm8958_hpf_put, \ + .private_value = xval } + static const struct snd_kcontrol_new wm8958_mbc_snd_controls[] = { WM8958_MBC_SWITCH("AIF1DAC1 MBC Switch", 0), WM8958_MBC_SWITCH("AIF1DAC2 MBC Switch", 1), WM8958_MBC_SWITCH("AIF2DAC MBC Switch", 2), }; -static void wm8958_mbc_loaded(const struct firmware *fw, void *context) +static const struct snd_kcontrol_new wm8958_vss_snd_controls[] = { +WM8958_VSS_SWITCH("AIF1DAC1 VSS Switch", 0), +WM8958_VSS_SWITCH("AIF1DAC2 VSS Switch", 1), +WM8958_VSS_SWITCH("AIF2DAC VSS Switch", 2), +WM8958_HPF_SWITCH("AIF1DAC1 HPF1 Switch", 0), +WM8958_HPF_SWITCH("AIF1DAC2 HPF1 Switch", 1), +WM8958_HPF_SWITCH("AIF2DAC HPF1 Switch", 2), +WM8958_HPF_SWITCH("AIF1DAC1 HPF2 Switch", 3), +WM8958_HPF_SWITCH("AIF1DAC2 HPF2 Switch", 4), +WM8958_HPF_SWITCH("AIF2DAC HPF2 Switch", 5), +}; + +static void wm8958_mbc_vss_loaded(const struct firmware *fw, void *context) { struct snd_soc_codec *codec = context; struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - if (fw && wm8958_dsp2_fw(codec, "MBC", fw, true) != 0) { + if (fw && (wm8958_dsp2_fw(codec, "MBC+VSS", fw, true) == 0)) { mutex_lock(&codec->mutex); - wm8994->mbc = fw; + wm8994->mbc_vss = fw; mutex_unlock(&codec->mutex); } + +} + +static void wm8958_mbc_loaded(const struct firmware *fw, void *context) +{ + struct snd_soc_codec *codec = context; + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + if (wm8958_dsp2_fw(codec, "MBC", fw, true) != 0) + return; + + mutex_lock(&codec->mutex); + wm8994->mbc = fw; + mutex_unlock(&codec->mutex); + + /* We can't have more than one request outstanding at once so + * we daisy chain. + */ + request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, + "wm8958_mbc_vss.wfw", codec->dev, GFP_KERNEL, + codec, wm8958_mbc_vss_loaded); } void wm8958_dsp2_init(struct snd_soc_codec *codec) @@ -454,6 +742,9 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) snd_soc_add_controls(codec, wm8958_mbc_snd_controls, ARRAY_SIZE(wm8958_mbc_snd_controls)); + snd_soc_add_controls(codec, wm8958_vss_snd_controls, + ARRAY_SIZE(wm8958_vss_snd_controls)); + /* We don't *require* firmware and don't want to delay boot */ request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, @@ -491,5 +782,61 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) "Failed to add MBC mode controls: %d\n", ret); } + if (pdata->num_vss_cfgs) { + struct snd_kcontrol_new control[] = { + SOC_ENUM_EXT("VSS Mode", wm8994->vss_enum, + wm8958_get_vss_enum, wm8958_put_vss_enum), + }; + /* We need an array of texts for the enum API */ + wm8994->vss_texts = kmalloc(sizeof(char *) + * pdata->num_vss_cfgs, GFP_KERNEL); + if (!wm8994->vss_texts) { + dev_err(wm8994->codec->dev, + "Failed to allocate %d VSS config texts\n", + pdata->num_vss_cfgs); + return; + } + + for (i = 0; i < pdata->num_vss_cfgs; i++) + wm8994->vss_texts[i] = pdata->vss_cfgs[i].name; + + wm8994->vss_enum.max = pdata->num_vss_cfgs; + wm8994->vss_enum.texts = wm8994->vss_texts; + + ret = snd_soc_add_controls(wm8994->codec, control, 1); + if (ret != 0) + dev_err(wm8994->codec->dev, + "Failed to add VSS mode controls: %d\n", ret); + } + + if (pdata->num_vss_hpf_cfgs) { + struct snd_kcontrol_new control[] = { + SOC_ENUM_EXT("VSS HPF Mode", wm8994->vss_hpf_enum, + wm8958_get_vss_hpf_enum, + wm8958_put_vss_hpf_enum), + }; + + /* We need an array of texts for the enum API */ + wm8994->vss_hpf_texts = kmalloc(sizeof(char *) + * pdata->num_vss_hpf_cfgs, GFP_KERNEL); + if (!wm8994->vss_hpf_texts) { + dev_err(wm8994->codec->dev, + "Failed to allocate %d VSS HPF config texts\n", + pdata->num_vss_hpf_cfgs); + return; + } + + for (i = 0; i < pdata->num_vss_hpf_cfgs; i++) + wm8994->vss_hpf_texts[i] = pdata->vss_hpf_cfgs[i].name; + + wm8994->vss_hpf_enum.max = pdata->num_vss_hpf_cfgs; + wm8994->vss_hpf_enum.texts = wm8994->vss_hpf_texts; + + ret = snd_soc_add_controls(wm8994->codec, control, 1); + if (ret != 0) + dev_err(wm8994->codec->dev, + "Failed to add VSS HPFmode controls: %d\n", + ret); + } } diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index f622ff691b41..01ef5704091e 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -3140,6 +3140,8 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec) } if (wm8994->mbc) release_firmware(wm8994->mbc); + if (wm8994->mbc_vss) + release_firmware(wm8994->mbc_vss); kfree(wm8994->retune_mobile_texts); kfree(wm8994->drc_texts); kfree(wm8994); diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h index a4bfde83065f..f337f3d50590 100644 --- a/sound/soc/codecs/wm8994.h +++ b/sound/soc/codecs/wm8994.h @@ -84,6 +84,9 @@ struct wm8994_priv { int lrclk_shared[2]; int mbc_ena[3]; + int hpf1_ena[3]; + int hpf2_ena[3]; + int vss_ena[3]; /* Platform dependant DRC configuration */ const char **drc_texts; @@ -101,6 +104,16 @@ struct wm8994_priv { const char **mbc_texts; struct soc_enum mbc_enum; + /* Platform dependant VSS configuration */ + int vss_cfg; + const char **vss_texts; + struct soc_enum vss_enum; + + /* Platform dependant VSS HPF configuration */ + int vss_hpf_cfg; + const char **vss_hpf_texts; + struct soc_enum vss_hpf_enum; + struct wm8994_micdet micdet[2]; wm8958_micdet_cb jack_cb; @@ -119,6 +132,7 @@ struct wm8994_priv { int dsp_active; const struct firmware *cur_fw; const struct firmware *mbc; + const struct firmware *mbc_vss; }; #endif -- cgit From 312158718fe2056703b2744801165a9574560495 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 17 Mar 2011 20:23:43 +0000 Subject: ASoC: Add WM8958 enhanced EQ support DSP2 in the WM8958 can be used to support an upgraded EQ for use in demanding applications. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- include/linux/mfd/wm8994/pdata.h | 15 +++ sound/soc/codecs/wm8958-dsp2.c | 192 ++++++++++++++++++++++++++++++++++++++- sound/soc/codecs/wm8994.c | 2 + sound/soc/codecs/wm8994.h | 7 ++ 4 files changed, 213 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h index c72174aff1fe..d12f8d635a81 100644 --- a/include/linux/mfd/wm8994/pdata.h +++ b/include/linux/mfd/wm8994/pdata.h @@ -35,6 +35,7 @@ struct wm8994_ldo_pdata { #define WM8958_MBC_COMBINED_REGS 56 #define WM8958_VSS_HPF_REGS 2 #define WM8958_VSS_REGS 148 +#define WM8958_ENH_EQ_REGS 32 /** * DRC configurations are specified with a label and a set of register @@ -101,6 +102,17 @@ struct wm8958_vss_cfg { u16 regs[WM8958_VSS_REGS]; }; +/** + * Enhanced EQ configurations are specified with a label and array of + * values to write. Configurations are expected to be generated using + * the multiband compressor configuration panel in WISCE - see + * http://www.wolfsonmicro.com/wisce/ + */ +struct wm8958_enh_eq_cfg { + const char *name; + u16 regs[WM8958_ENH_EQ_REGS]; +}; + struct wm8994_pdata { int gpio_base; @@ -129,6 +141,9 @@ struct wm8994_pdata { int num_vss_hpf_cfgs; struct wm8958_vss_hpf_cfg *vss_hpf_cfgs; + int num_enh_eq_cfgs; + struct wm8958_enh_eq_cfg *enh_eq_cfgs; + /* LINEOUT can be differential or single ended */ unsigned int lineout1_diff:1; unsigned int lineout2_diff:1; diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c index d0e257315d97..74983ee2b87f 100644 --- a/sound/soc/codecs/wm8958-dsp2.c +++ b/sound/soc/codecs/wm8958-dsp2.c @@ -294,6 +294,36 @@ static void wm8958_dsp_start_vss(struct snd_soc_codec *codec, int path) path << WM8958_MBC_SEL_SHIFT | WM8958_MBC_ENA); } +static void wm8958_dsp_start_enh_eq(struct snd_soc_codec *codec, int path) +{ + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + struct wm8994_pdata *pdata = wm8994->pdata; + int i; + + wm8958_dsp2_fw(codec, "ENH_EQ", wm8994->enh_eq, false); + + snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM, + WM8958_DSP2_ENA, WM8958_DSP2_ENA); + + /* If we've got user supplied settings use them */ + if (pdata && pdata->num_enh_eq_cfgs) { + struct wm8958_enh_eq_cfg *cfg + = &pdata->enh_eq_cfgs[wm8994->enh_eq_cfg]; + + for (i = 0; i < ARRAY_SIZE(cfg->regs); i++) + snd_soc_write(codec, i + 0x2200, + cfg->regs[i]); + } + + /* Run the DSP */ + snd_soc_write(codec, WM8958_DSP2_EXECCONTROL, + WM8958_DSP2_RUNR); + + /* Switch the DSP into the data path */ + snd_soc_update_bits(codec, WM8958_DSP2_CONFIG, + WM8958_MBC_SEL_MASK | WM8958_MBC_ENA, + path << WM8958_MBC_SEL_SHIFT | WM8958_MBC_ENA); +} static void wm8958_dsp_apply(struct snd_soc_codec *codec, int path, int start) { @@ -321,7 +351,8 @@ static void wm8958_dsp_apply(struct snd_soc_codec *codec, int path, int start) /* Do we have both an active AIF and an active algorithm? */ ena = wm8994->mbc_ena[path] || wm8994->vss_ena[path] || - wm8994->hpf1_ena[path] || wm8994->hpf2_ena[path]; + wm8994->hpf1_ena[path] || wm8994->hpf2_ena[path] || + wm8994->enh_eq_ena[path]; if (!pwr_reg) ena = 0; @@ -344,7 +375,9 @@ static void wm8958_dsp_apply(struct snd_soc_codec *codec, int path, int start) aif << WM8958_DSP2CLK_SRC_SHIFT | WM8958_DSP2CLK_ENA); - if (wm8994->vss_ena[path] || wm8994->hpf1_ena[path] || + if (wm8994->enh_eq_ena[path]) + wm8958_dsp_start_enh_eq(codec, path); + else if (wm8994->vss_ena[path] || wm8994->hpf1_ena[path] || wm8994->hpf2_ena[path]) wm8958_dsp_start_vss(codec, path); else if (wm8994->mbc_ena[path]) @@ -483,6 +516,9 @@ static int wm8958_mbc_put(struct snd_kcontrol *kcontrol, return -EBUSY; } + if (wm8994->enh_eq_ena[mbc]) + return -EBUSY; + wm8994->mbc_ena[mbc] = ucontrol->value.integer.value[0]; wm8958_dsp_apply(codec, mbc, wm8994->mbc_ena[mbc]); @@ -603,6 +639,9 @@ static int wm8958_vss_put(struct snd_kcontrol *kcontrol, return -EBUSY; } + if (wm8994->enh_eq_ena[vss]) + return -EBUSY; + wm8994->vss_ena[vss] = ucontrol->value.integer.value[0]; wm8958_dsp_apply(codec, vss, wm8994->vss_ena[vss]); @@ -661,7 +700,7 @@ static int wm8958_hpf_put(struct snd_kcontrol *kcontrol, return -EBUSY; } - if (wm8994->eq[hpf % 3]) + if (wm8994->enh_eq_ena[hpf % 3]) return -EBUSY; if (hpf < 3) @@ -681,6 +720,97 @@ static int wm8958_hpf_put(struct snd_kcontrol *kcontrol, .get = wm8958_hpf_get, .put = wm8958_hpf_put, \ .private_value = xval } +static int wm8958_put_enh_eq_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + struct wm8994_pdata *pdata = wm8994->pdata; + int value = ucontrol->value.integer.value[0]; + int reg; + + /* Don't allow on the fly reconfiguration */ + reg = snd_soc_read(codec, WM8994_CLOCKING_1); + if (reg < 0 || reg & WM8958_DSP2CLK_ENA) + return -EBUSY; + + if (value >= pdata->num_enh_eq_cfgs) + return -EINVAL; + + wm8994->enh_eq_cfg = value; + + return 0; +} + +static int wm8958_get_enh_eq_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.enumerated.item[0] = wm8994->enh_eq_cfg; + + return 0; +} + +static int wm8958_enh_eq_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + return 0; +} + +static int wm8958_enh_eq_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int eq = kcontrol->private_value; + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = wm8994->enh_eq_ena[eq]; + + return 0; +} + +static int wm8958_enh_eq_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int eq = kcontrol->private_value; + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + if (ucontrol->value.integer.value[0] > 1) + return -EINVAL; + + if (!wm8994->enh_eq) + return -ENODEV; + + if (wm8958_dsp2_busy(wm8994, eq)) { + dev_dbg(codec->dev, "DSP2 active on %d already\n", eq); + return -EBUSY; + } + + if (wm8994->mbc_ena[eq] || wm8994->vss_ena[eq] || + wm8994->hpf1_ena[eq] || wm8994->hpf2_ena[eq]) + return -EBUSY; + + wm8994->enh_eq_ena[eq] = ucontrol->value.integer.value[0]; + + wm8958_dsp_apply(codec, eq, ucontrol->value.integer.value[0]); + + return 0; +} + +#define WM8958_ENH_EQ_SWITCH(xname, xval) {\ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\ + .info = wm8958_enh_eq_info, \ + .get = wm8958_enh_eq_get, .put = wm8958_enh_eq_put, \ + .private_value = xval } + static const struct snd_kcontrol_new wm8958_mbc_snd_controls[] = { WM8958_MBC_SWITCH("AIF1DAC1 MBC Switch", 0), WM8958_MBC_SWITCH("AIF1DAC2 MBC Switch", 1), @@ -699,6 +829,24 @@ WM8958_HPF_SWITCH("AIF1DAC2 HPF2 Switch", 4), WM8958_HPF_SWITCH("AIF2DAC HPF2 Switch", 5), }; +static const struct snd_kcontrol_new wm8958_enh_eq_snd_controls[] = { +WM8958_ENH_EQ_SWITCH("AIF1DAC1 Enhanced EQ Switch", 0), +WM8958_ENH_EQ_SWITCH("AIF1DAC2 Enhanced EQ Switch", 1), +WM8958_ENH_EQ_SWITCH("AIF2DAC Enhanced EQ Switch", 2), +}; + +static void wm8958_enh_eq_loaded(const struct firmware *fw, void *context) +{ + struct snd_soc_codec *codec = context; + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + if (fw && (wm8958_dsp2_fw(codec, "ENH_EQ", fw, true) == 0)) { + mutex_lock(&codec->mutex); + wm8994->enh_eq = fw; + mutex_unlock(&codec->mutex); + } +} + static void wm8958_mbc_vss_loaded(const struct firmware *fw, void *context) { struct snd_soc_codec *codec = context; @@ -710,6 +858,12 @@ static void wm8958_mbc_vss_loaded(const struct firmware *fw, void *context) mutex_unlock(&codec->mutex); } + /* We can't have more than one request outstanding at once so + * we daisy chain. + */ + request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, + "wm8958_enh_eq.wfw", codec->dev, GFP_KERNEL, + codec, wm8958_enh_eq_loaded); } static void wm8958_mbc_loaded(const struct firmware *fw, void *context) @@ -744,6 +898,8 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) ARRAY_SIZE(wm8958_mbc_snd_controls)); snd_soc_add_controls(codec, wm8958_vss_snd_controls, ARRAY_SIZE(wm8958_vss_snd_controls)); + snd_soc_add_controls(codec, wm8958_enh_eq_snd_controls, + ARRAY_SIZE(wm8958_enh_eq_snd_controls)); /* We don't *require* firmware and don't want to delay boot */ @@ -839,4 +995,34 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) "Failed to add VSS HPFmode controls: %d\n", ret); } + + if (pdata->num_enh_eq_cfgs) { + struct snd_kcontrol_new control[] = { + SOC_ENUM_EXT("Enhanced EQ Mode", wm8994->enh_eq_enum, + wm8958_get_enh_eq_enum, + wm8958_put_enh_eq_enum), + }; + + /* We need an array of texts for the enum API */ + wm8994->enh_eq_texts = kmalloc(sizeof(char *) + * pdata->num_enh_eq_cfgs, GFP_KERNEL); + if (!wm8994->enh_eq_texts) { + dev_err(wm8994->codec->dev, + "Failed to allocate %d enhanced EQ config texts\n", + pdata->num_enh_eq_cfgs); + return; + } + + for (i = 0; i < pdata->num_enh_eq_cfgs; i++) + wm8994->enh_eq_texts[i] = pdata->enh_eq_cfgs[i].name; + + wm8994->enh_eq_enum.max = pdata->num_enh_eq_cfgs; + wm8994->enh_eq_enum.texts = wm8994->enh_eq_texts; + + ret = snd_soc_add_controls(wm8994->codec, control, 1); + if (ret != 0) + dev_err(wm8994->codec->dev, + "Failed to add enhanced EQ controls: %d\n", + ret); + } } diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 01ef5704091e..03ef62462bab 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -3142,6 +3142,8 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec) release_firmware(wm8994->mbc); if (wm8994->mbc_vss) release_firmware(wm8994->mbc_vss); + if (wm8994->enh_eq) + release_firmware(wm8994->enh_eq); kfree(wm8994->retune_mobile_texts); kfree(wm8994->drc_texts); kfree(wm8994); diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h index f337f3d50590..0a1db04b73bd 100644 --- a/sound/soc/codecs/wm8994.h +++ b/sound/soc/codecs/wm8994.h @@ -87,6 +87,7 @@ struct wm8994_priv { int hpf1_ena[3]; int hpf2_ena[3]; int vss_ena[3]; + int enh_eq_ena[3]; /* Platform dependant DRC configuration */ const char **drc_texts; @@ -114,6 +115,11 @@ struct wm8994_priv { const char **vss_hpf_texts; struct soc_enum vss_hpf_enum; + /* Platform dependant enhanced EQ configuration */ + int enh_eq_cfg; + const char **enh_eq_texts; + struct soc_enum enh_eq_enum; + struct wm8994_micdet micdet[2]; wm8958_micdet_cb jack_cb; @@ -133,6 +139,7 @@ struct wm8994_priv { const struct firmware *cur_fw; const struct firmware *mbc; const struct firmware *mbc_vss; + const struct firmware *enh_eq; }; #endif -- cgit From edf2ed153bcae52de70db00a98b0e81a5668e563 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 23 Mar 2011 10:37:00 +0100 Subject: ptrace: Kill tracehook_notify_jctl() tracehook_notify_jctl() aids in determining whether and what to report to the parent when a task is stopped or continued. The function also adds an extra requirement that siglock may be released across it, which is currently unused and quite difficult to satisfy in well-defined manner. As job control and the notifications are about to receive major overhaul, remove the tracehook and open code it. If ever necessary, let's factor it out after the overhaul. * Oleg spotted incorrect CLD_CONTINUED/STOPPED selection when ptraced. Fixed. Signed-off-by: Tejun Heo Cc: Oleg Nesterov Cc: Roland McGrath --- include/linux/tracehook.h | 27 --------------------------- kernel/signal.c | 34 ++++++++++++++-------------------- 2 files changed, 14 insertions(+), 47 deletions(-) (limited to 'include/linux') diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h index 3a2e66d88a32..b073f3c8adc3 100644 --- a/include/linux/tracehook.h +++ b/include/linux/tracehook.h @@ -468,33 +468,6 @@ static inline int tracehook_get_signal(struct task_struct *task, return 0; } -/** - * tracehook_notify_jctl - report about job control stop/continue - * @notify: zero, %CLD_STOPPED or %CLD_CONTINUED - * @why: %CLD_STOPPED or %CLD_CONTINUED - * - * This is called when we might call do_notify_parent_cldstop(). - * - * @notify is zero if we would not ordinarily send a %SIGCHLD, - * or is the %CLD_STOPPED or %CLD_CONTINUED .si_code for %SIGCHLD. - * - * @why is %CLD_STOPPED when about to stop for job control; - * we are already in %TASK_STOPPED state, about to call schedule(). - * It might also be that we have just exited (check %PF_EXITING), - * but need to report that a group-wide stop is complete. - * - * @why is %CLD_CONTINUED when waking up after job control stop and - * ready to make a delayed @notify report. - * - * Return the %CLD_* value for %SIGCHLD, or zero to generate no signal. - * - * Called with the siglock held. - */ -static inline int tracehook_notify_jctl(int notify, int why) -{ - return notify ?: (current->ptrace & PT_PTRACED) ? why : 0; -} - /** * tracehook_finish_jctl - report about return from job control stop * diff --git a/kernel/signal.c b/kernel/signal.c index f4db76986ec1..03d874e1058f 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1727,7 +1727,7 @@ void ptrace_notify(int exit_code) static int do_signal_stop(int signr) { struct signal_struct *sig = current->signal; - int notify; + int notify = 0; if (!sig->group_stop_count) { struct task_struct *t; @@ -1759,19 +1759,16 @@ static int do_signal_stop(int signr) * a group stop in progress and we are the last to stop, report * to the parent. When ptraced, every thread reports itself. */ - notify = sig->group_stop_count == 1 ? CLD_STOPPED : 0; - notify = tracehook_notify_jctl(notify, CLD_STOPPED); - /* - * tracehook_notify_jctl() can drop and reacquire siglock, so - * we keep ->group_stop_count != 0 before the call. If SIGCONT - * or SIGKILL comes in between ->group_stop_count == 0. - */ - if (sig->group_stop_count) { - if (!--sig->group_stop_count) - sig->flags = SIGNAL_STOP_STOPPED; - current->exit_code = sig->group_exit_code; - __set_current_state(TASK_STOPPED); + if (!--sig->group_stop_count) { + sig->flags = SIGNAL_STOP_STOPPED; + notify = CLD_STOPPED; } + if (task_ptrace(current)) + notify = CLD_STOPPED; + + current->exit_code = sig->group_exit_code; + __set_current_state(TASK_STOPPED); + spin_unlock_irq(¤t->sighand->siglock); if (notify) { @@ -1860,14 +1857,11 @@ relock: signal->flags &= ~SIGNAL_CLD_MASK; - why = tracehook_notify_jctl(why, CLD_CONTINUED); spin_unlock_irq(&sighand->siglock); - if (why) { - read_lock(&tasklist_lock); - do_notify_parent_cldstop(current->group_leader, why); - read_unlock(&tasklist_lock); - } + read_lock(&tasklist_lock); + do_notify_parent_cldstop(current->group_leader, why); + read_unlock(&tasklist_lock); goto relock; } @@ -2034,7 +2028,7 @@ void exit_signals(struct task_struct *tsk) if (unlikely(tsk->signal->group_stop_count) && !--tsk->signal->group_stop_count) { tsk->signal->flags = SIGNAL_STOP_STOPPED; - group_stop = tracehook_notify_jctl(CLD_STOPPED, CLD_STOPPED); + group_stop = CLD_STOPPED; } out: spin_unlock_irq(&tsk->sighand->siglock); -- cgit From e5c1902e9260a0075ea52cb5ef627a8d9aaede89 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 23 Mar 2011 10:37:00 +0100 Subject: signal: Fix premature completion of group stop when interfered by ptrace task->signal->group_stop_count is used to track the progress of group stop. It's initialized to the number of tasks which need to stop for group stop to finish and each stopping or trapping task decrements. However, each task doesn't keep track of whether it decremented the counter or not and if woken up before the group stop is complete and stops again, it can decrement the counter multiple times. Please consider the following example code. static void *worker(void *arg) { while (1) ; return NULL; } int main(void) { pthread_t thread; pid_t pid; int i; pid = fork(); if (!pid) { for (i = 0; i < 5; i++) pthread_create(&thread, NULL, worker, NULL); while (1) ; return 0; } ptrace(PTRACE_ATTACH, pid, NULL, NULL); while (1) { waitid(P_PID, pid, NULL, WSTOPPED); ptrace(PTRACE_SINGLESTEP, pid, NULL, (void *)(long)SIGSTOP); } return 0; } The child creates five threads and the parent continuously traps the first thread and whenever the child gets a signal, SIGSTOP is delivered. If an external process sends SIGSTOP to the child, all other threads in the process should reliably stop. However, due to the above bug, the first thread will often end up consuming group_stop_count multiple times and SIGSTOP often ends up stopping none or part of the other four threads. This patch adds a new field task->group_stop which is protected by siglock and uses GROUP_STOP_CONSUME flag to track which task is still to consume group_stop_count to fix this bug. task_clear_group_stop_pending() and task_participate_group_stop() are added to help manipulating group stop states. As ptrace_stop() now also uses task_participate_group_stop(), it will set SIGNAL_STOP_STOPPED if it completes a group stop. There still are many issues regarding the interaction between group stop and ptrace. Patches to address them will follow. - Oleg spotted duplicate GROUP_STOP_CONSUME. Dropped. Signed-off-by: Tejun Heo Acked-by: Oleg Nesterov Cc: Roland McGrath --- include/linux/sched.h | 6 +++++ kernel/signal.c | 62 ++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 60 insertions(+), 8 deletions(-) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index 4b601be3dace..85f51042c2b8 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1260,6 +1260,7 @@ struct task_struct { int exit_state; int exit_code, exit_signal; int pdeath_signal; /* The signal sent when the parent dies */ + unsigned int group_stop; /* GROUP_STOP_*, siglock protected */ /* ??? */ unsigned int personality; unsigned did_exec:1; @@ -1771,6 +1772,11 @@ extern void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t * #define tsk_used_math(p) ((p)->flags & PF_USED_MATH) #define used_math() tsk_used_math(current) +/* + * task->group_stop flags + */ +#define GROUP_STOP_CONSUME (1 << 17) /* consume group stop count */ + #ifdef CONFIG_PREEMPT_RCU #define RCU_READ_UNLOCK_BLOCKED (1 << 0) /* blocked while in RCU read-side. */ diff --git a/kernel/signal.c b/kernel/signal.c index 95ac42dc3bcb..ecb20089eaff 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -223,6 +223,52 @@ static inline void print_dropped_signal(int sig) current->comm, current->pid, sig); } +/** + * task_clear_group_stop_pending - clear pending group stop + * @task: target task + * + * Clear group stop states for @task. + * + * CONTEXT: + * Must be called with @task->sighand->siglock held. + */ +static void task_clear_group_stop_pending(struct task_struct *task) +{ + task->group_stop &= ~GROUP_STOP_CONSUME; +} + +/** + * task_participate_group_stop - participate in a group stop + * @task: task participating in a group stop + * + * @task is participating in a group stop. Group stop states are cleared + * and the group stop count is consumed if %GROUP_STOP_CONSUME was set. If + * the consumption completes the group stop, the appropriate %SIGNAL_* + * flags are set. + * + * CONTEXT: + * Must be called with @task->sighand->siglock held. + */ +static bool task_participate_group_stop(struct task_struct *task) +{ + struct signal_struct *sig = task->signal; + bool consume = task->group_stop & GROUP_STOP_CONSUME; + + task_clear_group_stop_pending(task); + + if (!consume) + return false; + + if (!WARN_ON_ONCE(sig->group_stop_count == 0)) + sig->group_stop_count--; + + if (!sig->group_stop_count) { + sig->flags = SIGNAL_STOP_STOPPED; + return true; + } + return false; +} + /* * allocate a new signal queue record * - this may be called without locks if and only if t == current, otherwise an @@ -1645,7 +1691,7 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info) * we must participate in the bookkeeping. */ if (current->signal->group_stop_count > 0) - --current->signal->group_stop_count; + task_participate_group_stop(current); current->last_siginfo = info; current->exit_code = exit_code; @@ -1730,6 +1776,7 @@ static int do_signal_stop(int signr) int notify = 0; if (!sig->group_stop_count) { + unsigned int gstop = GROUP_STOP_CONSUME; struct task_struct *t; if (!likely(sig->flags & SIGNAL_STOP_DEQUEUED) || @@ -1741,6 +1788,7 @@ static int do_signal_stop(int signr) */ sig->group_exit_code = signr; + current->group_stop = gstop; sig->group_stop_count = 1; for (t = next_thread(current); t != current; t = next_thread(t)) /* @@ -1750,19 +1798,19 @@ static int do_signal_stop(int signr) */ if (!(t->flags & PF_EXITING) && !task_is_stopped_or_traced(t)) { + t->group_stop = gstop; sig->group_stop_count++; signal_wake_up(t, 0); - } + } else + task_clear_group_stop_pending(t); } /* * If there are no other threads in the group, or if there is * a group stop in progress and we are the last to stop, report * to the parent. When ptraced, every thread reports itself. */ - if (!--sig->group_stop_count) { - sig->flags = SIGNAL_STOP_STOPPED; + if (task_participate_group_stop(current)) notify = CLD_STOPPED; - } if (task_ptrace(current)) notify = CLD_STOPPED; @@ -2026,10 +2074,8 @@ void exit_signals(struct task_struct *tsk) recalc_sigpending_and_wake(t); if (unlikely(tsk->signal->group_stop_count) && - !--tsk->signal->group_stop_count) { - tsk->signal->flags = SIGNAL_STOP_STOPPED; + task_participate_group_stop(tsk)) group_stop = CLD_STOPPED; - } out: spin_unlock_irq(&tsk->sighand->siglock); -- cgit From 39efa3ef3a376a4e53de2f82fc91182459d34200 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 23 Mar 2011 10:37:00 +0100 Subject: signal: Use GROUP_STOP_PENDING to stop once for a single group stop Currently task->signal->group_stop_count is used to decide whether to stop for group stop. However, if there is a task in the group which is taking a long time to stop, other tasks which are continued by ptrace would repeatedly stop for the same group stop until the group stop is complete. Conversely, if a ptraced task is in TASK_TRACED state, the debugger won't get notified of group stops which is inconsistent compared to the ptraced task in any other state. This patch introduces GROUP_STOP_PENDING which tracks whether a task is yet to stop for the group stop in progress. The flag is set when a group stop starts and cleared when the task stops the first time for the group stop, and consulted whenever whether the task should participate in a group stop needs to be determined. Note that now tasks in TASK_TRACED also participate in group stop. This results in the following behavior changes. * For a single group stop, a ptracer would see at most one stop reported. * A ptracee in TASK_TRACED now also participates in group stop and the tracer would get the notification. However, as a ptraced task could be in TASK_STOPPED state or any ptrace trap could consume group stop, the notification may still be missing. These will be addressed with further patches. * A ptracee may start a group stop while one is still in progress if the tracer let it continue with stop signal delivery. Group stop code handles this correctly. Oleg: * Spotted that a task might skip signal check even when its GROUP_STOP_PENDING is set. Fixed by updating recalc_sigpending_tsk() to check GROUP_STOP_PENDING instead of group_stop_count. * Pointed out that task->group_stop should be cleared whenever task->signal->group_stop_count is cleared. Fixed accordingly. * Pointed out the behavior inconsistency between TASK_TRACED and RUNNING and the last behavior change. Signed-off-by: Tejun Heo Acked-by: Oleg Nesterov Cc: Roland McGrath --- fs/exec.c | 1 + include/linux/sched.h | 3 +++ kernel/signal.c | 36 +++++++++++++++++++++--------------- 3 files changed, 25 insertions(+), 15 deletions(-) (limited to 'include/linux') diff --git a/fs/exec.c b/fs/exec.c index 5e62d26a4fec..8328beb9016f 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1659,6 +1659,7 @@ static int zap_process(struct task_struct *start, int exit_code) t = start; do { + task_clear_group_stop_pending(t); if (t != current && t->mm) { sigaddset(&t->pending.signal, SIGKILL); signal_wake_up(t, 1); diff --git a/include/linux/sched.h b/include/linux/sched.h index 85f51042c2b8..b2a17dfbdbad 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1775,8 +1775,11 @@ extern void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t * /* * task->group_stop flags */ +#define GROUP_STOP_PENDING (1 << 16) /* task should stop for group stop */ #define GROUP_STOP_CONSUME (1 << 17) /* consume group stop count */ +extern void task_clear_group_stop_pending(struct task_struct *task); + #ifdef CONFIG_PREEMPT_RCU #define RCU_READ_UNLOCK_BLOCKED (1 << 0) /* blocked while in RCU read-side. */ diff --git a/kernel/signal.c b/kernel/signal.c index ecb20089eaff..a2e7a6527d24 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -124,7 +124,7 @@ static inline int has_pending_signals(sigset_t *signal, sigset_t *blocked) static int recalc_sigpending_tsk(struct task_struct *t) { - if (t->signal->group_stop_count > 0 || + if ((t->group_stop & GROUP_STOP_PENDING) || PENDING(&t->pending, &t->blocked) || PENDING(&t->signal->shared_pending, &t->blocked)) { set_tsk_thread_flag(t, TIF_SIGPENDING); @@ -232,19 +232,19 @@ static inline void print_dropped_signal(int sig) * CONTEXT: * Must be called with @task->sighand->siglock held. */ -static void task_clear_group_stop_pending(struct task_struct *task) +void task_clear_group_stop_pending(struct task_struct *task) { - task->group_stop &= ~GROUP_STOP_CONSUME; + task->group_stop &= ~(GROUP_STOP_PENDING | GROUP_STOP_CONSUME); } /** * task_participate_group_stop - participate in a group stop * @task: task participating in a group stop * - * @task is participating in a group stop. Group stop states are cleared - * and the group stop count is consumed if %GROUP_STOP_CONSUME was set. If - * the consumption completes the group stop, the appropriate %SIGNAL_* - * flags are set. + * @task has GROUP_STOP_PENDING set and is participating in a group stop. + * Group stop states are cleared and the group stop count is consumed if + * %GROUP_STOP_CONSUME was set. If the consumption completes the group + * stop, the appropriate %SIGNAL_* flags are set. * * CONTEXT: * Must be called with @task->sighand->siglock held. @@ -254,6 +254,8 @@ static bool task_participate_group_stop(struct task_struct *task) struct signal_struct *sig = task->signal; bool consume = task->group_stop & GROUP_STOP_CONSUME; + WARN_ON_ONCE(!(task->group_stop & GROUP_STOP_PENDING)); + task_clear_group_stop_pending(task); if (!consume) @@ -765,6 +767,9 @@ static int prepare_signal(int sig, struct task_struct *p, int from_ancestor_ns) t = p; do { unsigned int state; + + task_clear_group_stop_pending(t); + rm_from_queue(SIG_KERNEL_STOP_MASK, &t->pending); /* * If there is a handler for SIGCONT, we must make @@ -906,6 +911,7 @@ static void complete_signal(int sig, struct task_struct *p, int group) signal->group_stop_count = 0; t = p; do { + task_clear_group_stop_pending(t); sigaddset(&t->pending.signal, SIGKILL); signal_wake_up(t, 1); } while_each_thread(p, t); @@ -1139,6 +1145,7 @@ int zap_other_threads(struct task_struct *p) p->signal->group_stop_count = 0; while_each_thread(p, t) { + task_clear_group_stop_pending(t); count++; /* Don't bother with already dead threads */ @@ -1690,7 +1697,7 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info) * If there is a group stop in progress, * we must participate in the bookkeeping. */ - if (current->signal->group_stop_count > 0) + if (current->group_stop & GROUP_STOP_PENDING) task_participate_group_stop(current); current->last_siginfo = info; @@ -1775,8 +1782,8 @@ static int do_signal_stop(int signr) struct signal_struct *sig = current->signal; int notify = 0; - if (!sig->group_stop_count) { - unsigned int gstop = GROUP_STOP_CONSUME; + if (!(current->group_stop & GROUP_STOP_PENDING)) { + unsigned int gstop = GROUP_STOP_PENDING | GROUP_STOP_CONSUME; struct task_struct *t; if (!likely(sig->flags & SIGNAL_STOP_DEQUEUED) || @@ -1796,8 +1803,7 @@ static int do_signal_stop(int signr) * stop is always done with the siglock held, * so this check has no races. */ - if (!(t->flags & PF_EXITING) && - !task_is_stopped_or_traced(t)) { + if (!(t->flags & PF_EXITING) && !task_is_stopped(t)) { t->group_stop = gstop; sig->group_stop_count++; signal_wake_up(t, 0); @@ -1926,8 +1932,8 @@ relock: if (unlikely(signr != 0)) ka = return_ka; else { - if (unlikely(signal->group_stop_count > 0) && - do_signal_stop(0)) + if (unlikely(current->group_stop & + GROUP_STOP_PENDING) && do_signal_stop(0)) goto relock; signr = dequeue_signal(current, ¤t->blocked, @@ -2073,7 +2079,7 @@ void exit_signals(struct task_struct *tsk) if (!signal_pending(t) && !(t->flags & PF_EXITING)) recalc_sigpending_and_wake(t); - if (unlikely(tsk->signal->group_stop_count) && + if (unlikely(tsk->group_stop & GROUP_STOP_PENDING) && task_participate_group_stop(tsk)) group_stop = CLD_STOPPED; out: -- cgit From d79fdd6d96f46fabb779d86332e3677c6f5c2a4f Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 23 Mar 2011 10:37:00 +0100 Subject: ptrace: Clean transitions between TASK_STOPPED and TRACED Currently, if the task is STOPPED on ptrace attach, it's left alone and the state is silently changed to TRACED on the next ptrace call. The behavior breaks the assumption that arch_ptrace_stop() is called before any task is poked by ptrace and is ugly in that a task manipulates the state of another task directly. With GROUP_STOP_PENDING, the transitions between TASK_STOPPED and TRACED can be made clean. The tracer can use the flag to tell the tracee to retry stop on attach and detach. On retry, the tracee will enter the desired state in the correct way. The lower 16bits of task->group_stop is used to remember the signal number which caused the last group stop. This is used while retrying for ptrace attach as the original group_exit_code could have been consumed with wait(2) by then. As the real parent may wait(2) and consume the group_exit_code anytime, the group_exit_code needs to be saved separately so that it can be used when switching from regular sleep to ptrace_stop(). This is recorded in the lower 16bits of task->group_stop. If a task is already stopped and there's no intervening SIGCONT, a ptrace request immediately following a successful PTRACE_ATTACH should always succeed even if the tracer doesn't wait(2) for attach completion; however, with this change, the tracee might still be TASK_RUNNING trying to enter TASK_TRACED which would cause the following request to fail with -ESRCH. This intermediate state is hidden from the ptracer by setting GROUP_STOP_TRAPPING on attach and making ptrace_check_attach() wait for it to clear on its signal->wait_chldexit. Completing the transition or getting killed clears TRAPPING and wakes up the tracer. Note that the STOPPED -> RUNNING -> TRACED transition is still visible to other threads which are in the same group as the ptracer and the reverse transition is visible to all. Please read the comments for details. Oleg: * Spotted a race condition where a task may retry group stop without proper bookkeeping. Fixed by redoing bookkeeping on retry. * Spotted that the transition is visible to userland in several different ways. Most are fixed with GROUP_STOP_TRAPPING. Unhandled corner case is documented. * Pointed out not setting GROUP_STOP_SIGMASK on an already stopped task would result in more consistent behavior. * Pointed out that calling ptrace_stop() from do_signal_stop() in TASK_STOPPED can race with group stop start logic and then confuse the TRAPPING wait in ptrace_check_attach(). ptrace_stop() is now called with TASK_RUNNING. * Suggested using signal->wait_chldexit instead of bit wait. * Spotted a race condition between TRACED transition and clearing of TRAPPING. Signed-off-by: Tejun Heo Acked-by: Oleg Nesterov Cc: Roland McGrath Cc: Jan Kratochvil --- include/linux/sched.h | 2 ++ kernel/ptrace.c | 49 ++++++++++++++++++++++++++++---- kernel/signal.c | 79 ++++++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 112 insertions(+), 18 deletions(-) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index b2a17dfbdbad..456d80ed3b78 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1775,8 +1775,10 @@ extern void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t * /* * task->group_stop flags */ +#define GROUP_STOP_SIGMASK 0xffff /* signr of the last group stop */ #define GROUP_STOP_PENDING (1 << 16) /* task should stop for group stop */ #define GROUP_STOP_CONSUME (1 << 17) /* consume group stop count */ +#define GROUP_STOP_TRAPPING (1 << 18) /* switching from STOPPED to TRACED */ extern void task_clear_group_stop_pending(struct task_struct *task); diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 6acf8954017c..745fc2dd00c5 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -49,14 +49,22 @@ static void ptrace_untrace(struct task_struct *child) spin_lock(&child->sighand->siglock); if (task_is_traced(child)) { /* - * If the group stop is completed or in progress, - * this thread was already counted as stopped. + * If group stop is completed or in progress, it should + * participate in the group stop. Set GROUP_STOP_PENDING + * before kicking it. + * + * This involves TRACED -> RUNNING -> STOPPED transition + * which is similar to but in the opposite direction of + * what happens while attaching to a stopped task. + * However, in this direction, the intermediate RUNNING + * state is not hidden even from the current ptracer and if + * it immediately re-attaches and performs a WNOHANG + * wait(2), it may fail. */ if (child->signal->flags & SIGNAL_STOP_STOPPED || child->signal->group_stop_count) - __set_task_state(child, TASK_STOPPED); - else - signal_wake_up(child, 1); + child->group_stop |= GROUP_STOP_PENDING; + signal_wake_up(child, 1); } spin_unlock(&child->sighand->siglock); } @@ -165,6 +173,7 @@ bool ptrace_may_access(struct task_struct *task, unsigned int mode) static int ptrace_attach(struct task_struct *task) { + bool wait_trap = false; int retval; audit_ptrace(task); @@ -204,12 +213,42 @@ static int ptrace_attach(struct task_struct *task) __ptrace_link(task, current); send_sig_info(SIGSTOP, SEND_SIG_FORCED, task); + spin_lock(&task->sighand->siglock); + + /* + * If the task is already STOPPED, set GROUP_STOP_PENDING and + * TRAPPING, and kick it so that it transits to TRACED. TRAPPING + * will be cleared if the child completes the transition or any + * event which clears the group stop states happens. We'll wait + * for the transition to complete before returning from this + * function. + * + * This hides STOPPED -> RUNNING -> TRACED transition from the + * attaching thread but a different thread in the same group can + * still observe the transient RUNNING state. IOW, if another + * thread's WNOHANG wait(2) on the stopped tracee races against + * ATTACH, the wait(2) may fail due to the transient RUNNING. + * + * The following task_is_stopped() test is safe as both transitions + * in and out of STOPPED are protected by siglock. + */ + if (task_is_stopped(task)) { + task->group_stop |= GROUP_STOP_PENDING | GROUP_STOP_TRAPPING; + signal_wake_up(task, 1); + wait_trap = true; + } + + spin_unlock(&task->sighand->siglock); + retval = 0; unlock_tasklist: write_unlock_irq(&tasklist_lock); unlock_creds: mutex_unlock(&task->signal->cred_guard_mutex); out: + if (wait_trap) + wait_event(current->signal->wait_chldexit, + !(task->group_stop & GROUP_STOP_TRAPPING)); return retval; } diff --git a/kernel/signal.c b/kernel/signal.c index 418776c41d24..1e199919ae09 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -223,6 +223,26 @@ static inline void print_dropped_signal(int sig) current->comm, current->pid, sig); } +/** + * task_clear_group_stop_trapping - clear group stop trapping bit + * @task: target task + * + * If GROUP_STOP_TRAPPING is set, a ptracer is waiting for us. Clear it + * and wake up the ptracer. Note that we don't need any further locking. + * @task->siglock guarantees that @task->parent points to the ptracer. + * + * CONTEXT: + * Must be called with @task->sighand->siglock held. + */ +static void task_clear_group_stop_trapping(struct task_struct *task) +{ + if (unlikely(task->group_stop & GROUP_STOP_TRAPPING)) { + task->group_stop &= ~GROUP_STOP_TRAPPING; + __wake_up_sync(&task->parent->signal->wait_chldexit, + TASK_UNINTERRUPTIBLE, 1); + } +} + /** * task_clear_group_stop_pending - clear pending group stop * @task: target task @@ -1706,8 +1726,20 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info) current->last_siginfo = info; current->exit_code = exit_code; - /* Let the debugger run. */ - __set_current_state(TASK_TRACED); + /* + * TRACED should be visible before TRAPPING is cleared; otherwise, + * the tracer might fail do_wait(). + */ + set_current_state(TASK_TRACED); + + /* + * We're committing to trapping. Clearing GROUP_STOP_TRAPPING and + * transition to TASK_TRACED should be atomic with respect to + * siglock. This hsould be done after the arch hook as siglock is + * released and regrabbed across it. + */ + task_clear_group_stop_trapping(current); + spin_unlock_irq(¤t->sighand->siglock); read_lock(&tasklist_lock); if (may_ptrace_stop()) { @@ -1788,6 +1820,9 @@ static int do_signal_stop(int signr) unsigned int gstop = GROUP_STOP_PENDING | GROUP_STOP_CONSUME; struct task_struct *t; + /* signr will be recorded in task->group_stop for retries */ + WARN_ON_ONCE(signr & ~GROUP_STOP_SIGMASK); + if (!likely(sig->flags & SIGNAL_STOP_DEQUEUED) || unlikely(signal_group_exit(sig))) return 0; @@ -1797,25 +1832,27 @@ static int do_signal_stop(int signr) */ sig->group_exit_code = signr; - current->group_stop = gstop; + current->group_stop &= ~GROUP_STOP_SIGMASK; + current->group_stop |= signr | gstop; sig->group_stop_count = 1; - for (t = next_thread(current); t != current; t = next_thread(t)) + for (t = next_thread(current); t != current; + t = next_thread(t)) { + t->group_stop &= ~GROUP_STOP_SIGMASK; /* * Setting state to TASK_STOPPED for a group * stop is always done with the siglock held, * so this check has no races. */ if (!(t->flags & PF_EXITING) && !task_is_stopped(t)) { - t->group_stop = gstop; + t->group_stop |= signr | gstop; sig->group_stop_count++; signal_wake_up(t, 0); - } else + } else { task_clear_group_stop_pending(t); + } + } } - - current->exit_code = sig->group_exit_code; - __set_current_state(TASK_STOPPED); - +retry: if (likely(!task_ptrace(current))) { int notify = 0; @@ -1827,6 +1864,7 @@ static int do_signal_stop(int signr) if (task_participate_group_stop(current)) notify = CLD_STOPPED; + __set_current_state(TASK_STOPPED); spin_unlock_irq(¤t->sighand->siglock); if (notify) { @@ -1839,13 +1877,28 @@ static int do_signal_stop(int signr) schedule(); spin_lock_irq(¤t->sighand->siglock); - } else - ptrace_stop(current->exit_code, CLD_STOPPED, 0, NULL); + } else { + ptrace_stop(current->group_stop & GROUP_STOP_SIGMASK, + CLD_STOPPED, 0, NULL); + current->exit_code = 0; + } + + /* + * GROUP_STOP_PENDING could be set if another group stop has + * started since being woken up or ptrace wants us to transit + * between TASK_STOPPED and TRACED. Retry group stop. + */ + if (current->group_stop & GROUP_STOP_PENDING) { + WARN_ON_ONCE(!(current->group_stop & GROUP_STOP_SIGMASK)); + goto retry; + } + + /* PTRACE_ATTACH might have raced with task killing, clear trapping */ + task_clear_group_stop_trapping(current); spin_unlock_irq(¤t->sighand->siglock); tracehook_finish_jctl(); - current->exit_code = 0; return 1; } -- cgit From 8323c3aa74cd92465350294567142d12ffdcc963 Mon Sep 17 00:00:00 2001 From: Tommi Virtanen Date: Fri, 25 Mar 2011 16:32:57 -0700 Subject: ceph: Move secret key parsing earlier. This makes the base64 logic be contained in mount option parsing, and prepares us for replacing the homebew key management with the kernel key retention service. Signed-off-by: Tommi Virtanen Signed-off-by: Sage Weil --- fs/ceph/super.c | 2 +- include/linux/ceph/auth.h | 4 ++-- include/linux/ceph/libceph.h | 2 +- net/ceph/auth.c | 8 ++++---- net/ceph/auth_x.c | 8 +++++--- net/ceph/ceph_common.c | 43 ++++++++++++++++++++++++++++++++++++------- net/ceph/crypto.c | 11 +++++++++++ net/ceph/crypto.h | 2 ++ net/ceph/mon_client.c | 2 +- 9 files changed, 63 insertions(+), 19 deletions(-) (limited to 'include/linux') diff --git a/fs/ceph/super.c b/fs/ceph/super.c index a9e78b4a258c..f2f77fd3c14c 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -353,7 +353,7 @@ static int ceph_show_options(struct seq_file *m, struct vfsmount *mnt) if (opt->name) seq_printf(m, ",name=%s", opt->name); - if (opt->secret) + if (opt->key) seq_puts(m, ",secret="); if (opt->mount_timeout != CEPH_MOUNT_TIMEOUT_DEFAULT) diff --git a/include/linux/ceph/auth.h b/include/linux/ceph/auth.h index 7fff521d7eb5..aa13392a7efb 100644 --- a/include/linux/ceph/auth.h +++ b/include/linux/ceph/auth.h @@ -67,12 +67,12 @@ struct ceph_auth_client { bool negotiating; /* true if negotiating protocol */ const char *name; /* entity name */ u64 global_id; /* our unique id in system */ - const char *secret; /* our secret key */ + const struct ceph_crypto_key *key; /* our secret key */ unsigned want_keys; /* which services we want */ }; extern struct ceph_auth_client *ceph_auth_init(const char *name, - const char *secret); + const struct ceph_crypto_key *key); extern void ceph_auth_destroy(struct ceph_auth_client *ac); extern void ceph_auth_reset(struct ceph_auth_client *ac); diff --git a/include/linux/ceph/libceph.h b/include/linux/ceph/libceph.h index 0d2e0fffb470..6365f041745b 100644 --- a/include/linux/ceph/libceph.h +++ b/include/linux/ceph/libceph.h @@ -61,7 +61,7 @@ struct ceph_options { pointer type of args */ int num_mon; char *name; - char *secret; + struct ceph_crypto_key *key; }; /* diff --git a/net/ceph/auth.c b/net/ceph/auth.c index 549c1f43e1d5..b4bf4ac090f1 100644 --- a/net/ceph/auth.c +++ b/net/ceph/auth.c @@ -35,12 +35,12 @@ static int ceph_auth_init_protocol(struct ceph_auth_client *ac, int protocol) /* * setup, teardown. */ -struct ceph_auth_client *ceph_auth_init(const char *name, const char *secret) +struct ceph_auth_client *ceph_auth_init(const char *name, const struct ceph_crypto_key *key) { struct ceph_auth_client *ac; int ret; - dout("auth_init name '%s' secret '%s'\n", name, secret); + dout("auth_init name '%s'\n", name); ret = -ENOMEM; ac = kzalloc(sizeof(*ac), GFP_NOFS); @@ -52,8 +52,8 @@ struct ceph_auth_client *ceph_auth_init(const char *name, const char *secret) ac->name = name; else ac->name = CEPH_AUTH_NAME_DEFAULT; - dout("auth_init name %s secret %s\n", ac->name, secret); - ac->secret = secret; + dout("auth_init name %s\n", ac->name); + ac->key = key; return ac; out: diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c index 7fd5dfcf6e18..1587dc6010c6 100644 --- a/net/ceph/auth_x.c +++ b/net/ceph/auth_x.c @@ -662,14 +662,16 @@ int ceph_x_init(struct ceph_auth_client *ac) goto out; ret = -EINVAL; - if (!ac->secret) { + if (!ac->key) { pr_err("no secret set (for auth_x protocol)\n"); goto out_nomem; } - ret = ceph_crypto_key_unarmor(&xi->secret, ac->secret); - if (ret) + ret = ceph_crypto_key_clone(&xi->secret, ac->key); + if (ret < 0) { + pr_err("cannot clone key: %d\n", ret); goto out_nomem; + } xi->starting = true; xi->ticket_handlers = RB_ROOT; diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c index 9bbb356b12e7..02e084f29d24 100644 --- a/net/ceph/ceph_common.c +++ b/net/ceph/ceph_common.c @@ -20,6 +20,7 @@ #include #include #include +#include "crypto.h" @@ -117,9 +118,29 @@ int ceph_compare_options(struct ceph_options *new_opt, if (ret) return ret; - ret = strcmp_null(opt1->secret, opt2->secret); - if (ret) - return ret; + if (opt1->key && !opt2->key) + return -1; + if (!opt1->key && opt2->key) + return 1; + if (opt1->key && opt2->key) { + if (opt1->key->type != opt2->key->type) + return -1; + if (opt1->key->created.tv_sec != opt2->key->created.tv_sec) + return -1; + if (opt1->key->created.tv_nsec != opt2->key->created.tv_nsec) + return -1; + if (opt1->key->len != opt2->key->len) + return -1; + if (opt1->key->key && !opt2->key->key) + return -1; + if (!opt1->key->key && opt2->key->key) + return 1; + if (opt1->key->key && opt2->key->key) { + ret = memcmp(opt1->key->key, opt2->key->key, opt1->key->len); + if (ret) + return ret; + } + } /* any matching mon ip implies a match */ for (i = 0; i < opt1->num_mon; i++) { @@ -203,7 +224,10 @@ void ceph_destroy_options(struct ceph_options *opt) { dout("destroy_options %p\n", opt); kfree(opt->name); - kfree(opt->secret); + if (opt->key) { + ceph_crypto_key_destroy(opt->key); + kfree(opt->key); + } kfree(opt); } EXPORT_SYMBOL(ceph_destroy_options); @@ -295,9 +319,14 @@ int ceph_parse_options(struct ceph_options **popt, char *options, GFP_KERNEL); break; case Opt_secret: - opt->secret = kstrndup(argstr[0].from, - argstr[0].to-argstr[0].from, - GFP_KERNEL); + opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL); + if (!opt->key) { + err = -ENOMEM; + goto out; + } + err = ceph_crypto_key_unarmor(opt->key, argstr[0].from); + if (err < 0) + goto out; break; /* misc */ diff --git a/net/ceph/crypto.c b/net/ceph/crypto.c index 7b505b0c983f..75f0893fa11f 100644 --- a/net/ceph/crypto.c +++ b/net/ceph/crypto.c @@ -9,6 +9,17 @@ #include #include "crypto.h" +int ceph_crypto_key_clone(struct ceph_crypto_key *dst, + const struct ceph_crypto_key *src) +{ + memcpy(dst, src, sizeof(struct ceph_crypto_key)); + dst->key = kmalloc(src->len, GFP_NOFS); + if (!dst->key) + return -ENOMEM; + memcpy(dst->key, src->key, src->len); + return 0; +} + int ceph_crypto_key_encode(struct ceph_crypto_key *key, void **p, void *end) { if (*p + sizeof(u16) + sizeof(key->created) + diff --git a/net/ceph/crypto.h b/net/ceph/crypto.h index f9eccace592b..6cf6edc91ec4 100644 --- a/net/ceph/crypto.h +++ b/net/ceph/crypto.h @@ -19,6 +19,8 @@ static inline void ceph_crypto_key_destroy(struct ceph_crypto_key *key) kfree(key->key); } +extern int ceph_crypto_key_clone(struct ceph_crypto_key *dst, + const struct ceph_crypto_key *src); extern int ceph_crypto_key_encode(struct ceph_crypto_key *key, void **p, void *end); extern int ceph_crypto_key_decode(struct ceph_crypto_key *key, diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c index 8a079399174a..cbe31fa45508 100644 --- a/net/ceph/mon_client.c +++ b/net/ceph/mon_client.c @@ -759,7 +759,7 @@ int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl) /* authentication */ monc->auth = ceph_auth_init(cl->options->name, - cl->options->secret); + cl->options->key); if (IS_ERR(monc->auth)) return PTR_ERR(monc->auth); monc->auth->want_keys = -- cgit From 380a26be7d5af83f3831c3b6697031dffbb1c8f3 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Mar 2011 00:35:34 +0200 Subject: genirq: Remove now obsolete set_irq_wake() Missed that one in the big compat remval patch Signed-off-by: Thomas Gleixner --- include/linux/interrupt.h | 8 -------- 1 file changed, 8 deletions(-) (limited to 'include/linux') diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 59b72ca1c5d1..943c9b53695c 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -338,14 +338,6 @@ static inline void enable_irq_lockdep_irqrestore(unsigned int irq, unsigned long /* IRQ wakeup (PM) control: */ extern int irq_set_irq_wake(unsigned int irq, unsigned int on); -#ifndef CONFIG_GENERIC_HARDIRQS_NO_COMPAT -/* Please do not use: Use the replacement functions instead */ -static inline int set_irq_wake(unsigned int irq, unsigned int on) -{ - return irq_set_irq_wake(irq, on); -} -#endif - static inline int enable_irq_wake(unsigned int irq) { return irq_set_irq_wake(irq, 1); -- cgit From 28959f268f910b2cd1c25e838b63c342062e28f2 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Mar 2011 00:37:41 +0200 Subject: genirq: Remove obsolete comment Signed-off-by: Thomas Gleixner --- include/linux/irq.h | 7 ------- 1 file changed, 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/irq.h b/include/linux/irq.h index 2a375a72ce3c..09a308072f56 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -64,13 +64,6 @@ typedef void (*irq_preflow_handler_t)(struct irq_data *data); * IRQ_NO_BALANCING - Interrupt cannot be balanced (affinity set) * IRQ_MOVE_PCNTXT - Interrupt can be migrated from process context * IRQ_NESTED_TRHEAD - Interrupt nests into another thread - * - * Deprecated bits. They are kept updated as long as - * CONFIG_GENERIC_HARDIRQS_NO_COMPAT is not set. Will go away soon. These bits - * are internal state of the core code and if you really need to acces - * them then talk to the genirq maintainer instead of hacking - * something weird. - * */ enum { IRQ_TYPE_NONE = 0x00000000, -- cgit From f6d5b33125c4fa63c16f7f54c533338c9695d82c Mon Sep 17 00:00:00 2001 From: John Stultz Date: Tue, 29 Mar 2011 18:00:27 -0700 Subject: RTC: Fix early irqs caused by calling rtc_set_alarm too early When we register an rtc device at boot, we read the alarm value in hardware and set the rtc device's aie_timer to that value. The initial method to do this was to simply call rtc_set_alarm() with the value read from hardware. However, this may cause problems as rtc_set_alarm may enable interupts, and the RTC alarm might fire, which can cause invalid pointer dereferencing since the RTC registration is not complete. This patch solves the issue by initializing the rtc_device.aie_timer y hand via rtc_initialize_alarm(). This avoids any calls to the RTC hardware which might enable interrupts too early. CC: Thomas Gleixner CC: Alessandro Zummo Reported-by: Konrad Rzeszutek Wilk Tested-by: Konrad Rzeszutek Wilk Signed-off-by: John Stultz --- drivers/rtc/class.c | 2 +- drivers/rtc/interface.c | 26 ++++++++++++++++++++++++++ include/linux/rtc.h | 2 ++ 3 files changed, 29 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 09b4437b3e61..39013867cbd6 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c @@ -171,7 +171,7 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev, err = __rtc_read_alarm(rtc, &alrm); if (!err && !rtc_valid_tm(&alrm.time)) - rtc_set_alarm(rtc, &alrm); + rtc_initialize_alarm(rtc, &alrm); strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE); dev_set_name(&rtc->dev, "rtc%d", id); diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 8ec6b069a7f5..b2fea80dfb65 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -375,6 +375,32 @@ int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) } EXPORT_SYMBOL_GPL(rtc_set_alarm); +/* Called once per device from rtc_device_register */ +int rtc_initialize_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) +{ + int err; + + err = rtc_valid_tm(&alarm->time); + if (err != 0) + return err; + + err = mutex_lock_interruptible(&rtc->ops_lock); + if (err) + return err; + + rtc->aie_timer.node.expires = rtc_tm_to_ktime(alarm->time); + rtc->aie_timer.period = ktime_set(0, 0); + if (alarm->enabled) { + rtc->aie_timer.enabled = 1; + timerqueue_add(&rtc->timerqueue, &rtc->aie_timer.node); + } + mutex_unlock(&rtc->ops_lock); + return err; +} +EXPORT_SYMBOL_GPL(rtc_initialize_alarm); + + + int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled) { int err = mutex_lock_interruptible(&rtc->ops_lock); diff --git a/include/linux/rtc.h b/include/linux/rtc.h index 2ca7e8a78060..877ece45426f 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -228,6 +228,8 @@ extern int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alrm); extern int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alrm); +extern int rtc_initialize_alarm(struct rtc_device *rtc, + struct rtc_wkalrm *alrm); extern void rtc_update_irq(struct rtc_device *rtc, unsigned long num, unsigned long events); -- cgit From eec009548e98f6b6d514ff5bb8a8627b8dd17a49 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 29 Mar 2011 23:34:08 -0700 Subject: net: Fix warnings caused by MAX_SKB_FRAGS change. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After commit a715dea3c8e9ef2771c534e05ee1d36f65987e64 ("net: Always allocate at least 16 skb frags regardless of page size"), the value of MAX_SKB_FRAGS can now take on either an "unsigned long" or an "int" value. This causes warnings like: net/packet/af_packet.c: In function ‘tpacket_fill_skb’: net/packet/af_packet.c:948: warning: format ‘%lu’ expects type ‘long unsigned int’, but argument 2 has type ‘int’ Fix by forcing the constant to be unsigned long, otherwise we have a situation where the type of a system wide constant is variable. Signed-off-by: David S. Miller --- include/linux/skbuff.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 239083bfea13..d9e52fa2416d 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -126,7 +126,7 @@ struct sk_buff; * GRO uses frags we allocate at least 16 regardless of page size. */ #if (65536/PAGE_SIZE + 2) < 16 -#define MAX_SKB_FRAGS 16 +#define MAX_SKB_FRAGS 16UL #else #define MAX_SKB_FRAGS (65536/PAGE_SIZE + 2) #endif -- cgit From 7a635ea989991d7f12d57a12f2ba7cb6d211e083 Mon Sep 17 00:00:00 2001 From: Andrzej Zaborowski Date: Mon, 28 Mar 2011 12:56:33 +0000 Subject: net/usb: Ethernet quirks for the LG-VL600 4G modem This adds a driver for the CDC Ethernet part of this modem. The device's ID is blacklisted in cdc_ether.c and is white-listed in this new driver because of the quirks needed to make it useful. The modem's firmware exposes a CDC ACM port for modem control and a CDC Ethernet port for network data. The descriptors look fine but both ports actually are some sort of multiplexers requiring non- standard headers added/removed from every packet or they get ignored. All information is based on a usb traffic log from a Windows machine. On the Verizon 4G network I've seen speeds up to 1.1MB/s so far with this driver, a speed-o-meter site reports 16.2Mbps/10.5Mbps. Userspace scripts are required to talk to the CDC ACM port. Signed-off-by: Andrzej Zaborowski Signed-off-by: David S. Miller --- drivers/net/usb/Kconfig | 15 ++ drivers/net/usb/Makefile | 1 + drivers/net/usb/cdc_ether.c | 21 ++- drivers/net/usb/lg-vl600.c | 346 ++++++++++++++++++++++++++++++++++++++++++++ drivers/net/usb/usbnet.c | 10 +- include/linux/usb/usbnet.h | 3 + 6 files changed, 387 insertions(+), 9 deletions(-) create mode 100644 drivers/net/usb/lg-vl600.c (limited to 'include/linux') diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index 6f600cced6e1..3ec22c307797 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -433,4 +433,19 @@ config USB_SIERRA_NET To compile this driver as a module, choose M here: the module will be called sierra_net. +config USB_VL600 + tristate "LG VL600 modem dongle" + depends on USB_NET_CDCETHER + select USB_ACM + help + Select this if you want to use an LG Electronics 4G/LTE usb modem + called VL600. This driver only handles the ethernet + interface exposed by the modem firmware. To establish a connection + you will first need a userspace program that sends the right + command to the modem through its CDC ACM port, and most + likely also a DHCP client. See this thread about using the + 4G modem from Verizon: + + http://ubuntuforums.org/showpost.php?p=10589647&postcount=17 + endmenu diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile index cac170301187..c7ec8a5f0a90 100644 --- a/drivers/net/usb/Makefile +++ b/drivers/net/usb/Makefile @@ -27,4 +27,5 @@ obj-$(CONFIG_USB_IPHETH) += ipheth.o obj-$(CONFIG_USB_SIERRA_NET) += sierra_net.o obj-$(CONFIG_USB_NET_CX82310_ETH) += cx82310_eth.o obj-$(CONFIG_USB_NET_CDC_NCM) += cdc_ncm.o +obj-$(CONFIG_USB_VL600) += lg-vl600.o diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 9a60e415d76b..51c259b69278 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -378,7 +378,7 @@ static void dumpspeed(struct usbnet *dev, __le32 *speeds) __le32_to_cpu(speeds[1]) / 1000); } -static void cdc_status(struct usbnet *dev, struct urb *urb) +void usbnet_cdc_status(struct usbnet *dev, struct urb *urb) { struct usb_cdc_notification *event; @@ -418,8 +418,9 @@ static void cdc_status(struct usbnet *dev, struct urb *urb) break; } } +EXPORT_SYMBOL_GPL(usbnet_cdc_status); -static int cdc_bind(struct usbnet *dev, struct usb_interface *intf) +int usbnet_cdc_bind(struct usbnet *dev, struct usb_interface *intf) { int status; struct cdc_state *info = (void *) &dev->data; @@ -441,6 +442,7 @@ static int cdc_bind(struct usbnet *dev, struct usb_interface *intf) */ return 0; } +EXPORT_SYMBOL_GPL(usbnet_cdc_bind); static int cdc_manage_power(struct usbnet *dev, int on) { @@ -452,18 +454,18 @@ static const struct driver_info cdc_info = { .description = "CDC Ethernet Device", .flags = FLAG_ETHER, // .check_connect = cdc_check_connect, - .bind = cdc_bind, + .bind = usbnet_cdc_bind, .unbind = usbnet_cdc_unbind, - .status = cdc_status, + .status = usbnet_cdc_status, .manage_power = cdc_manage_power, }; static const struct driver_info mbm_info = { .description = "Mobile Broadband Network Device", .flags = FLAG_WWAN, - .bind = cdc_bind, + .bind = usbnet_cdc_bind, .unbind = usbnet_cdc_unbind, - .status = cdc_status, + .status = usbnet_cdc_status, .manage_power = cdc_manage_power, }; @@ -560,6 +562,13 @@ static const struct usb_device_id products [] = { .driver_info = 0, }, +/* LG Electronics VL600 wants additional headers on every frame */ +{ + USB_DEVICE_AND_INTERFACE_INFO(0x1004, 0x61aa, USB_CLASS_COMM, + USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), + .driver_info = 0, +}, + /* * WHITELIST!!! * diff --git a/drivers/net/usb/lg-vl600.c b/drivers/net/usb/lg-vl600.c new file mode 100644 index 000000000000..1d83ccfd7277 --- /dev/null +++ b/drivers/net/usb/lg-vl600.c @@ -0,0 +1,346 @@ +/* + * Ethernet interface part of the LG VL600 LTE modem (4G dongle) + * + * Copyright (C) 2011 Intel Corporation + * Author: Andrzej Zaborowski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * The device has a CDC ACM port for modem control (it claims to be + * CDC ACM anyway) and a CDC Ethernet port for actual network data. + * It will however ignore data on both ports that is not encapsulated + * in a specific way, any data returned is also encapsulated the same + * way. The headers don't seem to follow any popular standard. + * + * This driver adds and strips these headers from the ethernet frames + * sent/received from the CDC Ethernet port. The proprietary header + * replaces the standard ethernet header in a packet so only actual + * ethernet frames are allowed. The headers allow some form of + * multiplexing by using non standard values of the .h_proto field. + * Windows/Mac drivers do send a couple of such frames to the device + * during initialisation, with protocol set to 0x0906 or 0x0b06 and (what + * seems to be) a flag in the .dummy_flags. This doesn't seem necessary + * for modem operation but can possibly be used for GPS or other funcitons. + */ + +struct vl600_frame_hdr { + __le32 len; + __le32 serial; + __le32 pkt_cnt; + __le32 dummy_flags; + __le32 dummy; + __le32 magic; +} __attribute__((packed)); + +struct vl600_pkt_hdr { + __le32 dummy[2]; + __le32 len; + __be16 h_proto; +} __attribute__((packed)); + +struct vl600_state { + struct sk_buff *current_rx_buf; +}; + +static int vl600_bind(struct usbnet *dev, struct usb_interface *intf) +{ + int ret; + struct vl600_state *s = kzalloc(sizeof(struct vl600_state), GFP_KERNEL); + + if (!s) + return -ENOMEM; + + ret = usbnet_cdc_bind(dev, intf); + if (ret) { + kfree(s); + return ret; + } + + dev->driver_priv = s; + + /* ARP packets don't go through, but they're also of no use. The + * subnet has only two hosts anyway: us and the gateway / DHCP + * server (probably simulated by modem firmware or network operator) + * whose address changes everytime we connect to the intarwebz and + * who doesn't bother answering ARP requests either. So hardware + * addresses have no meaning, the destination and the source of every + * packet depend only on whether it is on the IN or OUT endpoint. */ + dev->net->flags |= IFF_NOARP; + + return ret; +} + +static void vl600_unbind(struct usbnet *dev, struct usb_interface *intf) +{ + struct vl600_state *s = dev->driver_priv; + + if (s->current_rx_buf) + dev_kfree_skb(s->current_rx_buf); + + kfree(s); + + return usbnet_cdc_unbind(dev, intf); +} + +static int vl600_rx_fixup(struct usbnet *dev, struct sk_buff *skb) +{ + struct vl600_frame_hdr *frame; + struct vl600_pkt_hdr *packet; + struct ethhdr *ethhdr; + int packet_len, count; + struct sk_buff *buf = skb; + struct sk_buff *clone; + struct vl600_state *s = dev->driver_priv; + + /* Frame lengths are generally 4B multiplies but every couple of + * hours there's an odd number of bytes sized yet correct frame, + * so don't require this. */ + + /* Allow a packet (or multiple packets batched together) to be + * split across many frames. We don't allow a new batch to + * begin in the same frame another one is ending however, and no + * leading or trailing pad bytes. */ + if (s->current_rx_buf) { + frame = (struct vl600_frame_hdr *) s->current_rx_buf->data; + if (skb->len + s->current_rx_buf->len > + le32_to_cpup(&frame->len)) { + netif_err(dev, ifup, dev->net, "Fragment too long\n"); + dev->net->stats.rx_length_errors++; + goto error; + } + + buf = s->current_rx_buf; + memcpy(skb_put(buf, skb->len), skb->data, skb->len); + } else if (skb->len < 4) { + netif_err(dev, ifup, dev->net, "Frame too short\n"); + dev->net->stats.rx_length_errors++; + goto error; + } + + frame = (struct vl600_frame_hdr *) buf->data; + /* NOTE: Should check that frame->magic == 0x53544448? + * Otherwise if we receive garbage at the beginning of the frame + * we may end up allocating a huge buffer and saving all the + * future incoming data into it. */ + + if (buf->len < sizeof(*frame) || + buf->len != le32_to_cpup(&frame->len)) { + /* Save this fragment for later assembly */ + if (s->current_rx_buf) + return 0; + + s->current_rx_buf = skb_copy_expand(skb, 0, + le32_to_cpup(&frame->len), GFP_ATOMIC); + if (!s->current_rx_buf) { + netif_err(dev, ifup, dev->net, "Reserving %i bytes " + "for packet assembly failed.\n", + le32_to_cpup(&frame->len)); + dev->net->stats.rx_errors++; + } + + return 0; + } + + count = le32_to_cpup(&frame->pkt_cnt); + + skb_pull(buf, sizeof(*frame)); + + while (count--) { + if (buf->len < sizeof(*packet)) { + netif_err(dev, ifup, dev->net, "Packet too short\n"); + goto error; + } + + packet = (struct vl600_pkt_hdr *) buf->data; + packet_len = sizeof(*packet) + le32_to_cpup(&packet->len); + if (packet_len > buf->len) { + netif_err(dev, ifup, dev->net, + "Bad packet length stored in header\n"); + goto error; + } + + /* Packet header is same size as the ethernet header + * (sizeof(*packet) == sizeof(*ethhdr)), additionally + * the h_proto field is in the same place so we just leave it + * alone and fill in the remaining fields. + */ + ethhdr = (struct ethhdr *) skb->data; + if (be16_to_cpup(ðhdr->h_proto) == ETH_P_ARP && + buf->len > 0x26) { + /* Copy the addresses from packet contents */ + memcpy(ethhdr->h_source, + &buf->data[sizeof(*ethhdr) + 0x8], + ETH_ALEN); + memcpy(ethhdr->h_dest, + &buf->data[sizeof(*ethhdr) + 0x12], + ETH_ALEN); + } else { + memset(ethhdr->h_source, 0, ETH_ALEN); + memcpy(ethhdr->h_dest, dev->net->dev_addr, ETH_ALEN); + } + + if (count) { + /* Not the last packet in this batch */ + clone = skb_clone(buf, GFP_ATOMIC); + if (!clone) + goto error; + + skb_trim(clone, packet_len); + usbnet_skb_return(dev, clone); + + skb_pull(buf, (packet_len + 3) & ~3); + } else { + skb_trim(buf, packet_len); + + if (s->current_rx_buf) { + usbnet_skb_return(dev, buf); + s->current_rx_buf = NULL; + return 0; + } + + return 1; + } + } + +error: + if (s->current_rx_buf) { + dev_kfree_skb_any(s->current_rx_buf); + s->current_rx_buf = NULL; + } + dev->net->stats.rx_errors++; + return 0; +} + +static struct sk_buff *vl600_tx_fixup(struct usbnet *dev, + struct sk_buff *skb, gfp_t flags) +{ + struct sk_buff *ret; + struct vl600_frame_hdr *frame; + struct vl600_pkt_hdr *packet; + static uint32_t serial = 1; + int orig_len = skb->len - sizeof(struct ethhdr); + int full_len = (skb->len + sizeof(struct vl600_frame_hdr) + 3) & ~3; + + frame = (struct vl600_frame_hdr *) skb->data; + if (skb->len > sizeof(*frame) && skb->len == le32_to_cpup(&frame->len)) + return skb; /* Already encapsulated? */ + + if (skb->len < sizeof(struct ethhdr)) + /* Drop, device can only deal with ethernet packets */ + return NULL; + + if (!skb_cloned(skb)) { + int headroom = skb_headroom(skb); + int tailroom = skb_tailroom(skb); + + if (tailroom >= full_len - skb->len - sizeof(*frame) && + headroom >= sizeof(*frame)) + /* There's enough head and tail room */ + goto encapsulate; + + if (headroom + tailroom + skb->len >= full_len) { + /* There's enough total room, just readjust */ + skb->data = memmove(skb->head + sizeof(*frame), + skb->data, skb->len); + skb_set_tail_pointer(skb, skb->len); + goto encapsulate; + } + } + + /* Alloc a new skb with the required size */ + ret = skb_copy_expand(skb, sizeof(struct vl600_frame_hdr), full_len - + skb->len - sizeof(struct vl600_frame_hdr), flags); + dev_kfree_skb_any(skb); + if (!ret) + return ret; + skb = ret; + +encapsulate: + /* Packet header is same size as ethernet packet header + * (sizeof(*packet) == sizeof(struct ethhdr)), additionally the + * h_proto field is in the same place so we just leave it alone and + * overwrite the remaining fields. + */ + packet = (struct vl600_pkt_hdr *) skb->data; + memset(&packet->dummy, 0, sizeof(packet->dummy)); + packet->len = cpu_to_le32(orig_len); + + frame = (struct vl600_frame_hdr *) skb_push(skb, sizeof(*frame)); + memset(frame, 0, sizeof(*frame)); + frame->len = cpu_to_le32(full_len); + frame->serial = cpu_to_le32(serial++); + frame->pkt_cnt = cpu_to_le32(1); + + if (skb->len < full_len) /* Pad */ + skb_put(skb, full_len - skb->len); + + return skb; +} + +static const struct driver_info vl600_info = { + .description = "LG VL600 modem", + .flags = FLAG_ETHER | FLAG_RX_ASSEMBLE, + .bind = vl600_bind, + .unbind = vl600_unbind, + .status = usbnet_cdc_status, + .rx_fixup = vl600_rx_fixup, + .tx_fixup = vl600_tx_fixup, +}; + +static const struct usb_device_id products[] = { + { + USB_DEVICE_AND_INTERFACE_INFO(0x1004, 0x61aa, USB_CLASS_COMM, + USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), + .driver_info = (unsigned long) &vl600_info, + }, + {}, /* End */ +}; +MODULE_DEVICE_TABLE(usb, products); + +static struct usb_driver lg_vl600_driver = { + .name = "lg-vl600", + .id_table = products, + .probe = usbnet_probe, + .disconnect = usbnet_disconnect, + .suspend = usbnet_suspend, + .resume = usbnet_resume, +}; + +static int __init vl600_init(void) +{ + return usb_register(&lg_vl600_driver); +} +module_init(vl600_init); + +static void __exit vl600_exit(void) +{ + usb_deregister(&lg_vl600_driver); +} +module_exit(vl600_exit); + +MODULE_AUTHOR("Anrzej Zaborowski"); +MODULE_DESCRIPTION("LG-VL600 modem's ethernet link"); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 95c41d56631c..cf58b7682565 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -387,8 +387,12 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags) static inline void rx_process (struct usbnet *dev, struct sk_buff *skb) { if (dev->driver_info->rx_fixup && - !dev->driver_info->rx_fixup (dev, skb)) - goto error; + !dev->driver_info->rx_fixup (dev, skb)) { + /* With RX_ASSEMBLE, rx_fixup() must update counters */ + if (!(dev->driver_info->flags & FLAG_RX_ASSEMBLE)) + dev->net->stats.rx_errors++; + goto done; + } // else network stack removes extra byte if we forced a short packet if (skb->len) { @@ -401,8 +405,8 @@ static inline void rx_process (struct usbnet *dev, struct sk_buff *skb) } netif_dbg(dev, rx_err, dev->net, "drop\n"); -error: dev->net->stats.rx_errors++; +done: skb_queue_tail(&dev->done, skb); } diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h index 44842c8d38c0..201f2228f731 100644 --- a/include/linux/usb/usbnet.h +++ b/include/linux/usb/usbnet.h @@ -102,6 +102,7 @@ struct driver_info { * Affects statistic (counters) and short packet handling. */ #define FLAG_MULTI_PACKET 0x1000 +#define FLAG_RX_ASSEMBLE 0x2000 /* rx packets may span >1 frames */ /* init device ... can sleep, or cause probe() failure */ int (*bind)(struct usbnet *, struct usb_interface *); @@ -172,7 +173,9 @@ struct cdc_state { }; extern int usbnet_generic_cdc_bind(struct usbnet *, struct usb_interface *); +extern int usbnet_cdc_bind(struct usbnet *, struct usb_interface *); extern void usbnet_cdc_unbind(struct usbnet *, struct usb_interface *); +extern void usbnet_cdc_status(struct usbnet *, struct urb *); /* CDC and RNDIS support the same host-chosen packet filters for IN transfers */ #define DEFAULT_FILTER (USB_CDC_PACKET_TYPE_BROADCAST \ -- cgit From 6fb1b1e18fe3d141c54182c5d5b3af823bed455f Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 19 Mar 2011 13:55:39 +0100 Subject: ath9k: add support for overriding the MAC address through platform data On some devices the correct MAC address is not in the EEPROM data, but stored somewhere else. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/init.c | 7 ++++++- include/linux/ath9k_platform.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 79aec983279f..e22e8215d941 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -15,6 +15,7 @@ */ #include +#include #include "ath9k.h" @@ -537,6 +538,7 @@ static void ath9k_init_misc(struct ath_softc *sc) static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, const struct ath_bus_ops *bus_ops) { + struct ath9k_platform_data *pdata = sc->dev->platform_data; struct ath_hw *ah = NULL; struct ath_common *common; int ret = 0, i; @@ -551,7 +553,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, ah->hw_version.subsysid = subsysid; sc->sc_ah = ah; - if (!sc->dev->platform_data) + if (!pdata) ah->ah_flags |= AH_USE_EEPROM; common = ath9k_hw_common(ah); @@ -587,6 +589,9 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, if (ret) goto err_hw; + if (pdata && pdata->macaddr) + memcpy(common->macaddr, pdata->macaddr, ETH_ALEN); + ret = ath9k_init_queues(sc); if (ret) goto err_queues; diff --git a/include/linux/ath9k_platform.h b/include/linux/ath9k_platform.h index b847fc7b93f9..b5f06583a1ba 100644 --- a/include/linux/ath9k_platform.h +++ b/include/linux/ath9k_platform.h @@ -23,6 +23,7 @@ struct ath9k_platform_data { u16 eeprom_data[ATH9K_PLAT_EEP_MAX_WORDS]; + u8 *macaddr; }; #endif /* _LINUX_ATH9K_PLATFORM_H */ -- cgit From 6de66dd963ddd669667a81a2401f2fd6472ff55c Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 19 Mar 2011 13:55:40 +0100 Subject: ath9k: add support for overriding LED pin and GPIO settings from platform data Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/gpio.c | 14 ++++++++------ drivers/net/wireless/ath/ath9k/hw.h | 2 +- drivers/net/wireless/ath/ath9k/init.c | 8 +++++++- include/linux/ath9k_platform.h | 4 ++++ 4 files changed, 20 insertions(+), 8 deletions(-) (limited to 'include/linux') diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index 0fb8f8ac275a..44a0a886124d 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c @@ -41,12 +41,14 @@ void ath_init_leds(struct ath_softc *sc) { int ret; - if (AR_SREV_9287(sc->sc_ah)) - sc->sc_ah->led_pin = ATH_LED_PIN_9287; - else if (AR_SREV_9485(sc->sc_ah)) - sc->sc_ah->led_pin = ATH_LED_PIN_9485; - else - sc->sc_ah->led_pin = ATH_LED_PIN_DEF; + if (sc->sc_ah->led_pin < 0) { + if (AR_SREV_9287(sc->sc_ah)) + sc->sc_ah->led_pin = ATH_LED_PIN_9287; + else if (AR_SREV_9485(sc->sc_ah)) + sc->sc_ah->led_pin = ATH_LED_PIN_9485; + else + sc->sc_ah->led_pin = ATH_LED_PIN_DEF; + } /* Configure gpio 1 for output */ ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin, diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 775c0eb10b95..3d9fc6e391a7 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -798,7 +798,7 @@ struct ath_hw { u32 originalGain[22]; int initPDADC; int PDADCdelta; - u8 led_pin; + int led_pin; u32 gpio_mask; u32 gpio_val; diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index e22e8215d941..cdb0f1c89a0e 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -553,8 +553,14 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, ah->hw_version.subsysid = subsysid; sc->sc_ah = ah; - if (!pdata) + if (!pdata) { ah->ah_flags |= AH_USE_EEPROM; + sc->sc_ah->led_pin = -1; + } else { + sc->sc_ah->gpio_mask = pdata->gpio_mask; + sc->sc_ah->gpio_val = pdata->gpio_val; + sc->sc_ah->led_pin = pdata->led_pin; + } common = ath9k_hw_common(ah); common->ops = &ath9k_common_ops; diff --git a/include/linux/ath9k_platform.h b/include/linux/ath9k_platform.h index b5f06583a1ba..020387a114e3 100644 --- a/include/linux/ath9k_platform.h +++ b/include/linux/ath9k_platform.h @@ -24,6 +24,10 @@ struct ath9k_platform_data { u16 eeprom_data[ATH9K_PLAT_EEP_MAX_WORDS]; u8 *macaddr; + + int led_pin; + u32 gpio_mask; + u32 gpio_val; }; #endif /* _LINUX_ATH9K_PLATFORM_H */ -- cgit From c031235b395433350f25943b7580a5e343c7b7b2 Mon Sep 17 00:00:00 2001 From: "Philip A. Prindeville" Date: Wed, 30 Mar 2011 13:17:04 +0000 Subject: atm/solos-pci: Don't flap VCs when carrier state changes Don't flap VCs when carrier state changes; higher-level protocols can detect loss of connectivity and act accordingly. This is more consistent with how other network interfaces work. We no longer use release_vccs() so we can delete it. release_vccs() was duplicated from net/atm/common.c; make the corresponding function exported, since other code duplicates it and could leverage it if it were public. Signed-off-by: Philip A. Prindeville Signed-off-by: David S. Miller --- drivers/atm/solos-pci.c | 26 +------------------------- include/linux/atmdev.h | 1 + net/atm/common.c | 1 + 3 files changed, 3 insertions(+), 25 deletions(-) (limited to 'include/linux') diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c index 968f022d141a..cd0ff66469b2 100644 --- a/drivers/atm/solos-pci.c +++ b/drivers/atm/solos-pci.c @@ -165,7 +165,6 @@ static uint32_t fpga_tx(struct solos_card *); static irqreturn_t solos_irq(int irq, void *dev_id); static struct atm_vcc* find_vcc(struct atm_dev *dev, short vpi, int vci); static int list_vccs(int vci); -static void release_vccs(struct atm_dev *dev); static int atm_init(struct solos_card *, struct device *); static void atm_remove(struct solos_card *); static int send_command(struct solos_card *card, int dev, const char *buf, size_t size); @@ -384,7 +383,6 @@ static int process_status(struct solos_card *card, int port, struct sk_buff *skb /* Anything but 'Showtime' is down */ if (strcmp(state_str, "Showtime")) { atm_dev_signal_change(card->atmdev[port], ATM_PHY_SIG_LOST); - release_vccs(card->atmdev[port]); dev_info(&card->dev->dev, "Port %d: %s\n", port, state_str); return 0; } @@ -830,28 +828,6 @@ static int list_vccs(int vci) return num_found; } -static void release_vccs(struct atm_dev *dev) -{ - int i; - - write_lock_irq(&vcc_sklist_lock); - for (i = 0; i < VCC_HTABLE_SIZE; i++) { - struct hlist_head *head = &vcc_hash[i]; - struct hlist_node *node, *tmp; - struct sock *s; - struct atm_vcc *vcc; - - sk_for_each_safe(s, node, tmp, head) { - vcc = atm_sk(s); - if (vcc->dev == dev) { - vcc_release_async(vcc, -EPIPE); - sk_del_node_init(s); - } - } - } - write_unlock_irq(&vcc_sklist_lock); -} - static int popen(struct atm_vcc *vcc) { @@ -1269,7 +1245,7 @@ static int atm_init(struct solos_card *card, struct device *parent) card->atmdev[i]->ci_range.vci_bits = 16; card->atmdev[i]->dev_data = card; card->atmdev[i]->phy_data = (void *)(unsigned long)i; - atm_dev_signal_change(card->atmdev[i], ATM_PHY_SIG_UNKNOWN); + atm_dev_signal_change(card->atmdev[i], ATM_PHY_SIG_FOUND); skb = alloc_skb(sizeof(*header), GFP_ATOMIC); if (!skb) { diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h index 475f8c42c0e9..381f4cec8260 100644 --- a/include/linux/atmdev.h +++ b/include/linux/atmdev.h @@ -443,6 +443,7 @@ void atm_dev_signal_change(struct atm_dev *dev, char signal); void vcc_insert_socket(struct sock *sk); +void atm_dev_release_vccs(struct atm_dev *dev); /* * This is approximately the algorithm used by alloc_skb. diff --git a/net/atm/common.c b/net/atm/common.c index 1b9c52a02cd3..22b963d06a10 100644 --- a/net/atm/common.c +++ b/net/atm/common.c @@ -252,6 +252,7 @@ void atm_dev_release_vccs(struct atm_dev *dev) } write_unlock_irq(&vcc_sklist_lock); } +EXPORT_SYMBOL(atm_dev_release_vccs); static int adjust_tp(struct atm_trafprm *tp, unsigned char aal) { -- cgit From 04f482faf50535229a5a5c8d629cf963899f857c Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 28 Mar 2011 08:39:36 +0000 Subject: connector: convert to synchronous netlink message processing Commits 01a16b21 (netlink: kill eff_cap from struct netlink_skb_parms) and c53fa1ed (netlink: kill loginuid/sessionid/sid members from struct netlink_skb_parms) removed some members from struct netlink_skb_parms that depend on the current context, all netlink users are now required to do synchronous message processing. connector however queues received messages and processes them in a work queue, which is not valid anymore. This patch converts connector to do synchronous message processing by invoking the registered callback handler directly from the netlink receive function. In order to avoid invoking the callback with connector locks held, a reference count is added to struct cn_callback_entry, the reference is taken when finding a matching callback entry on the device's queue_list and released after the callback handler has been invoked. Signed-off-by: Patrick McHardy Acked-by: Evgeniy Polyakov Signed-off-by: David S. Miller --- drivers/connector/cn_queue.c | 58 +++++++++++++------------------------------ drivers/connector/connector.c | 47 +++++++++-------------------------- include/linux/connector.h | 16 +++--------- 3 files changed, 32 insertions(+), 89 deletions(-) (limited to 'include/linux') diff --git a/drivers/connector/cn_queue.c b/drivers/connector/cn_queue.c index 55653aba6735..c42c9d517790 100644 --- a/drivers/connector/cn_queue.c +++ b/drivers/connector/cn_queue.c @@ -31,24 +31,9 @@ #include #include -void cn_queue_wrapper(struct work_struct *work) -{ - struct cn_callback_entry *cbq = - container_of(work, struct cn_callback_entry, work); - struct cn_callback_data *d = &cbq->data; - struct cn_msg *msg = NLMSG_DATA(nlmsg_hdr(d->skb)); - struct netlink_skb_parms *nsp = &NETLINK_CB(d->skb); - - d->callback(msg, nsp); - - kfree_skb(d->skb); - d->skb = NULL; - - kfree(d->free); -} - static struct cn_callback_entry * -cn_queue_alloc_callback_entry(const char *name, struct cb_id *id, +cn_queue_alloc_callback_entry(struct cn_queue_dev *dev, const char *name, + struct cb_id *id, void (*callback)(struct cn_msg *, struct netlink_skb_parms *)) { struct cn_callback_entry *cbq; @@ -59,17 +44,23 @@ cn_queue_alloc_callback_entry(const char *name, struct cb_id *id, return NULL; } + atomic_set(&cbq->refcnt, 1); + + atomic_inc(&dev->refcnt); + cbq->pdev = dev; + snprintf(cbq->id.name, sizeof(cbq->id.name), "%s", name); memcpy(&cbq->id.id, id, sizeof(struct cb_id)); - cbq->data.callback = callback; - - INIT_WORK(&cbq->work, &cn_queue_wrapper); + cbq->callback = callback; return cbq; } -static void cn_queue_free_callback(struct cn_callback_entry *cbq) +void cn_queue_release_callback(struct cn_callback_entry *cbq) { - flush_workqueue(cbq->pdev->cn_queue); + if (!atomic_dec_and_test(&cbq->refcnt)) + return; + + atomic_dec(&cbq->pdev->refcnt); kfree(cbq); } @@ -85,13 +76,10 @@ int cn_queue_add_callback(struct cn_queue_dev *dev, const char *name, struct cn_callback_entry *cbq, *__cbq; int found = 0; - cbq = cn_queue_alloc_callback_entry(name, id, callback); + cbq = cn_queue_alloc_callback_entry(dev, name, id, callback); if (!cbq) return -ENOMEM; - atomic_inc(&dev->refcnt); - cbq->pdev = dev; - spin_lock_bh(&dev->queue_lock); list_for_each_entry(__cbq, &dev->queue_list, callback_entry) { if (cn_cb_equal(&__cbq->id.id, id)) { @@ -104,8 +92,7 @@ int cn_queue_add_callback(struct cn_queue_dev *dev, const char *name, spin_unlock_bh(&dev->queue_lock); if (found) { - cn_queue_free_callback(cbq); - atomic_dec(&dev->refcnt); + cn_queue_release_callback(cbq); return -EINVAL; } @@ -130,10 +117,8 @@ void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id) } spin_unlock_bh(&dev->queue_lock); - if (found) { - cn_queue_free_callback(cbq); - atomic_dec(&dev->refcnt); - } + if (found) + cn_queue_release_callback(cbq); } struct cn_queue_dev *cn_queue_alloc_dev(const char *name, struct sock *nls) @@ -151,12 +136,6 @@ struct cn_queue_dev *cn_queue_alloc_dev(const char *name, struct sock *nls) dev->nls = nls; - dev->cn_queue = alloc_ordered_workqueue(dev->name, 0); - if (!dev->cn_queue) { - kfree(dev); - return NULL; - } - return dev; } @@ -164,9 +143,6 @@ void cn_queue_free_dev(struct cn_queue_dev *dev) { struct cn_callback_entry *cbq, *n; - flush_workqueue(dev->cn_queue); - destroy_workqueue(dev->cn_queue); - spin_lock_bh(&dev->queue_lock); list_for_each_entry_safe(cbq, n, &dev->queue_list, callback_entry) list_del(&cbq->callback_entry); diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c index f7554de3be5e..d77005849af8 100644 --- a/drivers/connector/connector.c +++ b/drivers/connector/connector.c @@ -122,51 +122,28 @@ EXPORT_SYMBOL_GPL(cn_netlink_send); */ static int cn_call_callback(struct sk_buff *skb) { - struct cn_callback_entry *__cbq, *__new_cbq; + struct cn_callback_entry *i, *cbq = NULL; struct cn_dev *dev = &cdev; struct cn_msg *msg = NLMSG_DATA(nlmsg_hdr(skb)); + struct netlink_skb_parms *nsp = &NETLINK_CB(skb); int err = -ENODEV; spin_lock_bh(&dev->cbdev->queue_lock); - list_for_each_entry(__cbq, &dev->cbdev->queue_list, callback_entry) { - if (cn_cb_equal(&__cbq->id.id, &msg->id)) { - if (likely(!work_pending(&__cbq->work) && - __cbq->data.skb == NULL)) { - __cbq->data.skb = skb; - - if (queue_work(dev->cbdev->cn_queue, - &__cbq->work)) - err = 0; - else - err = -EINVAL; - } else { - struct cn_callback_data *d; - - err = -ENOMEM; - __new_cbq = kzalloc(sizeof(struct cn_callback_entry), GFP_ATOMIC); - if (__new_cbq) { - d = &__new_cbq->data; - d->skb = skb; - d->callback = __cbq->data.callback; - d->free = __new_cbq; - - INIT_WORK(&__new_cbq->work, - &cn_queue_wrapper); - - if (queue_work(dev->cbdev->cn_queue, - &__new_cbq->work)) - err = 0; - else { - kfree(__new_cbq); - err = -EINVAL; - } - } - } + list_for_each_entry(i, &dev->cbdev->queue_list, callback_entry) { + if (cn_cb_equal(&i->id.id, &msg->id)) { + atomic_inc(&i->refcnt); + cbq = i; break; } } spin_unlock_bh(&dev->cbdev->queue_lock); + if (cbq != NULL) { + cbq->callback(msg, nsp); + kfree_skb(skb); + cn_queue_release_callback(cbq); + } + return err; } diff --git a/include/linux/connector.h b/include/linux/connector.h index bcafc942e5e4..7c60d0942adb 100644 --- a/include/linux/connector.h +++ b/include/linux/connector.h @@ -88,8 +88,6 @@ struct cn_queue_dev { atomic_t refcnt; unsigned char name[CN_CBQ_NAMELEN]; - struct workqueue_struct *cn_queue; - struct list_head queue_list; spinlock_t queue_lock; @@ -101,20 +99,13 @@ struct cn_callback_id { struct cb_id id; }; -struct cn_callback_data { - struct sk_buff *skb; - void (*callback) (struct cn_msg *, struct netlink_skb_parms *); - - void *free; -}; - struct cn_callback_entry { struct list_head callback_entry; - struct work_struct work; + atomic_t refcnt; struct cn_queue_dev *pdev; struct cn_callback_id id; - struct cn_callback_data data; + void (*callback) (struct cn_msg *, struct netlink_skb_parms *); u32 seq, group; }; @@ -138,13 +129,12 @@ int cn_queue_add_callback(struct cn_queue_dev *dev, const char *name, struct cb_id *id, void (*callback)(struct cn_msg *, struct netlink_skb_parms *)); void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id); +void cn_queue_release_callback(struct cn_callback_entry *); struct cn_queue_dev *cn_queue_alloc_dev(const char *name, struct sock *); void cn_queue_free_dev(struct cn_queue_dev *dev); int cn_cb_equal(struct cb_id *, struct cb_id *); -void cn_queue_wrapper(struct work_struct *work); - #endif /* __KERNEL__ */ #endif /* __CONNECTOR_H */ -- cgit From cb6c8520f6f6bba7b7e1a6de3360a8edfd8243b6 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 30 Mar 2011 20:34:47 +0200 Subject: x86, amd-nb: Rename CPU PCI id define for F4 With increasing number of PCI function ids, add the PCI function id in the define name instead of its symbolic name in the BKDG for more clarity. This renames function 4 define. Signed-off-by: Borislav Petkov Cc: Jesse Barnes LKML-Reference: <20110330183447.GA3668@aftab> Signed-off-by: Ingo Molnar --- arch/x86/kernel/amd_nb.c | 2 +- include/linux/pci_ids.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c index 6801959a8b2a..4c39baa8facc 100644 --- a/arch/x86/kernel/amd_nb.c +++ b/arch/x86/kernel/amd_nb.c @@ -21,7 +21,7 @@ const struct pci_device_id amd_nb_misc_ids[] = { EXPORT_SYMBOL(amd_nb_misc_ids); static struct pci_device_id amd_nb_link_ids[] = { - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_LINK) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) }, {} }; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 11fd38151cc9..4e2c9150a785 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -518,7 +518,7 @@ #define PCI_DEVICE_ID_AMD_11H_NB_MISC 0x1303 #define PCI_DEVICE_ID_AMD_11H_NB_LINK 0x1304 #define PCI_DEVICE_ID_AMD_15H_NB_F3 0x1603 -#define PCI_DEVICE_ID_AMD_15H_NB_LINK 0x1604 +#define PCI_DEVICE_ID_AMD_15H_NB_F4 0x1604 #define PCI_DEVICE_ID_AMD_CNB17H_F3 0x1703 #define PCI_DEVICE_ID_AMD_LANCE 0x2000 #define PCI_DEVICE_ID_AMD_LANCE_HOME 0x2001 -- cgit From ab711fe08297de1485fff0a366e6db8828cafd6a Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 31 Mar 2011 10:29:26 +0200 Subject: perf: Fix task context scheduling Jiri reported: | | - once an event is created by sys_perf_event_open, task context | is created and it stays even if the event is closed, until the | task is finished ... thats what I see in code and I assume it's | correct | | - when the task opens event, perf_sched_events jump label is | incremented and following callbacks are started from scheduler | | __perf_event_task_sched_in | __perf_event_task_sched_out | | These callback *in/out set/unset cpuctx->task_ctx value to the | task context. | | - close is called on event on CPU 0: | - the task is scheduled on CPU 0 | - __perf_event_task_sched_in is called | - cpuctx->task_ctx is set | - perf_sched_events jump label is decremented and == 0 | - __perf_event_task_sched_out is not called | - cpuctx->task_ctx on CPU 0 stays set | | - exit is called on CPU 1: | - the task is scheduled on CPU 1 | - perf_event_exit_task is called | - task_ctx_sched_out unsets cpuctx->task_ctx on CPU 1 | - put_ctx destroys the context | | - another call of perf_rotate_context on CPU 0 will use invalid | task_ctx pointer, and eventualy panic. | Cure this the simplest possibly way by partially reverting the jump_label optimization for the sched_out case. Reported-and-tested-by: Jiri Olsa Signed-off-by: Peter Zijlstra Cc: Oleg Nesterov Cc: # .37+ LKML-Reference: <1301520405.4859.213.camel@twins> Signed-off-by: Ingo Molnar --- include/linux/perf_event.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 311b4dc785a1..04d75a8a20ee 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -1086,7 +1086,7 @@ void perf_event_task_sched_out(struct task_struct *task, struct task_struct *nex { perf_sw_event(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, 1, NULL, 0); - COND_STMT(&perf_sched_events, __perf_event_task_sched_out(task, next)); + __perf_event_task_sched_out(task, next); } extern void perf_event_mmap(struct vm_area_struct *vma); -- cgit From 25985edcedea6396277003854657b5f3cb31a628 Mon Sep 17 00:00:00 2001 From: Lucas De Marchi Date: Wed, 30 Mar 2011 22:57:33 -0300 Subject: Fix common misspellings Fixes generated by 'codespell' and manually reviewed. Signed-off-by: Lucas De Marchi --- CREDITS | 6 +-- Documentation/ABI/testing/sysfs-bus-css | 2 +- Documentation/ABI/testing/sysfs-class-led | 2 +- Documentation/DocBook/dvb/dvbproperty.xml | 2 +- Documentation/DocBook/dvb/frontend.xml | 2 +- Documentation/DocBook/kernel-locking.tmpl | 2 +- Documentation/DocBook/libata.tmpl | 10 ++-- Documentation/DocBook/mtdnand.tmpl | 12 ++--- Documentation/DocBook/regulator.tmpl | 4 +- Documentation/DocBook/uio-howto.tmpl | 2 +- Documentation/DocBook/usb.tmpl | 2 +- Documentation/DocBook/v4l/common.xml | 2 +- Documentation/DocBook/v4l/controls.xml | 2 +- Documentation/DocBook/v4l/dev-subdev.xml | 2 +- Documentation/DocBook/v4l/libv4l.xml | 2 +- Documentation/DocBook/v4l/remote_controllers.xml | 2 +- Documentation/DocBook/writing-an-alsa-driver.tmpl | 2 +- Documentation/PCI/MSI-HOWTO.txt | 4 +- Documentation/SecurityBugs | 2 +- Documentation/SubmittingDrivers | 2 +- Documentation/SubmittingPatches | 2 +- Documentation/arm/IXP4xx | 4 +- Documentation/arm/Samsung-S3C24XX/Suspend.txt | 2 +- Documentation/arm/Samsung/GPIO.txt | 2 +- Documentation/block/biodoc.txt | 4 +- Documentation/cpu-hotplug.txt | 2 +- Documentation/dell_rbu.txt | 2 +- Documentation/device-mapper/dm-service-time.txt | 2 +- Documentation/devicetree/bindings/fb/sm501fb.txt | 4 +- .../devicetree/bindings/mtd/fsl-upm-nand.txt | 2 +- .../devicetree/bindings/net/can/sja1000.txt | 2 +- .../devicetree/bindings/powerpc/fsl/mpic.txt | 2 +- Documentation/dvb/README.dvb-usb | 2 +- Documentation/dvb/ci.txt | 2 +- Documentation/dvb/faq.txt | 2 +- Documentation/edac.txt | 2 +- Documentation/eisa.txt | 2 +- Documentation/fb/viafb.txt | 4 +- .../filesystems/autofs4-mount-control.txt | 2 +- Documentation/filesystems/caching/netfs-api.txt | 18 ++++---- Documentation/filesystems/configfs/configfs.txt | 2 +- Documentation/filesystems/ext4.txt | 4 +- Documentation/filesystems/gfs2-uevents.txt | 2 +- Documentation/filesystems/gfs2.txt | 2 +- Documentation/filesystems/ntfs.txt | 2 +- Documentation/filesystems/ocfs2.txt | 2 +- Documentation/filesystems/path-lookup.txt | 4 +- .../filesystems/pohmelfs/network_protocol.txt | 2 +- Documentation/filesystems/proc.txt | 6 +-- Documentation/filesystems/squashfs.txt | 2 +- Documentation/filesystems/sysfs.txt | 2 +- Documentation/filesystems/vfs.txt | 2 +- .../filesystems/xfs-delayed-logging-design.txt | 8 ++-- Documentation/hwmon/abituguru | 2 +- Documentation/hwmon/abituguru-datasheet | 8 ++-- Documentation/hwmon/abituguru3 | 2 +- Documentation/hwmon/pmbus | 6 +-- Documentation/hwmon/sysfs-interface | 2 +- Documentation/hwmon/w83781d | 2 +- Documentation/hwmon/w83791d | 2 +- Documentation/i2c/busses/i2c-parport-light | 2 +- Documentation/i2c/busses/i2c-sis96x | 2 +- Documentation/i2c/busses/i2c-taos-evm | 2 +- Documentation/i2o/README | 2 +- Documentation/ia64/aliasing-test.c | 2 +- Documentation/input/joystick-parport.txt | 2 +- Documentation/input/rotary-encoder.txt | 2 +- Documentation/input/walkera0701.txt | 2 +- Documentation/irqflags-tracing.txt | 2 +- Documentation/isdn/INTERFACE.CAPI | 2 +- Documentation/kbuild/kbuild.txt | 8 ++-- Documentation/kernel-parameters.txt | 2 +- Documentation/kvm/mmu.txt | 2 +- Documentation/kvm/ppc-pv.txt | 2 +- Documentation/kvm/timekeeping.txt | 2 +- Documentation/media-framework.txt | 4 +- Documentation/mips/AU1xxx_IDE.README | 4 +- Documentation/misc-devices/ics932s401 | 2 +- Documentation/networking/3c359.txt | 2 +- Documentation/networking/README.ipw2200 | 2 +- Documentation/networking/bonding.txt | 2 +- Documentation/networking/caif/Linux-CAIF.txt | 2 +- Documentation/networking/caif/spi_porting.txt | 2 +- Documentation/networking/can.txt | 2 +- Documentation/networking/ieee802154.txt | 2 +- Documentation/networking/olympic.txt | 2 +- Documentation/networking/packet_mmap.txt | 2 +- Documentation/networking/s2io.txt | 4 +- Documentation/networking/tc-actions-env-rules.txt | 4 +- Documentation/power/devices.txt | 2 +- Documentation/power/notifiers.txt | 4 +- Documentation/power/opp.txt | 2 +- Documentation/power/swsusp.txt | 4 +- Documentation/power/userland-swsusp.txt | 6 +-- Documentation/powerpc/hvcs.txt | 2 +- Documentation/scsi/ChangeLog.lpfc | 18 ++++---- Documentation/scsi/ChangeLog.megaraid | 2 +- Documentation/scsi/ChangeLog.ncr53c8xx | 2 +- Documentation/scsi/ChangeLog.sym53c8xx | 2 +- Documentation/scsi/aha152x.txt | 2 +- Documentation/scsi/aic79xx.txt | 12 ++--- Documentation/scsi/ibmmca.txt | 4 +- Documentation/scsi/scsi-changer.txt | 2 +- Documentation/scsi/scsi_eh.txt | 2 +- Documentation/scsi/scsi_fc_transport.txt | 2 +- Documentation/serial/moxa-smartio | 2 +- Documentation/serial/n_gsm.txt | 2 +- Documentation/sound/alsa/ALSA-Configuration.txt | 4 +- Documentation/sound/oss/README.OSS | 2 +- Documentation/spi/pxa2xx | 2 +- Documentation/spi/spi-lm70llp | 2 +- Documentation/telephony/ixj.txt | 2 +- Documentation/trace/ring-buffer-design.txt | 2 +- Documentation/video4linux/README.pvrusb2 | 2 +- Documentation/video4linux/bttv/README | 2 +- Documentation/video4linux/bttv/README.freeze | 2 +- Documentation/video4linux/bttv/Sound-FAQ | 2 +- Documentation/video4linux/pxa_camera.txt | 8 ++-- Documentation/video4linux/v4l2-framework.txt | 2 +- Documentation/vm/active_mm.txt | 2 +- Documentation/vm/hugetlbpage.txt | 2 +- Documentation/vm/overcommit-accounting | 2 +- Documentation/w1/slaves/w1_ds2423 | 6 +-- Documentation/w1/w1.netlink | 2 +- Documentation/watchdog/hpwdt.txt | 2 +- arch/alpha/include/asm/elf.h | 2 +- arch/alpha/kernel/core_lca.c | 4 +- arch/alpha/kernel/err_marvel.c | 2 +- arch/alpha/lib/ev67-strrchr.S | 2 +- arch/alpha/lib/fls.c | 2 +- arch/alpha/lib/strrchr.S | 2 +- arch/alpha/oprofile/op_model_ev67.c | 2 +- arch/arm/Kconfig | 2 +- arch/arm/Kconfig-nommu | 2 +- arch/arm/common/pl330.c | 4 +- arch/arm/include/asm/fpstate.h | 2 +- arch/arm/include/asm/glue-cache.h | 2 +- arch/arm/include/asm/glue.h | 4 +- arch/arm/include/asm/hardware/pl080.h | 2 +- arch/arm/include/asm/system.h | 2 +- arch/arm/include/asm/ucontext.h | 2 +- arch/arm/kernel/swp_emulate.c | 2 +- arch/arm/mach-at91/board-carmeva.c | 2 +- arch/arm/mach-at91/include/mach/at91_mci.h | 2 +- arch/arm/mach-at91/include/mach/gpio.h | 2 +- arch/arm/mach-bcmring/csp/dmac/dmacHw_extra.c | 6 +-- arch/arm/mach-bcmring/dma.c | 4 +- arch/arm/mach-bcmring/include/csp/dmacHw.h | 6 +-- .../mach-bcmring/include/mach/csp/chipcHw_def.h | 2 +- .../mach-bcmring/include/mach/csp/chipcHw_inline.h | 2 +- .../arm/mach-bcmring/include/mach/csp/intcHw_reg.h | 4 +- arch/arm/mach-bcmring/include/mach/reg_umi.h | 2 +- arch/arm/mach-davinci/board-neuros-osd2.c | 2 +- arch/arm/mach-davinci/cpufreq.c | 2 +- arch/arm/mach-davinci/da850.c | 2 +- arch/arm/mach-davinci/dm355.c | 2 +- arch/arm/mach-davinci/dm644x.c | 2 +- arch/arm/mach-davinci/include/mach/cputype.h | 2 +- arch/arm/mach-ep93xx/gpio.c | 2 +- arch/arm/mach-exynos4/include/mach/gpio.h | 2 +- arch/arm/mach-exynos4/mct.c | 2 +- arch/arm/mach-exynos4/setup-sdhci-gpio.c | 4 +- arch/arm/mach-exynos4/setup-sdhci.c | 2 +- arch/arm/mach-iop13xx/pci.c | 4 +- arch/arm/mach-kirkwood/tsx1x-common.c | 2 +- arch/arm/mach-lpc32xx/pm.c | 2 +- arch/arm/mach-mmp/time.c | 2 +- arch/arm/mach-msm/acpuclock-arm11.c | 2 +- arch/arm/mach-msm/scm.c | 2 +- arch/arm/mach-omap1/ams-delta-fiq-handler.S | 2 +- arch/arm/mach-omap1/board-sx1.c | 2 +- arch/arm/mach-omap1/devices.c | 2 +- arch/arm/mach-omap1/include/mach/ams-delta-fiq.h | 2 +- arch/arm/mach-omap2/board-igep0020.c | 2 +- arch/arm/mach-omap2/board-igep0030.c | 2 +- arch/arm/mach-omap2/clockdomain.c | 2 +- arch/arm/mach-omap2/clockdomain.h | 2 +- arch/arm/mach-omap2/cpuidle34xx.c | 4 +- arch/arm/mach-omap2/devices.c | 6 +-- arch/arm/mach-omap2/dma.c | 2 +- arch/arm/mach-omap2/gpio.c | 2 +- arch/arm/mach-omap2/hsmmc.c | 2 +- arch/arm/mach-omap2/mcbsp.c | 2 +- arch/arm/mach-omap2/mux.c | 2 +- arch/arm/mach-omap2/mux2430.h | 2 +- arch/arm/mach-omap2/omap_hwmod_2430_data.c | 2 +- arch/arm/mach-omap2/omap_phy_internal.c | 4 +- arch/arm/mach-omap2/omap_twl.c | 2 +- arch/arm/mach-omap2/powerdomain.c | 2 +- arch/arm/mach-omap2/powerdomain.h | 2 +- arch/arm/mach-omap2/powerdomains3xxx_data.c | 2 +- arch/arm/mach-omap2/smartreflex.c | 2 +- arch/arm/mach-omap2/voltage.c | 4 +- arch/arm/mach-orion5x/addr-map.c | 2 +- arch/arm/mach-orion5x/net2big-setup.c | 2 +- arch/arm/mach-orion5x/ts209-setup.c | 2 +- arch/arm/mach-orion5x/ts409-setup.c | 2 +- arch/arm/mach-pxa/include/mach/pxa3xx-regs.h | 2 +- arch/arm/mach-pxa/include/mach/zeus.h | 2 +- arch/arm/mach-pxa/mioa701.c | 2 +- arch/arm/mach-s3c2410/include/mach/dma.h | 2 +- arch/arm/mach-s3c2410/include/mach/regs-mem.h | 2 +- arch/arm/mach-s3c2410/mach-n30.c | 2 +- arch/arm/mach-s3c2440/mach-mini2440.c | 2 +- arch/arm/mach-s3c64xx/dma.c | 2 +- arch/arm/mach-s5pc100/include/mach/regs-fb.h | 2 +- arch/arm/mach-s5pc100/setup-sdhci.c | 2 +- arch/arm/mach-s5pv210/include/mach/gpio.h | 2 +- arch/arm/mach-s5pv210/setup-sdhci-gpio.c | 4 +- arch/arm/mach-s5pv210/setup-sdhci.c | 2 +- arch/arm/mach-sa1100/Makefile | 2 +- arch/arm/mach-sa1100/cpu-sa1100.c | 2 +- arch/arm/mach-sa1100/include/mach/SA-1100.h | 2 +- arch/arm/mach-sa1100/jornada720_ssp.c | 4 +- arch/arm/mach-tegra/dma.c | 4 +- arch/arm/mach-tegra/include/mach/dma.h | 4 +- arch/arm/mach-u300/clock.c | 6 +-- arch/arm/mach-ux500/board-mop500.c | 2 +- arch/arm/mach-ux500/include/mach/db8500-regs.h | 10 ++-- arch/arm/mm/cache-v4wb.S | 2 +- arch/arm/mm/cache-v4wt.S | 2 +- arch/arm/mm/cache-v7.S | 2 +- arch/arm/mm/proc-arm1020.S | 2 +- arch/arm/mm/proc-arm1020e.S | 2 +- arch/arm/mm/proc-arm1022.S | 2 +- arch/arm/mm/proc-arm1026.S | 2 +- arch/arm/mm/proc-arm720.S | 2 +- arch/arm/mm/proc-arm920.S | 2 +- arch/arm/mm/proc-arm922.S | 2 +- arch/arm/mm/proc-arm925.S | 2 +- arch/arm/mm/proc-macros.S | 2 +- arch/arm/mm/proc-v6.S | 4 +- arch/arm/mm/proc-v7.S | 2 +- arch/arm/plat-mxc/cpufreq.c | 2 +- arch/arm/plat-mxc/include/mach/entry-macro.S | 4 +- arch/arm/plat-mxc/include/mach/mxc_nand.h | 2 +- arch/arm/plat-omap/devices.c | 2 +- arch/arm/plat-omap/dma.c | 4 +- arch/arm/plat-omap/include/plat/gpio.h | 2 +- arch/arm/plat-omap/include/plat/gpmc.h | 2 +- arch/arm/plat-omap/mcbsp.c | 2 +- arch/arm/plat-pxa/include/plat/mfp.h | 2 +- arch/arm/plat-s3c24xx/Makefile | 2 +- arch/arm/plat-s3c24xx/cpu-freq.c | 2 +- arch/arm/plat-s3c24xx/dma.c | 2 +- arch/arm/plat-s5p/irq-gpioint.c | 2 +- arch/arm/plat-samsung/include/plat/clock.h | 2 +- .../plat-samsung/include/plat/gpio-cfg-helpers.h | 2 +- arch/arm/plat-samsung/include/plat/gpio-cfg.h | 6 +-- arch/arm/plat-samsung/include/plat/gpio-core.h | 2 +- arch/arm/plat-samsung/include/plat/sdhci.h | 4 +- arch/arm/plat-samsung/s3c-pl330.c | 2 +- arch/arm/plat-spear/include/plat/clock.h | 2 +- arch/blackfin/Kconfig.debug | 2 +- arch/blackfin/include/asm/traps.h | 2 +- arch/blackfin/kernel/kgdb.c | 2 +- arch/blackfin/kernel/traps.c | 2 +- arch/blackfin/lib/ins.S | 2 +- arch/blackfin/lib/memmove.S | 2 +- arch/blackfin/mach-bf537/boards/stamp.c | 2 +- arch/blackfin/mach-common/entry.S | 4 +- arch/blackfin/mach-common/head.S | 2 +- arch/cris/arch-v10/README.mm | 2 +- arch/cris/arch-v10/drivers/sync_serial.c | 2 +- arch/cris/arch-v32/drivers/axisflashmap.c | 2 +- arch/cris/arch-v32/drivers/mach-a3/nandflash.c | 2 +- arch/cris/arch-v32/drivers/mach-fs/nandflash.c | 2 +- arch/cris/arch-v32/drivers/sync_serial.c | 2 +- arch/cris/arch-v32/kernel/entry.S | 2 +- arch/cris/arch-v32/kernel/irq.c | 2 +- arch/cris/arch-v32/kernel/kgdb.c | 2 +- arch/cris/arch-v32/kernel/process.c | 2 +- arch/cris/arch-v32/kernel/signal.c | 2 +- arch/cris/arch-v32/mach-a3/arbiter.c | 4 +- arch/cris/arch-v32/mach-fs/arbiter.c | 2 +- arch/cris/boot/rescue/head_v10.S | 2 +- arch/cris/include/arch-v32/arch/hwregs/Makefile | 2 +- .../cris/include/arch-v32/arch/hwregs/iop/Makefile | 2 +- arch/cris/include/asm/pgtable.h | 2 +- arch/cris/kernel/traps.c | 2 +- arch/frv/include/asm/pci.h | 2 +- arch/frv/include/asm/spr-regs.h | 2 +- arch/frv/include/asm/virtconvert.h | 2 +- arch/frv/kernel/entry-table.S | 4 +- arch/ia64/Kconfig | 4 +- arch/ia64/include/asm/pal.h | 2 +- arch/ia64/include/asm/perfmon_default_smpl.h | 4 +- arch/ia64/include/asm/sn/bte.h | 2 +- arch/ia64/include/asm/sn/shub_mmr.h | 2 +- arch/ia64/include/asm/sn/shubio.h | 4 +- arch/ia64/kernel/cyclone.c | 2 +- arch/ia64/kernel/perfmon_default_smpl.c | 2 +- arch/ia64/kernel/smpboot.c | 2 +- arch/ia64/kernel/topology.c | 2 +- arch/ia64/kvm/process.c | 2 +- arch/ia64/lib/do_csum.S | 2 +- arch/ia64/sn/kernel/irq.c | 4 +- arch/ia64/sn/pci/pcibr/pcibr_dma.c | 2 +- arch/m32r/include/asm/m32104ut/m32104ut_pld.h | 2 +- arch/m32r/include/asm/m32700ut/m32700ut_pld.h | 2 +- arch/m32r/include/asm/opsput/opsput_pld.h | 2 +- arch/m32r/include/asm/pgtable-2level.h | 2 +- arch/m32r/mm/fault.c | 4 +- arch/m68k/atari/atakeyb.c | 2 +- arch/m68k/fpsp040/bindec.S | 2 +- arch/m68k/ifpsp060/src/fpsp.S | 10 ++-- arch/m68k/ifpsp060/src/pfpsp.S | 8 ++-- arch/m68k/include/asm/atariints.h | 2 +- arch/m68k/include/asm/bootstd.h | 2 +- arch/m68k/include/asm/commproc.h | 4 +- arch/m68k/include/asm/delay_no.h | 2 +- arch/m68k/include/asm/gpio.h | 2 +- arch/m68k/include/asm/m520xsim.h | 2 +- arch/m68k/include/asm/m523xsim.h | 2 +- arch/m68k/include/asm/m527xsim.h | 2 +- arch/m68k/include/asm/m5307sim.h | 2 +- arch/m68k/include/asm/m5407sim.h | 2 +- arch/m68k/include/asm/m68360_quicc.h | 2 +- arch/m68k/include/asm/mac_oss.h | 2 +- arch/m68k/include/asm/mac_via.h | 2 +- arch/m68k/include/asm/macintosh.h | 2 +- arch/m68k/include/asm/mcftimer.h | 2 +- arch/m68k/kernel/head.S | 12 ++--- arch/m68k/kernel/vmlinux.lds_no.S | 2 +- arch/m68k/platform/523x/config.c | 2 +- arch/m68k/platform/5272/intc.c | 2 +- arch/m68k/platform/527x/config.c | 2 +- arch/m68k/platform/528x/config.c | 2 +- arch/m68k/platform/coldfire/cache.c | 2 +- arch/m68k/platform/coldfire/entry.S | 2 +- arch/m68k/platform/coldfire/head.S | 2 +- arch/m68k/platform/coldfire/intc.c | 2 +- arch/m68k/platform/coldfire/sltimers.c | 2 +- arch/m68k/q40/README | 2 +- arch/microblaze/Makefile | 2 +- arch/microblaze/include/asm/io.h | 2 +- arch/microblaze/include/asm/pci-bridge.h | 2 +- arch/microblaze/include/asm/pci.h | 2 +- arch/microblaze/kernel/cpu/cache.c | 2 +- arch/microblaze/lib/memcpy.c | 8 ++-- arch/microblaze/lib/memmove.c | 6 +-- arch/microblaze/lib/memset.c | 2 +- arch/microblaze/pci/indirect_pci.c | 2 +- arch/microblaze/platform/generic/Kconfig.auto | 2 +- arch/mips/Kconfig | 2 +- arch/mips/Makefile | 4 +- arch/mips/alchemy/common/clocks.c | 2 +- arch/mips/cavium-octeon/executive/octeon-model.c | 2 +- arch/mips/cavium-octeon/octeon-platform.c | 2 +- arch/mips/cavium-octeon/setup.c | 2 +- arch/mips/fw/arc/promlib.c | 2 +- arch/mips/include/asm/dec/prom.h | 2 +- arch/mips/include/asm/floppy.h | 2 +- arch/mips/include/asm/hw_irq.h | 2 +- arch/mips/include/asm/io.h | 2 +- arch/mips/include/asm/irqflags.h | 2 +- arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h | 2 +- arch/mips/include/asm/mach-ip32/mc146818rtc.h | 2 +- .../mips/include/asm/mach-loongson/cs5536/cs5536.h | 2 +- arch/mips/include/asm/mach-pb1x00/pb1000.h | 2 +- arch/mips/include/asm/mach-pb1x00/pb1200.h | 2 +- arch/mips/include/asm/mach-pb1x00/pb1550.h | 2 +- arch/mips/include/asm/mach-powertv/dma-coherence.h | 2 +- arch/mips/include/asm/mipsregs.h | 4 +- arch/mips/include/asm/octeon/cvmx-bootinfo.h | 2 +- arch/mips/include/asm/octeon/cvmx-bootmem.h | 2 +- arch/mips/include/asm/octeon/cvmx-l2c.h | 2 +- arch/mips/include/asm/octeon/cvmx.h | 2 +- arch/mips/include/asm/paccess.h | 2 +- arch/mips/include/asm/pci/bridge.h | 2 +- .../include/asm/pmc-sierra/msp71xx/msp_regops.h | 2 +- arch/mips/include/asm/processor.h | 2 +- arch/mips/include/asm/sgi/ioc.h | 2 +- arch/mips/include/asm/sibyte/sb1250_mac.h | 4 +- arch/mips/include/asm/siginfo.h | 2 +- arch/mips/include/asm/sn/klconfig.h | 4 +- arch/mips/include/asm/sn/sn0/hubio.h | 2 +- arch/mips/include/asm/stackframe.h | 2 +- arch/mips/include/asm/war.h | 2 +- arch/mips/jz4740/board-qi_lb60.c | 4 +- arch/mips/kernel/cpu-bugs64.c | 2 +- arch/mips/kernel/perf_event_mipsxx.c | 2 +- arch/mips/kernel/process.c | 2 +- arch/mips/kernel/smp-mt.c | 2 +- arch/mips/kernel/time.c | 2 +- arch/mips/kernel/vpe.c | 2 +- arch/mips/lib/strnlen_user.S | 2 +- arch/mips/math-emu/dp_fsp.c | 2 +- arch/mips/math-emu/dp_mul.c | 2 +- arch/mips/math-emu/dsemul.c | 2 +- arch/mips/math-emu/sp_mul.c | 2 +- arch/mips/mm/cex-sb1.S | 2 +- arch/mips/mm/tlbex.c | 2 +- arch/mips/mti-malta/malta-smtc.c | 2 +- arch/mips/pci/ops-pmcmsp.c | 4 +- arch/mips/pci/pci-bcm1480.c | 2 +- arch/mips/pci/pci-octeon.c | 4 +- arch/mips/pci/pci.c | 2 +- arch/mips/pmc-sierra/msp71xx/msp_setup.c | 2 +- arch/mips/pnx833x/common/platform.c | 2 +- arch/mips/sgi-ip27/Kconfig | 2 +- arch/mips/sgi-ip27/TODO | 2 +- arch/mips/sgi-ip27/ip27-init.c | 2 +- arch/mips/sgi-ip27/ip27-irq.c | 2 +- arch/mn10300/include/asm/cpu-regs.h | 2 +- arch/parisc/include/asm/eisa_eeprom.h | 2 +- arch/parisc/kernel/entry.S | 10 ++-- arch/parisc/kernel/head.S | 2 +- arch/parisc/kernel/inventory.c | 2 +- arch/parisc/kernel/signal.c | 2 +- arch/parisc/kernel/syscall.S | 2 +- arch/parisc/kernel/syscall_table.S | 2 +- arch/parisc/math-emu/dfadd.c | 2 +- arch/parisc/math-emu/dfsub.c | 2 +- arch/parisc/math-emu/fmpyfadd.c | 8 ++-- arch/parisc/math-emu/sfadd.c | 2 +- arch/parisc/math-emu/sfsub.c | 2 +- arch/powerpc/include/asm/bitops.h | 4 +- arch/powerpc/include/asm/compat.h | 2 +- arch/powerpc/include/asm/cpm.h | 2 +- arch/powerpc/include/asm/cpm1.h | 2 +- arch/powerpc/include/asm/hvcall.h | 2 +- arch/powerpc/include/asm/kprobes.h | 2 +- arch/powerpc/include/asm/lppaca.h | 2 +- arch/powerpc/include/asm/page_64.h | 2 +- arch/powerpc/include/asm/pasemi_dma.h | 2 +- arch/powerpc/include/asm/pci-bridge.h | 2 +- arch/powerpc/include/asm/pmac_feature.h | 4 +- arch/powerpc/include/asm/pte-common.h | 4 +- arch/powerpc/include/asm/reg_booke.h | 2 +- arch/powerpc/include/asm/spu_priv1.h | 2 +- arch/powerpc/include/asm/uninorth.h | 2 +- arch/powerpc/include/asm/vdso_datapage.h | 2 +- arch/powerpc/kernel/btext.c | 2 +- arch/powerpc/kernel/exceptions-64e.S | 2 +- arch/powerpc/kernel/exceptions-64s.S | 2 +- arch/powerpc/kernel/head_40x.S | 2 +- arch/powerpc/kernel/head_44x.S | 2 +- arch/powerpc/kernel/head_64.S | 2 +- arch/powerpc/kernel/head_fsl_booke.S | 2 +- arch/powerpc/kernel/l2cr_6xx.S | 2 +- arch/powerpc/kernel/lparcfg.c | 2 +- arch/powerpc/kernel/perf_event.c | 2 +- arch/powerpc/kernel/ppc_save_regs.S | 2 +- arch/powerpc/kernel/prom.c | 4 +- arch/powerpc/kernel/ptrace.c | 2 +- arch/powerpc/kernel/rtasd.c | 2 +- arch/powerpc/kernel/swsusp_32.S | 2 +- arch/powerpc/kernel/traps.c | 2 +- arch/powerpc/kernel/udbg_16550.c | 2 +- arch/powerpc/kernel/vdso32/sigtramp.S | 2 +- arch/powerpc/kernel/vdso64/sigtramp.S | 2 +- arch/powerpc/mm/hash_low_64.S | 24 +++++----- arch/powerpc/mm/hash_utils_64.c | 2 +- arch/powerpc/mm/mem.c | 2 +- arch/powerpc/mm/numa.c | 10 ++-- arch/powerpc/mm/tlb_low_64e.S | 4 +- arch/powerpc/oprofile/op_model_cell.c | 6 +-- arch/powerpc/oprofile/op_model_power4.c | 2 +- arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c | 6 +-- arch/powerpc/platforms/52xx/mpc52xx_pic.c | 2 +- arch/powerpc/platforms/cell/spufs/lscsa_alloc.c | 2 +- arch/powerpc/platforms/cell/spufs/sched.c | 2 +- arch/powerpc/platforms/cell/spufs/spu_restore.c | 2 +- arch/powerpc/platforms/iseries/mf.c | 2 +- arch/powerpc/platforms/iseries/viopath.c | 8 ++-- arch/powerpc/platforms/pasemi/dma_lib.c | 4 +- arch/powerpc/platforms/powermac/Makefile | 2 +- arch/powerpc/platforms/powermac/low_i2c.c | 2 +- arch/powerpc/platforms/powermac/pci.c | 2 +- arch/powerpc/platforms/pseries/dlpar.c | 2 +- arch/powerpc/platforms/pseries/eeh.c | 2 +- arch/powerpc/platforms/pseries/hotplug-cpu.c | 2 +- arch/powerpc/platforms/pseries/iommu.c | 6 +-- arch/powerpc/platforms/pseries/xics.c | 2 +- arch/powerpc/sysdev/axonram.c | 2 +- arch/powerpc/sysdev/bestcomm/bestcomm.h | 2 +- arch/powerpc/sysdev/bestcomm/bestcomm_priv.h | 2 +- arch/powerpc/sysdev/cpm1.c | 2 +- arch/powerpc/sysdev/indirect_pci.c | 2 +- arch/powerpc/sysdev/ppc4xx_pci.h | 2 +- arch/s390/include/asm/atomic.h | 2 +- arch/s390/include/asm/cio.h | 2 +- arch/s390/kernel/reipl64.S | 2 +- arch/s390/kernel/setup.c | 2 +- arch/s390/kernel/time.c | 6 +-- arch/s390/kernel/vtime.c | 2 +- arch/s390/kvm/kvm-s390.c | 2 +- arch/s390/kvm/priv.c | 2 +- arch/s390/mm/fault.c | 2 +- arch/score/Makefile | 2 +- arch/sh/Kconfig.debug | 2 +- arch/sh/boards/mach-dreamcast/irq.c | 2 +- arch/sh/boards/mach-ecovec24/setup.c | 2 +- arch/sh/drivers/pci/pci-sh7751.h | 2 +- arch/sh/drivers/pci/pci.c | 2 +- arch/sh/include/asm/page.h | 2 +- arch/sh/include/asm/pgtable_32.h | 2 +- arch/sh/include/asm/unaligned-sh4a.h | 2 +- arch/sh/include/mach-common/mach/highlander.h | 4 +- arch/sh/include/mach-common/mach/r2d.h | 6 +-- arch/sh/kernel/cpu/clock-cpg.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7786.c | 2 +- arch/sh/kernel/irq.c | 2 +- arch/sh/kernel/setup.c | 2 +- arch/sh/lib64/copy_user_memcpy.S | 2 +- arch/sh/lib64/memcpy.S | 2 +- arch/sparc/include/asm/hypervisor.h | 20 ++++---- arch/sparc/include/asm/ns87303.h | 2 +- arch/sparc/include/asm/pcr.h | 2 +- arch/sparc/include/asm/ptrace.h | 2 +- arch/sparc/kernel/entry.S | 4 +- arch/sparc/kernel/head_64.S | 2 +- arch/sparc/kernel/init_task.c | 2 +- arch/sparc/kernel/of_device_64.c | 2 +- arch/sparc/kernel/perf_event.c | 2 +- arch/sparc/math-emu/Makefile | 2 +- arch/tile/Kconfig | 2 +- arch/tile/include/hv/drv_xgbe_intf.h | 2 +- arch/tile/include/hv/hypervisor.h | 4 +- arch/tile/kernel/pci.c | 4 +- arch/tile/mm/fault.c | 2 +- arch/tile/mm/hugetlbpage.c | 2 +- arch/um/Kconfig.net | 2 +- arch/unicore32/include/mach/regs-umal.h | 4 +- arch/unicore32/kernel/head.S | 2 +- arch/xtensa/include/asm/dma.h | 2 +- arch/xtensa/kernel/entry.S | 2 +- block/blk-cgroup.c | 4 +- block/blk-core.c | 2 +- block/blk-throttle.c | 2 +- block/blk.h | 2 +- block/cfq-iosched.c | 2 +- block/genhd.c | 2 +- crypto/ansi_cprng.c | 2 +- crypto/async_tx/async_xor.c | 2 +- crypto/gf128mul.c | 2 +- crypto/vmac.c | 2 +- crypto/xts.c | 2 +- drivers/acpi/apei/ghes.c | 2 +- drivers/acpi/processor_throttling.c | 2 +- drivers/acpi/video.c | 4 +- drivers/amba/bus.c | 2 +- drivers/ata/ahci.c | 2 +- drivers/ata/ahci.h | 4 +- drivers/ata/ata_piix.c | 10 ++-- drivers/ata/libata-core.c | 2 +- drivers/ata/libata-eh.c | 10 ++-- drivers/ata/libata-scsi.c | 2 +- drivers/ata/libata-sff.c | 4 +- drivers/ata/pata_amd.c | 2 +- drivers/ata/pata_arasan_cf.c | 8 ++-- drivers/ata/pata_bf54x.c | 2 +- drivers/ata/pata_cs5520.c | 2 +- drivers/ata/pata_mpiix.c | 2 +- drivers/ata/pata_rz1000.c | 2 +- drivers/ata/pata_sil680.c | 4 +- drivers/ata/pata_sis.c | 4 +- drivers/ata/pata_triflex.c | 2 +- drivers/ata/sata_fsl.c | 4 +- drivers/ata/sata_mv.c | 4 +- drivers/ata/sata_nv.c | 2 +- drivers/ata/sata_via.c | 2 +- drivers/atm/ambassador.c | 2 +- drivers/atm/firestream.c | 2 +- drivers/atm/fore200e.h | 4 +- drivers/atm/horizon.c | 10 ++-- drivers/atm/idt77252.c | 2 +- drivers/atm/idt77252.h | 2 +- drivers/atm/iphase.c | 6 +-- drivers/atm/lanai.c | 4 +- drivers/auxdisplay/cfag12864b.c | 4 +- drivers/base/power/runtime.c | 2 +- drivers/base/sys.c | 14 +++--- drivers/block/DAC960.c | 2 +- drivers/block/drbd/drbd_actlog.c | 2 +- drivers/block/drbd/drbd_int.h | 10 ++-- drivers/block/drbd/drbd_main.c | 4 +- drivers/block/drbd/drbd_receiver.c | 2 +- drivers/block/drbd/drbd_vli.h | 2 +- drivers/block/hd.c | 2 +- drivers/block/viodasd.c | 2 +- drivers/block/xsysace.c | 8 ++-- drivers/bluetooth/hci_ll.c | 2 +- drivers/cdrom/cdrom.c | 4 +- drivers/char/agp/agp.h | 2 +- drivers/char/agp/amd-k7-agp.c | 2 +- drivers/char/agp/sworks-agp.c | 2 +- drivers/char/agp/via-agp.c | 2 +- drivers/char/ipmi/ipmi_poweroff.c | 2 +- drivers/char/ipmi/ipmi_si_intf.c | 4 +- drivers/char/mbcs.h | 4 +- drivers/char/mwave/3780i.h | 2 +- drivers/char/nwbutton.c | 2 +- drivers/char/pcmcia/cm4000_cs.c | 2 +- drivers/char/pcmcia/synclink_cs.c | 4 +- drivers/char/random.c | 2 +- drivers/char/sonypi.c | 4 +- drivers/char/xilinx_hwicap/xilinx_hwicap.c | 2 +- drivers/cpufreq/cpufreq.c | 2 +- drivers/crypto/amcc/crypto4xx_sa.c | 2 +- drivers/crypto/amcc/crypto4xx_sa.h | 2 +- drivers/crypto/ixp4xx_crypto.c | 2 +- drivers/dma/at_hdmac.c | 2 +- drivers/dma/coh901318.c | 2 +- drivers/dma/intel_mid_dma.c | 8 ++-- drivers/dma/intel_mid_dma_regs.h | 4 +- drivers/dma/mpc512x_dma.c | 2 +- drivers/dma/ste_dma40.c | 4 +- drivers/edac/Kconfig | 2 +- drivers/edac/cpc925_edac.c | 2 +- drivers/edac/edac_core.h | 8 ++-- drivers/edac/edac_device.c | 4 +- drivers/edac/edac_device_sysfs.c | 4 +- drivers/edac/edac_mc.c | 2 +- drivers/edac/edac_mc_sysfs.c | 2 +- drivers/edac/edac_pci_sysfs.c | 4 +- drivers/edac/i5000_edac.c | 2 +- drivers/edac/i5100_edac.c | 2 +- drivers/edac/i5400_edac.c | 4 +- drivers/edac/i7300_edac.c | 2 +- drivers/edac/i7core_edac.c | 2 +- drivers/edac/i82443bxgx_edac.c | 4 +- drivers/edac/mce_amd_inj.c | 2 +- drivers/edac/r82600_edac.c | 6 +-- drivers/firewire/net.c | 2 +- drivers/gpio/mc33880.c | 2 +- drivers/gpu/drm/drm_crtc.c | 4 +- drivers/gpu/drm/drm_mm.c | 2 +- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/intel_dp.c | 2 +- drivers/gpu/drm/i915/intel_sdvo_regs.h | 2 +- drivers/gpu/drm/mga/mga_dma.c | 2 +- drivers/gpu/drm/nouveau/nouveau_channel.c | 4 +- drivers/gpu/drm/nouveau/nouveau_drv.h | 2 +- drivers/gpu/drm/nouveau/nouveau_state.c | 2 +- drivers/gpu/drm/nouveau/nv04_crtc.c | 4 +- drivers/gpu/drm/nouveau/nv40_graph.c | 2 +- drivers/gpu/drm/radeon/atombios.h | 34 +++++++------- drivers/gpu/drm/radeon/evergreen_cs.c | 2 +- drivers/gpu/drm/radeon/r300.c | 2 +- drivers/gpu/drm/radeon/r300_reg.h | 4 +- drivers/gpu/drm/radeon/r600_cs.c | 2 +- drivers/gpu/drm/radeon/r600_hdmi.c | 2 +- drivers/gpu/drm/radeon/radeon.h | 4 +- drivers/gpu/drm/radeon/radeon_cp.c | 2 +- drivers/gpu/drm/radeon/radeon_cursor.c | 2 +- drivers/gpu/drm/radeon/radeon_device.c | 2 +- drivers/gpu/drm/radeon/radeon_display.c | 2 +- drivers/gpu/drm/radeon/radeon_drv.h | 2 +- drivers/gpu/drm/radeon/radeon_object.h | 2 +- drivers/gpu/drm/radeon/radeon_state.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 2 +- drivers/gpu/vga/vgaarb.c | 4 +- drivers/hid/hid-core.c | 4 +- drivers/hid/hid-debug.c | 2 +- drivers/hid/hid-magicmouse.c | 2 +- drivers/hid/hid-picolcd.c | 4 +- drivers/hid/hid-roccat-kone.h | 2 +- drivers/hwmon/abituguru.c | 2 +- drivers/hwmon/abituguru3.c | 2 +- drivers/hwmon/adm1026.c | 2 +- drivers/hwmon/lm85.c | 2 +- drivers/hwmon/lm90.c | 2 +- drivers/hwmon/sht15.c | 6 +-- drivers/hwmon/tmp102.c | 2 +- drivers/hwmon/w83791d.c | 2 +- drivers/hwmon/w83792d.c | 2 +- drivers/hwmon/w83793.c | 2 +- drivers/i2c/algos/i2c-algo-pca.c | 2 +- drivers/i2c/busses/i2c-ali1535.c | 2 +- drivers/i2c/busses/i2c-ali15x3.c | 2 +- drivers/i2c/busses/i2c-davinci.c | 2 +- drivers/i2c/busses/i2c-designware.c | 2 +- drivers/i2c/busses/i2c-elektor.c | 2 +- drivers/i2c/busses/i2c-i801.c | 2 +- drivers/i2c/busses/i2c-ibm_iic.c | 4 +- drivers/i2c/busses/i2c-intel-mid.c | 14 +++--- drivers/i2c/busses/i2c-isch.c | 2 +- drivers/i2c/busses/i2c-mxs.c | 2 +- drivers/i2c/busses/i2c-nomadik.c | 8 ++-- drivers/i2c/busses/i2c-s6000.c | 2 +- drivers/i2c/busses/i2c-stu300.c | 4 +- drivers/i2c/busses/i2c-tegra.c | 2 +- drivers/i2c/busses/i2c-xiic.c | 2 +- drivers/i2c/i2c-core.c | 2 +- drivers/ide/cy82c693.c | 2 +- drivers/ide/ide-floppy.c | 2 +- drivers/ide/ide-taskfile.c | 2 +- drivers/ide/piix.c | 4 +- drivers/ide/sis5513.c | 4 +- drivers/ide/triflex.c | 2 +- drivers/ide/via82cxxx.c | 2 +- drivers/infiniband/hw/amso1100/c2_ae.c | 2 +- drivers/infiniband/hw/amso1100/c2_qp.c | 2 +- drivers/infiniband/hw/amso1100/c2_wr.h | 4 +- drivers/infiniband/hw/ipath/ipath_driver.c | 2 +- drivers/infiniband/hw/ipath/ipath_file_ops.c | 2 +- drivers/infiniband/hw/ipath/ipath_init_chip.c | 2 +- drivers/infiniband/hw/ipath/ipath_ud.c | 4 +- drivers/infiniband/hw/ipath/ipath_user_sdma.c | 2 +- drivers/infiniband/hw/nes/nes_cm.c | 2 +- drivers/infiniband/hw/nes/nes_hw.c | 4 +- drivers/infiniband/hw/nes/nes_nic.c | 2 +- drivers/infiniband/hw/qib/qib.h | 2 +- drivers/infiniband/hw/qib/qib_file_ops.c | 4 +- drivers/infiniband/hw/qib/qib_iba6120.c | 4 +- drivers/infiniband/hw/qib/qib_iba7220.c | 6 +-- drivers/infiniband/hw/qib/qib_iba7322.c | 8 ++-- drivers/infiniband/hw/qib/qib_init.c | 2 +- drivers/infiniband/hw/qib/qib_mad.h | 2 +- drivers/infiniband/hw/qib/qib_twsi.c | 2 +- drivers/infiniband/hw/qib/qib_ud.c | 4 +- drivers/infiniband/hw/qib/qib_user_sdma.c | 2 +- drivers/infiniband/ulp/iser/iscsi_iser.h | 2 +- drivers/input/joydev.c | 4 +- drivers/input/joystick/a3d.c | 4 +- drivers/input/keyboard/davinci_keyscan.c | 2 +- drivers/input/misc/adxl34x.c | 2 +- drivers/input/misc/keyspan_remote.c | 2 +- drivers/input/misc/wistron_btns.c | 2 +- drivers/input/mouse/bcm5974.c | 2 +- drivers/input/mouse/synaptics_i2c.c | 2 +- drivers/input/mouse/vsxxxaa.c | 2 +- drivers/input/serio/hp_sdc.c | 2 +- drivers/input/serio/xilinx_ps2.c | 2 +- drivers/input/touchscreen/intel-mid-touch.c | 2 +- drivers/input/touchscreen/ucb1400_ts.c | 2 +- drivers/input/touchscreen/wm9705.c | 2 +- drivers/input/touchscreen/wm9712.c | 2 +- drivers/input/touchscreen/wm9713.c | 2 +- drivers/input/touchscreen/wm97xx-core.c | 4 +- drivers/isdn/hardware/eicon/divacapi.h | 2 +- drivers/isdn/hardware/eicon/io.h | 2 +- drivers/isdn/hardware/eicon/message.c | 4 +- drivers/isdn/hardware/eicon/pc.h | 2 +- drivers/isdn/hardware/eicon/um_idi.c | 2 +- drivers/isdn/hardware/mISDN/hfcmulti.c | 4 +- drivers/isdn/hardware/mISDN/hfcpci.c | 2 +- drivers/isdn/hisax/hfc_pci.c | 2 +- drivers/isdn/hisax/hfc_sx.c | 2 +- drivers/isdn/hisax/hfc_usb.h | 2 +- drivers/isdn/hisax/l3dss1.c | 4 +- drivers/isdn/hisax/l3ni1.c | 4 +- drivers/isdn/hisax/nj_s.c | 2 +- drivers/isdn/hisax/st5481_b.c | 2 +- drivers/isdn/hisax/st5481_usb.c | 2 +- drivers/isdn/hisax/teles_cs.c | 2 +- drivers/isdn/hysdn/hysdn_sched.c | 2 +- drivers/isdn/i4l/isdn_net.c | 4 +- drivers/isdn/i4l/isdn_ppp.c | 4 +- drivers/isdn/i4l/isdn_tty.c | 2 +- drivers/isdn/isdnloop/isdnloop.c | 2 +- drivers/isdn/mISDN/dsp.h | 2 +- drivers/isdn/mISDN/dsp_cmx.c | 4 +- drivers/isdn/mISDN/dsp_core.c | 8 ++-- drivers/isdn/mISDN/dsp_dtmf.c | 4 +- drivers/isdn/mISDN/dsp_tones.c | 2 +- drivers/isdn/mISDN/l1oip_core.c | 6 +-- drivers/isdn/mISDN/layer2.c | 4 +- drivers/leds/leds-pca9532.c | 2 +- drivers/leds/leds-wm8350.c | 4 +- drivers/lguest/lguest_user.c | 2 +- drivers/macintosh/adbhid.c | 2 +- drivers/macintosh/macio-adb.c | 2 +- drivers/macintosh/therm_adt746x.c | 2 +- drivers/macintosh/therm_pm72.c | 6 +-- drivers/macintosh/therm_windtunnel.c | 2 +- drivers/md/bitmap.h | 2 +- drivers/md/dm-region-hash.c | 2 +- drivers/md/faulty.c | 2 +- drivers/md/md.c | 2 +- drivers/md/md.h | 2 +- drivers/md/raid10.c | 6 +-- drivers/md/raid10.h | 4 +- drivers/media/common/saa7146_i2c.c | 8 ++-- drivers/media/common/tuners/mxl5005s.c | 2 +- drivers/media/common/tuners/tda18271.h | 2 +- drivers/media/dvb/b2c2/flexcop-pci.c | 2 +- drivers/media/dvb/bt8xx/dvb-bt8xx.c | 4 +- drivers/media/dvb/dvb-core/dvb_frontend.c | 4 +- drivers/media/dvb/dvb-usb/af9005-fe.c | 8 ++-- drivers/media/dvb/dvb-usb/friio.h | 2 +- drivers/media/dvb/dvb-usb/lmedm04.c | 12 ++--- drivers/media/dvb/frontends/atbm8830.h | 2 +- drivers/media/dvb/frontends/au8522_dig.c | 6 +-- drivers/media/dvb/frontends/bcm3510.c | 6 +-- drivers/media/dvb/frontends/cx22700.c | 2 +- drivers/media/dvb/frontends/cx22702.c | 6 +-- drivers/media/dvb/frontends/cx24110.c | 2 +- drivers/media/dvb/frontends/cx24113.h | 2 +- drivers/media/dvb/frontends/cx24123.c | 2 +- drivers/media/dvb/frontends/drx397xD.c | 2 +- drivers/media/dvb/frontends/mb86a16.c | 2 +- drivers/media/dvb/frontends/mb86a20s.c | 2 +- drivers/media/dvb/frontends/mt312.c | 2 +- drivers/media/dvb/frontends/s5h1420.c | 2 +- drivers/media/dvb/frontends/stb6100.c | 2 +- drivers/media/dvb/frontends/stv0297.c | 2 +- drivers/media/dvb/frontends/stv0367.c | 2 +- drivers/media/dvb/frontends/stv0900_priv.h | 2 +- drivers/media/dvb/frontends/stv090x.c | 12 ++--- drivers/media/dvb/mantis/mantis_uart.c | 2 +- drivers/media/dvb/ngene/ngene-core.c | 4 +- drivers/media/dvb/pluto2/pluto2.c | 10 ++-- drivers/media/dvb/siano/smsdvb.c | 2 +- drivers/media/dvb/ttpci/av7110.c | 2 +- drivers/media/dvb/ttpci/budget-patch.c | 2 +- drivers/media/dvb/ttusb-dec/ttusb_dec.c | 2 +- drivers/media/radio/radio-mr800.c | 2 +- drivers/media/radio/si4713-i2c.c | 2 +- drivers/media/radio/wl128x/fmdrv_common.c | 6 +-- drivers/media/radio/wl128x/fmdrv_common.h | 2 +- drivers/media/rc/ene_ir.c | 4 +- drivers/media/rc/imon.c | 2 +- drivers/media/rc/ir-raw.c | 2 +- drivers/media/rc/keymaps/rc-lme2510.c | 4 +- drivers/media/rc/keymaps/rc-msi-tvanywhere.c | 2 +- drivers/media/rc/keymaps/rc-norwood.c | 2 +- drivers/media/rc/rc-main.c | 4 +- drivers/media/video/au0828/au0828-video.c | 2 +- drivers/media/video/bt8xx/bttv-cards.c | 6 +-- drivers/media/video/bt8xx/bttv-gpio.c | 2 +- drivers/media/video/cafe_ccic.c | 2 +- drivers/media/video/cx18/cx18-av-core.h | 2 +- drivers/media/video/cx18/cx18-ioctl.c | 2 +- drivers/media/video/cx18/cx18-vbi.c | 2 +- drivers/media/video/cx231xx/cx231xx-avcore.c | 2 +- drivers/media/video/cx231xx/cx231xx-vbi.c | 2 +- drivers/media/video/cx231xx/cx231xx-video.c | 2 +- drivers/media/video/cx23885/cimax2.c | 2 +- drivers/media/video/cx23885/cx23885.h | 2 +- drivers/media/video/cx25840/cx25840-core.c | 10 ++-- drivers/media/video/davinci/dm644x_ccdc.c | 4 +- drivers/media/video/davinci/vpfe_capture.c | 2 +- drivers/media/video/em28xx/em28xx-video.c | 4 +- drivers/media/video/gspca/gl860/gl860-mi1320.c | 2 +- drivers/media/video/gspca/gspca.c | 4 +- drivers/media/video/gspca/mars.c | 2 +- drivers/media/video/gspca/mr97310a.c | 2 +- drivers/media/video/gspca/ov519.c | 4 +- drivers/media/video/gspca/sonixb.c | 2 +- drivers/media/video/gspca/spca500.c | 4 +- drivers/media/video/gspca/spca508.c | 2 +- drivers/media/video/gspca/sq905.c | 2 +- drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c | 2 +- drivers/media/video/hexium_gemini.c | 2 +- drivers/media/video/ivtv/ivtv-firmware.c | 4 +- drivers/media/video/ivtv/ivtvfb.c | 2 +- drivers/media/video/msp3400-driver.c | 4 +- drivers/media/video/msp3400-kthreads.c | 2 +- drivers/media/video/omap/omap_vout.c | 4 +- drivers/media/video/omap/omap_voutlib.c | 6 +-- drivers/media/video/omap1_camera.c | 4 +- drivers/media/video/omap3isp/isp.c | 8 ++-- drivers/media/video/omap3isp/ispccdc.h | 4 +- drivers/media/video/omap3isp/ispccp2.c | 2 +- drivers/media/video/omap3isp/ispcsi2.c | 2 +- drivers/media/video/omap3isp/isppreview.c | 20 ++++---- drivers/media/video/omap3isp/isppreview.h | 2 +- drivers/media/video/omap3isp/ispqueue.h | 4 +- drivers/media/video/omap3isp/ispresizer.c | 4 +- drivers/media/video/omap3isp/ispvideo.c | 6 +-- drivers/media/video/ov6650.c | 2 +- drivers/media/video/ov9640.c | 2 +- drivers/media/video/pvrusb2/pvrusb2-eeprom.c | 2 +- drivers/media/video/pvrusb2/pvrusb2-hdw.h | 2 +- drivers/media/video/pxa_camera.c | 2 +- drivers/media/video/s5p-fimc/fimc-reg.c | 2 +- drivers/media/video/saa7134/saa7134-cards.c | 4 +- drivers/media/video/saa7164/saa7164-cmd.c | 2 +- drivers/media/video/saa7164/saa7164-fw.c | 2 +- drivers/media/video/saa7164/saa7164-types.h | 2 +- drivers/media/video/sn9c102/sn9c102_core.c | 2 +- drivers/media/video/sn9c102/sn9c102_sensor.h | 2 +- drivers/media/video/tcm825x.c | 4 +- drivers/media/video/tvaudio.c | 10 ++-- drivers/media/video/uvc/uvc_video.c | 8 ++-- drivers/media/video/v4l2-ioctl.c | 2 +- drivers/media/video/vpx3220.c | 2 +- drivers/media/video/zoran/videocodec.h | 2 +- drivers/media/video/zoran/zoran.h | 2 +- drivers/media/video/zoran/zoran_driver.c | 2 +- drivers/memstick/core/mspro_block.c | 2 +- drivers/memstick/host/r592.c | 2 +- drivers/memstick/host/r592.h | 6 +-- drivers/message/fusion/lsi/mpi_log_fc.h | 4 +- drivers/message/fusion/lsi/mpi_log_sas.h | 14 +++--- drivers/message/fusion/mptbase.c | 6 +-- drivers/message/fusion/mptctl.c | 4 +- drivers/message/fusion/mptsas.c | 8 ++-- drivers/message/i2o/README | 2 +- drivers/message/i2o/device.c | 8 ++-- drivers/message/i2o/i2o_block.c | 4 +- drivers/message/i2o/i2o_block.h | 2 +- drivers/message/i2o/i2o_scsi.c | 2 +- drivers/mfd/Kconfig | 2 +- drivers/mfd/ab8500-gpadc.c | 2 +- drivers/mfd/ezx-pcap.c | 4 +- drivers/mfd/omap-usb-host.c | 2 +- drivers/mfd/pcf50633-core.c | 4 +- drivers/mfd/twl6030-irq.c | 4 +- drivers/mfd/ucb1400_core.c | 2 +- drivers/misc/bmp085.c | 4 +- drivers/misc/c2port/c2port-duramar2150.c | 2 +- drivers/misc/ibmasm/remote.h | 2 +- drivers/misc/iwmc3200top/main.c | 2 +- drivers/misc/kgdbts.c | 2 +- drivers/misc/sgi-gru/grukservices.c | 2 +- drivers/misc/sgi-gru/grutables.h | 2 +- drivers/misc/ti-st/st_kim.c | 2 +- drivers/mmc/card/mmc_test.c | 2 +- drivers/mmc/core/mmc.c | 2 +- drivers/mmc/core/mmc_ops.c | 2 +- drivers/mmc/core/sdio_irq.c | 2 +- drivers/mmc/host/atmel-mci.c | 4 +- drivers/mmc/host/mmc_spi.c | 2 +- drivers/mmc/host/s3cmci.c | 6 +-- drivers/mmc/host/tmio_mmc_pio.c | 2 +- drivers/mmc/host/wbsd.c | 6 +-- drivers/mtd/chips/Kconfig | 2 +- drivers/mtd/chips/cfi_cmdset_0001.c | 4 +- drivers/mtd/chips/cfi_cmdset_0002.c | 10 ++-- drivers/mtd/chips/cfi_util.c | 2 +- drivers/mtd/chips/jedec_probe.c | 2 +- drivers/mtd/devices/block2mtd.c | 2 +- drivers/mtd/devices/doc2001plus.c | 2 +- drivers/mtd/devices/docecc.c | 4 +- drivers/mtd/devices/lart.c | 4 +- drivers/mtd/devices/pmc551.c | 4 +- drivers/mtd/lpddr/lpddr_cmds.c | 4 +- drivers/mtd/maps/ceiva.c | 4 +- drivers/mtd/maps/cfi_flagadm.c | 2 +- drivers/mtd/maps/pcmciamtd.c | 2 +- drivers/mtd/maps/pmcmsp-flash.c | 2 +- drivers/mtd/maps/sc520cdp.c | 2 +- drivers/mtd/maps/tqm8xxl.c | 2 +- drivers/mtd/mtdblock.c | 2 +- drivers/mtd/mtdchar.c | 2 +- drivers/mtd/nand/Kconfig | 2 +- drivers/mtd/nand/ams-delta.c | 2 +- drivers/mtd/nand/autcpu12.c | 2 +- drivers/mtd/nand/cs553x_nand.c | 2 +- drivers/mtd/nand/denali.c | 6 +-- drivers/mtd/nand/diskonchip.c | 8 ++-- drivers/mtd/nand/fsl_elbc_nand.c | 2 +- drivers/mtd/nand/fsmc_nand.c | 10 ++-- drivers/mtd/nand/nand_base.c | 2 +- drivers/mtd/nand/nand_bbt.c | 2 +- drivers/mtd/nand/nandsim.c | 2 +- drivers/mtd/nand/nomadik_nand.c | 2 +- drivers/mtd/nand/pasemi_nand.c | 2 +- drivers/mtd/nand/plat_nand.c | 2 +- drivers/mtd/nand/pxa3xx_nand.c | 2 +- drivers/mtd/nand/r852.c | 10 ++-- drivers/mtd/nand/sh_flctl.c | 2 +- drivers/mtd/nand/sm_common.c | 2 +- drivers/mtd/nand/tmio_nand.c | 2 +- drivers/mtd/onenand/omap2.c | 4 +- drivers/mtd/onenand/onenand_sim.c | 4 +- drivers/mtd/sm_ftl.c | 4 +- drivers/mtd/ubi/scan.c | 2 +- drivers/net/3c501.c | 6 +-- drivers/net/3c523.c | 2 +- drivers/net/3c527.c | 4 +- drivers/net/3c59x.c | 2 +- drivers/net/acenic.c | 4 +- drivers/net/amd8111e.c | 2 +- drivers/net/at1700.c | 2 +- drivers/net/atl1e/atl1e_main.c | 2 +- drivers/net/atlx/atl2.c | 2 +- drivers/net/bcm63xx_enet.c | 2 +- drivers/net/benet/be_cmds.c | 2 +- drivers/net/benet/be_main.c | 2 +- drivers/net/bna/bna_hw.h | 2 +- drivers/net/bnx2x/bnx2x.h | 2 +- drivers/net/bnx2x/bnx2x_hsi.h | 2 +- drivers/net/bnx2x/bnx2x_link.c | 14 +++--- drivers/net/bnx2x/bnx2x_main.c | 10 ++-- drivers/net/bnx2x/bnx2x_reg.h | 44 +++++++++--------- drivers/net/bonding/bond_alb.h | 2 +- drivers/net/caif/caif_shmcore.c | 2 +- drivers/net/caif/caif_spi.c | 2 +- drivers/net/caif/caif_spi_slave.c | 4 +- drivers/net/can/at91_can.c | 4 +- drivers/net/can/c_can/c_can.c | 4 +- drivers/net/can/janz-ican3.c | 8 ++-- drivers/net/can/mscan/mscan.c | 2 +- drivers/net/can/sja1000/sja1000.c | 2 +- drivers/net/can/softing/softing.h | 2 +- drivers/net/can/softing/softing_main.c | 2 +- drivers/net/can/ti_hecc.c | 2 +- drivers/net/can/usb/ems_usb.c | 2 +- drivers/net/can/usb/esd_usb2.c | 2 +- drivers/net/cassini.c | 4 +- drivers/net/cassini.h | 2 +- drivers/net/chelsio/mv88e1xxx.c | 2 +- drivers/net/chelsio/pm3393.c | 2 +- drivers/net/chelsio/sge.c | 2 +- drivers/net/chelsio/vsc7326.c | 2 +- drivers/net/cris/eth_v10.c | 2 +- drivers/net/cxgb3/sge.c | 2 +- drivers/net/cxgb3/t3_hw.c | 6 +-- drivers/net/cxgb4/t4_hw.c | 2 +- drivers/net/cxgb4vf/cxgb4vf_main.c | 2 +- drivers/net/cxgb4vf/sge.c | 8 ++-- drivers/net/davinci_emac.c | 8 ++-- drivers/net/e1000/e1000_ethtool.c | 2 +- drivers/net/e1000/e1000_hw.h | 2 +- drivers/net/e1000/e1000_main.c | 2 +- drivers/net/e1000e/netdev.c | 2 +- drivers/net/enc28j60_hw.h | 2 +- drivers/net/eth16i.c | 2 +- drivers/net/ethoc.c | 2 +- drivers/net/fec.h | 4 +- drivers/net/forcedeth.c | 14 +++--- drivers/net/gianfar.h | 2 +- drivers/net/hamradio/Makefile | 2 +- drivers/net/hamradio/yam.c | 2 +- drivers/net/hp100.c | 16 +++---- drivers/net/hp100.h | 2 +- drivers/net/ibm_newemac/tah.c | 2 +- drivers/net/ibmlana.c | 4 +- drivers/net/ibmlana.h | 2 +- drivers/net/igb/e1000_mac.c | 4 +- drivers/net/igb/e1000_phy.c | 2 +- drivers/net/igb/igb_main.c | 14 +++--- drivers/net/igbvf/netdev.c | 2 +- drivers/net/ipg.c | 28 +++++------ drivers/net/irda/ali-ircc.c | 4 +- drivers/net/irda/donauboe.c | 2 +- drivers/net/irda/donauboe.h | 2 +- drivers/net/irda/girbil-sir.c | 2 +- drivers/net/irda/irda-usb.c | 4 +- drivers/net/irda/mcs7780.c | 6 +-- drivers/net/irda/nsc-ircc.c | 2 +- drivers/net/irda/nsc-ircc.h | 2 +- drivers/net/irda/pxaficp_ir.c | 4 +- drivers/net/irda/smsc-ircc2.c | 2 +- drivers/net/irda/via-ircc.c | 4 +- drivers/net/irda/vlsi_ir.h | 4 +- drivers/net/ixgbe/ixgbe_dcb.c | 2 +- drivers/net/ixgbe/ixgbe_dcb_nl.c | 4 +- drivers/net/ixgbe/ixgbe_main.c | 8 ++-- drivers/net/ixgbe/ixgbe_phy.c | 2 +- drivers/net/ixgbe/ixgbe_x540.c | 2 +- drivers/net/ixgbevf/ixgbevf_main.c | 2 +- drivers/net/ks8842.c | 2 +- drivers/net/ks8851.c | 8 ++-- drivers/net/ks8851_mll.c | 4 +- drivers/net/lib8390.c | 4 +- drivers/net/lp486e.c | 2 +- drivers/net/meth.h | 4 +- drivers/net/mlx4/en_main.c | 2 +- drivers/net/mlx4/en_netdev.c | 10 ++-- drivers/net/mlx4/en_rx.c | 2 +- drivers/net/mlx4/en_selftest.c | 2 +- drivers/net/mlx4/en_tx.c | 2 +- drivers/net/mlx4/mcg.c | 2 +- drivers/net/mlx4/port.c | 4 +- drivers/net/myri10ge/myri10ge.c | 2 +- drivers/net/myri_sbus.c | 2 +- drivers/net/natsemi.c | 6 +-- drivers/net/netxen/netxen_nic_hdr.h | 2 +- drivers/net/ns83820.c | 4 +- drivers/net/pch_gbe/pch_gbe.h | 14 +++--- drivers/net/pch_gbe/pch_gbe_ethtool.c | 2 +- drivers/net/pch_gbe/pch_gbe_main.c | 4 +- drivers/net/pci-skeleton.c | 2 +- drivers/net/pcmcia/3c574_cs.c | 2 +- drivers/net/pcmcia/axnet_cs.c | 4 +- drivers/net/pcmcia/smc91c92_cs.c | 2 +- drivers/net/pcnet32.c | 2 +- drivers/net/phy/phy_device.c | 4 +- drivers/net/ppp_generic.c | 2 +- drivers/net/ppp_synctty.c | 2 +- drivers/net/pppoe.c | 2 +- drivers/net/ps3_gelic_net.c | 4 +- drivers/net/ps3_gelic_net.h | 2 +- drivers/net/ps3_gelic_wireless.c | 2 +- drivers/net/pxa168_eth.c | 2 +- drivers/net/qla3xxx.h | 2 +- drivers/net/qlge/qlge_main.c | 10 ++-- drivers/net/r6040.c | 2 +- drivers/net/s2io.c | 6 +-- drivers/net/s2io.h | 2 +- drivers/net/sfc/falcon.c | 4 +- drivers/net/sfc/mcdi.c | 2 +- drivers/net/sfc/mcdi_pcol.h | 6 +-- drivers/net/sfc/mcdi_phy.c | 2 +- drivers/net/sfc/net_driver.h | 2 +- drivers/net/sgiseeq.c | 4 +- drivers/net/sh_eth.c | 2 +- drivers/net/sis190.c | 4 +- drivers/net/sis900.c | 6 +-- drivers/net/skfp/ess.c | 8 ++-- drivers/net/skfp/fplustm.c | 6 +-- drivers/net/skfp/h/cmtdef.h | 4 +- drivers/net/skfp/h/fplustm.h | 4 +- drivers/net/skfp/h/smc.h | 2 +- drivers/net/skfp/h/smt.h | 2 +- drivers/net/skfp/h/supern_2.h | 4 +- drivers/net/skfp/hwmtm.c | 2 +- drivers/net/skfp/pcmplc.c | 6 +-- drivers/net/skfp/smt.c | 2 +- drivers/net/skge.h | 8 ++-- drivers/net/sky2.c | 4 +- drivers/net/sky2.h | 6 +-- drivers/net/smc91x.h | 2 +- drivers/net/smsc911x.c | 2 +- drivers/net/smsc9420.c | 2 +- drivers/net/stmmac/norm_desc.c | 2 +- drivers/net/sunbmac.h | 2 +- drivers/net/sungem.c | 2 +- drivers/net/sunhme.h | 2 +- drivers/net/tc35815.c | 38 +++++++-------- drivers/net/tehuti.c | 12 ++--- drivers/net/tehuti.h | 2 +- drivers/net/tg3.c | 2 +- drivers/net/tg3.h | 4 +- drivers/net/tokenring/3c359.c | 2 +- drivers/net/tokenring/madgemc.c | 6 +-- drivers/net/tokenring/smctr.c | 12 ++--- drivers/net/tokenring/tms380tr.h | 2 +- drivers/net/tsi108_eth.h | 8 ++-- drivers/net/tulip/de4x5.c | 6 +-- drivers/net/tulip/dmfe.c | 2 +- drivers/net/tulip/eeprom.c | 2 +- drivers/net/typhoon.c | 2 +- drivers/net/ucc_geth.h | 4 +- drivers/net/usb/cdc_eem.c | 2 +- drivers/net/usb/kaweth.c | 2 +- drivers/net/via-rhine.c | 4 +- drivers/net/via-velocity.c | 4 +- drivers/net/vmxnet3/vmxnet3_drv.c | 4 +- drivers/net/vxge/vxge-config.c | 2 +- drivers/net/vxge/vxge-main.c | 8 ++-- drivers/net/vxge/vxge-traffic.c | 4 +- drivers/net/vxge/vxge-traffic.h | 2 +- drivers/net/wan/cosa.c | 2 +- drivers/net/wan/dscc4.c | 8 ++-- drivers/net/wan/hostess_sv11.c | 2 +- drivers/net/wan/ixp4xx_hss.c | 4 +- drivers/net/wan/lmc/lmc_main.c | 2 +- drivers/net/wan/lmc/lmc_var.h | 6 +-- drivers/net/wan/z85230.c | 8 ++-- drivers/net/wimax/i2400m/control.c | 4 +- drivers/net/wimax/i2400m/driver.c | 4 +- drivers/net/wimax/i2400m/fw.c | 4 +- drivers/net/wimax/i2400m/i2400m-usb.h | 6 +-- drivers/net/wimax/i2400m/i2400m.h | 4 +- drivers/net/wimax/i2400m/netdev.c | 2 +- drivers/net/wimax/i2400m/op-rfkill.c | 4 +- drivers/net/wimax/i2400m/rx.c | 4 +- drivers/net/wimax/i2400m/tx.c | 4 +- drivers/net/wimax/i2400m/usb-fw.c | 2 +- drivers/net/wimax/i2400m/usb-rx.c | 2 +- drivers/net/wimax/i2400m/usb-tx.c | 2 +- drivers/net/wireless/airo.c | 14 +++--- drivers/net/wireless/ath/ar9170/main.c | 2 +- drivers/net/wireless/ath/ar9170/phy.c | 2 +- drivers/net/wireless/ath/ath5k/ani.h | 2 +- drivers/net/wireless/ath/ath5k/base.c | 6 +-- drivers/net/wireless/ath/ath5k/desc.c | 14 +++--- drivers/net/wireless/ath/ath5k/eeprom.c | 4 +- drivers/net/wireless/ath/ath5k/pci.c | 2 +- drivers/net/wireless/ath/ath5k/pcu.c | 6 +-- drivers/net/wireless/ath/ath5k/phy.c | 22 ++++----- drivers/net/wireless/ath/ath5k/reg.h | 12 ++--- drivers/net/wireless/ath/ath9k/ar5008_phy.c | 2 +- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 2 +- drivers/net/wireless/ath/ath9k/htc_hst.c | 2 +- drivers/net/wireless/ath/ath9k/pci.c | 2 +- drivers/net/wireless/ath/ath9k/rc.c | 2 +- drivers/net/wireless/ath/ath9k/xmit.c | 4 +- drivers/net/wireless/ath/carl9170/carl9170.h | 2 +- drivers/net/wireless/ath/carl9170/phy.c | 2 +- drivers/net/wireless/ath/carl9170/rx.c | 2 +- drivers/net/wireless/ath/carl9170/usb.c | 2 +- drivers/net/wireless/ath/hw.c | 2 +- drivers/net/wireless/ath/regd.c | 4 +- drivers/net/wireless/atmel.c | 4 +- drivers/net/wireless/atmel_cs.c | 2 +- drivers/net/wireless/b43/b43.h | 2 +- drivers/net/wireless/b43/main.c | 2 +- drivers/net/wireless/b43/phy_g.h | 2 +- drivers/net/wireless/b43/phy_n.h | 2 +- drivers/net/wireless/b43legacy/b43legacy.h | 2 +- drivers/net/wireless/hostap/hostap_ap.c | 2 +- drivers/net/wireless/hostap/hostap_ap.h | 2 +- drivers/net/wireless/hostap/hostap_ioctl.c | 4 +- drivers/net/wireless/hostap/hostap_wlan.h | 2 +- drivers/net/wireless/ipw2x00/ipw2100.c | 2 +- drivers/net/wireless/ipw2x00/ipw2200.c | 18 ++++---- drivers/net/wireless/ipw2x00/libipw_rx.c | 2 +- drivers/net/wireless/iwlegacy/iwl-core.c | 2 +- drivers/net/wireless/iwlegacy/iwl-fh.h | 2 +- drivers/net/wireless/iwlegacy/iwl-scan.c | 2 +- drivers/net/wireless/iwlegacy/iwl-sta.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-ict.c | 2 +- drivers/net/wireless/iwlwifi/iwl-core.c | 2 +- drivers/net/wireless/iwlwifi/iwl-fh.h | 2 +- drivers/net/wireless/iwlwifi/iwl-scan.c | 2 +- drivers/net/wireless/iwmc3200wifi/hal.c | 4 +- drivers/net/wireless/iwmc3200wifi/tx.c | 2 +- drivers/net/wireless/libertas/README | 4 +- drivers/net/wireless/libertas/cfg.c | 2 +- drivers/net/wireless/libertas/if_cs.c | 2 +- drivers/net/wireless/libertas/if_spi.h | 2 +- drivers/net/wireless/mac80211_hwsim.c | 2 +- drivers/net/wireless/orinoco/hw.c | 2 +- drivers/net/wireless/p54/main.c | 2 +- drivers/net/wireless/p54/p54spi.c | 2 +- drivers/net/wireless/prism54/islpci_eth.c | 4 +- drivers/net/wireless/rayctl.h | 2 +- drivers/net/wireless/rt2x00/rt2800.h | 2 +- drivers/net/wireless/rt2x00/rt2800lib.c | 2 +- drivers/net/wireless/rt2x00/rt2x00.h | 8 ++-- drivers/net/wireless/rt2x00/rt2x00config.c | 2 +- drivers/net/wireless/rt2x00/rt2x00crypto.c | 2 +- drivers/net/wireless/rt2x00/rt2x00dump.h | 2 +- drivers/net/wireless/rt2x00/rt2x00link.c | 2 +- drivers/net/wireless/rt2x00/rt2x00queue.c | 6 +-- drivers/net/wireless/rt2x00/rt2x00queue.h | 12 ++--- drivers/net/wireless/rt2x00/rt2x00usb.c | 2 +- drivers/net/wireless/rt2x00/rt2x00usb.h | 2 +- drivers/net/wireless/rtlwifi/base.c | 2 +- drivers/net/wireless/rtlwifi/pci.c | 2 +- drivers/net/wireless/rtlwifi/regd.c | 2 +- drivers/net/wireless/rtlwifi/wifi.h | 2 +- drivers/net/wireless/wl1251/cmd.c | 2 +- drivers/net/wireless/wl1251/rx.c | 2 +- drivers/net/wireless/wl12xx/cmd.c | 2 +- drivers/net/wireless/wl12xx/conf.h | 8 ++-- drivers/net/wireless/wl12xx/io.h | 2 +- drivers/net/wireless/wl3501_cs.c | 4 +- drivers/net/wireless/zd1211rw/zd_rf_rf2959.c | 2 +- drivers/net/wireless/zd1211rw/zd_rf_uw2453.c | 2 +- drivers/net/xilinx_emaclite.c | 2 +- drivers/net/znet.c | 2 +- drivers/of/fdt.c | 2 +- drivers/of/of_mdio.c | 2 +- drivers/parisc/pdc_stable.c | 4 +- drivers/parport/Kconfig | 2 +- drivers/parport/ieee1284.c | 2 +- drivers/parport/parport_pc.c | 6 +-- drivers/pci/hotplug/acpi_pcihp.c | 2 +- drivers/pci/hotplug/acpiphp_glue.c | 2 +- drivers/pci/hotplug/rpaphp_core.c | 2 +- drivers/pci/intel-iommu.c | 2 +- drivers/pci/intr_remapping.c | 2 +- drivers/pci/iova.c | 2 +- drivers/pci/pci-sysfs.c | 2 +- drivers/pci/quirks.c | 4 +- drivers/pcmcia/i82092.c | 2 +- drivers/pcmcia/pcmcia_resource.c | 2 +- drivers/pcmcia/pxa2xx_lubbock.c | 2 +- drivers/pcmcia/ti113x.h | 2 +- drivers/platform/x86/intel_mid_thermal.c | 2 +- drivers/pnp/card.c | 4 +- drivers/pnp/pnpbios/bioscalls.c | 2 +- drivers/pps/Kconfig | 2 +- drivers/ps3/ps3-lpm.c | 6 +-- drivers/ps3/ps3-sys-manager.c | 2 +- drivers/rapidio/rio-scan.c | 2 +- drivers/regulator/core.c | 2 +- drivers/regulator/max8952.c | 2 +- drivers/rtc/interface.c | 2 +- drivers/rtc/rtc-at91rm9200.c | 2 +- drivers/rtc/rtc-bfin.c | 4 +- drivers/rtc/rtc-lpc32xx.c | 2 +- drivers/rtc/rtc-x1205.c | 2 +- drivers/s390/block/dasd_3990_erp.c | 6 +-- drivers/s390/block/dasd_devmap.c | 2 +- drivers/s390/block/dasd_eckd.c | 2 +- drivers/s390/char/raw3270.c | 2 +- drivers/s390/char/tape_char.c | 2 +- drivers/s390/char/tty3270.c | 2 +- drivers/s390/cio/device_fsm.c | 4 +- drivers/s390/crypto/zcrypt_api.h | 2 +- drivers/s390/net/claw.c | 2 +- drivers/s390/net/ctcm_fsms.c | 2 +- drivers/s390/net/lcs.c | 2 +- drivers/s390/net/qeth_core_main.c | 2 +- drivers/s390/scsi/zfcp_fsf.c | 2 +- drivers/s390/scsi/zfcp_qdio.c | 2 +- drivers/sbus/char/jsflash.c | 2 +- drivers/sbus/char/max1617.h | 2 +- drivers/scsi/3w-9xxx.h | 2 +- drivers/scsi/3w-xxxx.h | 2 +- drivers/scsi/53c700.scr | 2 +- drivers/scsi/53c700_d.h_shipped | 2 +- drivers/scsi/FlashPoint.c | 4 +- drivers/scsi/NCR5380.c | 8 ++-- drivers/scsi/aacraid/aachba.c | 4 +- drivers/scsi/aacraid/aacraid.h | 2 +- drivers/scsi/aacraid/commsup.c | 2 +- drivers/scsi/advansys.c | 2 +- drivers/scsi/aha1740.c | 2 +- drivers/scsi/aic7xxx/aic79xx.h | 4 +- drivers/scsi/aic7xxx/aic79xx.reg | 24 +++++----- drivers/scsi/aic7xxx/aic79xx.seq | 18 ++++---- drivers/scsi/aic7xxx/aic79xx_core.c | 24 +++++----- drivers/scsi/aic7xxx/aic79xx_osm.c | 2 +- drivers/scsi/aic7xxx/aic7xxx.h | 4 +- drivers/scsi/aic7xxx/aic7xxx.reg | 2 +- drivers/scsi/aic7xxx/aic7xxx.seq | 10 ++-- drivers/scsi/aic7xxx/aic7xxx_core.c | 18 ++++---- drivers/scsi/aic7xxx/aic7xxx_osm.c | 4 +- drivers/scsi/aic7xxx/aic7xxx_pci.c | 6 +-- drivers/scsi/aic7xxx/aicasm/aicasm_gram.y | 8 ++-- drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y | 2 +- drivers/scsi/aic7xxx_old.c | 12 ++--- drivers/scsi/aic7xxx_old/aic7xxx.seq | 8 ++-- drivers/scsi/aic94xx/aic94xx_reg_def.h | 2 +- drivers/scsi/arm/acornscsi.c | 4 +- drivers/scsi/arm/acornscsi.h | 6 +-- drivers/scsi/arm/arxescsi.c | 2 +- drivers/scsi/arm/cumana_2.c | 2 +- drivers/scsi/arm/eesox.c | 2 +- drivers/scsi/arm/fas216.c | 4 +- drivers/scsi/arm/fas216.h | 10 ++-- drivers/scsi/arm/powertec.c | 2 +- drivers/scsi/atari_NCR5380.c | 6 +-- drivers/scsi/atp870u.c | 2 +- drivers/scsi/be2iscsi/be_cmds.h | 18 ++++---- drivers/scsi/bfa/bfa_core.c | 2 +- drivers/scsi/bfa/bfa_defs_svc.h | 6 +-- drivers/scsi/bfa/bfa_fc.h | 2 +- drivers/scsi/bfa/bfa_fcs.c | 2 +- drivers/scsi/bfa/bfa_fcs.h | 2 +- drivers/scsi/bfa/bfa_fcs_lport.c | 2 +- drivers/scsi/bfa/bfa_svc.c | 4 +- drivers/scsi/bfa/bfa_svc.h | 2 +- drivers/scsi/bfa/bfad.c | 2 +- drivers/scsi/bnx2fc/57xx_hsi_bnx2fc.h | 2 +- drivers/scsi/bnx2fc/bnx2fc_els.c | 2 +- drivers/scsi/bnx2fc/bnx2fc_io.c | 4 +- drivers/scsi/bnx2fc/bnx2fc_tgt.c | 2 +- drivers/scsi/bnx2i/bnx2i_hwi.c | 2 +- drivers/scsi/cxgbi/libcxgbi.h | 6 +-- drivers/scsi/dc395x.c | 14 +++--- drivers/scsi/dc395x.h | 2 +- drivers/scsi/device_handler/scsi_dh_alua.c | 4 +- drivers/scsi/dpt/sys_info.h | 6 +-- drivers/scsi/eata.c | 2 +- drivers/scsi/fcoe/fcoe_ctlr.c | 4 +- drivers/scsi/fdomain.c | 2 +- drivers/scsi/fnic/fnic_fcs.c | 2 +- drivers/scsi/fnic/fnic_scsi.c | 4 +- drivers/scsi/g_NCR5380.c | 4 +- drivers/scsi/gdth.h | 2 +- drivers/scsi/gvp11.c | 2 +- drivers/scsi/imm.c | 2 +- drivers/scsi/initio.c | 4 +- drivers/scsi/initio.h | 4 +- drivers/scsi/ips.c | 4 +- drivers/scsi/ips.h | 2 +- drivers/scsi/iscsi_tcp.c | 2 +- drivers/scsi/libfc/fc_exch.c | 4 +- drivers/scsi/libfc/fc_fcp.c | 4 +- drivers/scsi/libfc/fc_lport.c | 18 ++++---- drivers/scsi/libsas/sas_expander.c | 2 +- drivers/scsi/lpfc/lpfc_attr.c | 2 +- drivers/scsi/lpfc/lpfc_bsg.c | 2 +- drivers/scsi/lpfc/lpfc_debugfs.c | 8 ++-- drivers/scsi/lpfc/lpfc_els.c | 4 +- drivers/scsi/lpfc/lpfc_hbadisc.c | 16 +++---- drivers/scsi/lpfc/lpfc_init.c | 20 ++++---- drivers/scsi/lpfc/lpfc_mbox.c | 2 +- drivers/scsi/lpfc/lpfc_nl.h | 2 +- drivers/scsi/lpfc/lpfc_nportdisc.c | 2 +- drivers/scsi/lpfc/lpfc_scsi.c | 10 ++-- drivers/scsi/lpfc/lpfc_scsi.h | 2 +- drivers/scsi/lpfc/lpfc_sli.c | 26 +++++------ drivers/scsi/megaraid.c | 4 +- drivers/scsi/megaraid.h | 6 +-- drivers/scsi/megaraid/mbox_defs.h | 8 ++-- drivers/scsi/megaraid/megaraid_mbox.c | 6 +-- drivers/scsi/megaraid/megaraid_sas.h | 2 +- drivers/scsi/megaraid/megaraid_sas_base.c | 2 +- drivers/scsi/mpt2sas/mpi/mpi2_init.h | 2 +- drivers/scsi/mpt2sas/mpt2sas_base.c | 12 ++--- drivers/scsi/mpt2sas/mpt2sas_config.c | 2 +- drivers/scsi/mpt2sas/mpt2sas_ctl.c | 2 +- drivers/scsi/mpt2sas/mpt2sas_scsih.c | 20 ++++---- drivers/scsi/ncr53c8xx.c | 2 +- drivers/scsi/nsp32.c | 6 +-- drivers/scsi/nsp32.h | 2 +- drivers/scsi/osst.c | 6 +-- drivers/scsi/osst.h | 2 +- drivers/scsi/pcmcia/nsp_cs.c | 2 +- drivers/scsi/pm8001/pm8001_hwi.c | 2 +- drivers/scsi/pm8001/pm8001_hwi.h | 4 +- drivers/scsi/pm8001/pm8001_sas.h | 2 +- drivers/scsi/pmcraid.c | 10 ++-- drivers/scsi/pmcraid.h | 2 +- drivers/scsi/qla1280.c | 2 +- drivers/scsi/qla2xxx/qla_def.h | 2 +- drivers/scsi/qla2xxx/qla_fw.h | 2 +- drivers/scsi/qla2xxx/qla_isr.c | 2 +- drivers/scsi/qla2xxx/qla_mbx.c | 6 +-- drivers/scsi/qla2xxx/qla_nx.c | 2 +- drivers/scsi/qla2xxx/qla_os.c | 6 +-- drivers/scsi/qla4xxx/ql4_def.h | 2 +- drivers/scsi/qla4xxx/ql4_init.c | 2 +- drivers/scsi/qla4xxx/ql4_nvram.h | 2 +- drivers/scsi/qla4xxx/ql4_os.c | 8 ++-- drivers/scsi/scsi_debug.c | 2 +- drivers/scsi/scsi_netlink.c | 2 +- drivers/scsi/scsi_tgt_lib.c | 2 +- drivers/scsi/scsi_transport_fc.c | 4 +- drivers/scsi/sd.c | 2 +- drivers/scsi/sr.c | 2 +- drivers/scsi/sun3_NCR5380.c | 6 +-- drivers/scsi/sym53c416.c | 2 +- drivers/scsi/sym53c8xx_2/sym_fw1.h | 2 +- drivers/scsi/sym53c8xx_2/sym_fw2.h | 2 +- drivers/scsi/sym53c8xx_2/sym_hipd.c | 4 +- drivers/scsi/sym53c8xx_2/sym_malloc.c | 2 +- drivers/scsi/wd33c93.c | 2 +- drivers/scsi/wd7000.c | 2 +- drivers/sfi/sfi_core.c | 2 +- drivers/spi/amba-pl022.c | 16 +++---- drivers/spi/au1550_spi.c | 2 +- drivers/spi/dw_spi.c | 2 +- drivers/spi/dw_spi.h | 2 +- drivers/spi/ep93xx_spi.c | 2 +- drivers/spi/pxa2xx_spi.c | 4 +- drivers/spi/spi.c | 2 +- drivers/spi/spi_bfin5xx.c | 2 +- drivers/spi/spi_fsl_espi.c | 2 +- drivers/ssb/pci.c | 2 +- drivers/ssb/sprom.c | 2 +- .../ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c | 6 +-- drivers/staging/ath6kl/include/aggr_recv_api.h | 2 +- drivers/staging/ath6kl/include/common/a_hci.h | 4 +- drivers/staging/ath6kl/include/common/dbglog.h | 2 +- .../staging/ath6kl/include/common/epping_test.h | 2 +- drivers/staging/ath6kl/include/common/ini_dset.h | 2 +- drivers/staging/ath6kl/include/common/testcmd.h | 4 +- drivers/staging/ath6kl/include/common/wmi.h | 8 ++-- drivers/staging/ath6kl/include/common/wmix.h | 2 +- drivers/staging/ath6kl/include/htc_api.h | 6 +-- drivers/staging/ath6kl/miscdrv/credit_dist.c | 6 +-- drivers/staging/ath6kl/os/linux/ar6000_android.c | 2 +- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 8 ++-- drivers/staging/ath6kl/wmi/wmi.c | 2 +- drivers/staging/bcm/Adapter.h | 10 ++-- drivers/staging/bcm/CmHost.c | 16 +++---- drivers/staging/bcm/HostMIBSInterface.h | 2 +- drivers/staging/bcm/IPv6Protocol.c | 4 +- drivers/staging/bcm/InterfaceIdleMode.c | 4 +- drivers/staging/bcm/InterfaceIsr.c | 4 +- drivers/staging/bcm/InterfaceRx.c | 10 ++-- drivers/staging/bcm/Ioctl.h | 2 +- drivers/staging/bcm/LeakyBucket.c | 2 +- drivers/staging/bcm/Misc.c | 6 +-- drivers/staging/bcm/Qos.c | 2 +- drivers/staging/bcm/cntrl_SignalingInterface.h | 6 +-- drivers/staging/bcm/nvm.c | 54 +++++++++++----------- drivers/staging/brcm80211/README | 2 +- drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c | 2 +- .../staging/brcm80211/brcmfmac/dhd_custom_gpio.c | 2 +- drivers/staging/brcm80211/brcmfmac/dhd_linux.c | 2 +- drivers/staging/brcm80211/brcmfmac/dhd_sdio.c | 4 +- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 2 +- drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c | 6 +-- drivers/staging/brcm80211/brcmsmac/wlc_bmac.c | 2 +- drivers/staging/brcm80211/brcmsmac/wlc_main.c | 4 +- drivers/staging/brcm80211/brcmsmac/wlc_rate.c | 2 +- drivers/staging/brcm80211/include/bcmsrom_fmt.h | 2 +- drivers/staging/brcm80211/include/hndsoc.h | 2 +- drivers/staging/brcm80211/util/bcmotp.c | 4 +- drivers/staging/brcm80211/util/bcmsrom.c | 2 +- drivers/staging/brcm80211/util/hnddma.c | 6 +-- drivers/staging/brcm80211/util/sbpcmcia.h | 2 +- drivers/staging/brcm80211/util/siutils.c | 2 +- drivers/staging/comedi/comedi_fops.c | 2 +- .../comedi/drivers/addi-data/APCI1710_Chrono.c | 8 ++-- .../comedi/drivers/addi-data/addi_amcc_S5920.c | 2 +- .../comedi/drivers/addi-data/hwdrv_apci2032.c | 2 +- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 18 ++++---- .../comedi/drivers/addi-data/hwdrv_apci3120.h | 2 +- .../comedi/drivers/addi-data/hwdrv_apci3200.c | 4 +- drivers/staging/comedi/drivers/adl_pci9118.c | 6 +-- drivers/staging/comedi/drivers/adq12b.c | 4 +- drivers/staging/comedi/drivers/adv_pci1710.c | 8 ++-- drivers/staging/comedi/drivers/cb_pcidas.c | 6 +-- drivers/staging/comedi/drivers/cb_pcidas64.c | 14 +++--- drivers/staging/comedi/drivers/comedi_test.c | 2 +- drivers/staging/comedi/drivers/das1800.c | 2 +- drivers/staging/comedi/drivers/das800.c | 2 +- drivers/staging/comedi/drivers/dmm32at.c | 2 +- drivers/staging/comedi/drivers/dt2811.c | 2 +- drivers/staging/comedi/drivers/dt9812.c | 2 +- drivers/staging/comedi/drivers/gsc_hpdi.c | 4 +- drivers/staging/comedi/drivers/icp_multi.c | 6 +-- drivers/staging/comedi/drivers/me4000.c | 4 +- drivers/staging/comedi/drivers/mpc624.c | 14 +++--- drivers/staging/comedi/drivers/ni_at_a2150.c | 12 ++--- drivers/staging/comedi/drivers/ni_labpc.c | 14 +++--- drivers/staging/comedi/drivers/ni_pcidio.c | 2 +- drivers/staging/comedi/drivers/pcl812.c | 2 +- drivers/staging/comedi/drivers/pcl816.c | 6 +-- drivers/staging/comedi/drivers/pcl818.c | 6 +-- drivers/staging/comedi/drivers/pcmmio.c | 4 +- drivers/staging/comedi/drivers/pcmuio.c | 2 +- drivers/staging/comedi/drivers/quatech_daqp_cs.c | 4 +- drivers/staging/comedi/drivers/rtd520.c | 12 ++--- drivers/staging/comedi/drivers/s626.c | 18 ++++---- drivers/staging/comedi/drivers/usbdux.c | 22 ++++----- drivers/staging/comedi/drivers/usbduxfast.c | 8 ++-- drivers/staging/cptm1217/clearpad_tm1217.c | 2 +- drivers/staging/crystalhd/crystalhd_cmds.c | 2 +- drivers/staging/crystalhd/crystalhd_hw.c | 6 +-- drivers/staging/cxt1e1/musycc.c | 2 +- drivers/staging/cxt1e1/musycc.h | 4 +- drivers/staging/cxt1e1/pmcc4_defs.h | 4 +- drivers/staging/cxt1e1/sbecrc.c | 2 +- drivers/staging/cxt1e1/sbeproc.c | 2 +- drivers/staging/et131x/et1310_address_map.h | 4 +- drivers/staging/et131x/et1310_phy.h | 2 +- drivers/staging/et131x/et1310_rx.c | 2 +- drivers/staging/et131x/et131x_isr.c | 2 +- drivers/staging/et131x/et131x_netdev.c | 2 +- drivers/staging/ft1000/ft1000-pcmcia/ft1000_dev.h | 4 +- drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c | 44 +++++++++--------- .../staging/ft1000/ft1000-usb/ft1000_download.c | 8 ++-- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 16 +++---- drivers/staging/ft1000/ft1000-usb/ft1000_ioctl.h | 2 +- drivers/staging/ft1000/ft1000-usb/ft1000_usb.h | 2 +- drivers/staging/generic_serial/generic_serial.c | 2 +- drivers/staging/generic_serial/rio/map.h | 2 +- drivers/staging/generic_serial/rio/rioboot.c | 8 ++-- drivers/staging/generic_serial/rio/riocmd.c | 2 +- drivers/staging/generic_serial/rio/rioroute.c | 4 +- drivers/staging/generic_serial/rio/riotty.c | 4 +- drivers/staging/generic_serial/sx.c | 8 ++-- drivers/staging/gma500/psb_drm.h | 2 +- drivers/staging/gma500/psb_drv.c | 2 +- drivers/staging/gma500/psb_intel_bios.c | 2 +- drivers/staging/gma500/psb_intel_sdvo.c | 2 +- drivers/staging/gma500/psb_intel_sdvo_regs.h | 2 +- drivers/staging/gma500/psb_ttm_fence_user.h | 2 +- drivers/staging/go7007/go7007.txt | 2 +- drivers/staging/hv/blkvsc_drv.c | 2 +- drivers/staging/hv/channel_mgmt.c | 2 +- drivers/staging/hv/hv.c | 2 +- drivers/staging/hv/hv_api.h | 4 +- drivers/staging/hv/hv_kvp.h | 2 +- drivers/staging/hv/hv_util.c | 2 +- drivers/staging/hv/rndis_filter.c | 2 +- drivers/staging/hv/tools/hv_kvp_daemon.c | 2 +- drivers/staging/iio/Documentation/iio_utils.h | 2 +- drivers/staging/iio/accel/adis16201.h | 2 +- drivers/staging/iio/accel/adis16203.h | 2 +- drivers/staging/iio/accel/adis16204.h | 2 +- drivers/staging/iio/accel/adis16209.h | 2 +- drivers/staging/iio/accel/adis16220.h | 2 +- drivers/staging/iio/accel/adis16240.h | 2 +- drivers/staging/iio/accel/lis3l02dq.h | 26 +++++------ drivers/staging/iio/accel/lis3l02dq_core.c | 2 +- drivers/staging/iio/accel/lis3l02dq_ring.c | 4 +- drivers/staging/iio/accel/sca3000.h | 4 +- drivers/staging/iio/accel/sca3000_ring.c | 2 +- drivers/staging/iio/adc/ad7298_ring.c | 2 +- drivers/staging/iio/adc/ad7476_ring.c | 2 +- drivers/staging/iio/adc/ad7887_ring.c | 2 +- drivers/staging/iio/adc/ad799x_core.c | 2 +- drivers/staging/iio/adc/ad799x_ring.c | 2 +- drivers/staging/iio/adc/max1363_core.c | 4 +- drivers/staging/iio/adc/max1363_ring.c | 2 +- drivers/staging/iio/chrdev.h | 6 +-- drivers/staging/iio/gyro/adis16060_core.c | 2 +- drivers/staging/iio/gyro/adis16080_core.c | 2 +- drivers/staging/iio/gyro/adis16260.h | 2 +- drivers/staging/iio/iio.h | 2 +- drivers/staging/iio/imu/adis16300.h | 2 +- drivers/staging/iio/imu/adis16350.h | 2 +- drivers/staging/iio/imu/adis16400.h | 2 +- drivers/staging/iio/industrialio-core.c | 2 +- drivers/staging/iio/meter/ade7753.h | 2 +- drivers/staging/iio/meter/ade7754.h | 2 +- drivers/staging/iio/meter/ade7758.h | 2 +- drivers/staging/iio/meter/ade7759.h | 2 +- drivers/staging/iio/meter/ade7854.h | 2 +- drivers/staging/iio/ring_generic.h | 2 +- drivers/staging/intel_sst/TODO | 2 +- drivers/staging/intel_sst/intel_sst.c | 4 +- .../staging/intel_sst/intel_sst_app_interface.c | 16 +++---- .../staging/intel_sst/intel_sst_drv_interface.c | 2 +- drivers/staging/intel_sst/intel_sst_dsp.c | 4 +- drivers/staging/intel_sst/intel_sst_fw_ipc.h | 2 +- drivers/staging/intel_sst/intel_sst_stream.c | 2 +- .../staging/intel_sst/intel_sst_stream_encoded.c | 2 +- drivers/staging/intel_sst/intelmid.c | 2 +- drivers/staging/intel_sst/intelmid.h | 2 +- drivers/staging/keucr/init.c | 4 +- drivers/staging/keucr/smilmain.c | 8 ++-- drivers/staging/keucr/smilsub.c | 6 +-- drivers/staging/lirc/lirc_ene0100.h | 4 +- drivers/staging/memrar/memrar_handler.c | 2 +- drivers/staging/msm/mdp4_overlay.c | 2 +- drivers/staging/msm/mdp_ppp_dq.c | 2 +- drivers/staging/msm/msm_fb.c | 6 +-- drivers/staging/octeon/cvmx-cmd-queue.h | 2 +- drivers/staging/octeon/cvmx-fpa.h | 2 +- drivers/staging/octeon/cvmx-helper-board.h | 2 +- drivers/staging/octeon/cvmx-helper-util.c | 2 +- drivers/staging/octeon/cvmx-helper.c | 2 +- drivers/staging/octeon/cvmx-mdio.h | 2 +- drivers/staging/octeon/cvmx-pko.h | 4 +- drivers/staging/octeon/cvmx-pow.h | 12 ++--- drivers/staging/octeon/ethernet-util.h | 2 +- drivers/staging/olpc_dcon/olpc_dcon_xo_1.c | 2 +- drivers/staging/pohmelfs/crypto.c | 2 +- drivers/staging/quatech_usb2/quatech_usb2.c | 12 ++--- drivers/staging/rt2860/chip/rtmp_phy.h | 2 +- drivers/staging/rt2860/common/ba_action.c | 4 +- drivers/staging/rt2860/common/cmm_aes.c | 2 +- drivers/staging/rt2860/common/cmm_cfg.c | 2 +- drivers/staging/rt2860/common/cmm_data.c | 4 +- drivers/staging/rt2860/common/cmm_data_pci.c | 6 +-- drivers/staging/rt2860/common/cmm_data_usb.c | 6 +-- drivers/staging/rt2860/common/cmm_mac_pci.c | 2 +- drivers/staging/rt2860/common/cmm_sanity.c | 4 +- drivers/staging/rt2860/common/cmm_sync.c | 2 +- drivers/staging/rt2860/common/cmm_wpa.c | 4 +- drivers/staging/rt2860/common/mlme.c | 16 +++---- drivers/staging/rt2860/common/rtmp_init.c | 14 +++--- drivers/staging/rt2860/common/spectrum.c | 12 ++--- drivers/staging/rt2860/mlme.h | 8 ++-- drivers/staging/rt2860/rt_linux.c | 2 +- drivers/staging/rt2860/rt_pci_rbus.c | 2 +- drivers/staging/rt2860/rtmp.h | 4 +- drivers/staging/rt2860/sta_ioctl.c | 2 +- drivers/staging/rt2870/common/rtusb_bulk.c | 6 +-- drivers/staging/rt2870/common/rtusb_data.c | 2 +- drivers/staging/rtl8187se/ieee80211/ieee80211.h | 6 +-- .../rtl8187se/ieee80211/ieee80211_softmac.c | 2 +- drivers/staging/rtl8187se/r8180_core.c | 4 +- drivers/staging/rtl8187se/r8180_dm.c | 4 +- drivers/staging/rtl8187se/r8180_rtl8225z2.c | 2 +- drivers/staging/rtl8187se/r8185b_init.c | 2 +- drivers/staging/rtl8192e/ieee80211/ieee80211.h | 8 ++-- drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c | 2 +- .../staging/rtl8192e/ieee80211/ieee80211_softmac.c | 4 +- drivers/staging/rtl8192e/ieee80211/rtl819x_HT.h | 2 +- .../staging/rtl8192e/ieee80211/rtl819x_HTProc.c | 8 ++-- drivers/staging/rtl8192e/ieee80211/rtl819x_TS.h | 2 +- .../staging/rtl8192e/ieee80211/rtl819x_TSProc.c | 2 +- drivers/staging/rtl8192e/r819xE_phy.c | 6 +-- drivers/staging/rtl8192u/ieee80211/ieee80211.h | 8 ++-- drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c | 2 +- .../staging/rtl8192u/ieee80211/ieee80211_softmac.c | 4 +- drivers/staging/rtl8192u/ieee80211/rtl819x_HT.h | 2 +- .../staging/rtl8192u/ieee80211/rtl819x_HTProc.c | 8 ++-- drivers/staging/rtl8192u/ieee80211/rtl819x_TS.h | 2 +- .../staging/rtl8192u/ieee80211/rtl819x_TSProc.c | 2 +- drivers/staging/rtl8192u/ieee80211/scatterwalk.c | 2 +- drivers/staging/rtl8192u/r8192U_core.c | 6 +-- drivers/staging/rtl8192u/r819xU_HTType.h | 2 +- drivers/staging/rtl8192u/r819xU_phy.c | 6 +-- drivers/staging/rtl8712/rtl871x_cmd.h | 2 +- drivers/staging/rtl8712/rtl871x_led.h | 4 +- drivers/staging/rtl8712/rtl871x_mlme.c | 6 +-- drivers/staging/rtl8712/rtl871x_mlme.h | 2 +- drivers/staging/rtl8712/rtl871x_mp_phy_regdef.h | 2 +- drivers/staging/rtl8712/usb_halinit.c | 2 +- drivers/staging/rts_pstor/rtsx_chip.h | 10 ++-- drivers/staging/rts_pstor/rtsx_scsi.h | 2 +- drivers/staging/rts_pstor/sd.c | 2 +- drivers/staging/sep/sep_driver.c | 10 ++-- drivers/staging/sep/sep_driver_config.h | 4 +- drivers/staging/slicoss/README | 2 +- drivers/staging/sm7xx/smtcfb.c | 4 +- drivers/staging/speakup/keyhelp.c | 2 +- drivers/staging/speakup/spkguide.txt | 2 +- drivers/staging/spectra/ffsport.c | 4 +- drivers/staging/spectra/flash.c | 6 +-- drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c | 20 ++++---- drivers/staging/tidspbridge/core/_tiomap.h | 2 +- drivers/staging/tidspbridge/core/chnl_sm.c | 2 +- drivers/staging/tidspbridge/dynload/cload.c | 2 +- drivers/staging/tidspbridge/hw/hw_mmu.c | 6 +-- .../tidspbridge/include/dspbridge/_chnl_sm.h | 4 +- .../staging/tidspbridge/include/dspbridge/clk.h | 6 +-- .../staging/tidspbridge/include/dspbridge/cmm.h | 2 +- .../staging/tidspbridge/include/dspbridge/cod.h | 2 +- .../staging/tidspbridge/include/dspbridge/dev.h | 2 +- .../staging/tidspbridge/include/dspbridge/drv.h | 6 +-- .../tidspbridge/include/dspbridge/dspdefs.h | 14 +++--- .../staging/tidspbridge/include/dspbridge/mgr.h | 4 +- .../staging/tidspbridge/include/dspbridge/node.h | 2 +- .../staging/tidspbridge/include/dspbridge/proc.h | 6 +-- .../staging/tidspbridge/include/dspbridge/pwr.h | 8 ++-- drivers/staging/tidspbridge/pmgr/dev.c | 6 +-- drivers/staging/tidspbridge/rmgr/drv.c | 2 +- drivers/staging/tidspbridge/rmgr/nldr.c | 6 +-- drivers/staging/tidspbridge/rmgr/proc.c | 4 +- drivers/staging/tm6000/tm6000-video.c | 2 +- drivers/staging/tty/cd1865.h | 2 +- drivers/staging/tty/epca.c | 16 +++---- drivers/staging/tty/ip2/i2hw.h | 4 +- drivers/staging/tty/ip2/i2lib.c | 8 ++-- drivers/staging/tty/ip2/ip2main.c | 2 +- drivers/staging/tty/specialix.c | 4 +- drivers/staging/tty/specialix_io8.h | 4 +- drivers/staging/usbip/vhci_hcd.c | 2 +- drivers/staging/vme/bridges/vme_ca91cx42.c | 6 +-- drivers/staging/vme/bridges/vme_tsi148.c | 4 +- drivers/staging/vme/bridges/vme_tsi148.h | 8 ++-- drivers/staging/vme/vme_api.txt | 6 +-- drivers/staging/vt6655/card.c | 2 +- drivers/staging/vt6655/device_main.c | 2 +- drivers/staging/vt6655/wcmd.c | 2 +- drivers/staging/vt6655/wmgr.h | 4 +- drivers/staging/vt6656/rxtx.c | 2 +- drivers/staging/vt6656/wcmd.c | 4 +- drivers/staging/vt6656/wmgr.h | 4 +- .../staging/westbridge/astoria/api/src/cyasdma.c | 2 +- .../westbridge/astoria/api/src/cyaslep2pep.c | 2 +- .../westbridge/astoria/api/src/cyaslowlevel.c | 2 +- .../staging/westbridge/astoria/api/src/cyasmisc.c | 6 +-- .../staging/westbridge/astoria/api/src/cyasmtp.c | 4 +- .../westbridge/astoria/api/src/cyasstorage.c | 6 +-- .../staging/westbridge/astoria/api/src/cyasusb.c | 4 +- .../arch/arm/mach-omap2/cyashalomap_kernel.c | 12 ++--- .../cyashalomap_kernel.h | 2 +- .../westbridge-omap3-pnand-hal/cyasmemmap.h | 4 +- .../westbridge/astoria/block/cyasblkdev_queue.c | 2 +- .../astoria/include/linux/westbridge/cyasdevice.h | 6 +-- .../astoria/include/linux/westbridge/cyasdma.h | 10 ++-- .../astoria/include/linux/westbridge/cyaserr.h | 4 +- .../astoria/include/linux/westbridge/cyashaldoc.h | 2 +- .../astoria/include/linux/westbridge/cyasintr.h | 2 +- .../astoria/include/linux/westbridge/cyasmisc.h | 8 ++-- .../include/linux/westbridge/cyasprotocol.h | 4 +- .../astoria/include/linux/westbridge/cyasstorage.h | 34 +++++++------- .../astoria/include/linux/westbridge/cyasusb.h | 40 ++++++++-------- drivers/staging/winbond/mds.c | 2 +- drivers/staging/wlags49_h2/README.ubuntu | 2 +- drivers/staging/wlags49_h2/TODO | 4 +- drivers/staging/wlags49_h2/hcf.c | 24 +++++----- drivers/staging/wlags49_h2/hcfdef.h | 2 +- drivers/staging/wlags49_h2/wl_wext.c | 6 +-- drivers/staging/wlags49_h25/TODO | 4 +- drivers/staging/wlan-ng/prism2sta.c | 2 +- drivers/staging/xgifb/vb_setmode.c | 2 +- drivers/staging/xgifb/vgatypes.h | 2 +- drivers/target/target_core_alua.c | 10 ++-- drivers/target/target_core_device.c | 2 +- drivers/target/target_core_fabric_lib.c | 2 +- drivers/target/target_core_file.c | 2 +- drivers/target/target_core_pr.c | 6 +-- drivers/target/target_core_transport.c | 14 +++--- drivers/target/target_core_ua.c | 4 +- drivers/telephony/ixj.c | 8 ++-- drivers/telephony/ixj.h | 2 +- drivers/tty/hvc/hvc_iucv.c | 4 +- drivers/tty/hvc/hvc_vio.c | 2 +- drivers/tty/hvc/hvcs.c | 8 ++-- drivers/tty/mxser.h | 2 +- drivers/tty/n_gsm.c | 10 ++-- drivers/tty/nozomi.c | 2 +- drivers/tty/rocket.c | 4 +- drivers/tty/serial/8250.c | 2 +- drivers/tty/serial/8250_pci.c | 2 +- drivers/tty/serial/amba-pl011.c | 2 +- drivers/tty/serial/icom.c | 2 +- drivers/tty/serial/imx.c | 2 +- drivers/tty/serial/ip22zilog.c | 2 +- drivers/tty/serial/jsm/jsm.h | 2 +- drivers/tty/serial/jsm/jsm_neo.c | 4 +- drivers/tty/serial/max3107.h | 2 +- drivers/tty/serial/mrst_max3110.c | 2 +- drivers/tty/serial/mrst_max3110.h | 2 +- drivers/tty/serial/msm_serial_hs.c | 4 +- drivers/tty/serial/omap-serial.c | 2 +- drivers/tty/serial/pmac_zilog.c | 6 +-- drivers/tty/serial/samsung.c | 4 +- drivers/tty/serial/sh-sci.c | 2 +- drivers/tty/serial/sn_console.c | 4 +- drivers/tty/serial/sunzilog.c | 2 +- drivers/tty/synclink.c | 10 ++-- drivers/tty/synclink_gt.c | 2 +- drivers/tty/synclinkmp.c | 10 ++-- drivers/tty/tty_io.c | 8 ++-- drivers/tty/tty_ioctl.c | 6 +-- drivers/tty/vt/vt.c | 2 +- drivers/uio/uio_pruss.c | 2 +- drivers/usb/atm/ueagle-atm.c | 8 ++-- drivers/usb/c67x00/c67x00-drv.c | 2 +- drivers/usb/c67x00/c67x00-hcd.h | 2 +- drivers/usb/c67x00/c67x00-sched.c | 2 +- drivers/usb/class/cdc-acm.h | 2 +- drivers/usb/class/usbtmc.c | 2 +- drivers/usb/core/hcd.c | 2 +- drivers/usb/core/hub.c | 2 +- drivers/usb/early/ehci-dbgp.c | 2 +- drivers/usb/gadget/amd5536udc.c | 14 +++--- drivers/usb/gadget/amd5536udc.h | 2 +- drivers/usb/gadget/at91_udc.c | 2 +- drivers/usb/gadget/composite.c | 6 +-- drivers/usb/gadget/f_audio.c | 2 +- drivers/usb/gadget/f_ncm.c | 2 +- drivers/usb/gadget/fsl_qe_udc.h | 6 +-- drivers/usb/gadget/fsl_udc_core.c | 6 +-- drivers/usb/gadget/fsl_usb2_udc.h | 4 +- drivers/usb/gadget/gmidi.c | 2 +- drivers/usb/gadget/langwell_udc.c | 2 +- drivers/usb/gadget/mv_udc_core.c | 6 +-- drivers/usb/gadget/net2280.c | 2 +- drivers/usb/gadget/nokia.c | 2 +- drivers/usb/gadget/printer.c | 2 +- drivers/usb/gadget/pxa27x_udc.c | 12 ++--- drivers/usb/gadget/s3c-hsotg.c | 18 ++++---- drivers/usb/host/Kconfig | 2 +- drivers/usb/host/ehci.h | 2 +- drivers/usb/host/fhci-hcd.c | 2 +- drivers/usb/host/fhci-tds.c | 8 ++-- drivers/usb/host/fhci.h | 4 +- drivers/usb/host/imx21-hcd.c | 2 +- drivers/usb/host/isp116x.h | 2 +- drivers/usb/host/isp1362-hcd.c | 2 +- drivers/usb/host/ohci-hcd.c | 2 +- drivers/usb/host/oxu210hp-hcd.c | 4 +- drivers/usb/host/whci/qset.c | 2 +- drivers/usb/host/xhci.c | 4 +- drivers/usb/host/xhci.h | 2 +- drivers/usb/image/microtek.c | 8 ++-- drivers/usb/misc/iowarrior.c | 2 +- drivers/usb/otg/isp1301_omap.c | 2 +- drivers/usb/otg/langwell_otg.c | 4 +- drivers/usb/serial/aircable.c | 4 +- drivers/usb/serial/cp210x.c | 2 +- drivers/usb/serial/cypress_m8.c | 2 +- drivers/usb/serial/ftdi_sio.c | 2 +- drivers/usb/serial/io_edgeport.c | 2 +- drivers/usb/serial/io_edgeport.h | 2 +- drivers/usb/serial/io_ti.c | 2 +- drivers/usb/serial/opticon.c | 2 +- drivers/usb/storage/ene_ub6250.c | 4 +- drivers/usb/storage/isd200.c | 2 +- drivers/usb/storage/scsiglue.c | 2 +- drivers/usb/storage/shuttle_usbat.c | 2 +- drivers/usb/wusbcore/crypto.c | 4 +- drivers/usb/wusbcore/reservation.c | 2 +- drivers/usb/wusbcore/rh.c | 2 +- drivers/usb/wusbcore/wa-rpipe.c | 2 +- drivers/usb/wusbcore/wa-xfer.c | 8 ++-- drivers/usb/wusbcore/wusbhc.h | 2 +- drivers/uwb/driver.c | 2 +- drivers/uwb/drp.c | 6 +-- drivers/uwb/lc-rc.c | 2 +- drivers/uwb/reset.c | 2 +- drivers/uwb/umc-dev.c | 2 +- drivers/video/atmel_lcdfb.c | 2 +- drivers/video/aty/atyfb_base.c | 4 +- drivers/video/aty/mach64_cursor.c | 2 +- drivers/video/au1200fb.c | 2 +- drivers/video/backlight/corgi_lcd.c | 2 +- drivers/video/backlight/locomolcd.c | 2 +- drivers/video/bfin_adv7393fb.h | 24 +++++----- drivers/video/console/font_mini_4x6.c | 2 +- drivers/video/da8xx-fb.c | 2 +- drivers/video/display/display-sysfs.c | 2 +- drivers/video/ep93xx-fb.c | 2 +- drivers/video/fbsysfs.c | 2 +- drivers/video/fm2fb.c | 2 +- drivers/video/fsl-diu-fb.c | 2 +- drivers/video/gbefb.c | 2 +- drivers/video/geode/lxfb.h | 2 +- drivers/video/i810/i810_accel.c | 2 +- drivers/video/kyro/STG4000OverlayDevice.c | 2 +- drivers/video/kyro/STG4000Reg.h | 2 +- drivers/video/matrox/matroxfb_DAC1064.h | 2 +- drivers/video/matrox/matroxfb_Ti3026.c | 4 +- drivers/video/matrox/matroxfb_base.c | 2 +- drivers/video/matrox/matroxfb_base.h | 2 +- drivers/video/nuc900fb.h | 2 +- drivers/video/omap/Kconfig | 2 +- drivers/video/omap2/dss/hdmi.c | 2 +- drivers/video/pxa3xx-gcu.c | 2 +- drivers/video/savage/savagefb.h | 2 +- drivers/video/savage/savagefb_driver.c | 4 +- drivers/video/sm501fb.c | 4 +- drivers/video/sstfb.c | 8 ++-- drivers/video/sticore.h | 2 +- drivers/video/tdfxfb.c | 18 ++++---- drivers/video/tmiofb.c | 2 +- drivers/video/udlfb.c | 2 +- drivers/video/vga16fb.c | 2 +- drivers/video/via/via_utility.c | 2 +- drivers/video/via/via_utility.h | 2 +- drivers/video/via/viafbdev.c | 2 +- drivers/video/w100fb.c | 2 +- drivers/w1/masters/omap_hdq.c | 2 +- drivers/watchdog/Kconfig | 2 +- drivers/watchdog/Makefile | 4 +- drivers/watchdog/acquirewdt.c | 2 +- drivers/watchdog/pc87413_wdt.c | 2 +- drivers/watchdog/sbc7240_wdt.c | 2 +- drivers/watchdog/sch311x_wdt.c | 2 +- drivers/watchdog/shwdt.c | 2 +- drivers/watchdog/smsc37b787_wdt.c | 2 +- drivers/watchdog/sp805_wdt.c | 2 +- drivers/xen/events.c | 4 +- fs/adfs/map.c | 2 +- fs/afs/cache.c | 12 ++--- fs/afs/cell.c | 2 +- fs/attr.c | 2 +- fs/autofs4/root.c | 2 +- fs/befs/ChangeLog | 10 ++-- fs/befs/befs_fs_types.h | 2 +- fs/befs/btree.c | 2 +- fs/befs/linuxvfs.c | 2 +- fs/binfmt_flat.c | 2 +- fs/bio.c | 2 +- fs/block_dev.c | 2 +- fs/btrfs/extent_map.c | 2 +- fs/btrfs/inode.c | 2 +- fs/btrfs/relocation.c | 2 +- fs/cachefiles/interface.c | 2 +- fs/ceph/addr.c | 2 +- fs/ceph/caps.c | 2 +- fs/ceph/snap.c | 2 +- fs/cifs/AUTHORS | 2 +- fs/cifs/cifs_dfs_ref.c | 2 +- fs/cifs/cifssmb.c | 2 +- fs/cifs/connect.c | 4 +- fs/cifs/dir.c | 2 +- fs/configfs/dir.c | 2 +- fs/dlm/lock.c | 2 +- fs/dlm/lowcomms.c | 2 +- fs/dlm/recover.c | 2 +- fs/ecryptfs/main.c | 4 +- fs/eventpoll.c | 8 ++-- fs/exofs/common.h | 4 +- fs/ext2/balloc.c | 6 +-- fs/ext2/inode.c | 8 ++-- fs/ext2/super.c | 2 +- fs/ext2/xattr.c | 2 +- fs/ext3/balloc.c | 10 ++-- fs/ext3/inode.c | 6 +-- fs/ext3/resize.c | 2 +- fs/ext3/super.c | 2 +- fs/ext4/balloc.c | 2 +- fs/ext4/extents.c | 10 ++-- fs/ext4/fsync.c | 2 +- fs/ext4/inode.c | 20 ++++---- fs/ext4/mballoc.c | 2 +- fs/ext4/migrate.c | 2 +- fs/ext4/super.c | 4 +- fs/freevxfs/vxfs_fshead.c | 2 +- fs/freevxfs/vxfs_lookup.c | 2 +- fs/freevxfs/vxfs_olt.h | 2 +- fs/fs-writeback.c | 2 +- fs/fuse/file.c | 2 +- fs/gfs2/bmap.c | 2 +- fs/gfs2/glock.c | 2 +- fs/gfs2/super.c | 2 +- fs/jbd/commit.c | 2 +- fs/jbd/journal.c | 4 +- fs/jbd/revoke.c | 2 +- fs/jbd/transaction.c | 2 +- fs/jbd2/commit.c | 2 +- fs/jbd2/journal.c | 4 +- fs/jbd2/revoke.c | 2 +- fs/jbd2/transaction.c | 2 +- fs/jffs2/TODO | 2 +- fs/jffs2/readinode.c | 2 +- fs/jffs2/summary.c | 4 +- fs/jffs2/wbuf.c | 2 +- fs/jfs/jfs_dmap.c | 4 +- fs/jfs/jfs_extent.c | 6 +-- fs/jfs/jfs_imap.c | 14 +++--- fs/jfs/jfs_logmgr.h | 2 +- fs/jfs/jfs_metapage.h | 2 +- fs/jfs/jfs_txnmgr.c | 2 +- fs/jfs/resize.c | 4 +- fs/jfs/super.c | 2 +- fs/logfs/dev_mtd.c | 2 +- fs/logfs/dir.c | 2 +- fs/logfs/readwrite.c | 2 +- fs/mbcache.c | 2 +- fs/namei.c | 2 +- fs/ncpfs/inode.c | 2 +- fs/nfs/callback_xdr.c | 2 +- fs/nfs/file.c | 2 +- fs/nfs/nfs4filelayout.h | 2 +- fs/nfs_common/nfsacl.c | 2 +- fs/nfsd/nfs3xdr.c | 2 +- fs/nfsd/nfs4state.c | 4 +- fs/nfsd/nfsxdr.c | 2 +- fs/notify/fanotify/fanotify_user.c | 2 +- fs/notify/inotify/inotify_fsnotify.c | 2 +- fs/notify/mark.c | 2 +- fs/ntfs/attrib.c | 4 +- fs/ntfs/compress.c | 2 +- fs/ntfs/inode.c | 4 +- fs/ntfs/layout.h | 12 ++--- fs/ntfs/logfile.c | 2 +- fs/ntfs/logfile.h | 2 +- fs/ntfs/mft.c | 8 ++-- fs/ntfs/runlist.c | 2 +- fs/ntfs/super.c | 14 +++--- fs/ocfs2/alloc.c | 2 +- fs/ocfs2/aops.h | 2 +- fs/ocfs2/cluster/heartbeat.c | 2 +- fs/ocfs2/cluster/quorum.c | 4 +- fs/ocfs2/cluster/tcp.c | 2 +- fs/ocfs2/dlm/dlmmaster.c | 4 +- fs/ocfs2/inode.c | 4 +- fs/ocfs2/journal.c | 2 +- fs/ocfs2/journal.h | 2 +- fs/ocfs2/namei.c | 2 +- fs/ocfs2/ocfs2_fs.h | 4 +- fs/ocfs2/quota_global.c | 2 +- fs/ocfs2/reservations.h | 2 +- fs/ocfs2/stackglue.h | 2 +- fs/ocfs2/suballoc.c | 4 +- fs/ocfs2/super.c | 2 +- fs/ocfs2/xattr.c | 4 +- fs/partitions/check.c | 4 +- fs/proc/base.c | 2 +- fs/pstore/Kconfig | 2 +- fs/quota/dquot.c | 2 +- fs/reiserfs/journal.c | 4 +- fs/reiserfs/lock.c | 2 +- fs/reiserfs/super.c | 4 +- fs/reiserfs/xattr.c | 2 +- fs/squashfs/cache.c | 4 +- fs/ubifs/budget.c | 2 +- fs/ufs/inode.c | 2 +- fs/ufs/super.c | 6 +-- fs/xfs/linux-2.6/xfs_aops.c | 2 +- fs/xfs/linux-2.6/xfs_buf.c | 4 +- fs/xfs/linux-2.6/xfs_file.c | 2 +- fs/xfs/linux-2.6/xfs_iops.c | 2 +- fs/xfs/linux-2.6/xfs_sync.c | 2 +- fs/xfs/quota/xfs_dquot.c | 2 +- fs/xfs/quota/xfs_qm_bhv.c | 2 +- fs/xfs/quota/xfs_qm_syscalls.c | 4 +- fs/xfs/xfs_buf_item.c | 2 +- fs/xfs/xfs_inode.c | 2 +- fs/xfs/xfs_inode.h | 4 +- fs/xfs/xfs_log_priv.h | 2 +- fs/xfs/xfs_log_recover.c | 4 +- fs/xfs/xfs_trans_inode.c | 2 +- fs/xfs/xfs_vnodeops.c | 4 +- include/acpi/actbl.h | 2 +- include/asm-generic/siginfo.h | 2 +- include/asm-generic/vmlinux.lds.h | 2 +- include/drm/drmP.h | 4 +- include/drm/drm_crtc.h | 4 +- include/drm/drm_mm.h | 2 +- include/drm/drm_mode.h | 2 +- include/drm/mga_drm.h | 2 +- include/drm/radeon_drm.h | 2 +- include/drm/savage_drm.h | 2 +- include/drm/ttm/ttm_bo_api.h | 14 +++--- include/drm/ttm/ttm_bo_driver.h | 6 +-- include/drm/vmwgfx_drm.h | 2 +- include/linux/amba/clcd.h | 2 +- include/linux/amba/mmci.h | 6 +-- include/linux/can/error.h | 2 +- include/linux/can/netlink.h | 2 +- include/linux/cdk.h | 2 +- include/linux/cfag12864b.h | 2 +- include/linux/cgroup.h | 2 +- include/linux/cm4000_cs.h | 2 +- include/linux/configfs.h | 2 +- include/linux/cper.h | 2 +- include/linux/decompress/mm.h | 2 +- include/linux/dmaengine.h | 2 +- include/linux/drbd.h | 4 +- include/linux/drbd_limits.h | 6 +-- include/linux/ethtool.h | 2 +- include/linux/eventpoll.h | 2 +- include/linux/exportfs.h | 2 +- include/linux/fb.h | 8 ++-- include/linux/firewire-cdev.h | 2 +- include/linux/fs.h | 4 +- include/linux/fscache-cache.h | 2 +- include/linux/fscache.h | 6 +-- include/linux/hid.h | 2 +- include/linux/hp_sdc.h | 2 +- include/linux/i2o.h | 2 +- include/linux/interrupt.h | 4 +- include/linux/ipmi.h | 4 +- include/linux/isdn/hdlc.h | 2 +- include/linux/ixjuser.h | 2 +- include/linux/jiffies.h | 2 +- include/linux/ktime.h | 4 +- include/linux/led-lm3530.h | 2 +- include/linux/libata.h | 2 +- include/linux/lru_cache.h | 2 +- include/linux/mfd/wm8350/pmic.h | 2 +- include/linux/mm.h | 2 +- include/linux/mmc/dw_mmc.h | 4 +- include/linux/mroute6.h | 2 +- include/linux/mtd/cfi.h | 2 +- include/linux/mtd/nand.h | 6 +-- include/linux/mtd/xip.h | 2 +- include/linux/netfilter/nf_conntrack_proto_gre.h | 2 +- include/linux/netfilter_bridge/ebtables.h | 2 +- include/linux/nfs4.h | 2 +- include/linux/nfsd/export.h | 2 +- include/linux/nfsd/nfsfh.h | 2 +- include/linux/nl80211.h | 10 ++-- include/linux/notifier.h | 2 +- include/linux/omap3isp.h | 2 +- include/linux/page_cgroup.h | 2 +- include/linux/pci_regs.h | 4 +- include/linux/perf_event.h | 2 +- include/linux/pid.h | 2 +- include/linux/pkt_sched.h | 2 +- include/linux/poll.h | 2 +- include/linux/prefetch.h | 2 +- include/linux/pxa2xx_ssp.h | 2 +- include/linux/raid/md_p.h | 2 +- include/linux/reiserfs_fs.h | 2 +- include/linux/sched.h | 2 +- include/linux/skbuff.h | 2 +- include/linux/smc91x.h | 2 +- include/linux/socket.h | 2 +- include/linux/soundcard.h | 2 +- include/linux/spi/spidev.h | 2 +- include/linux/spinlock.h | 2 +- include/linux/stmmac.h | 2 +- include/linux/stop_machine.h | 2 +- include/linux/sunrpc/cache.h | 4 +- include/linux/sunrpc/svcauth_gss.h | 2 +- include/linux/sysdev.h | 6 +-- include/linux/timerqueue.h | 2 +- include/linux/tracehook.h | 4 +- include/linux/ucb1400.h | 2 +- include/linux/usb.h | 4 +- include/linux/usb/composite.h | 2 +- include/linux/usb/ehci_def.h | 2 +- include/linux/usb/functionfs.h | 4 +- include/linux/usb/gadget.h | 4 +- include/linux/usb/midi.h | 2 +- include/linux/usb/wusb.h | 2 +- include/linux/uwb.h | 6 +-- include/linux/uwb/umc.h | 2 +- include/linux/vgaarb.h | 4 +- include/linux/wimax.h | 2 +- include/linux/xilinxfb.h | 2 +- include/media/davinci/dm355_ccdc.h | 2 +- include/media/davinci/isif.h | 2 +- include/media/lirc.h | 2 +- include/net/9p/9p.h | 8 ++-- include/net/9p/client.h | 2 +- include/net/9p/transport.h | 2 +- include/net/caif/cfcnfg.h | 2 +- include/net/gen_stats.h | 2 +- include/net/ip_vs.h | 2 +- include/net/irda/irlap.h | 2 +- include/net/irda/wrapper.h | 2 +- include/net/iucv/iucv.h | 2 +- include/net/iw_handler.h | 4 +- include/net/mac80211.h | 2 +- include/net/pkt_sched.h | 2 +- include/net/sock.h | 2 +- include/net/transp_v6.h | 2 +- include/net/wimax.h | 2 +- include/net/wpan-phy.h | 2 +- include/rxrpc/packet.h | 2 +- include/scsi/fc/fc_fcp.h | 2 +- include/scsi/iscsi_if.h | 2 +- include/scsi/libfc.h | 8 ++-- include/scsi/libiscsi_tcp.h | 2 +- include/scsi/osd_initiator.h | 2 +- include/scsi/scsi_host.h | 2 +- include/scsi/scsi_transport_fc.h | 6 +-- include/sound/ac97_codec.h | 2 +- include/sound/control.h | 2 +- include/sound/cs46xx_dsp_spos.h | 2 +- include/sound/hdspm.h | 2 +- include/sound/soc-dapm.h | 2 +- include/target/target_core_base.h | 6 +-- include/target/target_core_fabric_ops.h | 2 +- include/video/kyro.h | 2 +- include/video/neomagic.h | 2 +- include/video/newport.h | 2 +- include/video/sisfb.h | 2 +- include/video/sstfb.h | 6 +-- include/xen/interface/elfnote.h | 2 +- init/do_mounts.c | 2 +- ipc/msg.c | 4 +- ipc/sem.c | 2 +- ipc/shm.c | 2 +- kernel/audit_tree.c | 2 +- kernel/auditsc.c | 2 +- kernel/cgroup.c | 2 +- kernel/cpu.c | 2 +- kernel/debug/debug_core.c | 2 +- kernel/debug/kdb/kdb_main.c | 6 +-- kernel/debug/kdb/kdb_support.c | 2 +- kernel/exit.c | 2 +- kernel/irq/chip.c | 2 +- kernel/irq/migration.c | 2 +- kernel/kexec.c | 6 +-- kernel/kthread.c | 2 +- kernel/latencytop.c | 2 +- kernel/lockdep.c | 4 +- kernel/module.c | 6 +-- kernel/mutex.c | 2 +- kernel/padata.c | 8 ++-- kernel/params.c | 2 +- kernel/posix-cpu-timers.c | 2 +- kernel/posix-timers.c | 2 +- kernel/power/main.c | 2 +- kernel/sched.c | 6 +-- kernel/sched_autogroup.c | 2 +- kernel/sched_fair.c | 2 +- kernel/sched_rt.c | 4 +- kernel/signal.c | 2 +- kernel/softirq.c | 2 +- kernel/time/jiffies.c | 2 +- kernel/time/timer_stats.c | 2 +- kernel/trace/ftrace.c | 4 +- kernel/trace/ring_buffer.c | 4 +- kernel/trace/trace.c | 2 +- kernel/trace/trace_clock.c | 2 +- kernel/trace/trace_entries.h | 2 +- kernel/trace/trace_functions_graph.c | 2 +- kernel/trace/trace_irqsoff.c | 2 +- kernel/trace/trace_kprobe.c | 2 +- kernel/user-return-notifier.c | 2 +- kernel/wait.c | 2 +- kernel/workqueue.c | 2 +- lib/bitmap.c | 2 +- lib/btree.c | 4 +- lib/decompress_unxz.c | 2 +- lib/parser.c | 2 +- lib/timerqueue.c | 2 +- mm/backing-dev.c | 2 +- mm/hugetlb.c | 10 ++-- mm/hwpoison-inject.c | 2 +- mm/internal.h | 2 +- mm/kmemleak.c | 6 +-- mm/ksm.c | 2 +- mm/memcontrol.c | 8 ++-- mm/memory-failure.c | 6 +-- mm/memory_hotplug.c | 2 +- mm/migrate.c | 2 +- mm/nobootmem.c | 2 +- mm/page_alloc.c | 4 +- mm/page_cgroup.c | 2 +- mm/percpu.c | 10 ++-- mm/slab.c | 4 +- mm/slub.c | 8 ++-- mm/sparse.c | 2 +- mm/util.c | 2 +- mm/vmscan.c | 4 +- net/8021q/vlanproc.c | 2 +- net/9p/client.c | 2 +- net/9p/trans_common.c | 4 +- net/9p/util.c | 2 +- net/atm/br2684.c | 2 +- net/atm/lec.h | 2 +- net/batman-adv/soft-interface.c | 2 +- net/bluetooth/hci_core.c | 2 +- net/bluetooth/l2cap_sock.c | 2 +- net/bridge/br_fdb.c | 2 +- net/bridge/br_ioctl.c | 2 +- net/caif/caif_socket.c | 2 +- net/can/bcm.c | 2 +- net/ceph/osd_client.c | 2 +- net/core/dev.c | 12 ++--- net/core/filter.c | 2 +- net/core/link_watch.c | 2 +- net/core/rtnetlink.c | 4 +- net/core/skbuff.c | 2 +- net/core/sock.c | 10 ++-- net/dccp/output.c | 2 +- net/dsa/mv88e6131.c | 2 +- net/ipv4/cipso_ipv4.c | 8 ++-- net/ipv4/fib_trie.c | 2 +- net/ipv4/icmp.c | 2 +- net/ipv4/ip_output.c | 2 +- net/ipv4/ipconfig.c | 2 +- net/ipv4/netfilter/arp_tables.c | 4 +- net/ipv4/netfilter/ip_tables.c | 2 +- net/ipv4/netfilter/nf_nat_core.c | 4 +- net/ipv4/raw.c | 2 +- net/ipv4/route.c | 4 +- net/ipv4/tcp_lp.c | 2 +- net/ipv4/tcp_output.c | 2 +- net/ipv4/tcp_yeah.c | 2 +- net/ipv4/udp.c | 2 +- net/ipv6/addrconf.c | 4 +- net/ipv6/af_inet6.c | 2 +- net/ipv6/ip6_output.c | 2 +- net/ipv6/netfilter/ip6_tables.c | 2 +- net/ipv6/netfilter/nf_defrag_ipv6_hooks.c | 2 +- net/irda/irlap.c | 2 +- net/irda/irlap_event.c | 8 ++-- net/irda/irlap_frame.c | 2 +- net/irda/irlmp_event.c | 2 +- net/irda/irnet/irnet.h | 2 +- net/irda/irqueue.c | 2 +- net/irda/irttp.c | 2 +- net/irda/qos.c | 8 ++-- net/irda/timer.c | 2 +- net/iucv/af_iucv.c | 2 +- net/iucv/iucv.c | 4 +- net/mac80211/ieee80211_i.h | 2 +- net/mac80211/mesh_pathtbl.c | 2 +- net/mac80211/rc80211_minstrel_ht.c | 2 +- net/mac80211/rc80211_pid.h | 2 +- net/mac80211/rx.c | 2 +- net/mac80211/sta_info.c | 4 +- net/mac80211/sta_info.h | 2 +- net/netfilter/ipset/ip_set_core.c | 2 +- net/netfilter/ipvs/ip_vs_conn.c | 4 +- net/netfilter/ipvs/ip_vs_lblc.c | 2 +- net/netfilter/ipvs/ip_vs_lblcr.c | 2 +- net/netfilter/ipvs/ip_vs_proto_sctp.c | 8 ++-- net/netfilter/nf_conntrack_core.c | 4 +- net/netfilter/nf_conntrack_proto_dccp.c | 2 +- net/netfilter/nf_conntrack_proto_sctp.c | 6 +-- net/netfilter/nf_conntrack_sip.c | 2 +- net/netfilter/nf_queue.c | 2 +- net/netlabel/netlabel_domainhash.c | 10 ++-- net/netlabel/netlabel_mgmt.c | 2 +- net/rds/ib_send.c | 2 +- net/rds/iw_cm.c | 2 +- net/rds/iw_rdma.c | 2 +- net/rds/iw_send.c | 2 +- net/rds/send.c | 2 +- net/rose/rose_route.c | 2 +- net/sched/act_api.c | 2 +- net/sched/act_pedit.c | 2 +- net/sched/em_meta.c | 2 +- net/sched/sch_htb.c | 2 +- net/sched/sch_netem.c | 6 +-- net/sctp/associola.c | 2 +- net/sctp/auth.c | 6 +-- net/sctp/input.c | 2 +- net/sctp/output.c | 2 +- net/sctp/outqueue.c | 6 +-- net/sctp/sm_sideeffect.c | 2 +- net/sctp/sm_statefuns.c | 20 ++++---- net/sctp/socket.c | 2 +- net/sctp/ulpevent.c | 2 +- net/sctp/ulpqueue.c | 2 +- net/socket.c | 2 +- net/sunrpc/auth_gss/svcauth_gss.c | 2 +- net/sunrpc/xprtsock.c | 4 +- net/tipc/link.c | 2 +- net/tipc/name_distr.c | 2 +- net/unix/af_unix.c | 2 +- net/wanrouter/wanproc.c | 2 +- net/wireless/reg.c | 4 +- net/x25/x25_facilities.c | 2 +- net/x25/x25_forward.c | 4 +- net/xfrm/xfrm_user.c | 6 +-- samples/Kconfig | 2 +- samples/hw_breakpoint/data_breakpoint.c | 2 +- scripts/Makefile.modpost | 4 +- scripts/checkpatch.pl | 6 +-- scripts/dtc/libfdt/libfdt.h | 2 +- scripts/dtc/livetree.c | 2 +- scripts/gen_initramfs_list.sh | 2 +- scripts/kernel-doc | 2 +- scripts/package/buildtar | 2 +- scripts/rt-tester/rt-tester.py | 2 +- security/apparmor/match.c | 2 +- security/apparmor/policy_unpack.c | 2 +- security/selinux/netlabel.c | 2 +- security/selinux/ss/services.c | 4 +- security/smack/smack_access.c | 2 +- security/smack/smack_lsm.c | 6 +-- security/smack/smackfs.c | 6 +-- security/tomoyo/load_policy.c | 2 +- sound/aoa/codecs/tas.c | 2 +- sound/core/pcm_memory.c | 6 +-- sound/core/pcm_native.c | 2 +- sound/core/seq/seq_dummy.c | 2 +- sound/core/vmaster.c | 2 +- sound/drivers/pcm-indirect2.c | 4 +- sound/drivers/vx/vx_pcm.c | 2 +- sound/isa/sb/emu8000.c | 2 +- sound/isa/wavefront/wavefront_midi.c | 2 +- sound/isa/wss/wss_lib.c | 2 +- sound/oss/ac97_codec.c | 6 +-- sound/oss/audio.c | 4 +- sound/oss/dmasound/dmasound_core.c | 2 +- sound/oss/midibuf.c | 2 +- sound/oss/sb_card.c | 2 +- sound/oss/sb_ess.c | 2 +- sound/oss/swarm_cs4297a.c | 2 +- sound/oss/vidc.c | 2 +- sound/pci/ad1889.c | 2 +- sound/pci/asihpi/asihpi.c | 2 +- sound/pci/asihpi/hpi.h | 2 +- sound/pci/asihpi/hpi6000.c | 2 +- sound/pci/asihpi/hpi6205.c | 2 +- sound/pci/asihpi/hpi_internal.h | 2 +- sound/pci/asihpi/hpimsgx.c | 2 +- sound/pci/au88x0/au88x0.h | 2 +- sound/pci/au88x0/au88x0_a3d.c | 4 +- sound/pci/au88x0/au88x0_pcm.c | 2 +- sound/pci/azt3328.c | 2 +- sound/pci/ca0106/ca0106.h | 6 +-- sound/pci/ca0106/ca0106_main.c | 2 +- sound/pci/ca0106/ca0106_mixer.c | 2 +- sound/pci/ca0106/ca0106_proc.c | 2 +- sound/pci/cmipci.c | 8 ++-- sound/pci/ctxfi/ctatc.c | 2 +- sound/pci/ctxfi/cthw20k1.c | 2 +- sound/pci/emu10k1/memory.c | 2 +- sound/pci/emu10k1/p16v.c | 2 +- sound/pci/emu10k1/p16v.h | 4 +- sound/pci/hda/hda_codec.c | 4 +- sound/pci/hda/patch_realtek.c | 4 +- sound/pci/hda/patch_sigmatel.c | 2 +- sound/pci/ice1712/aureon.c | 4 +- sound/pci/ice1712/ice1712.c | 4 +- sound/pci/ice1712/pontis.c | 2 +- sound/pci/ice1712/prodigy_hifi.c | 4 +- sound/pci/intel8x0.c | 2 +- sound/pci/intel8x0m.c | 2 +- sound/pci/mixart/mixart_core.c | 4 +- sound/pci/pcxhr/pcxhr_core.c | 12 ++--- sound/pci/rme96.c | 2 +- sound/pci/rme9652/hdspm.c | 4 +- sound/pci/sis7019.c | 6 +-- sound/ppc/snd_ps3.c | 2 +- sound/ppc/snd_ps3_reg.h | 14 +++--- sound/soc/atmel/atmel_ssc_dai.c | 2 +- sound/soc/codecs/alc5623.c | 2 +- sound/soc/codecs/lm4857.c | 2 +- sound/soc/codecs/tlv320aic26.h | 4 +- sound/soc/codecs/tlv320aic3x.c | 2 +- sound/soc/codecs/tlv320dac33.c | 2 +- sound/soc/codecs/twl4030.c | 6 +-- sound/soc/codecs/wm8580.c | 2 +- sound/soc/codecs/wm8753.c | 2 +- sound/soc/codecs/wm8904.c | 2 +- sound/soc/codecs/wm8955.c | 2 +- sound/soc/codecs/wm8962.c | 2 +- sound/soc/codecs/wm8991.c | 2 +- sound/soc/codecs/wm8993.c | 2 +- sound/soc/codecs/wm8994.c | 6 +-- sound/soc/codecs/wm9081.c | 4 +- sound/soc/imx/imx-ssi.c | 2 +- sound/soc/kirkwood/kirkwood-dma.c | 4 +- sound/soc/mid-x86/sst_platform.c | 4 +- sound/soc/omap/ams-delta.c | 6 +-- sound/soc/samsung/neo1973_wm8753.c | 4 +- sound/usb/6fire/firmware.c | 4 +- sound/usb/mixer.c | 2 +- sound/usb/quirks.c | 2 +- sound/usb/usx2y/usx2yhwdeppcm.c | 4 +- tools/perf/util/string.c | 2 +- .../x86_energy_perf_policy.c | 2 +- virt/kvm/eventfd.c | 2 +- 2463 files changed, 4252 insertions(+), 4252 deletions(-) (limited to 'include/linux') diff --git a/CREDITS b/CREDITS index 1d39a6d0a510..dca6abcead6b 100644 --- a/CREDITS +++ b/CREDITS @@ -1677,7 +1677,7 @@ W: http://www.codemonkey.org.uk D: Assorted VIA x86 support. D: 2.5 AGPGART overhaul. D: CPUFREQ maintenance. -D: Fedora kernel maintainence. +D: Fedora kernel maintenance. D: Misc/Other. S: 314 Littleton Rd, Westford, MA 01886, USA @@ -3211,7 +3211,7 @@ N: James Simmons E: jsimmons@infradead.org E: jsimmons@users.sf.net D: Frame buffer device maintainer -D: input layer developement +D: input layer development D: tty/console layer D: various mipsel devices S: 115 Carmel Avenue @@ -3290,7 +3290,7 @@ S: USA N: Manfred Spraul E: manfred@colorfullife.com W: http://www.colorfullife.com/~manfred -D: Lots of tiny hacks. Larger improvments to SysV IPC msg, +D: Lots of tiny hacks. Larger improvements to SysV IPC msg, D: slab, pipe, select. S: 71701 Schwieberdingen S: Germany diff --git a/Documentation/ABI/testing/sysfs-bus-css b/Documentation/ABI/testing/sysfs-bus-css index b585ec258a08..2979c40c10e9 100644 --- a/Documentation/ABI/testing/sysfs-bus-css +++ b/Documentation/ABI/testing/sysfs-bus-css @@ -29,7 +29,7 @@ Contact: Cornelia Huck linux-s390@vger.kernel.org Description: Contains the PIM/PAM/POM values, as reported by the channel subsystem when last queried by the common I/O - layer (this implies that this attribute is not neccessarily + layer (this implies that this attribute is not necessarily in sync with the values current in the channel subsystem). Note: This is an I/O-subchannel specific attribute. Users: s390-tools, HAL diff --git a/Documentation/ABI/testing/sysfs-class-led b/Documentation/ABI/testing/sysfs-class-led index edff6630c805..3646ec85d513 100644 --- a/Documentation/ABI/testing/sysfs-class-led +++ b/Documentation/ABI/testing/sysfs-class-led @@ -33,5 +33,5 @@ Contact: Richard Purdie Description: Invert the LED on/off state. This parameter is specific to gpio and backlight triggers. In case of the backlight trigger, - it is usefull when driving a LED which is intended to indicate + it is useful when driving a LED which is intended to indicate a device in a standby like state. diff --git a/Documentation/DocBook/dvb/dvbproperty.xml b/Documentation/DocBook/dvb/dvbproperty.xml index 5f57c7ccd4ba..97f397e2fb3a 100644 --- a/Documentation/DocBook/dvb/dvbproperty.xml +++ b/Documentation/DocBook/dvb/dvbproperty.xml @@ -40,7 +40,7 @@ Central frequency of the channel. - For ISDB-T the channels are usally transmitted with an offset of 143kHz. E.g. a + For ISDB-T the channels are usually transmitted with an offset of 143kHz. E.g. a valid frequncy could be 474143 kHz. The stepping is bound to the bandwidth of the channel which is 6MHz. diff --git a/Documentation/DocBook/dvb/frontend.xml b/Documentation/DocBook/dvb/frontend.xml index 78d756de5906..60c6976fb311 100644 --- a/Documentation/DocBook/dvb/frontend.xml +++ b/Documentation/DocBook/dvb/frontend.xml @@ -139,7 +139,7 @@ consistently to the DiSEqC commands as described in the DiSEqC spec.
SEC continuous tone -The continous 22KHz tone is usually used with non-DiSEqC capable LNBs to switch the +The continuous 22KHz tone is usually used with non-DiSEqC capable LNBs to switch the high/low band of a dual-band LNB. When using DiSEqC epuipment this voltage has to be switched consistently to the DiSEqC commands as described in the DiSEqC spec. diff --git a/Documentation/DocBook/kernel-locking.tmpl b/Documentation/DocBook/kernel-locking.tmpl index f66f4df18690..67e7ab41c0a6 100644 --- a/Documentation/DocBook/kernel-locking.tmpl +++ b/Documentation/DocBook/kernel-locking.tmpl @@ -1763,7 +1763,7 @@ as it would be on UP. There is a furthur optimization possible here: remember our original cache code, where there were no reference counts and the caller simply held the lock whenever using the object? This is still possible: if -you hold the lock, noone can delete the object, so you don't need to +you hold the lock, no one can delete the object, so you don't need to get and put the reference count. diff --git a/Documentation/DocBook/libata.tmpl b/Documentation/DocBook/libata.tmpl index 8c5411cfeaf0..cdd1bb9aac0d 100644 --- a/Documentation/DocBook/libata.tmpl +++ b/Documentation/DocBook/libata.tmpl @@ -1032,7 +1032,7 @@ and other resources, etc. This is indicated by ICRC bit in the ERROR register and - means that corruption occurred during data transfer. Upto + means that corruption occurred during data transfer. Up to ATA/ATAPI-7, the standard specifies that this bit is only applicable to UDMA transfers but ATA/ATAPI-8 draft revision 1f says that the bit may be applicable to multiword DMA and @@ -1045,10 +1045,10 @@ and other resources, etc. ABRT error during data transfer or on completion - Upto ATA/ATAPI-7, the standard specifies that ABRT could be + Up to ATA/ATAPI-7, the standard specifies that ABRT could be set on ICRC errors and on cases where a device is not able to complete a command. Combined with the fact that MWDMA - and PIO transfer errors aren't allowed to use ICRC bit upto + and PIO transfer errors aren't allowed to use ICRC bit up to ATA/ATAPI-7, it seems to imply that ABRT bit alone could indicate tranfer errors. @@ -1122,7 +1122,7 @@ and other resources, etc. Depending on commands, not all STATUS/ERROR bits are applicable. These non-applicable bits are marked with - "na" in the output descriptions but upto ATA/ATAPI-7 + "na" in the output descriptions but up to ATA/ATAPI-7 no definition of "na" can be found. However, ATA/ATAPI-8 draft revision 1f describes "N/A" as follows. @@ -1507,7 +1507,7 @@ and other resources, etc. - CHS set up with INITIALIZE DEVICE PARAMETERS (seldomly used) + CHS set up with INITIALIZE DEVICE PARAMETERS (seldom used) diff --git a/Documentation/DocBook/mtdnand.tmpl b/Documentation/DocBook/mtdnand.tmpl index 620eb3f6a90a..6f242d5dee9a 100644 --- a/Documentation/DocBook/mtdnand.tmpl +++ b/Documentation/DocBook/mtdnand.tmpl @@ -485,7 +485,7 @@ static void board_select_chip (struct mtd_info *mtd, int chip) Reed-Solomon library. - The ECC bytes must be placed immidiately after the data + The ECC bytes must be placed immediately after the data bytes in order to make the syndrome generator work. This is contrary to the usual layout used by software ECC. The separation of data and out of band area is not longer @@ -629,7 +629,7 @@ static void board_select_chip (struct mtd_info *mtd, int chip) holds the bad block table. Store a pointer to the pattern in the pattern field. Further the length of the pattern has to be stored in len and the offset in the spare area must be given - in the offs member of the nand_bbt_descr stucture. For mirrored + in the offs member of the nand_bbt_descr structure. For mirrored bad block tables different patterns are mandatory. Table creation Set the option NAND_BBT_CREATE to enable the table creation @@ -648,7 +648,7 @@ static void board_select_chip (struct mtd_info *mtd, int chip) Table version control Set the option NAND_BBT_VERSION to enable the table version control. It's highly recommended to enable this for mirrored tables with write - support. It makes sure that the risk of loosing the bad block + support. It makes sure that the risk of losing the bad block table information is reduced to the loss of the information about the one worn out block which should be marked bad. The version is stored in 4 consecutive bytes in the spare area of the device. The position of @@ -1060,19 +1060,19 @@ data in this page 0x3D ECC byte 21 -Error correction code byte 0 of the eigth 256 Bytes of data +Error correction code byte 0 of the eighth 256 Bytes of data in this page 0x3E ECC byte 22 -Error correction code byte 1 of the eigth 256 Bytes of data +Error correction code byte 1 of the eighth 256 Bytes of data in this page 0x3F ECC byte 23 -Error correction code byte 2 of the eigth 256 Bytes of data +Error correction code byte 2 of the eighth 256 Bytes of data in this page diff --git a/Documentation/DocBook/regulator.tmpl b/Documentation/DocBook/regulator.tmpl index 53f4f8d3b810..346e552fa2cc 100644 --- a/Documentation/DocBook/regulator.tmpl +++ b/Documentation/DocBook/regulator.tmpl @@ -267,8 +267,8 @@ Constraints - As well as definining the connections the machine interface - also provides constraints definining the operations that + As well as defining the connections the machine interface + also provides constraints defining the operations that clients are allowed to perform and the parameters that may be set. This is required since generally regulator devices will offer more flexibility than it is safe to use on a given diff --git a/Documentation/DocBook/uio-howto.tmpl b/Documentation/DocBook/uio-howto.tmpl index b4665b9c40b0..7c4b514d62b1 100644 --- a/Documentation/DocBook/uio-howto.tmpl +++ b/Documentation/DocBook/uio-howto.tmpl @@ -797,7 +797,7 @@ framework to set up sysfs files for this region. Simply leave it alone. perform some initialization. After that, your hardware starts working and will generate an interrupt as soon as it's finished, has some data available, or needs your - attention because an error occured. + attention because an error occurred. /dev/uioX is a read-only file. A diff --git a/Documentation/DocBook/usb.tmpl b/Documentation/DocBook/usb.tmpl index af293606fbe3..8d57c1888dca 100644 --- a/Documentation/DocBook/usb.tmpl +++ b/Documentation/DocBook/usb.tmpl @@ -690,7 +690,7 @@ usbdev_ioctl (int fd, int ifno, unsigned request, void *param) This request lets kernel drivers talk to user mode code through filesystem operations even when they don't create - a charactor or block special device. + a character or block special device. It's also been used to do things like ask devices what device special file should be used. Two pre-defined ioctls are used diff --git a/Documentation/DocBook/v4l/common.xml b/Documentation/DocBook/v4l/common.xml index dbab79c215c1..9028721438dc 100644 --- a/Documentation/DocBook/v4l/common.xml +++ b/Documentation/DocBook/v4l/common.xml @@ -100,7 +100,7 @@ linux-kernel@vger.kernel.org, 2002-11-20. --> By convention system administrators create various character device special files with these major and minor numbers in -the /dev directory. The names recomended for the +the /dev directory. The names recommended for the different V4L2 device types are listed in . diff --git a/Documentation/DocBook/v4l/controls.xml b/Documentation/DocBook/v4l/controls.xml index 2fae3e87ce73..a920ee80f640 100644 --- a/Documentation/DocBook/v4l/controls.xml +++ b/Documentation/DocBook/v4l/controls.xml @@ -1243,7 +1243,7 @@ values are: Mutes the audio when capturing. This is not done by muting audio hardware, which can still produce a slight hiss, but in the encoder itself, guaranteeing a fixed -and reproducable audio bitstream. 0 = unmuted, 1 = muted. +and reproducible audio bitstream. 0 = unmuted, 1 = muted. diff --git a/Documentation/DocBook/v4l/dev-subdev.xml b/Documentation/DocBook/v4l/dev-subdev.xml index 21caff6d159b..05c8fefcbcbe 100644 --- a/Documentation/DocBook/v4l/dev-subdev.xml +++ b/Documentation/DocBook/v4l/dev-subdev.xml @@ -90,7 +90,7 @@ processing hardware.
- Image Format Negotation on Pipelines + Image Format Negotiation on Pipelines diff --git a/Documentation/DocBook/v4l/libv4l.xml b/Documentation/DocBook/v4l/libv4l.xml index c14fc3db2a81..3cb10ec51929 100644 --- a/Documentation/DocBook/v4l/libv4l.xml +++ b/Documentation/DocBook/v4l/libv4l.xml @@ -140,7 +140,7 @@ and is not locked sets the cid to the scaled value. int v4l2_get_control(int fd, int cid) - This function returns a value of 0 - 65535, scaled to from the actual range of the given v4l control id. when the cid does not exist, could not be -accessed for some reason, or some error occured 0 is returned. +accessed for some reason, or some error occurred 0 is returned.
diff --git a/Documentation/DocBook/v4l/remote_controllers.xml b/Documentation/DocBook/v4l/remote_controllers.xml index 3c3b667b28e7..160e464d44b7 100644 --- a/Documentation/DocBook/v4l/remote_controllers.xml +++ b/Documentation/DocBook/v4l/remote_controllers.xml @@ -133,7 +133,7 @@ different IR's. Due to that, V4L2 API now specifies a standard for mapping Media KEY_LEFTLeft keyLEFT KEY_RIGHTRight keyRIGHT -Miscelaneous keys +Miscellaneous keys KEY_DOTReturn a dot. KEY_FNSelect a functionFUNCTION diff --git a/Documentation/DocBook/writing-an-alsa-driver.tmpl b/Documentation/DocBook/writing-an-alsa-driver.tmpl index 0ba149de2608..58ced2346e67 100644 --- a/Documentation/DocBook/writing-an-alsa-driver.tmpl +++ b/Documentation/DocBook/writing-an-alsa-driver.tmpl @@ -4784,7 +4784,7 @@ struct _snd_pcm_runtime { FM registers can be directly accessed through the direct-FM API, defined in <sound/asound_fm.h>. In ALSA native mode, FM registers are accessed through - the Hardware-Dependant Device direct-FM extension API, whereas in + the Hardware-Dependent Device direct-FM extension API, whereas in OSS compatible mode, FM registers can be accessed with the OSS direct-FM compatible API in /dev/dmfmX device. diff --git a/Documentation/PCI/MSI-HOWTO.txt b/Documentation/PCI/MSI-HOWTO.txt index dcf7acc720e1..3f5e0b09bed5 100644 --- a/Documentation/PCI/MSI-HOWTO.txt +++ b/Documentation/PCI/MSI-HOWTO.txt @@ -253,8 +253,8 @@ In constrast, MSI is restricted to a maximum of 32 interrupts (and must be a power of two). In addition, the MSI interrupt vectors must be allocated consecutively, so the system may not be able to allocate as many vectors for MSI as it could for MSI-X. On some platforms, MSI -interrupts must all be targetted at the same set of CPUs whereas MSI-X -interrupts can all be targetted at different CPUs. +interrupts must all be targeted at the same set of CPUs whereas MSI-X +interrupts can all be targeted at different CPUs. 4.5.2 Spinlocks diff --git a/Documentation/SecurityBugs b/Documentation/SecurityBugs index 26c3b3635d9f..a660d494c8ed 100644 --- a/Documentation/SecurityBugs +++ b/Documentation/SecurityBugs @@ -28,7 +28,7 @@ expect these delays to be short, measurable in days, not weeks or months. A disclosure date is negotiated by the security team working with the bug submitter as well as vendors. However, the kernel security team holds the final say when setting a disclosure date. The timeframe for -disclosure is from immediate (esp. if it's already publically known) +disclosure is from immediate (esp. if it's already publicly known) to a few weeks. As a basic default policy, we expect report date to disclosure date to be on the order of 7 days. diff --git a/Documentation/SubmittingDrivers b/Documentation/SubmittingDrivers index 38d2aab59cac..319baa8b60dd 100644 --- a/Documentation/SubmittingDrivers +++ b/Documentation/SubmittingDrivers @@ -101,7 +101,7 @@ PM support: Since Linux is used on many portable and desktop systems, your complete overview of the power management issues related to drivers see Documentation/power/devices.txt . -Control: In general if there is active maintainance of a driver by +Control: In general if there is active maintenance of a driver by the author then patches will be redirected to them unless they are totally obvious and without need of checking. If you want to be the contact and update point for the diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches index 689e2371095c..e439cd0d3375 100644 --- a/Documentation/SubmittingPatches +++ b/Documentation/SubmittingPatches @@ -729,7 +729,7 @@ Linus Torvalds's mail on the canonical patch format: Andi Kleen, "On submitting kernel patches" - Some strategies to get difficult or controversal changes in. + Some strategies to get difficult or controversial changes in. http://halobates.de/on-submitting-patches.pdf -- diff --git a/Documentation/arm/IXP4xx b/Documentation/arm/IXP4xx index 133c5fa6c7a1..7b9351f2f555 100644 --- a/Documentation/arm/IXP4xx +++ b/Documentation/arm/IXP4xx @@ -36,7 +36,7 @@ Linux currently supports the following features on the IXP4xx chips: - Timers (watchdog, OS) The following components of the chips are not supported by Linux and -require the use of Intel's propietary CSR softare: +require the use of Intel's proprietary CSR softare: - USB device interface - Network interfaces (HSS, Utopia, NPEs, etc) @@ -47,7 +47,7 @@ software from: http://developer.intel.com/design/network/products/npfamily/ixp425.htm -DO NOT POST QUESTIONS TO THE LINUX MAILING LISTS REGARDING THE PROPIETARY +DO NOT POST QUESTIONS TO THE LINUX MAILING LISTS REGARDING THE PROPRIETARY SOFTWARE. There are several websites that provide directions/pointers on using diff --git a/Documentation/arm/Samsung-S3C24XX/Suspend.txt b/Documentation/arm/Samsung-S3C24XX/Suspend.txt index 7edd0e2e6c5b..1ca63b3e5635 100644 --- a/Documentation/arm/Samsung-S3C24XX/Suspend.txt +++ b/Documentation/arm/Samsung-S3C24XX/Suspend.txt @@ -116,7 +116,7 @@ Configuration Allows the entire memory to be checksummed before and after the suspend to see if there has been any corruption of the contents. - Note, the time to calculate the CRC is dependant on the CPU speed + Note, the time to calculate the CRC is dependent on the CPU speed and the size of memory. For an 64Mbyte RAM area on an 200MHz S3C2410, this can take approximately 4 seconds to complete. diff --git a/Documentation/arm/Samsung/GPIO.txt b/Documentation/arm/Samsung/GPIO.txt index 05850c62abeb..513f2562c1a3 100644 --- a/Documentation/arm/Samsung/GPIO.txt +++ b/Documentation/arm/Samsung/GPIO.txt @@ -5,7 +5,7 @@ Introduction ------------ This outlines the Samsung GPIO implementation and the architecture -specfic calls provided alongisde the drivers/gpio core. +specific calls provided alongisde the drivers/gpio core. S3C24XX (Legacy) diff --git a/Documentation/block/biodoc.txt b/Documentation/block/biodoc.txt index 2a7b38c832c7..c6d84cfd2f56 100644 --- a/Documentation/block/biodoc.txt +++ b/Documentation/block/biodoc.txt @@ -497,7 +497,7 @@ The scatter gather list is in the form of an array of entries with their corresponding dma address mappings filled in at the appropriate time. As an optimization, contiguous physical pages can be covered by a single entry where refers to the first page and -covers the range of pages (upto 16 contiguous pages could be covered this +covers the range of pages (up to 16 contiguous pages could be covered this way). There is a helper routine (blk_rq_map_sg) which drivers can use to build the sg list. @@ -565,7 +565,7 @@ struct request { . int tag; /* command tag associated with request */ void *special; /* same as before */ - char *buffer; /* valid only for low memory buffers upto + char *buffer; /* valid only for low memory buffers up to current_nr_sectors */ . . diff --git a/Documentation/cpu-hotplug.txt b/Documentation/cpu-hotplug.txt index 45d5a217484f..a20bfd415e41 100644 --- a/Documentation/cpu-hotplug.txt +++ b/Documentation/cpu-hotplug.txt @@ -196,7 +196,7 @@ the state as 0 when a cpu if offline and 1 when its online. #To display the current cpu state. #cat /sys/devices/system/cpu/cpuX/online -Q: Why cant i remove CPU0 on some systems? +Q: Why can't i remove CPU0 on some systems? A: Some architectures may have some special dependency on a certain CPU. For e.g in IA64 platforms we have ability to sent platform interrupts to the diff --git a/Documentation/dell_rbu.txt b/Documentation/dell_rbu.txt index 15174985ad08..d262e22bddec 100644 --- a/Documentation/dell_rbu.txt +++ b/Documentation/dell_rbu.txt @@ -62,7 +62,7 @@ image file and then arrange all these packets back to back in to one single file. This file is then copied to /sys/class/firmware/dell_rbu/data. Once this file gets to the driver, the driver extracts packet_size data from -the file and spreads it accross the physical memory in contiguous packet_sized +the file and spreads it across the physical memory in contiguous packet_sized space. This method makes sure that all the packets get to the driver in a single operation. diff --git a/Documentation/device-mapper/dm-service-time.txt b/Documentation/device-mapper/dm-service-time.txt index 7d00668e97bb..fb1d4a0cf122 100644 --- a/Documentation/device-mapper/dm-service-time.txt +++ b/Documentation/device-mapper/dm-service-time.txt @@ -37,7 +37,7 @@ Algorithm ========= dm-service-time adds the I/O size to 'in-flight-size' when the I/O is -dispatched and substracts when completed. +dispatched and subtracts when completed. Basically, dm-service-time selects a path having minimum service time which is calculated by: diff --git a/Documentation/devicetree/bindings/fb/sm501fb.txt b/Documentation/devicetree/bindings/fb/sm501fb.txt index 7d319fba9b5b..9d9f0098092b 100644 --- a/Documentation/devicetree/bindings/fb/sm501fb.txt +++ b/Documentation/devicetree/bindings/fb/sm501fb.txt @@ -18,9 +18,9 @@ Optional properties: - edid : verbatim EDID data block describing attached display. Data from the detailed timing descriptor will be used to program the display controller. -- little-endian: availiable on big endian systems, to +- little-endian: available on big endian systems, to set different foreign endian. -- big-endian: availiable on little endian systems, to +- big-endian: available on little endian systems, to set different foreign endian. Example for MPC5200: diff --git a/Documentation/devicetree/bindings/mtd/fsl-upm-nand.txt b/Documentation/devicetree/bindings/mtd/fsl-upm-nand.txt index a48b2cadc7f0..00f1f546b32e 100644 --- a/Documentation/devicetree/bindings/mtd/fsl-upm-nand.txt +++ b/Documentation/devicetree/bindings/mtd/fsl-upm-nand.txt @@ -15,7 +15,7 @@ Optional properties: - gpios : may specify optional GPIOs connected to the Ready-Not-Busy pins (R/B#). For multi-chip devices, "n" GPIO definitions are required according to the number of chips. -- chip-delay : chip dependent delay for transfering data from array to +- chip-delay : chip dependent delay for transferring data from array to read registers (tR). Required if property "gpios" is not used (R/B# pins not connected). diff --git a/Documentation/devicetree/bindings/net/can/sja1000.txt b/Documentation/devicetree/bindings/net/can/sja1000.txt index d6d209ded937..c2dbcec0ee31 100644 --- a/Documentation/devicetree/bindings/net/can/sja1000.txt +++ b/Documentation/devicetree/bindings/net/can/sja1000.txt @@ -39,7 +39,7 @@ Optional properties: - nxp,no-comparator-bypass : Allows to disable the CAN input comperator. -For futher information, please have a look to the SJA1000 data sheet. +For further information, please have a look to the SJA1000 data sheet. Examples: diff --git a/Documentation/devicetree/bindings/powerpc/fsl/mpic.txt b/Documentation/devicetree/bindings/powerpc/fsl/mpic.txt index 8aa10f45ebe6..4f6145859aab 100644 --- a/Documentation/devicetree/bindings/powerpc/fsl/mpic.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/mpic.txt @@ -199,7 +199,7 @@ EXAMPLE 4 EXAMPLE 5 /* - * Definition of an error interrupt (interupt type 1). + * Definition of an error interrupt (interrupt type 1). * SoC interrupt number is 16 and the specific error * interrupt bit in the error interrupt summary register * is 23. diff --git a/Documentation/dvb/README.dvb-usb b/Documentation/dvb/README.dvb-usb index c8238e44ed6b..c4d963a67d6f 100644 --- a/Documentation/dvb/README.dvb-usb +++ b/Documentation/dvb/README.dvb-usb @@ -138,7 +138,7 @@ Hotplug is able to load the driver, when it is needed (because you plugged in the device). If you want to enable debug output, you have to load the driver manually and -from withing the dvb-kernel cvs repository. +from within the dvb-kernel cvs repository. first have a look, which debug level are available: diff --git a/Documentation/dvb/ci.txt b/Documentation/dvb/ci.txt index 4a0c2b56e690..6c3bda50f7dc 100644 --- a/Documentation/dvb/ci.txt +++ b/Documentation/dvb/ci.txt @@ -47,7 +47,7 @@ so on. * CI modules that are supported ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The CI module support is largely dependant upon the firmware on the cards +The CI module support is largely dependent upon the firmware on the cards Some cards do support almost all of the available CI modules. There is nothing much that can be done in order to make additional CI modules working with these cards. diff --git a/Documentation/dvb/faq.txt b/Documentation/dvb/faq.txt index 121832e5d899..97b1373f2428 100644 --- a/Documentation/dvb/faq.txt +++ b/Documentation/dvb/faq.txt @@ -106,7 +106,7 @@ Some very frequently asked questions about linuxtv-dvb 5. The dvb_net device doesn't give me any packets at all Run tcpdump on the dvb0_0 interface. This sets the interface - into promiscous mode so it accepts any packets from the PID + into promiscuous mode so it accepts any packets from the PID you have configured with the dvbnet utility. Check if there are any packets with the IP addr and MAC addr you have configured with ifconfig. diff --git a/Documentation/edac.txt b/Documentation/edac.txt index 9ee774de57cd..44364fa3598d 100644 --- a/Documentation/edac.txt +++ b/Documentation/edac.txt @@ -741,7 +741,7 @@ were done at i7core_edac driver. This chapter will cover those differences As EDAC API maps the minimum unity is csrows, the driver sequencially maps channel/dimm into different csrows. - For example, suposing the following layout: + For example, supposing the following layout: Ch0 phy rd0, wr0 (0x063f4031): 2 ranks, UDIMMs dimm 0 1024 Mb offset: 0, bank: 8, rank: 1, row: 0x4000, col: 0x400 dimm 1 1024 Mb offset: 4, bank: 8, rank: 1, row: 0x4000, col: 0x400 diff --git a/Documentation/eisa.txt b/Documentation/eisa.txt index f297fc1202ae..38cf0c7b559f 100644 --- a/Documentation/eisa.txt +++ b/Documentation/eisa.txt @@ -84,7 +84,7 @@ struct eisa_driver { id_table : an array of NULL terminated EISA id strings, followed by an empty string. Each string can - optionally be paired with a driver-dependant value + optionally be paired with a driver-dependent value (driver_data). driver : a generic driver, such as described in diff --git a/Documentation/fb/viafb.txt b/Documentation/fb/viafb.txt index 1a2e8aa3fbb1..444e34b52ae1 100644 --- a/Documentation/fb/viafb.txt +++ b/Documentation/fb/viafb.txt @@ -204,7 +204,7 @@ Notes: supported_output_devices - This read-only file contains a full ',' seperated list containing all + This read-only file contains a full ',' separated list containing all output devices that could be available on your platform. It is likely that not all of those have a connector on your hardware but it should provide a good starting point to figure out which of those names match @@ -225,7 +225,7 @@ Notes: This can happen for example if only one (the other) iga is used. Writing to these files allows adjusting the output devices during runtime. One can add new devices, remove existing ones or switch - between igas. Essentially you can write a ',' seperated list of device + between igas. Essentially you can write a ',' separated list of device names (or a single one) in the same format as the output to those files. You can add a '+' or '-' as a prefix allowing simple addition and removal of devices. So a prefix '+' adds the devices from your list diff --git a/Documentation/filesystems/autofs4-mount-control.txt b/Documentation/filesystems/autofs4-mount-control.txt index 51986bf08a4d..4c95935cbcf4 100644 --- a/Documentation/filesystems/autofs4-mount-control.txt +++ b/Documentation/filesystems/autofs4-mount-control.txt @@ -309,7 +309,7 @@ ioctlfd field set to the descriptor obtained from the open call. AUTOFS_DEV_IOCTL_TIMEOUT_CMD ---------------------------- -Set the expire timeout for mounts withing an autofs mount point. +Set the expire timeout for mounts within an autofs mount point. The call requires an initialized struct autofs_dev_ioctl with the ioctlfd field set to the descriptor obtained from the open call. diff --git a/Documentation/filesystems/caching/netfs-api.txt b/Documentation/filesystems/caching/netfs-api.txt index 1902c57b72ef..a167ab876c35 100644 --- a/Documentation/filesystems/caching/netfs-api.txt +++ b/Documentation/filesystems/caching/netfs-api.txt @@ -95,7 +95,7 @@ restraints as possible on how an index is structured and where it is placed in the tree. The netfs can even mix indices and data files at the same level, but it's not recommended. -Each index entry consists of a key of indeterminate length plus some auxilliary +Each index entry consists of a key of indeterminate length plus some auxiliary data, also of indeterminate length. There are some limits on indices: @@ -203,23 +203,23 @@ This has the following fields: If the function is absent, a file size of 0 is assumed. - (6) A function to retrieve auxilliary data from the netfs [optional]. + (6) A function to retrieve auxiliary data from the netfs [optional]. This function will be called with the netfs data that was passed to the - cookie acquisition function and the maximum length of auxilliary data that - it may provide. It should write the auxilliary data into the given buffer + cookie acquisition function and the maximum length of auxiliary data that + it may provide. It should write the auxiliary data into the given buffer and return the quantity it wrote. - If this function is absent, the auxilliary data length will be set to 0. + If this function is absent, the auxiliary data length will be set to 0. - The length of the auxilliary data buffer may be dependent on the key + The length of the auxiliary data buffer may be dependent on the key length. A netfs mustn't rely on being able to provide more than 400 bytes for both. - (7) A function to check the auxilliary data [optional]. + (7) A function to check the auxiliary data [optional]. This function will be called to check that a match found in the cache for - this object is valid. For instance with AFS it could check the auxilliary + this object is valid. For instance with AFS it could check the auxiliary data against the data version number returned by the server to determine whether the index entry in a cache is still valid. @@ -232,7 +232,7 @@ This has the following fields: (*) FSCACHE_CHECKAUX_NEEDS_UPDATE - the entry requires update (*) FSCACHE_CHECKAUX_OBSOLETE - the entry should be deleted - This function can also be used to extract data from the auxilliary data in + This function can also be used to extract data from the auxiliary data in the cache and copy it into the netfs's structures. (8) A pair of functions to manage contexts for the completion callback diff --git a/Documentation/filesystems/configfs/configfs.txt b/Documentation/filesystems/configfs/configfs.txt index fabcb0e00f25..dd57bb6bb390 100644 --- a/Documentation/filesystems/configfs/configfs.txt +++ b/Documentation/filesystems/configfs/configfs.txt @@ -409,7 +409,7 @@ As a consequence of this, default_groups cannot be removed directly via rmdir(2). They also are not considered when rmdir(2) on the parent group is checking for children. -[Dependant Subsystems] +[Dependent Subsystems] Sometimes other drivers depend on particular configfs items. For example, ocfs2 mounts depend on a heartbeat region item. If that diff --git a/Documentation/filesystems/ext4.txt b/Documentation/filesystems/ext4.txt index 6b050464a90d..c79ec58fd7f6 100644 --- a/Documentation/filesystems/ext4.txt +++ b/Documentation/filesystems/ext4.txt @@ -97,7 +97,7 @@ Note: More extensive information for getting started with ext4 can be * Inode allocation using large virtual block groups via flex_bg * delayed allocation * large block (up to pagesize) support -* efficent new ordered mode in JBD2 and ext4(avoid using buffer head to force +* efficient new ordered mode in JBD2 and ext4(avoid using buffer head to force the ordering) [1] Filesystems with a block size of 1k may see a limit imposed by the @@ -106,7 +106,7 @@ directory hash tree having a maximum depth of two. 2.2 Candidate features for future inclusion * Online defrag (patches available but not well tested) -* reduced mke2fs time via lazy itable initialization in conjuction with +* reduced mke2fs time via lazy itable initialization in conjunction with the uninit_bg feature (capability to do this is available in e2fsprogs but a kernel thread to do lazy zeroing of unused inode table blocks after filesystem is first mounted is required for safety) diff --git a/Documentation/filesystems/gfs2-uevents.txt b/Documentation/filesystems/gfs2-uevents.txt index fd966dc9979a..d81889669293 100644 --- a/Documentation/filesystems/gfs2-uevents.txt +++ b/Documentation/filesystems/gfs2-uevents.txt @@ -62,7 +62,7 @@ be fixed. The REMOVE uevent is generated at the end of an unsuccessful mount or at the end of a umount of the filesystem. All REMOVE uevents will -have been preceeded by at least an ADD uevent for the same fileystem, +have been preceded by at least an ADD uevent for the same fileystem, and unlike the other uevents is generated automatically by the kernel's kobject subsystem. diff --git a/Documentation/filesystems/gfs2.txt b/Documentation/filesystems/gfs2.txt index 0b59c0200912..4cda926628aa 100644 --- a/Documentation/filesystems/gfs2.txt +++ b/Documentation/filesystems/gfs2.txt @@ -11,7 +11,7 @@ their I/O so file system consistency is maintained. One of the nifty features of GFS is perfect consistency -- changes made to the file system on one machine show up immediately on all other machines in the cluster. -GFS uses interchangable inter-node locking mechanisms, the currently +GFS uses interchangeable inter-node locking mechanisms, the currently supported mechanisms are: lock_nolock -- allows gfs to be used as a local file system diff --git a/Documentation/filesystems/ntfs.txt b/Documentation/filesystems/ntfs.txt index 933bc66ccff1..791af8dac065 100644 --- a/Documentation/filesystems/ntfs.txt +++ b/Documentation/filesystems/ntfs.txt @@ -350,7 +350,7 @@ Note the "Should sync?" parameter "nosync" means that the two mirrors are already in sync which will be the case on a clean shutdown of Windows. If the mirrors are not clean, you can specify the "sync" option instead of "nosync" and the Device-Mapper driver will then copy the entirety of the "Source Device" -to the "Target Device" or if you specified multipled target devices to all of +to the "Target Device" or if you specified multiple target devices to all of them. Once you have your table, save it in a file somewhere (e.g. /etc/ntfsvolume1), diff --git a/Documentation/filesystems/ocfs2.txt b/Documentation/filesystems/ocfs2.txt index 5393e6611691..9ed920a8cd79 100644 --- a/Documentation/filesystems/ocfs2.txt +++ b/Documentation/filesystems/ocfs2.txt @@ -80,7 +80,7 @@ user_xattr (*) Enables Extended User Attributes. nouser_xattr Disables Extended User Attributes. acl Enables POSIX Access Control Lists support. noacl (*) Disables POSIX Access Control Lists support. -resv_level=2 (*) Set how agressive allocation reservations will be. +resv_level=2 (*) Set how aggressive allocation reservations will be. Valid values are between 0 (reservations off) to 8 (maximum space for reservations). dir_resv_level= (*) By default, directory reservations will scale with file diff --git a/Documentation/filesystems/path-lookup.txt b/Documentation/filesystems/path-lookup.txt index eb59c8b44be9..3571667c7105 100644 --- a/Documentation/filesystems/path-lookup.txt +++ b/Documentation/filesystems/path-lookup.txt @@ -42,7 +42,7 @@ Path walking overview A name string specifies a start (root directory, cwd, fd-relative) and a sequence of elements (directory entry names), which together refer to a path in the namespace. A path is represented as a (dentry, vfsmount) tuple. The name -elements are sub-strings, seperated by '/'. +elements are sub-strings, separated by '/'. Name lookups will want to find a particular path that a name string refers to (usually the final element, or parent of final element). This is done by taking @@ -354,7 +354,7 @@ vfstest 24185492 4945 708725(2.9%) 1076136(4.4%) 0 2651 What this shows is that failed rcu-walk lookups, ie. ones that are restarted entirely with ref-walk, are quite rare. Even the "vfstest" case which -specifically has concurrent renames/mkdir/rmdir/ creat/unlink/etc to excercise +specifically has concurrent renames/mkdir/rmdir/ creat/unlink/etc to exercise such races is not showing a huge amount of restarts. Dropping from rcu-walk to ref-walk mean that we have encountered a dentry where diff --git a/Documentation/filesystems/pohmelfs/network_protocol.txt b/Documentation/filesystems/pohmelfs/network_protocol.txt index 40ea6c295afb..65e03dd44823 100644 --- a/Documentation/filesystems/pohmelfs/network_protocol.txt +++ b/Documentation/filesystems/pohmelfs/network_protocol.txt @@ -20,7 +20,7 @@ Commands can be embedded into transaction command (which in turn has own command so one can extend protocol as needed without breaking backward compatibility as long as old commands are supported. All string lengths include tail 0 byte. -All commans are transfered over the network in big-endian. CPU endianess is used at the end peers. +All commands are transferred over the network in big-endian. CPU endianess is used at the end peers. @cmd - command number, which specifies command to be processed. Following commands are used currently: diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index 23cae6548d3a..b0b814d75ca1 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt @@ -543,7 +543,7 @@ just those considered 'most important'. The new vectors are: their statistics are used by kernel developers and interested users to determine the occurrence of interrupts of the given type. -The above IRQ vectors are displayed only when relevent. For example, +The above IRQ vectors are displayed only when relevant. For example, the threshold vector does not exist on x86_64 platforms. Others are suppressed when the system is a uniprocessor. As of this writing, only i386 and x86_64 platforms support the new IRQ vector displays. @@ -1202,7 +1202,7 @@ The columns are: W = can do write operations U = can do unblank flags E = it is enabled - C = it is prefered console + C = it is preferred console B = it is primary boot console p = it is used for printk buffer b = it is not a TTY but a Braille device @@ -1331,7 +1331,7 @@ NOTICE: /proc//oom_adj is deprecated and will be removed, please see Documentation/feature-removal-schedule.txt. Caveat: when a parent task is selected, the oom killer will sacrifice any first -generation children with seperate address spaces instead, if possible. This +generation children with separate address spaces instead, if possible. This avoids servers and important system daemons from being killed and loses the minimal amount of work. diff --git a/Documentation/filesystems/squashfs.txt b/Documentation/filesystems/squashfs.txt index 2d78f1911844..d4d41465a0b1 100644 --- a/Documentation/filesystems/squashfs.txt +++ b/Documentation/filesystems/squashfs.txt @@ -219,7 +219,7 @@ or if it is stored out of line (in which case the value field stores a reference to where the actual value is stored). This allows large values to be stored out of line improving scanning and lookup performance and it also allows values to be de-duplicated, the value being stored once, and -all other occurences holding an out of line reference to that value. +all other occurrences holding an out of line reference to that value. The xattr lists are packed into compressed 8K metadata blocks. To reduce overhead in inodes, rather than storing the on-disk diff --git a/Documentation/filesystems/sysfs.txt b/Documentation/filesystems/sysfs.txt index f806e50aaa63..597f728e7b4e 100644 --- a/Documentation/filesystems/sysfs.txt +++ b/Documentation/filesystems/sysfs.txt @@ -62,7 +62,7 @@ values of the same type. Mixing types, expressing multiple lines of data, and doing fancy formatting of data is heavily frowned upon. Doing these things may get -you publically humiliated and your code rewritten without notice. +you publicly humiliated and your code rewritten without notice. An attribute definition is simply: diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index 80815ed654cb..21a7dc467bba 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt @@ -97,7 +97,7 @@ functions: The passed struct file_system_type describes your filesystem. When a request is made to mount a filesystem onto a directory in your namespace, the VFS will call the appropriate mount() method for the specific -filesystem. New vfsmount refering to the tree returned by ->mount() +filesystem. New vfsmount referring to the tree returned by ->mount() will be attached to the mountpoint, so that when pathname resolution reaches the mountpoint it will jump into the root of that vfsmount. diff --git a/Documentation/filesystems/xfs-delayed-logging-design.txt b/Documentation/filesystems/xfs-delayed-logging-design.txt index 5282e3e51413..2ce36439c09f 100644 --- a/Documentation/filesystems/xfs-delayed-logging-design.txt +++ b/Documentation/filesystems/xfs-delayed-logging-design.txt @@ -42,7 +42,7 @@ the aggregation of all the previous changes currently held only in the log. This relogging technique also allows objects to be moved forward in the log so that an object being relogged does not prevent the tail of the log from ever moving forward. This can be seen in the table above by the changing -(increasing) LSN of each subsquent transaction - the LSN is effectively a +(increasing) LSN of each subsequent transaction - the LSN is effectively a direct encoding of the location in the log of the transaction. This relogging is also used to implement long-running, multiple-commit @@ -338,7 +338,7 @@ the same time another transaction modifies the item and inserts the log item into the new CIL, then checkpoint transaction commit code cannot use log items to store the list of log vectors that need to be written into the transaction. Hence log vectors need to be able to be chained together to allow them to be -detatched from the log items. That is, when the CIL is flushed the memory +detached from the log items. That is, when the CIL is flushed the memory buffer and log vector attached to each log item needs to be attached to the checkpoint context so that the log item can be released. In diagrammatic form, the CIL would look like this before the flush: @@ -577,7 +577,7 @@ only becomes unpinned when all the transactions complete and there are no pending transactions. Thus the pinning and unpinning of a log item is symmetric as there is a 1:1 relationship with transaction commit and log item completion. -For delayed logging, however, we have an assymetric transaction commit to +For delayed logging, however, we have an asymmetric transaction commit to completion relationship. Every time an object is relogged in the CIL it goes through the commit process without a corresponding completion being registered. That is, we now have a many-to-one relationship between transaction commit and @@ -780,7 +780,7 @@ With delayed logging, there are new steps inserted into the life cycle: From this, it can be seen that the only life cycle differences between the two logging methods are in the middle of the life cycle - they still have the same beginning and end and execution constraints. The only differences are in the -commiting of the log items to the log itself and the completion processing. +committing of the log items to the log itself and the completion processing. Hence delayed logging should not introduce any constraints on log item behaviour, allocation or freeing that don't already exist. diff --git a/Documentation/hwmon/abituguru b/Documentation/hwmon/abituguru index 5eb3b9d5f0d5..915f32063a26 100644 --- a/Documentation/hwmon/abituguru +++ b/Documentation/hwmon/abituguru @@ -78,7 +78,7 @@ motherboards (most modern Abit motherboards). The first and second revision of the uGuru chip in reality is a Winbond W83L950D in disguise (despite Abit claiming it is "a new microprocessor -designed by the ABIT Engineers"). Unfortunatly this doesn't help since the +designed by the ABIT Engineers"). Unfortunately this doesn't help since the W83L950D is a generic microcontroller with a custom Abit application running on it. diff --git a/Documentation/hwmon/abituguru-datasheet b/Documentation/hwmon/abituguru-datasheet index d9251efdcec7..8d2be8a0b1e3 100644 --- a/Documentation/hwmon/abituguru-datasheet +++ b/Documentation/hwmon/abituguru-datasheet @@ -5,9 +5,9 @@ First of all, what I know about uGuru is no fact based on any help, hints or datasheet from Abit. The data I have got on uGuru have I assembled through my weak knowledge in "backwards engineering". And just for the record, you may have noticed uGuru isn't a chip developed by -Abit, as they claim it to be. It's realy just an microprocessor (uC) created by +Abit, as they claim it to be. It's really just an microprocessor (uC) created by Winbond (W83L950D). And no, reading the manual for this specific uC or -mailing Windbond for help won't give any usefull data about uGuru, as it is +mailing Windbond for help won't give any useful data about uGuru, as it is the program inside the uC that is responding to calls. Olle Sandberg , 2005-05-25 @@ -41,7 +41,7 @@ later on attached again data-port will hold 0x08, more about this later. After wider testing of the Linux kernel driver some variants of the uGuru have turned up which will hold 0x00 instead of 0xAC at the CMD port, thus we also -have to test CMD for two different values. On these uGuru's DATA will initally +have to test CMD for two different values. On these uGuru's DATA will initially hold 0x09 and will only hold 0x08 after reading CMD first, so CMD must be read first! @@ -308,5 +308,5 @@ the voltage / clock programming out, I tried reading and only reading banks resulted in a _permanent_ reprogramming of the voltages, luckily I had the sensors part configured so that it would shutdown my system on any out of spec voltages which proprably safed my computer (after a reboot I managed to -immediatly enter the bios and reload the defaults). This probably means that +immediately enter the bios and reload the defaults). This probably means that the read/write cycle for the non sensor part is different from the sensor part. diff --git a/Documentation/hwmon/abituguru3 b/Documentation/hwmon/abituguru3 index fa598aac22fa..a6ccfe4bb6aa 100644 --- a/Documentation/hwmon/abituguru3 +++ b/Documentation/hwmon/abituguru3 @@ -47,7 +47,7 @@ This driver supports the hardware monitoring features of the third revision of the Abit uGuru chip, found on recent Abit uGuru featuring motherboards. The 3rd revision of the uGuru chip in reality is a Winbond W83L951G. -Unfortunatly this doesn't help since the W83L951G is a generic microcontroller +Unfortunately this doesn't help since the W83L951G is a generic microcontroller with a custom Abit application running on it. Despite Abit not releasing any information regarding the uGuru revision 3, diff --git a/Documentation/hwmon/pmbus b/Documentation/hwmon/pmbus index f2d42e8bdf48..dc4933e96344 100644 --- a/Documentation/hwmon/pmbus +++ b/Documentation/hwmon/pmbus @@ -150,11 +150,11 @@ The following attributes are supported. Limits are read-write; all other attributes are read-only. inX_input Measured voltage. From READ_VIN or READ_VOUT register. -inX_min Minumum Voltage. +inX_min Minimum Voltage. From VIN_UV_WARN_LIMIT or VOUT_UV_WARN_LIMIT register. inX_max Maximum voltage. From VIN_OV_WARN_LIMIT or VOUT_OV_WARN_LIMIT register. -inX_lcrit Critical minumum Voltage. +inX_lcrit Critical minimum Voltage. From VIN_UV_FAULT_LIMIT or VOUT_UV_FAULT_LIMIT register. inX_crit Critical maximum voltage. From VIN_OV_FAULT_LIMIT or VOUT_OV_FAULT_LIMIT register. @@ -169,7 +169,7 @@ inX_label "vin", "vcap", or "voutY" currX_input Measured current. From READ_IIN or READ_IOUT register. currX_max Maximum current. From IIN_OC_WARN_LIMIT or IOUT_OC_WARN_LIMIT register. -currX_lcrit Critical minumum output current. +currX_lcrit Critical minimum output current. From IOUT_UC_FAULT_LIMIT register. currX_crit Critical maximum current. From IIN_OC_FAULT_LIMIT or IOUT_OC_FAULT_LIMIT register. diff --git a/Documentation/hwmon/sysfs-interface b/Documentation/hwmon/sysfs-interface index 83a698773ade..8f63c244f1aa 100644 --- a/Documentation/hwmon/sysfs-interface +++ b/Documentation/hwmon/sysfs-interface @@ -579,7 +579,7 @@ channel should not be trusted. fan[1-*]_fault temp[1-*]_fault Input fault condition - 0: no fault occured + 0: no fault occurred 1: fault condition RO diff --git a/Documentation/hwmon/w83781d b/Documentation/hwmon/w83781d index ecbc1e4574b4..129b0a3b555b 100644 --- a/Documentation/hwmon/w83781d +++ b/Documentation/hwmon/w83781d @@ -403,7 +403,7 @@ found out the following values do work as a form of coarse pwm: 0x80 - seems to turn fans off after some time(1-2 minutes)... might be some form of auto-fan-control based on temp? hmm (Qfan? this mobo is an -old ASUS, it isn't marketed as Qfan. Maybe some beta pre-attemp at Qfan +old ASUS, it isn't marketed as Qfan. Maybe some beta pre-attempt at Qfan that was dropped at the BIOS) 0x81 - off 0x82 - slightly "on-ner" than off, but my fans do not get to move. I can diff --git a/Documentation/hwmon/w83791d b/Documentation/hwmon/w83791d index 5663e491655c..90387c3540f7 100644 --- a/Documentation/hwmon/w83791d +++ b/Documentation/hwmon/w83791d @@ -93,7 +93,7 @@ The sysfs interface to the beep bitmask has migrated from the original legacy method of a single sysfs beep_mask file to a newer method using multiple *_beep files as described in .../Documentation/hwmon/sysfs-interface. -A similar change has occured for the bitmap corresponding to the alarms. The +A similar change has occurred for the bitmap corresponding to the alarms. The original legacy method used a single sysfs alarms file containing a bitmap of triggered alarms. The newer method uses multiple sysfs *_alarm files (again following the pattern described in sysfs-interface). diff --git a/Documentation/i2c/busses/i2c-parport-light b/Documentation/i2c/busses/i2c-parport-light index bdc9cbb2e0f2..c22ee063e1e5 100644 --- a/Documentation/i2c/busses/i2c-parport-light +++ b/Documentation/i2c/busses/i2c-parport-light @@ -4,7 +4,7 @@ Author: Jean Delvare This driver is a light version of i2c-parport. It doesn't depend on the parport driver, and uses direct I/O access instead. This might be -prefered on embedded systems where wasting memory for the clean but heavy +preferred on embedded systems where wasting memory for the clean but heavy parport handling is not an option. The drawback is a reduced portability and the impossibility to daisy-chain other parallel port devices. diff --git a/Documentation/i2c/busses/i2c-sis96x b/Documentation/i2c/busses/i2c-sis96x index 70e6a0cc1e15..0b979f3252a4 100644 --- a/Documentation/i2c/busses/i2c-sis96x +++ b/Documentation/i2c/busses/i2c-sis96x @@ -35,7 +35,7 @@ or perhaps this... (kernel versions later than 2.4.18 may fill in the "Unknown"s) -If you cant see it please look on quirk_sis_96x_smbus +If you can't see it please look on quirk_sis_96x_smbus (drivers/pci/quirks.c) (also if southbridge detection fails) I suspect that this driver could be made to work for the following SiS diff --git a/Documentation/i2c/busses/i2c-taos-evm b/Documentation/i2c/busses/i2c-taos-evm index 9146e33be6dd..63f62bcbf592 100644 --- a/Documentation/i2c/busses/i2c-taos-evm +++ b/Documentation/i2c/busses/i2c-taos-evm @@ -13,7 +13,7 @@ Currently supported devices are: * TAOS TSL2550 EVM -For addtional information on TAOS products, please see +For additional information on TAOS products, please see http://www.taosinc.com/ diff --git a/Documentation/i2o/README b/Documentation/i2o/README index 0ebf58c73f54..ee91e2626ff0 100644 --- a/Documentation/i2o/README +++ b/Documentation/i2o/README @@ -53,7 +53,7 @@ Symbios Logic (Now LSI) BoxHill Corporation Loan of initial FibreChannel disk array used for development work. -European Comission +European Commission Funding the work done by the University of Helsinki SysKonnect diff --git a/Documentation/ia64/aliasing-test.c b/Documentation/ia64/aliasing-test.c index 3dfb76ca6931..5caa2af33207 100644 --- a/Documentation/ia64/aliasing-test.c +++ b/Documentation/ia64/aliasing-test.c @@ -177,7 +177,7 @@ static int scan_rom(char *path, char *file) /* * It's OK if the ROM is unreadable. Maybe there - * is no ROM, or some other error ocurred. The + * is no ROM, or some other error occurred. The * important thing is that no MCA happened. */ if (rc > 0) diff --git a/Documentation/input/joystick-parport.txt b/Documentation/input/joystick-parport.txt index 1c856f32ff2c..56870c70a796 100644 --- a/Documentation/input/joystick-parport.txt +++ b/Documentation/input/joystick-parport.txt @@ -272,7 +272,7 @@ if you want to use gamecon.c. Also, the connection is a bit more complex. You'll need a bunch of diodes, and one pullup resistor. First, you connect the Directions and the button -the same as for db9, however with the diodes inbetween. +the same as for db9, however with the diodes between. Diodes (pin 2) -----|<|----> Up diff --git a/Documentation/input/rotary-encoder.txt b/Documentation/input/rotary-encoder.txt index 8b4129de1d2d..943e8f6f2b15 100644 --- a/Documentation/input/rotary-encoder.txt +++ b/Documentation/input/rotary-encoder.txt @@ -46,7 +46,7 @@ c) Falling edge on channel A, channel B in high state d) Falling edge on channel B, channel A in low state Parking position. If the encoder enters this state, a full transition - should have happend, unless it flipped back on half the way. The + should have happened, unless it flipped back on half the way. The 'armed' state tells us about that. 2. Platform requirements diff --git a/Documentation/input/walkera0701.txt b/Documentation/input/walkera0701.txt index 8f4289efc5c4..561385d38482 100644 --- a/Documentation/input/walkera0701.txt +++ b/Documentation/input/walkera0701.txt @@ -77,7 +77,7 @@ pulse length: 24 bin+oct values + 1 bin value = 24*4+1 bits = 97 bits -(Warning, pulses on ACK ar inverted by transistor, irq is rised up on sync +(Warning, pulses on ACK are inverted by transistor, irq is raised up on sync to bin change or octal value to bin change). Binary data representations: diff --git a/Documentation/irqflags-tracing.txt b/Documentation/irqflags-tracing.txt index 6a444877ee0b..67aa71e73035 100644 --- a/Documentation/irqflags-tracing.txt +++ b/Documentation/irqflags-tracing.txt @@ -53,5 +53,5 @@ implementation in an architecture: lockdep will detect that and will turn itself off. I.e. the lock validator will still be reliable. There should be no crashes due to irq-tracing bugs. (except if the assembly changes break other code by modifying conditions or registers that -shouldnt be) +shouldn't be) diff --git a/Documentation/isdn/INTERFACE.CAPI b/Documentation/isdn/INTERFACE.CAPI index 309eb5ed942b..1688b5a1fd77 100644 --- a/Documentation/isdn/INTERFACE.CAPI +++ b/Documentation/isdn/INTERFACE.CAPI @@ -240,7 +240,7 @@ Functions capi_cmsg2message() and capi_message2cmsg() are provided to convert messages between their transport encoding described in the CAPI 2.0 standard and their _cmsg structure representation. Note that capi_cmsg2message() does not know or check the size of its destination buffer. The caller must make -sure it is big enough to accomodate the resulting CAPI message. +sure it is big enough to accommodate the resulting CAPI message. 5. Lower Layer Interface Functions diff --git a/Documentation/kbuild/kbuild.txt b/Documentation/kbuild/kbuild.txt index f1431d099fce..7c2a89ba674c 100644 --- a/Documentation/kbuild/kbuild.txt +++ b/Documentation/kbuild/kbuild.txt @@ -26,11 +26,11 @@ Additional options to the assembler (for built-in and modules). AFLAGS_MODULE -------------------------------------------------- -Addtional module specific options to use for $(AS). +Additional module specific options to use for $(AS). AFLAGS_KERNEL -------------------------------------------------- -Addtional options for $(AS) when used for assembler +Additional options for $(AS) when used for assembler code for code that is compiled as built-in. KCFLAGS @@ -39,12 +39,12 @@ Additional options to the C compiler (for built-in and modules). CFLAGS_KERNEL -------------------------------------------------- -Addtional options for $(CC) when used to compile +Additional options for $(CC) when used to compile code that is compiled as built-in. CFLAGS_MODULE -------------------------------------------------- -Addtional module specific options to use for $(CC). +Additional module specific options to use for $(CC). LDFLAGS_MODULE -------------------------------------------------- diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index c357a31411cd..49e9796a86a5 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -699,7 +699,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted. ekgdboc= [X86,KGDB] Allow early kernel console debugging ekgdboc=kbd - This is desgined to be used in conjunction with + This is designed to be used in conjunction with the boot argument: earlyprintk=vga edd= [EDD] diff --git a/Documentation/kvm/mmu.txt b/Documentation/kvm/mmu.txt index 142cc5136650..f46aa58389ca 100644 --- a/Documentation/kvm/mmu.txt +++ b/Documentation/kvm/mmu.txt @@ -23,7 +23,7 @@ The mmu code attempts to satisfy the following requirements: and framebuffer-based displays - footprint: keep the amount of pinned kernel memory low (most memory should be shrinkable) -- reliablity: avoid multipage or GFP_ATOMIC allocations +- reliability: avoid multipage or GFP_ATOMIC allocations Acronyms ======== diff --git a/Documentation/kvm/ppc-pv.txt b/Documentation/kvm/ppc-pv.txt index a7f2244b3be9..3ab969c59046 100644 --- a/Documentation/kvm/ppc-pv.txt +++ b/Documentation/kvm/ppc-pv.txt @@ -136,7 +136,7 @@ Patched instructions ==================== The "ld" and "std" instructions are transormed to "lwz" and "stw" instructions -respectively on 32 bit systems with an added offset of 4 to accomodate for big +respectively on 32 bit systems with an added offset of 4 to accommodate for big endianness. The following is a list of mapping the Linux kernel performs when running as diff --git a/Documentation/kvm/timekeeping.txt b/Documentation/kvm/timekeeping.txt index 0c5033a58c9e..df8946377cb6 100644 --- a/Documentation/kvm/timekeeping.txt +++ b/Documentation/kvm/timekeeping.txt @@ -81,7 +81,7 @@ Mode 0: Single Timeout. This is a one-shot software timeout that counts down when the gate is high (always true for timers 0 and 1). When the count reaches zero, the output goes high. -Mode 1: Triggered One-shot. The output is intially set high. When the gate +Mode 1: Triggered One-shot. The output is initially set high. When the gate line is set high, a countdown is initiated (which does not stop if the gate is lowered), during which the output is set low. When the count reaches zero, the output goes high. diff --git a/Documentation/media-framework.txt b/Documentation/media-framework.txt index fd48add02cb0..76a2087db205 100644 --- a/Documentation/media-framework.txt +++ b/Documentation/media-framework.txt @@ -194,7 +194,7 @@ each pad. Links are represented by a struct media_link instance, defined in include/media/media-entity.h. Each entity stores all links originating at or -targetting any of its pads in a links array. A given link is thus stored +targeting any of its pads in a links array. A given link is thus stored twice, once in the source entity and once in the target entity. The array is pre-allocated and grows dynamically as needed. @@ -348,6 +348,6 @@ a streaming entity. Links that can be modified while streaming must be marked with the MEDIA_LNK_FL_DYNAMIC flag. If other operations need to be disallowed on streaming entities (such as -changing entities configuration parameters) drivers can explictly check the +changing entities configuration parameters) drivers can explicitly check the media_entity stream_count field to find out if an entity is streaming. This operation must be done with the media_device graph_mutex held. diff --git a/Documentation/mips/AU1xxx_IDE.README b/Documentation/mips/AU1xxx_IDE.README index 8ace35ebdcd5..cc887ecfd6eb 100644 --- a/Documentation/mips/AU1xxx_IDE.README +++ b/Documentation/mips/AU1xxx_IDE.README @@ -39,13 +39,13 @@ Note: for more information, please refer "AMD Alchemy Au1200/Au1550 IDE Interface and Linux Device Driver" Application Note. -FILES, CONFIGS AND COMPATABILITY +FILES, CONFIGS AND COMPATIBILITY -------------------------------- Two files are introduced: a) 'arch/mips/include/asm/mach-au1x00/au1xxx_ide.h' - containes : struct _auide_hwif + contains : struct _auide_hwif timing parameters for PIO mode 0/1/2/3/4 timing parameters for MWDMA 0/1/2 diff --git a/Documentation/misc-devices/ics932s401 b/Documentation/misc-devices/ics932s401 index 07a739f406d8..bdac67ff6e3f 100644 --- a/Documentation/misc-devices/ics932s401 +++ b/Documentation/misc-devices/ics932s401 @@ -5,7 +5,7 @@ Supported chips: * IDT ICS932S401 Prefix: 'ics932s401' Addresses scanned: I2C 0x69 - Datasheet: Publically available at the IDT website + Datasheet: Publicly available at the IDT website Author: Darrick J. Wong diff --git a/Documentation/networking/3c359.txt b/Documentation/networking/3c359.txt index 4af8071a6d18..dadfe8147ab8 100644 --- a/Documentation/networking/3c359.txt +++ b/Documentation/networking/3c359.txt @@ -45,7 +45,7 @@ debugging messages on, that must be done by modified the source code. Variable MTU size: -The driver can handle a MTU size upto either 4500 or 18000 depending upon +The driver can handle a MTU size up to either 4500 or 18000 depending upon ring speed. The driver also changes the size of the receive buffers as part of the mtu re-sizing, so if you set mtu = 18000, you will need to be able to allocate 16 * (sk_buff with 18000 buffer size) call it 18500 bytes per ring diff --git a/Documentation/networking/README.ipw2200 b/Documentation/networking/README.ipw2200 index 616a8e540b0b..b7658bed4906 100644 --- a/Documentation/networking/README.ipw2200 +++ b/Documentation/networking/README.ipw2200 @@ -256,7 +256,7 @@ You can set the debug level via: Where $VALUE would be a number in the case of this sysfs entry. The input to sysfs files does not have to be a number. For example, the -firmware loader used by hotplug utilizes sysfs entries for transfering +firmware loader used by hotplug utilizes sysfs entries for transferring the firmware image from user space into the driver. The Intel(R) PRO/Wireless 2915ABG Driver for Linux exposes sysfs entries diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt index b36e741e94db..e27202bb8d75 100644 --- a/Documentation/networking/bonding.txt +++ b/Documentation/networking/bonding.txt @@ -368,7 +368,7 @@ fail_over_mac gratuitous ARP is lost, communication may be disrupted. - When this policy is used in conjuction with the mii + When this policy is used in conjunction with the mii monitor, devices which assert link up prior to being able to actually transmit and receive are particularly susceptible to loss of the gratuitous ARP, and an diff --git a/Documentation/networking/caif/Linux-CAIF.txt b/Documentation/networking/caif/Linux-CAIF.txt index 7fe7a9a33a4f..e52fd62bef3a 100644 --- a/Documentation/networking/caif/Linux-CAIF.txt +++ b/Documentation/networking/caif/Linux-CAIF.txt @@ -136,7 +136,7 @@ The CAIF Protocol implementation contains: - CFMUX CAIF Mux layer. Handles multiplexing between multiple physical bearers and multiple channels such as VEI, Datagram, etc. The MUX keeps track of the existing CAIF Channels and - Physical Instances and selects the apropriate instance based + Physical Instances and selects the appropriate instance based on Channel-Id and Physical-ID. - CFFRML CAIF Framing layer. Handles Framing i.e. Frame length diff --git a/Documentation/networking/caif/spi_porting.txt b/Documentation/networking/caif/spi_porting.txt index 0cb8cb9098f4..9efd0687dc4c 100644 --- a/Documentation/networking/caif/spi_porting.txt +++ b/Documentation/networking/caif/spi_porting.txt @@ -150,7 +150,7 @@ static int sspi_init_xfer(struct cfspi_xfer *xfer, struct cfspi_dev *dev) void sspi_sig_xfer(bool xfer, struct cfspi_dev *dev) { /* If xfer is true then you should assert the SPI_INT to indicate to - * the master that you are ready to recieve the data from the master + * the master that you are ready to receive the data from the master * SPI. If xfer is false then you should de-assert SPI_INT to indicate * that the transfer is done. */ diff --git a/Documentation/networking/can.txt b/Documentation/networking/can.txt index 5b04b67ddca2..56ca3b75376e 100644 --- a/Documentation/networking/can.txt +++ b/Documentation/networking/can.txt @@ -240,7 +240,7 @@ solution for a couple of reasons: the user application using the common CAN filter mechanisms. Inside this filter definition the (interested) type of errors may be selected. The reception of error frames is disabled by default. - The format of the CAN error frame is briefly decribed in the Linux + The format of the CAN error frame is briefly described in the Linux header file "include/linux/can/error.h". 4. How to use Socket CAN diff --git a/Documentation/networking/ieee802154.txt b/Documentation/networking/ieee802154.txt index 23c995e64032..f41ea2405220 100644 --- a/Documentation/networking/ieee802154.txt +++ b/Documentation/networking/ieee802154.txt @@ -9,7 +9,7 @@ The Linux-ZigBee project goal is to provide complete implementation of IEEE 802.15.4 / ZigBee / 6LoWPAN protocols. IEEE 802.15.4 is a stack of protocols for organizing Low-Rate Wireless Personal Area Networks. -Currently only IEEE 802.15.4 layer is implemented. We have choosen +Currently only IEEE 802.15.4 layer is implemented. We have chosen to use plain Berkeley socket API, the generic Linux networking stack to transfer IEEE 802.15.4 messages and a special protocol over genetlink for configuration/management diff --git a/Documentation/networking/olympic.txt b/Documentation/networking/olympic.txt index c65a94010ea8..b95b5bf96751 100644 --- a/Documentation/networking/olympic.txt +++ b/Documentation/networking/olympic.txt @@ -65,7 +65,7 @@ together. Variable MTU size: -The driver can handle a MTU size upto either 4500 or 18000 depending upon +The driver can handle a MTU size up to either 4500 or 18000 depending upon ring speed. The driver also changes the size of the receive buffers as part of the mtu re-sizing, so if you set mtu = 18000, you will need to be able to allocate 16 * (sk_buff with 18000 buffer size) call it 18500 bytes per ring diff --git a/Documentation/networking/packet_mmap.txt b/Documentation/networking/packet_mmap.txt index 073894d1c093..4acea6603720 100644 --- a/Documentation/networking/packet_mmap.txt +++ b/Documentation/networking/packet_mmap.txt @@ -223,7 +223,7 @@ we will get the following buffer structure: A frame can be of any size with the only condition it can fit in a block. A block can only hold an integer number of frames, or in other words, a frame cannot -be spawned accross two blocks, so there are some details you have to take into +be spawned across two blocks, so there are some details you have to take into account when choosing the frame_size. See "Mapping and use of the circular buffer (ring)". diff --git a/Documentation/networking/s2io.txt b/Documentation/networking/s2io.txt index 9d4e0f4df5a8..4be0c039edbc 100644 --- a/Documentation/networking/s2io.txt +++ b/Documentation/networking/s2io.txt @@ -37,7 +37,7 @@ To associate an interface with a physical adapter use "ethtool -p ". The corresponding adapter's LED will blink multiple times. 3. Features supported: -a. Jumbo frames. Xframe I/II supports MTU upto 9600 bytes, +a. Jumbo frames. Xframe I/II supports MTU up to 9600 bytes, modifiable using ifconfig command. b. Offloads. Supports checksum offload(TCP/UDP/IP) on transmit @@ -49,7 +49,7 @@ significant performance improvement on certain platforms(SGI Altix, IBM xSeries). d. MSI/MSI-X. Can be enabled on platforms which support this feature -(IA64, Xeon) resulting in noticeable performance improvement(upto 7% +(IA64, Xeon) resulting in noticeable performance improvement(up to 7% on certain platforms). e. Statistics. Comprehensive MAC-level and software statistics displayed diff --git a/Documentation/networking/tc-actions-env-rules.txt b/Documentation/networking/tc-actions-env-rules.txt index dcadf6f88e34..70d6cf608251 100644 --- a/Documentation/networking/tc-actions-env-rules.txt +++ b/Documentation/networking/tc-actions-env-rules.txt @@ -1,5 +1,5 @@ -The "enviromental" rules for authors of any new tc actions are: +The "environmental" rules for authors of any new tc actions are: 1) If you stealeth or borroweth any packet thou shalt be branching from the righteous path and thou shalt cloneth. @@ -20,7 +20,7 @@ this way any action downstream can stomp on the packet. 3) Dropping packets you don't own is a no-no. You simply return TC_ACT_SHOT to the caller and they will drop it. -The "enviromental" rules for callers of actions (qdiscs etc) are: +The "environmental" rules for callers of actions (qdiscs etc) are: *) Thou art responsible for freeing anything returned as being TC_ACT_SHOT/STOLEN/QUEUED. If none of TC_ACT_SHOT/STOLEN/QUEUED is diff --git a/Documentation/power/devices.txt b/Documentation/power/devices.txt index f023ba6bba62..1971bcf48a60 100644 --- a/Documentation/power/devices.txt +++ b/Documentation/power/devices.txt @@ -367,7 +367,7 @@ Drivers need to be able to handle hardware which has been reset since the suspend methods were called, for example by complete reinitialization. This may be the hardest part, and the one most protected by NDA'd documents and chip errata. It's simplest if the hardware state hasn't changed since -the suspend was carried out, but that can't be guaranteed (in fact, it ususally +the suspend was carried out, but that can't be guaranteed (in fact, it usually is not the case). Drivers must also be prepared to notice that the device has been removed diff --git a/Documentation/power/notifiers.txt b/Documentation/power/notifiers.txt index ae1b7ec07684..cf980709122a 100644 --- a/Documentation/power/notifiers.txt +++ b/Documentation/power/notifiers.txt @@ -24,7 +24,7 @@ PM_HIBERNATION_PREPARE The system is going to hibernate or suspend, tasks will be frozen immediately. PM_POST_HIBERNATION The system memory state has been restored from a - hibernation image or an error occured during the + hibernation image or an error occurred during the hibernation. Device drivers' .resume() callbacks have been executed and tasks have been thawed. @@ -38,7 +38,7 @@ PM_POST_RESTORE An error occurred during the hibernation restore. PM_SUSPEND_PREPARE The system is preparing for a suspend. -PM_POST_SUSPEND The system has just resumed or an error occured during +PM_POST_SUSPEND The system has just resumed or an error occurred during the suspend. Device drivers' .resume() callbacks have been executed and tasks have been thawed. diff --git a/Documentation/power/opp.txt b/Documentation/power/opp.txt index cd445582d1f8..5ae70a12c1e2 100644 --- a/Documentation/power/opp.txt +++ b/Documentation/power/opp.txt @@ -178,7 +178,7 @@ opp_find_freq_ceil - Search for an available OPP which is *at least* the if (!IS_ERR(opp)) soc_switch_to_freq_voltage(freq); else - /* do something when we cant satisfy the req */ + /* do something when we can't satisfy the req */ /* do other stuff */ } diff --git a/Documentation/power/swsusp.txt b/Documentation/power/swsusp.txt index ea718891a665..ac190cf1963e 100644 --- a/Documentation/power/swsusp.txt +++ b/Documentation/power/swsusp.txt @@ -192,7 +192,7 @@ Q: There don't seem to be any generally useful behavioral distinctions between SUSPEND and FREEZE. A: Doing SUSPEND when you are asked to do FREEZE is always correct, -but it may be unneccessarily slow. If you want your driver to stay simple, +but it may be unnecessarily slow. If you want your driver to stay simple, slowness may not matter to you. It can always be fixed later. For devices like disk it does matter, you do not want to spindown for @@ -237,7 +237,7 @@ disk. Whole sequence goes like running system, user asks for suspend-to-disk - user processes are stopped (in common case there are none, but with resume-from-initrd, noone knows) + user processes are stopped (in common case there are none, but with resume-from-initrd, no one knows) read image from disk diff --git a/Documentation/power/userland-swsusp.txt b/Documentation/power/userland-swsusp.txt index 81680f9f5909..1101bee4e822 100644 --- a/Documentation/power/userland-swsusp.txt +++ b/Documentation/power/userland-swsusp.txt @@ -98,7 +98,7 @@ SNAPSHOT_S2RAM - suspend to RAM; using this call causes the kernel to The device's read() operation can be used to transfer the snapshot image from the kernel. It has the following limitations: - you cannot read() more than one virtual memory page at a time -- read()s accross page boundaries are impossible (ie. if ypu read() 1/2 of +- read()s across page boundaries are impossible (ie. if ypu read() 1/2 of a page in the previous call, you will only be able to read() _at_ _most_ 1/2 of the page in the next call) @@ -137,7 +137,7 @@ mechanism and the userland utilities using the interface SHOULD use additional means, such as checksums, to ensure the integrity of the snapshot image. The suspending and resuming utilities MUST lock themselves in memory, -preferrably using mlockall(), before calling SNAPSHOT_FREEZE. +preferably using mlockall(), before calling SNAPSHOT_FREEZE. The suspending utility MUST check the value stored by SNAPSHOT_CREATE_IMAGE in the memory location pointed to by the last argument of ioctl() and proceed @@ -147,7 +147,7 @@ in accordance with it: (a) The suspending utility MUST NOT close the snapshot device _unless_ the whole suspend procedure is to be cancelled, in which case, if the snapshot image has already been saved, the - suspending utility SHOULD destroy it, preferrably by zapping + suspending utility SHOULD destroy it, preferably by zapping its header. If the suspend is not to be cancelled, the system MUST be powered off or rebooted after the snapshot image has been saved. diff --git a/Documentation/powerpc/hvcs.txt b/Documentation/powerpc/hvcs.txt index 6d8be3468d7d..a730ca5a07f8 100644 --- a/Documentation/powerpc/hvcs.txt +++ b/Documentation/powerpc/hvcs.txt @@ -528,7 +528,7 @@ this driver assignment of hotplug added vty-servers may be in a different order than how they would be exposed on module load. Rebooting or reloading the module after dynamic addition may result in the /dev/hvcs* and vty-server coupling changing if a vty-server adapter was added in a -slot inbetween two other vty-server adapters. Refer to the section above +slot between two other vty-server adapters. Refer to the section above on how to determine which vty-server goes with which /dev/hvcs* node. Hint; look at the sysfs "index" attribute for the vty-server. diff --git a/Documentation/scsi/ChangeLog.lpfc b/Documentation/scsi/ChangeLog.lpfc index 5e83769c6aa9..c56ec99d7b2f 100644 --- a/Documentation/scsi/ChangeLog.lpfc +++ b/Documentation/scsi/ChangeLog.lpfc @@ -352,7 +352,7 @@ Changes from 20041229 to 20050110 lpfc_scsiport.c * In remote port changes: no longer nulling target->pnode when removing from mapped list. Pnode get nulled when the node is - freed (after nodev tmo). This bug was causing i/o recieved in + freed (after nodev tmo). This bug was causing i/o received in the small window while the device was blocked to be errored w/ did_no_connect. With the fix, it returns host_busy (per the pre-remote port changes). @@ -530,7 +530,7 @@ Changes from 20041018 to 20041123 coherent mappings. Note: There are more consistent mappings that are using pci_dma_sync calls. Probably these should be removed as well. - * Modified lpfc_free_scsi_buf to accomodate all three scsi_buf + * Modified lpfc_free_scsi_buf to accommodate all three scsi_buf free types to alleviate miscellaneous panics with cable pull testing. * Set hotplug to default 0 and lpfc_target_remove to not remove @@ -583,7 +583,7 @@ Changes from 20041018 to 20041123 included more than once. * Replaced "set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(timeout)" with "msleep(timeout)". - * Fixnode was loosing starget when rediscovered. We saw messages + * Fixnode was losing starget when rediscovered. We saw messages like: lpfc 0000:04:02.0: 0:0263 Cannot block scsi target as a result. Moved starget field into struct lpfc_target which is referenced from the node. @@ -604,7 +604,7 @@ Changes from 20041018 to 20041123 * Make 3 functions static: lpfc_get_hba_sym_node_name, lpfc_intr_prep and lpfc_setup_slim_access. Move lpfc_intr_prep and lpfc_setup_slim_access so they're defined before being used. - * Remove an unecessary list_del() in lpfc_hbadisc.c. + * Remove an unnecessary list_del() in lpfc_hbadisc.c. * Set nlp_state before calling lpfc_nlp_list() since this will potentially call fc_target_unblock which may cause a race in queuecommand by releasing host_lock. @@ -753,7 +753,7 @@ Changes from 20040908 to 20040920 * Changed version number to 8.0.12 * Removed used #defines: DEFAULT_PCI_LATENCY_CLOCKS and PCI_LATENCY_VALUE from lpfc_hw.h. - * Changes to accomodate rnid. + * Changes to accommodate rnid. * Fix RSCN handling so RSCN NS queries only effect NPorts found in RSCN data. * If we rcv a plogi on a NPort queued up for discovery, clear the @@ -813,7 +813,7 @@ Changes from 20040908 to 20040920 counter instead, brd_no isn't reused anymore. Also some tiny whitespace cleanups in surrounding code. * Reorder functions in lpfc_els.c to remove need for prototypes. - * Removed unsed prototypes from lpfc_crtn.h - + * Removed unused prototypes from lpfc_crtn.h - lpfc_ip_timeout_handler, lpfc_read_pci and lpfc_revoke. * Removed some unused prototypes from lpfc_crtn.h - lpfc_scsi_hba_reset, lpfc_scsi_issue_inqsn, @@ -863,7 +863,7 @@ Changes from 20040823 to 20040908 * Minimal support for SCSI flat space addressing/volume set addressing. Use 16 bits of LUN address so that flat addressing/VSA will work. - * Changed 2 occurences of if( 1 != f(x)) to if(f(x) != 1) + * Changed 2 occurrences of if( 1 != f(x)) to if(f(x) != 1) * Drop include of lpfc_cfgparm.h. * Reduce stack usage of lpfc_fdmi_cmd in lpfc_ct.c. * Add minimum range checking property to /sys write/store @@ -1449,7 +1449,7 @@ Changes from 20040402 to 20040409 * Removed lpfc_els_chk_latt from the lpfc_config_post function. lpfc_els_chk_latt will enable the link event interrupts when flogi is pending which causes two discovery state machines - running parallely. + running parallelly. * Add pci_disable_device to unload path. * Move lpfc_sleep_event from lpfc_fcp.c to lpfc_util_ioctl.c * Call dma_map_single() & pci_map_single() directly instead of via @@ -1590,7 +1590,7 @@ Changes from 20040326 to 20040402 ELX_WRITE_HS ELX_WRITE_HA ELX_WRITE_CA ELX_READ_HC ELX_READ_HS ELX_READ_HA ELX_READ_CA ELX_READ_MB ELX_RESET ELX_READ_HBA ELX_INSTANCE ELX_LIP. Also introduced - attribute "set" to be used in conjuction with the above + attribute "set" to be used in conjunction with the above attributes. * Removed DLINK, enque and deque declarations now that clock doesn't use them anymore diff --git a/Documentation/scsi/ChangeLog.megaraid b/Documentation/scsi/ChangeLog.megaraid index 5e07d320817d..d2052fdbedd2 100644 --- a/Documentation/scsi/ChangeLog.megaraid +++ b/Documentation/scsi/ChangeLog.megaraid @@ -168,7 +168,7 @@ Older Version : 2.20.4.6 (scsi module), 2.20.2.6 (cmm module) 1. Sorted out PCI IDs to remove megaraid support overlaps. Based on the patch from Daniel, sorted out PCI IDs along with - charactor node name change from 'megadev' to 'megadev_legacy' to avoid + character node name change from 'megadev' to 'megadev_legacy' to avoid conflict. --- Hopefully we'll be getting the build restriction zapped much sooner, diff --git a/Documentation/scsi/ChangeLog.ncr53c8xx b/Documentation/scsi/ChangeLog.ncr53c8xx index 8b278c10edfd..9288e3d8974a 100644 --- a/Documentation/scsi/ChangeLog.ncr53c8xx +++ b/Documentation/scsi/ChangeLog.ncr53c8xx @@ -200,7 +200,7 @@ Sun Feb 14:00 1999 Gerard Roudier (groudier@club-internet.fr) By default the driver uses both IRQF_SHARED and IRQF_DISABLED. Option 'ncr53c8xx=irqm:0x20' may be used when an IRQ is shared by a 53C8XX adapter and a network board. - - Tiny mispelling fixed (ABORT instead of ABRT). Was fortunately + - Tiny misspelling fixed (ABORT instead of ABRT). Was fortunately harmless. - Negotiate SYNC data transfers with CCS devices. diff --git a/Documentation/scsi/ChangeLog.sym53c8xx b/Documentation/scsi/ChangeLog.sym53c8xx index 02ffbc1e8a84..c1933707d0bc 100644 --- a/Documentation/scsi/ChangeLog.sym53c8xx +++ b/Documentation/scsi/ChangeLog.sym53c8xx @@ -457,7 +457,7 @@ Fri Jan 1 20:00 1999 Gerard Roudier (groudier@club-internet.fr) Sat Dec 19 21:00 1998 Gerard Roudier (groudier@club-internet.fr) * version sym53c8xx-1.0 - Define some new IO registers for the 896 (istat1, mbox0, mbox1) - - Revamp slighly the Symbios NVRAM lay-out based on the excerpt of + - Revamp slightly the Symbios NVRAM lay-out based on the excerpt of the header file I received from Symbios. - Check the PCI bus number for the boot order (Using a fast PCI controller behing a PCI-PCI bridge seems sub-optimal). diff --git a/Documentation/scsi/aha152x.txt b/Documentation/scsi/aha152x.txt index 29ce6d87e451..94848734ac66 100644 --- a/Documentation/scsi/aha152x.txt +++ b/Documentation/scsi/aha152x.txt @@ -124,7 +124,7 @@ in the partition table and therefore every operating system has to know the right geometry to be able to interpret it. Moreover there are certain limitations to the C/H/S addressing scheme, -namely the address space is limited to upto 255 heads, upto 63 sectors +namely the address space is limited to up to 255 heads, up to 63 sectors and a maximum of 1023 cylinders. The AHA-1522 BIOS calculates the geometry by fixing the number of heads diff --git a/Documentation/scsi/aic79xx.txt b/Documentation/scsi/aic79xx.txt index 16e054c9c70b..64ac7093c872 100644 --- a/Documentation/scsi/aic79xx.txt +++ b/Documentation/scsi/aic79xx.txt @@ -267,7 +267,7 @@ The following information is available in this file: Option: tag_info:{{value[,value...]}[,{value[,value...]}...]} Definition: Set the per-target tagged queue depth on a per controller basis. Both controllers and targets - may be ommitted indicating that they should retain + may be omitted indicating that they should retain the default tag depth. Examples: tag_info:{{16,32,32,64,8,8,,32,32,32,32,32,32,32,32,32} On Controller 0 @@ -291,7 +291,7 @@ The following information is available in this file: The rd_strm_bitmask is a 16 bit hex value in which each bit represents a target. Setting the target's bit to '1' enables read streaming for that - target. Controllers may be ommitted indicating that + target. Controllers may be omitted indicating that they should retain the default read streaming setting. Example: rd_strm:{0x0041} On Controller 0 @@ -313,7 +313,7 @@ The following information is available in this file: ----------------------------------------------------------------- Option: dv: {value[,value...]} Definition: Set Domain Validation Policy on a per-controller basis. - Controllers may be ommitted indicating that + Controllers may be omitted indicating that they should retain the default read streaming setting. Example: dv:{-1,0,,1,1,0} On Controller 0 leave DV at its default setting. @@ -340,7 +340,7 @@ The following information is available in this file: Option: precomp: {value[,value...]} Definition: Set IO Cell precompensation value on a per-controller basis. - Controllers may be ommitted indicating that + Controllers may be omitted indicating that they should retain the default precompensation setting. Example: precomp:{0x1} On Controller 0 set precompensation to 1. @@ -353,7 +353,7 @@ The following information is available in this file: ----------------------------------------------------------------- Option: slewrate: {value[,value...]} Definition: Set IO Cell slew rate on a per-controller basis. - Controllers may be ommitted indicating that + Controllers may be omitted indicating that they should retain the default slew rate setting. Example: slewrate:{0x1} On Controller 0 set slew rate to 1. @@ -366,7 +366,7 @@ The following information is available in this file: ----------------------------------------------------------------- Option: amplitude: {value[,value...]} Definition: Set IO Cell signal amplitude on a per-controller basis. - Controllers may be ommitted indicating that + Controllers may be omitted indicating that they should retain the default read streaming setting. Example: amplitude:{0x1} On Controller 0 set amplitude to 1. diff --git a/Documentation/scsi/ibmmca.txt b/Documentation/scsi/ibmmca.txt index 45d61ad8c6f7..ac41a9fcac77 100644 --- a/Documentation/scsi/ibmmca.txt +++ b/Documentation/scsi/ibmmca.txt @@ -303,7 +303,7 @@ (scb) and calls a local function issue_cmd(), which writes a scb command into subsystem I/O ports. Once the scb command is carried out, the interrupt_handler() is invoked. If a device is determined to be - existant and it has not assigned any ldn, it gets one dynamically. + existent and it has not assigned any ldn, it gets one dynamically. For this, the whole stuff is done in ibmmca_queuecommand(). 2.6 Abort & Reset Commands @@ -741,7 +741,7 @@ some error appeared, else it is undefined. Now, this is fixed. Before any SCB command gets queued, the tsb.dev_status is set to 0, so the cmd->result won't screw up Linux higher level drivers. - 2) The reset-function has slightly improved. This is still planed for + 2) The reset-function has slightly improved. This is still planned for abort. During the abort and the reset function, no interrupts are allowed. This is however quite hard to cope with, so the INT-status register is read. When the interrupt gets queued, one can find its diff --git a/Documentation/scsi/scsi-changer.txt b/Documentation/scsi/scsi-changer.txt index 032399b16a53..ade046ea7c17 100644 --- a/Documentation/scsi/scsi-changer.txt +++ b/Documentation/scsi/scsi-changer.txt @@ -102,7 +102,7 @@ Trouble? If you insmod the driver with "insmod debug=1", it will be verbose and prints a lot of stuff to the syslog. Compiling the kernel with -CONFIG_SCSI_CONSTANTS=y improves the quality of the error messages alot +CONFIG_SCSI_CONSTANTS=y improves the quality of the error messages a lot because the kernel will translate the error codes into human-readable strings then. diff --git a/Documentation/scsi/scsi_eh.txt b/Documentation/scsi/scsi_eh.txt index 7acbebb17fa6..6ff16b620d84 100644 --- a/Documentation/scsi/scsi_eh.txt +++ b/Documentation/scsi/scsi_eh.txt @@ -290,7 +290,7 @@ scmd->allowed. SCSI transports/LLDDs automatically acquire sense data on command failures (autosense). Autosense is recommended for performance reasons and as sense information could get out of - sync inbetween occurrence of CHECK CONDITION and this action. + sync between occurrence of CHECK CONDITION and this action. Note that if autosense is not supported, scmd->sense_buffer contains invalid sense data when error-completing the scmd diff --git a/Documentation/scsi/scsi_fc_transport.txt b/Documentation/scsi/scsi_fc_transport.txt index e00192de4d1c..f79282fc48d7 100644 --- a/Documentation/scsi/scsi_fc_transport.txt +++ b/Documentation/scsi/scsi_fc_transport.txt @@ -291,7 +291,7 @@ Transport <-> LLDD Interfaces : Vport support by LLDD: The LLDD indicates support for vports by supplying a vport_create() - function in the transport template. The presense of this function will + function in the transport template. The presence of this function will cause the creation of the new attributes on the fc_host. As part of the physical port completing its initialization relative to the transport, it should set the max_npiv_vports attribute to indicate the diff --git a/Documentation/serial/moxa-smartio b/Documentation/serial/moxa-smartio index d10443918684..5d2a33be0bd8 100644 --- a/Documentation/serial/moxa-smartio +++ b/Documentation/serial/moxa-smartio @@ -473,7 +473,7 @@ Content spd_normal Use 38.4kb when the application requests 38.4kb. spd_cust Use the custom divisor to set the speed when the application requests 38.4kb. - divisor This option set the custom divison. + divisor This option set the custom division. baud_base This option set the base baud rate. ----------------------------------------------------------------------------- diff --git a/Documentation/serial/n_gsm.txt b/Documentation/serial/n_gsm.txt index 397f41a1f153..a5d91126a8f7 100644 --- a/Documentation/serial/n_gsm.txt +++ b/Documentation/serial/n_gsm.txt @@ -34,7 +34,7 @@ Major parts of the initialization program : /* configure the serial port : speed, flow control ... */ /* send the AT commands to switch the modem to CMUX mode - and check that it's succesful (should return OK) */ + and check that it's successful (should return OK) */ write(fd, "AT+CMUX=0\r", 10); /* experience showed that some modems need some time before diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 3c1eddd9fcc7..b9b7f30ab500 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -322,7 +322,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. "port" needs to match the BASE ADDRESS jumper on the card (0x220 or 0x240) or the value stored in the card's EEPROM for cards that have an EEPROM and their "CONFIG MODE" jumper set to "EEPROM SETTING". The other values can - be choosen freely from the options enumerated above. + be chosen freely from the options enumerated above. If dma2 is specified and different from dma1, the card will operate in full-duplex mode. When dma1=3, only dma2=0 is valid and the only way to @@ -356,7 +356,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. "port" needs to match the BASE ADDRESS jumper on the card (0x220 or 0x240) or the value stored in the card's EEPROM for cards that have an EEPROM and their "CONFIG MODE" jumper set to "EEPROM SETTING". The other values can - be choosen freely from the options enumerated above. + be chosen freely from the options enumerated above. If dma2 is specified and different from dma1, the card will operate in full-duplex mode. When dma1=3, only dma2=0 is valid and the only way to diff --git a/Documentation/sound/oss/README.OSS b/Documentation/sound/oss/README.OSS index c615debbf08d..4be259428a1c 100644 --- a/Documentation/sound/oss/README.OSS +++ b/Documentation/sound/oss/README.OSS @@ -1352,7 +1352,7 @@ OSS-mixer. The PCM20 contains a radio tuner, which is also controlled by ACI. This radio tuner is supported by the ACI driver together with the miropcm20.o module. Also the 7-band equalizer is integrated -(limited by the OSS-design). Developement has started and maybe +(limited by the OSS-design). Development has started and maybe finished for the RDS decoder on this card, too. You will be able to read RadioText, the Programme Service name, Programme TYpe and others. Even the v4l radio module benefits from it with a refined diff --git a/Documentation/spi/pxa2xx b/Documentation/spi/pxa2xx index 68a4fe3818a1..493dada57372 100644 --- a/Documentation/spi/pxa2xx +++ b/Documentation/spi/pxa2xx @@ -143,7 +143,7 @@ configured to use SSPFRM instead. NOTE: the SPI driver cannot control the chip select if SSPFRM is used, so the chipselect is dropped after each spi_transfer. Most devices need chip select asserted around the complete message. Use SSPFRM as a GPIO (through cs_control) -to accomodate these chips. +to accommodate these chips. NSSP SLAVE SAMPLE diff --git a/Documentation/spi/spi-lm70llp b/Documentation/spi/spi-lm70llp index 34a9cfd746bd..463f6d01fa15 100644 --- a/Documentation/spi/spi-lm70llp +++ b/Documentation/spi/spi-lm70llp @@ -46,7 +46,7 @@ The hardware interfacing on the LM70 LLP eval board is as follows: Note that since the LM70 uses a "3-wire" variant of SPI, the SI/SO pin is connected to both pin D7 (as Master Out) and Select (as Master In) -using an arrangment that lets either the parport or the LM70 pull the +using an arrangement that lets either the parport or the LM70 pull the pin low. This can't be shared with true SPI devices, but other 3-wire devices might share the same SI/SO pin. diff --git a/Documentation/telephony/ixj.txt b/Documentation/telephony/ixj.txt index 4fb314d51702..db94fb6c5678 100644 --- a/Documentation/telephony/ixj.txt +++ b/Documentation/telephony/ixj.txt @@ -51,7 +51,7 @@ be removed to protect the rights of others. Specifically, very old Internet PhoneJACK cards have non-standard G.723.1 codecs (due to the early nature of the DSPs in those days). The auto-conversion code to bring those cards into compliance with -todays standards is available as a binary only module to those people +today's standards is available as a binary only module to those people needing it. If you bought your card after 1997 or so, you are OK - it's only the very old cards that are affected. diff --git a/Documentation/trace/ring-buffer-design.txt b/Documentation/trace/ring-buffer-design.txt index d299ff31df57..7d350b496585 100644 --- a/Documentation/trace/ring-buffer-design.txt +++ b/Documentation/trace/ring-buffer-design.txt @@ -237,7 +237,7 @@ with the previous write. |written | +---------+ |written | - +---------+ <--- next positon for write (current commit) + +---------+ <--- next position for write (current commit) | empty | +---------+ diff --git a/Documentation/video4linux/README.pvrusb2 b/Documentation/video4linux/README.pvrusb2 index a747200fe67c..2137b589276b 100644 --- a/Documentation/video4linux/README.pvrusb2 +++ b/Documentation/video4linux/README.pvrusb2 @@ -172,7 +172,7 @@ Source file list / functional overview: to provide a streaming API usable by a read() system call style of I/O. Right now this is the only layer on top of pvrusb2-io.[ch], however the underlying architecture here was intended to allow for - other styles of I/O to be implemented with additonal modules, like + other styles of I/O to be implemented with additional modules, like mmap()'ed buffers or something even more exotic. pvrusb2-main.c - This is the top level of the driver. Module level diff --git a/Documentation/video4linux/bttv/README b/Documentation/video4linux/bttv/README index 3a367cdb664e..7cbf4fb6cf31 100644 --- a/Documentation/video4linux/bttv/README +++ b/Documentation/video4linux/bttv/README @@ -70,7 +70,7 @@ If you have trouble with some specific TV card, try to ask there instead of mailing me directly. The chance that someone with the same card listens there is much higher... -For problems with sound: There are alot of different systems used +For problems with sound: There are a lot of different systems used for TV sound all over the world. And there are also different chips which decode the audio signal. Reports about sound problems ("stereo does'nt work") are pretty useless unless you include some details diff --git a/Documentation/video4linux/bttv/README.freeze b/Documentation/video4linux/bttv/README.freeze index 4259dccc8287..5eddfa076cfb 100644 --- a/Documentation/video4linux/bttv/README.freeze +++ b/Documentation/video4linux/bttv/README.freeze @@ -33,7 +33,7 @@ state is stuck. I've seen reports that bttv 0.7.x crashes whereas 0.8.x works rock solid for some people. Thus probably a small buglet left somewhere in bttv -0.7.x. I have no idea where exactly, it works stable for me and alot of +0.7.x. I have no idea where exactly, it works stable for me and a lot of other people. But in case you have problems with the 0.7.x versions you can give 0.8.x a try ... diff --git a/Documentation/video4linux/bttv/Sound-FAQ b/Documentation/video4linux/bttv/Sound-FAQ index 1e6328f91083..b6e6debbbc94 100644 --- a/Documentation/video4linux/bttv/Sound-FAQ +++ b/Documentation/video4linux/bttv/Sound-FAQ @@ -2,7 +2,7 @@ bttv and sound mini howto ========================= -There are alot of different bt848/849/878/879 based boards available. +There are a lot of different bt848/849/878/879 based boards available. Making video work often is not a big deal, because this is handled completely by the bt8xx chip, which is common on all boards. But sound is handled in slightly different ways on each board. diff --git a/Documentation/video4linux/pxa_camera.txt b/Documentation/video4linux/pxa_camera.txt index 4f6d0ca01956..51ed1578b0e8 100644 --- a/Documentation/video4linux/pxa_camera.txt +++ b/Documentation/video4linux/pxa_camera.txt @@ -84,12 +84,12 @@ DMA usage transfer is not started. On "End Of Frame" interrupt, the irq handler starts the DMA chain. - capture of one videobuffer - The DMA chain starts transfering data into videobuffer RAM pages. - When all pages are transfered, the DMA irq is raised on "ENDINTR" status + The DMA chain starts transferring data into videobuffer RAM pages. + When all pages are transferred, the DMA irq is raised on "ENDINTR" status - finishing one videobuffer The DMA irq handler marks the videobuffer as "done", and removes it from the active running queue - Meanwhile, the next videobuffer (if there is one), is transfered by DMA + Meanwhile, the next videobuffer (if there is one), is transferred by DMA - finishing the last videobuffer On the DMA irq of the last videobuffer, the QCI is stopped. @@ -101,7 +101,7 @@ DMA usage This structure is pointed by dma->sg_cpu. The descriptors are used as follows : - - desc-sg[i]: i-th descriptor, transfering the i-th sg + - desc-sg[i]: i-th descriptor, transferring the i-th sg element to the video buffer scatter gather - finisher: has ddadr=DADDR_STOP, dcmd=ENDIRQEN - linker: has ddadr= desc-sg[0] of next video buffer, dcmd=0 diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt index 3b15608ee070..cf21f7aae976 100644 --- a/Documentation/video4linux/v4l2-framework.txt +++ b/Documentation/video4linux/v4l2-framework.txt @@ -343,7 +343,7 @@ ignored. If you want to check for errors use this: err = v4l2_device_call_until_err(v4l2_dev, 0, core, g_chip_ident, &chip); Any error except -ENOIOCTLCMD will exit the loop with that error. If no -errors (except -ENOIOCTLCMD) occured, then 0 is returned. +errors (except -ENOIOCTLCMD) occurred, then 0 is returned. The second argument to both calls is a group ID. If 0, then all subdevs are called. If non-zero, then only those whose group ID match that value will diff --git a/Documentation/vm/active_mm.txt b/Documentation/vm/active_mm.txt index 4ee1f643d897..dbf45817405f 100644 --- a/Documentation/vm/active_mm.txt +++ b/Documentation/vm/active_mm.txt @@ -74,7 +74,7 @@ we have a user context", and is generally done by the page fault handler and things like that). Anyway, I put a pre-patch-2.3.13-1 on ftp.kernel.org just a moment ago, -because it slightly changes the interfaces to accomodate the alpha (who +because it slightly changes the interfaces to accommodate the alpha (who would have thought it, but the alpha actually ends up having one of the ugliest context switch codes - unlike the other architectures where the MM and register state is separate, the alpha PALcode joins the two, and you diff --git a/Documentation/vm/hugetlbpage.txt b/Documentation/vm/hugetlbpage.txt index 457634c1e03e..f8551b3879f8 100644 --- a/Documentation/vm/hugetlbpage.txt +++ b/Documentation/vm/hugetlbpage.txt @@ -72,7 +72,7 @@ number of huge pages requested. This is the most reliable method of allocating huge pages as memory has not yet become fragmented. Some platforms support multiple huge page sizes. To allocate huge pages -of a specific size, one must preceed the huge pages boot command parameters +of a specific size, one must precede the huge pages boot command parameters with a huge page size selection parameter "hugepagesz=". must be specified in bytes with optional scale suffix [kKmMgG]. The default huge page size may be selected with the "default_hugepagesz=" boot parameter. diff --git a/Documentation/vm/overcommit-accounting b/Documentation/vm/overcommit-accounting index 21c7b1f8f32b..706d7ed9d8d2 100644 --- a/Documentation/vm/overcommit-accounting +++ b/Documentation/vm/overcommit-accounting @@ -4,7 +4,7 @@ The Linux kernel supports the following overcommit handling modes address space are refused. Used for a typical system. It ensures a seriously wild allocation fails while allowing overcommit to reduce swap usage. root is allowed to - allocate slighly more memory in this mode. This is the + allocate slightly more memory in this mode. This is the default. 1 - Always overcommit. Appropriate for some scientific diff --git a/Documentation/w1/slaves/w1_ds2423 b/Documentation/w1/slaves/w1_ds2423 index 90a65d23cf59..3f98b505a0ee 100644 --- a/Documentation/w1/slaves/w1_ds2423 +++ b/Documentation/w1/slaves/w1_ds2423 @@ -21,8 +21,8 @@ value and associated ram buffer is outpputed to own line. Each lines will contain the values of 42 bytes read from the counter and memory page along the crc=YES or NO for indicating whether the read operation -was successfull and CRC matched. -If the operation was successfull, there is also in the end of each line +was successful and CRC matched. +If the operation was successful, there is also in the end of each line a counter value expressed as an integer after c= Meaning of 42 bytes represented is following: @@ -34,7 +34,7 @@ Meaning of 42 bytes represented is following: - crc=YES/NO indicating whether read was ok and crc matched - c= current counter value -example from the successfull read: +example from the successful read: 00 02 00 00 00 00 00 00 00 6d 38 00 ff ff 00 00 fe ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff crc=YES c=2 00 02 00 00 00 00 00 00 00 e0 1f 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff crc=YES c=2 00 29 c6 5d 18 00 00 00 00 04 37 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff crc=YES c=408798761 diff --git a/Documentation/w1/w1.netlink b/Documentation/w1/w1.netlink index 804445f745ed..f59a31965d50 100644 --- a/Documentation/w1/w1.netlink +++ b/Documentation/w1/w1.netlink @@ -81,7 +81,7 @@ which will contain list of all registered master ids in the following format: cn_msg (CN_W1_IDX.CN_W1_VAL as id, len is equal to sizeof(struct - w1_netlink_msg) plus number of masters multipled by 4) + w1_netlink_msg) plus number of masters multiplied by 4) w1_netlink_msg (type: W1_LIST_MASTERS, len is equal to number of masters multiplied by 4 (u32 size)) id0 ... idN diff --git a/Documentation/watchdog/hpwdt.txt b/Documentation/watchdog/hpwdt.txt index 9c24d5ffbb06..9488078900e0 100644 --- a/Documentation/watchdog/hpwdt.txt +++ b/Documentation/watchdog/hpwdt.txt @@ -8,7 +8,7 @@ Last reviewed: 06/02/2009 The HP iLO2 NMI Watchdog driver is a kernel module that provides basic watchdog functionality and the added benefit of NMI sourcing. Both the watchdog functionality and the NMI sourcing capability need to be enabled - by the user. Remember that the two modes are not dependant on one another. + by the user. Remember that the two modes are not dependent on one another. A user can have the NMI sourcing without the watchdog timer and vice-versa. Watchdog functionality is enabled like any other common watchdog driver. That diff --git a/arch/alpha/include/asm/elf.h b/arch/alpha/include/asm/elf.h index 9baae8afe8a3..da5449e22175 100644 --- a/arch/alpha/include/asm/elf.h +++ b/arch/alpha/include/asm/elf.h @@ -101,7 +101,7 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; #define ELF_PLAT_INIT(_r, load_addr) _r->r0 = 0 -/* The registers are layed out in pt_regs for PAL and syscall +/* The registers are laid out in pt_regs for PAL and syscall convenience. Re-order them for the linear elf_gregset_t. */ struct pt_regs; diff --git a/arch/alpha/kernel/core_lca.c b/arch/alpha/kernel/core_lca.c index 4843f6ec9f3a..cb2801cfd3df 100644 --- a/arch/alpha/kernel/core_lca.c +++ b/arch/alpha/kernel/core_lca.c @@ -133,7 +133,7 @@ conf_read(unsigned long addr) local_irq_save(flags); - /* Reset status register to avoid loosing errors. */ + /* Reset status register to avoid losing errors. */ stat0 = *(vulp)LCA_IOC_STAT0; *(vulp)LCA_IOC_STAT0 = stat0; mb(); @@ -170,7 +170,7 @@ conf_write(unsigned long addr, unsigned int value) local_irq_save(flags); /* avoid getting hit by machine check */ - /* Reset status register to avoid loosing errors. */ + /* Reset status register to avoid losing errors. */ stat0 = *(vulp)LCA_IOC_STAT0; *(vulp)LCA_IOC_STAT0 = stat0; mb(); diff --git a/arch/alpha/kernel/err_marvel.c b/arch/alpha/kernel/err_marvel.c index 648ae88aeb8a..ae54ad91e18f 100644 --- a/arch/alpha/kernel/err_marvel.c +++ b/arch/alpha/kernel/err_marvel.c @@ -1027,7 +1027,7 @@ marvel_process_logout_frame(struct ev7_lf_subpackets *lf_subpackets, int print) * normal operation, dismiss them. * * Dismiss if: - * C_STAT = 0x14 (Error Reponse) + * C_STAT = 0x14 (Error Response) * C_STS<3> = 0 (C_ADDR valid) * C_ADDR<42> = 1 (I/O) * C_ADDR<31:22> = 111110xxb (PCI Config space) diff --git a/arch/alpha/lib/ev67-strrchr.S b/arch/alpha/lib/ev67-strrchr.S index 3fd8bf414c7b..dd0d8c6b9f59 100644 --- a/arch/alpha/lib/ev67-strrchr.S +++ b/arch/alpha/lib/ev67-strrchr.S @@ -82,7 +82,7 @@ $loop: $eos: negq t1, t4 # E : isolate first null byte match and t1, t4, t4 # E : - subq t4, 1, t5 # E : build a mask of the bytes upto... + subq t4, 1, t5 # E : build a mask of the bytes up to... or t4, t5, t4 # E : ... and including the null and t3, t4, t3 # E : mask out char matches after null diff --git a/arch/alpha/lib/fls.c b/arch/alpha/lib/fls.c index 32afaa3fa686..ddd048c0d825 100644 --- a/arch/alpha/lib/fls.c +++ b/arch/alpha/lib/fls.c @@ -6,7 +6,7 @@ #include /* This is fls(x)-1, except zero is held to zero. This allows most - efficent input into extbl, plus it allows easy handling of fls(0)=0. */ + efficient input into extbl, plus it allows easy handling of fls(0)=0. */ const unsigned char __flsm1_tab[256] = { diff --git a/arch/alpha/lib/strrchr.S b/arch/alpha/lib/strrchr.S index 82cfd0ac907b..1970dc07cfd1 100644 --- a/arch/alpha/lib/strrchr.S +++ b/arch/alpha/lib/strrchr.S @@ -54,7 +54,7 @@ $loop: $eos: negq t1, t4 # e0 : isolate first null byte match and t1, t4, t4 # e1 : - subq t4, 1, t5 # e0 : build a mask of the bytes upto... + subq t4, 1, t5 # e0 : build a mask of the bytes up to... or t4, t5, t4 # e1 : ... and including the null and t3, t4, t3 # e0 : mask out char matches after null diff --git a/arch/alpha/oprofile/op_model_ev67.c b/arch/alpha/oprofile/op_model_ev67.c index 70302086283c..5b9d178e0228 100644 --- a/arch/alpha/oprofile/op_model_ev67.c +++ b/arch/alpha/oprofile/op_model_ev67.c @@ -192,7 +192,7 @@ ev67_handle_interrupt(unsigned long which, struct pt_regs *regs, case TRAP_INVALID1: case TRAP_INVALID2: case TRAP_INVALID3: - /* Pipeline redirection ocurred. PMPC points + /* Pipeline redirection occurred. PMPC points to PALcode. Recognize ITB miss by PALcode offset address, and get actual PC from EXC_ADDR. */ diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5b9f78b570e8..fdc9d4dbf85b 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -694,7 +694,7 @@ config ARCH_S3C2410 the Samsung SMDK2410 development board (and derivatives). Note, the S3C2416 and the S3C2450 are so close that they even share - the same SoC ID code. This means that there is no seperate machine + the same SoC ID code. This means that there is no separate machine directory (no arch/arm/mach-s3c2450) as the S3C2416 was first. config ARCH_S3C64XX diff --git a/arch/arm/Kconfig-nommu b/arch/arm/Kconfig-nommu index 901e6dff8437..2cef8e13f9f8 100644 --- a/arch/arm/Kconfig-nommu +++ b/arch/arm/Kconfig-nommu @@ -34,7 +34,7 @@ config PROCESSOR_ID used instead of the auto-probing which utilizes the register. config REMAP_VECTORS_TO_RAM - bool 'Install vectors to the begining of RAM' if DRAM_BASE + bool 'Install vectors to the beginning of RAM' if DRAM_BASE depends on DRAM_BASE help The kernel needs to change the hardware exception vectors. diff --git a/arch/arm/common/pl330.c b/arch/arm/common/pl330.c index 8f0f86db3602..97912fa48782 100644 --- a/arch/arm/common/pl330.c +++ b/arch/arm/common/pl330.c @@ -1045,7 +1045,7 @@ static inline int _loop(unsigned dry_run, u8 buf[], unsigned lcnt0, lcnt1, ljmp0, ljmp1; struct _arg_LPEND lpend; - /* Max iterations possibile in DMALP is 256 */ + /* Max iterations possible in DMALP is 256 */ if (*bursts >= 256*256) { lcnt1 = 256; lcnt0 = 256; @@ -1446,7 +1446,7 @@ int pl330_update(const struct pl330_info *pi) } for (ev = 0; ev < pi->pcfg.num_events; ev++) { - if (val & (1 << ev)) { /* Event occured */ + if (val & (1 << ev)) { /* Event occurred */ struct pl330_thread *thrd; u32 inten = readl(regs + INTEN); int active; diff --git a/arch/arm/include/asm/fpstate.h b/arch/arm/include/asm/fpstate.h index ee5e03efc1bb..3ad4c10d0d84 100644 --- a/arch/arm/include/asm/fpstate.h +++ b/arch/arm/include/asm/fpstate.h @@ -18,7 +18,7 @@ * VFP storage area has: * - FPEXC, FPSCR, FPINST and FPINST2. * - 16 or 32 double precision data registers - * - an implementation-dependant word of state for FLDMX/FSTMX (pre-ARMv6) + * - an implementation-dependent word of state for FLDMX/FSTMX (pre-ARMv6) * * FPEXC will always be non-zero once the VFP has been used in this process. */ diff --git a/arch/arm/include/asm/glue-cache.h b/arch/arm/include/asm/glue-cache.h index c7afbc552c7f..7e30874377e6 100644 --- a/arch/arm/include/asm/glue-cache.h +++ b/arch/arm/include/asm/glue-cache.h @@ -126,7 +126,7 @@ #endif #if !defined(_CACHE) && !defined(MULTI_CACHE) -#error Unknown cache maintainence model +#error Unknown cache maintenance model #endif #ifndef MULTI_CACHE diff --git a/arch/arm/include/asm/glue.h b/arch/arm/include/asm/glue.h index 0ec35d1698aa..fbf71d75ec83 100644 --- a/arch/arm/include/asm/glue.h +++ b/arch/arm/include/asm/glue.h @@ -10,8 +10,8 @@ * * This file provides the glue to stick the processor-specific bits * into the kernel in an efficient manner. The idea is to use branches - * when we're only targetting one class of TLB, or indirect calls - * when we're targetting multiple classes of TLBs. + * when we're only targeting one class of TLB, or indirect calls + * when we're targeting multiple classes of TLBs. */ #ifdef __KERNEL__ diff --git a/arch/arm/include/asm/hardware/pl080.h b/arch/arm/include/asm/hardware/pl080.h index f35b86e68dd5..e4a04e4e5627 100644 --- a/arch/arm/include/asm/hardware/pl080.h +++ b/arch/arm/include/asm/hardware/pl080.h @@ -16,7 +16,7 @@ * make it not entierly compatible with the PL080 specification from * ARM. When in doubt, check the Samsung documentation first. * - * The Samsung defines are PL080S, and add an extra controll register, + * The Samsung defines are PL080S, and add an extra control register, * the ability to move more than 2^11 counts of data and some extra * OneNAND features. */ diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index 9a87823642d0..885be097769d 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -249,7 +249,7 @@ do { \ * cache totally. This means that the cache becomes inconsistent, and, * since we use normal loads/stores as well, this is really bad. * Typically, this causes oopsen in filp_close, but could have other, - * more disasterous effects. There are two work-arounds: + * more disastrous effects. There are two work-arounds: * 1. Disable interrupts and emulate the atomic swap * 2. Clean the cache, perform atomic swap, flush the cache * diff --git a/arch/arm/include/asm/ucontext.h b/arch/arm/include/asm/ucontext.h index 47f023aa8495..14749aec94bf 100644 --- a/arch/arm/include/asm/ucontext.h +++ b/arch/arm/include/asm/ucontext.h @@ -47,7 +47,7 @@ struct crunch_sigframe { #endif #ifdef CONFIG_IWMMXT -/* iwmmxt_area is 0x98 bytes long, preceeded by 8 bytes of signature */ +/* iwmmxt_area is 0x98 bytes long, preceded by 8 bytes of signature */ #define IWMMXT_MAGIC 0x12ef842a #define IWMMXT_STORAGE_SIZE (IWMMXT_SIZE + 8) diff --git a/arch/arm/kernel/swp_emulate.c b/arch/arm/kernel/swp_emulate.c index 7a5760922914..40ee7e5045e4 100644 --- a/arch/arm/kernel/swp_emulate.c +++ b/arch/arm/kernel/swp_emulate.c @@ -158,7 +158,7 @@ static int emulate_swpX(unsigned int address, unsigned int *data, if (res == 0) { /* - * Barrier also required between aquiring a lock for a + * Barrier also required between acquiring a lock for a * protected resource and accessing the resource. Inserted for * same reason as above. */ diff --git a/arch/arm/mach-at91/board-carmeva.c b/arch/arm/mach-at91/board-carmeva.c index 2e74a19874d1..295e1e77fa60 100644 --- a/arch/arm/mach-at91/board-carmeva.c +++ b/arch/arm/mach-at91/board-carmeva.c @@ -76,7 +76,7 @@ static struct at91_udc_data __initdata carmeva_udc_data = { .pullup_pin = AT91_PIN_PD9, }; -/* FIXME: user dependant */ +/* FIXME: user dependent */ // static struct at91_cf_data __initdata carmeva_cf_data = { // .det_pin = AT91_PIN_PB0, // .rst_pin = AT91_PIN_PC5, diff --git a/arch/arm/mach-at91/include/mach/at91_mci.h b/arch/arm/mach-at91/include/mach/at91_mci.h index 27ac6f550fe3..02182c16a022 100644 --- a/arch/arm/mach-at91/include/mach/at91_mci.h +++ b/arch/arm/mach-at91/include/mach/at91_mci.h @@ -102,7 +102,7 @@ #define AT91_MCI_RDIRE (1 << 17) /* Response Direction Error */ #define AT91_MCI_RCRCE (1 << 18) /* Response CRC Error */ #define AT91_MCI_RENDE (1 << 19) /* Response End Bit Error */ -#define AT91_MCI_RTOE (1 << 20) /* Reponse Time-out Error */ +#define AT91_MCI_RTOE (1 << 20) /* Response Time-out Error */ #define AT91_MCI_DCRCE (1 << 21) /* Data CRC Error */ #define AT91_MCI_DTOE (1 << 22) /* Data Time-out Error */ #define AT91_MCI_OVRE (1 << 30) /* Overrun */ diff --git a/arch/arm/mach-at91/include/mach/gpio.h b/arch/arm/mach-at91/include/mach/gpio.h index ddeb64536756..056dc6674b6b 100644 --- a/arch/arm/mach-at91/include/mach/gpio.h +++ b/arch/arm/mach-at91/include/mach/gpio.h @@ -208,7 +208,7 @@ extern void at91_gpio_resume(void); /*-------------------------------------------------------------------------*/ -/* wrappers for "new style" GPIO calls. the old AT91-specfic ones should +/* wrappers for "new style" GPIO calls. the old AT91-specific ones should * eventually be removed (along with this errno.h inclusion), and the * gpio request/free calls should probably be implemented. */ diff --git a/arch/arm/mach-bcmring/csp/dmac/dmacHw_extra.c b/arch/arm/mach-bcmring/csp/dmac/dmacHw_extra.c index 77f84b40dda9..a1f328357aa4 100644 --- a/arch/arm/mach-bcmring/csp/dmac/dmacHw_extra.c +++ b/arch/arm/mach-bcmring/csp/dmac/dmacHw_extra.c @@ -551,7 +551,7 @@ int dmacHw_calculateDescriptorCount(dmacHw_CONFIG_t *pConfig, /* [ IN ] Config /****************************************************************************/ /** -* @brief Check the existance of pending descriptor +* @brief Check the existence of pending descriptor * * This function confirmes if there is any pending descriptor in the chain * to program the channel @@ -775,7 +775,7 @@ int dmacHw_setVariableDataDescriptor(dmacHw_HANDLE_t handle, /* [ IN ] DMA Cha /** * @brief Read data DMAed to memory * -* This function will read data that has been DMAed to memory while transfering from: +* This function will read data that has been DMAed to memory while transferring from: * - Memory to memory * - Peripheral to memory * @@ -941,7 +941,7 @@ int dmacHw_setControlDescriptor(dmacHw_CONFIG_t *pConfig, /* [ IN ] Configurat /** * @brief Sets channel specific user data * -* This function associates user data to a specif DMA channel +* This function associates user data to a specific DMA channel * */ /****************************************************************************/ diff --git a/arch/arm/mach-bcmring/dma.c b/arch/arm/mach-bcmring/dma.c index 8d1baf3f4683..d87ad30dda35 100644 --- a/arch/arm/mach-bcmring/dma.c +++ b/arch/arm/mach-bcmring/dma.c @@ -629,7 +629,7 @@ EXPORT_SYMBOL(dma_get_device_descriptor_ring); * Configures a DMA channel. * * @return -* >= 0 - Initialization was successfull. +* >= 0 - Initialization was successful. * * -EBUSY - Device is currently being used. * -ENODEV - Device handed in is invalid. @@ -673,7 +673,7 @@ static int ConfigChannel(DMA_Handle_t handle) /** * Initializes all of the data structures associated with the DMA. * @return -* >= 0 - Initialization was successfull. +* >= 0 - Initialization was successful. * * -EBUSY - Device is currently being used. * -ENODEV - Device handed in is invalid. diff --git a/arch/arm/mach-bcmring/include/csp/dmacHw.h b/arch/arm/mach-bcmring/include/csp/dmacHw.h index 6c8da2b9fc1f..e6a1dc484ca7 100644 --- a/arch/arm/mach-bcmring/include/csp/dmacHw.h +++ b/arch/arm/mach-bcmring/include/csp/dmacHw.h @@ -362,7 +362,7 @@ int dmacHw_setControlDescriptor(dmacHw_CONFIG_t *pConfig, /* [ IN ] Configurati /** * @brief Read data DMA transferred to memory * -* This function will read data that has been DMAed to memory while transfering from: +* This function will read data that has been DMAed to memory while transferring from: * - Memory to memory * - Peripheral to memory * @@ -446,7 +446,7 @@ void dmacHw_stopTransfer(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle * /****************************************************************************/ /** -* @brief Check the existance of pending descriptor +* @brief Check the existence of pending descriptor * * This function confirmes if there is any pending descriptor in the chain * to program the channel @@ -542,7 +542,7 @@ dmacHw_HANDLE_t dmacHw_getInterruptSource(void); /** * @brief Sets channel specific user data * -* This function associates user data to a specif DMA channel +* This function associates user data to a specific DMA channel * */ /****************************************************************************/ diff --git a/arch/arm/mach-bcmring/include/mach/csp/chipcHw_def.h b/arch/arm/mach-bcmring/include/mach/csp/chipcHw_def.h index 70eaea866cfe..161973385faf 100644 --- a/arch/arm/mach-bcmring/include/mach/csp/chipcHw_def.h +++ b/arch/arm/mach-bcmring/include/mach/csp/chipcHw_def.h @@ -180,7 +180,7 @@ typedef enum { #define chipcHw_XTAL_FREQ_Hz 25000000 /* Reference clock frequency in Hz */ -/* Programable pin defines */ +/* Programmable pin defines */ #define chipcHw_PIN_GPIO(n) ((((n) >= 0) && ((n) < (chipcHw_GPIO_COUNT))) ? (n) : 0xFFFFFFFF) /* GPIO pin 0 - 60 */ #define chipcHw_PIN_UARTTXD (chipcHw_GPIO_COUNT + 0) /* UART Transmit */ diff --git a/arch/arm/mach-bcmring/include/mach/csp/chipcHw_inline.h b/arch/arm/mach-bcmring/include/mach/csp/chipcHw_inline.h index c78833acb37a..03238c299001 100644 --- a/arch/arm/mach-bcmring/include/mach/csp/chipcHw_inline.h +++ b/arch/arm/mach-bcmring/include/mach/csp/chipcHw_inline.h @@ -832,7 +832,7 @@ static inline void chipcHw_setUsbDevice(void) /****************************************************************************/ /** -* @brief Lower layer funtion to enable/disable a clock of a certain device +* @brief Lower layer function to enable/disable a clock of a certain device * * This function enables/disables a core clock * diff --git a/arch/arm/mach-bcmring/include/mach/csp/intcHw_reg.h b/arch/arm/mach-bcmring/include/mach/csp/intcHw_reg.h index e01fc4607c91..0aeb6a6fe7f8 100644 --- a/arch/arm/mach-bcmring/include/mach/csp/intcHw_reg.h +++ b/arch/arm/mach-bcmring/include/mach/csp/intcHw_reg.h @@ -109,9 +109,9 @@ #define INTCHW_INTC0_DMA0C0 (1<cpuinfo.transition_latency = 2000 * 1000; diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 68fe4c289d77..b95b9196deed 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -1123,7 +1123,7 @@ void __init da850_init(void) * This helps keeping the peripherals on this domain insulated * from CPU frequency changes caused by DVFS. The firmware sets * both PLL0 and PLL1 to the same frequency so, there should not - * be any noticible change even in non-DVFS use cases. + * be any noticeable change even in non-DVFS use cases. */ da850_set_async3_src(1); diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index 76364d1345df..f68012239641 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -314,7 +314,7 @@ static struct clk timer2_clk = { .name = "timer2", .parent = &pll1_aux_clk, .lpsc = DAVINCI_LPSC_TIMER2, - .usecount = 1, /* REVISIT: why cant' this be disabled? */ + .usecount = 1, /* REVISIT: why can't' this be disabled? */ }; static struct clk timer3_clk = { diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 9a2376b3137c..5f8a65424184 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -274,7 +274,7 @@ static struct clk timer2_clk = { .name = "timer2", .parent = &pll1_aux_clk, .lpsc = DAVINCI_LPSC_TIMER2, - .usecount = 1, /* REVISIT: why cant' this be disabled? */ + .usecount = 1, /* REVISIT: why can't' this be disabled? */ }; static struct clk_lookup dm644x_clks[] = { diff --git a/arch/arm/mach-davinci/include/mach/cputype.h b/arch/arm/mach-davinci/include/mach/cputype.h index cea6b8972043..957fb87e832e 100644 --- a/arch/arm/mach-davinci/include/mach/cputype.h +++ b/arch/arm/mach-davinci/include/mach/cputype.h @@ -4,7 +4,7 @@ * Author: Kevin Hilman, Deep Root Systems, LLC * * Defines the cpu_is_*() macros for runtime detection of DaVinci - * device type. In addtion, if support for a given device is not + * device type. In addition, if support for a given device is not * compiled in to the kernel, the macros return 0 so that * resulting code can be optimized out. * diff --git a/arch/arm/mach-ep93xx/gpio.c b/arch/arm/mach-ep93xx/gpio.c index 180b8a9d0d21..a5a9ff70b198 100644 --- a/arch/arm/mach-ep93xx/gpio.c +++ b/arch/arm/mach-ep93xx/gpio.c @@ -101,7 +101,7 @@ static void ep93xx_gpio_ab_irq_handler(unsigned int irq, struct irq_desc *desc) static void ep93xx_gpio_f_irq_handler(unsigned int irq, struct irq_desc *desc) { /* - * map discontiguous hw irq range to continous sw irq range: + * map discontiguous hw irq range to continuous sw irq range: * * IRQ_EP93XX_GPIO{0..7}MUX -> gpio_to_irq(EP93XX_GPIO_LINE_F({0..7}) */ diff --git a/arch/arm/mach-exynos4/include/mach/gpio.h b/arch/arm/mach-exynos4/include/mach/gpio.h index 939728b38d48..be9266b10fdb 100644 --- a/arch/arm/mach-exynos4/include/mach/gpio.h +++ b/arch/arm/mach-exynos4/include/mach/gpio.h @@ -18,7 +18,7 @@ #define gpio_cansleep __gpio_cansleep #define gpio_to_irq __gpio_to_irq -/* Practically, GPIO banks upto GPZ are the configurable gpio banks */ +/* Practically, GPIO banks up to GPZ are the configurable gpio banks */ /* GPIO bank sizes */ #define EXYNOS4_GPIO_A0_NR (8) diff --git a/arch/arm/mach-exynos4/mct.c b/arch/arm/mach-exynos4/mct.c index af82a8fbb68b..14ac10b7ec02 100644 --- a/arch/arm/mach-exynos4/mct.c +++ b/arch/arm/mach-exynos4/mct.c @@ -276,7 +276,7 @@ static void exynos4_mct_tick_start(unsigned long cycles, /* update interrupt count buffer */ exynos4_mct_write(tmp, mevt->base + MCT_L_ICNTB_OFFSET); - /* enable MCT tick interupt */ + /* enable MCT tick interrupt */ exynos4_mct_write(0x1, mevt->base + MCT_L_INT_ENB_OFFSET); tmp = __raw_readl(mevt->base + MCT_L_TCON_OFFSET); diff --git a/arch/arm/mach-exynos4/setup-sdhci-gpio.c b/arch/arm/mach-exynos4/setup-sdhci-gpio.c index 1b3d3a2de95c..e8d08bf8965a 100644 --- a/arch/arm/mach-exynos4/setup-sdhci-gpio.c +++ b/arch/arm/mach-exynos4/setup-sdhci-gpio.c @@ -38,14 +38,14 @@ void exynos4_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width) switch (width) { case 8: for (gpio = EXYNOS4_GPK1(3); gpio <= EXYNOS4_GPK1(6); gpio++) { - /* Data pin GPK1[3:6] to special-funtion 3 */ + /* Data pin GPK1[3:6] to special-function 3 */ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3)); s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP); s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4); } case 4: for (gpio = EXYNOS4_GPK0(3); gpio <= EXYNOS4_GPK0(6); gpio++) { - /* Data pin GPK0[3:6] to special-funtion 2 */ + /* Data pin GPK0[3:6] to special-function 2 */ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP); s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4); diff --git a/arch/arm/mach-exynos4/setup-sdhci.c b/arch/arm/mach-exynos4/setup-sdhci.c index 85f9433d4836..1e83f8cf236d 100644 --- a/arch/arm/mach-exynos4/setup-sdhci.c +++ b/arch/arm/mach-exynos4/setup-sdhci.c @@ -35,7 +35,7 @@ void exynos4_setup_sdhci_cfg_card(struct platform_device *dev, void __iomem *r, { u32 ctrl2, ctrl3; - /* don't need to alter anything acording to card-type */ + /* don't need to alter anything according to card-type */ ctrl2 = readl(r + S3C_SDHCI_CONTROL2); diff --git a/arch/arm/mach-iop13xx/pci.c b/arch/arm/mach-iop13xx/pci.c index 773ea0c95b9f..ba3dae352a2d 100644 --- a/arch/arm/mach-iop13xx/pci.c +++ b/arch/arm/mach-iop13xx/pci.c @@ -225,7 +225,7 @@ static u32 iop13xx_atue_cfg_address(struct pci_bus *bus, int devfn, int where) /* This routine checks the status of the last configuration cycle. If an error * was detected it returns >0, else it returns a 0. The errors being checked * are parity, master abort, target abort (master and target). These types of - * errors occure during a config cycle where there is no device, like during + * errors occur during a config cycle where there is no device, like during * the discovery stage. */ static int iop13xx_atux_pci_status(int clear) @@ -332,7 +332,7 @@ static struct pci_ops iop13xx_atux_ops = { /* This routine checks the status of the last configuration cycle. If an error * was detected it returns >0, else it returns a 0. The errors being checked * are parity, master abort, target abort (master and target). These types of - * errors occure during a config cycle where there is no device, like during + * errors occur during a config cycle where there is no device, like during * the discovery stage. */ static int iop13xx_atue_pci_status(int clear) diff --git a/arch/arm/mach-kirkwood/tsx1x-common.c b/arch/arm/mach-kirkwood/tsx1x-common.c index f781164e623f..24294b2bc469 100644 --- a/arch/arm/mach-kirkwood/tsx1x-common.c +++ b/arch/arm/mach-kirkwood/tsx1x-common.c @@ -15,7 +15,7 @@ /**************************************************************************** * 16 MiB NOR flash. The struct mtd_partition is not in the same order as the - * partitions on the device because we want to keep compatability with + * partitions on the device because we want to keep compatibility with * the QNAP firmware. * Layout as used by QNAP: * 0x00000000-0x00080000 : "U-Boot" diff --git a/arch/arm/mach-lpc32xx/pm.c b/arch/arm/mach-lpc32xx/pm.c index e76d41bb7056..b9c80597b7bf 100644 --- a/arch/arm/mach-lpc32xx/pm.c +++ b/arch/arm/mach-lpc32xx/pm.c @@ -41,7 +41,7 @@ * DRAM clocking and refresh are slightly different for systems with DDR * DRAM or regular SDRAM devices. If SDRAM is used in the system, the * SDRAM will still be accessible in direct-run mode. In DDR based systems, - * a transistion to direct-run mode will stop all DDR accesses (no clocks). + * a transition to direct-run mode will stop all DDR accesses (no clocks). * Because of this, the code to switch power modes and the code to enter * and exit DRAM self-refresh modes must not be executed in DRAM. A small * section of IRAM is used instead for this. diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c index aeb9ae23e6ce..99833b9485cf 100644 --- a/arch/arm/mach-mmp/time.c +++ b/arch/arm/mach-mmp/time.c @@ -9,7 +9,7 @@ * 2008-04-11: Jason Chagas * 2008-10-08: Bin Yang * - * The timers module actually includes three timers, each timer with upto + * The timers module actually includes three timers, each timer with up to * three match comparators. Timer #0 is used here in free-running mode as * the clock source, and match comparator #1 used as clock event device. * diff --git a/arch/arm/mach-msm/acpuclock-arm11.c b/arch/arm/mach-msm/acpuclock-arm11.c index 7ffbd987eb5d..805d4ee53f7e 100644 --- a/arch/arm/mach-msm/acpuclock-arm11.c +++ b/arch/arm/mach-msm/acpuclock-arm11.c @@ -343,7 +343,7 @@ int acpuclk_set_rate(unsigned long rate, int for_power_collapse) } } - /* Set wait states for CPU inbetween frequency changes */ + /* Set wait states for CPU between frequency changes */ reg_clkctl = readl(A11S_CLK_CNTL_ADDR); reg_clkctl |= (100 << 16); /* set WT_ST_CNT */ writel(reg_clkctl, A11S_CLK_CNTL_ADDR); diff --git a/arch/arm/mach-msm/scm.c b/arch/arm/mach-msm/scm.c index cfa808dd4897..232f97a04504 100644 --- a/arch/arm/mach-msm/scm.c +++ b/arch/arm/mach-msm/scm.c @@ -46,7 +46,7 @@ static DEFINE_MUTEX(scm_lock); * @id: command to be executed * @buf: buffer returned from scm_get_command_buffer() * - * An SCM command is layed out in memory as follows: + * An SCM command is laid out in memory as follows: * * ------------------- <--- struct scm_command * | command header | diff --git a/arch/arm/mach-omap1/ams-delta-fiq-handler.S b/arch/arm/mach-omap1/ams-delta-fiq-handler.S index 927d5a181760..c1c5fb6a5b4c 100644 --- a/arch/arm/mach-omap1/ams-delta-fiq-handler.S +++ b/arch/arm/mach-omap1/ams-delta-fiq-handler.S @@ -79,7 +79,7 @@ /* - * Register useage + * Register usage * r8 - temporary * r9 - the driver buffer * r10 - temporary diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c index d41fe2d0616a..0ad781db4e66 100644 --- a/arch/arm/mach-omap1/board-sx1.c +++ b/arch/arm/mach-omap1/board-sx1.c @@ -399,7 +399,7 @@ static void __init omap_sx1_init(void) sx1_mmc_init(); /* turn on USB power */ - /* sx1_setusbpower(1); cant do it here because i2c is not ready */ + /* sx1_setusbpower(1); can't do it here because i2c is not ready */ gpio_request(1, "A_IRDA_OFF"); gpio_request(11, "A_SWITCH"); gpio_request(15, "A_USB_ON"); diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c index b0f4c231595f..36f26c3fa25e 100644 --- a/arch/arm/mach-omap1/devices.c +++ b/arch/arm/mach-omap1/devices.c @@ -281,7 +281,7 @@ static inline void omap_init_audio(void) {} * Claiming GPIOs, and setting their direction and initial values, is the * responsibility of the device drivers. So is responding to probe(). * - * Board-specific knowlege like creating devices or pin setup is to be + * Board-specific knowledge like creating devices or pin setup is to be * kept out of drivers as much as possible. In particular, pin setup * may be handled by the boot loader, and drivers should expect it will * normally have been done by the time they're probed. diff --git a/arch/arm/mach-omap1/include/mach/ams-delta-fiq.h b/arch/arm/mach-omap1/include/mach/ams-delta-fiq.h index 7a2df29400ca..23eed0035ed8 100644 --- a/arch/arm/mach-omap1/include/mach/ams-delta-fiq.h +++ b/arch/arm/mach-omap1/include/mach/ams-delta-fiq.h @@ -31,7 +31,7 @@ #endif /* - * These are the offsets from the begining of the fiq_buffer. They are put here + * These are the offsets from the beginning of the fiq_buffer. They are put here * since the buffer and header need to be accessed by drivers servicing devices * which generate GPIO interrupts - e.g. keyboard, modem, hook switch. */ diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c index 5f8a2fd06337..34cf982b9679 100644 --- a/arch/arm/mach-omap2/board-igep0020.c +++ b/arch/arm/mach-omap2/board-igep0020.c @@ -696,7 +696,7 @@ static void __init igep2_init(void) igep2_init_smsc911x(); /* - * WLAN-BT combo module from MuRata wich has a Marvell WLAN + * WLAN-BT combo module from MuRata which has a Marvell WLAN * (88W8686) + CSR Bluetooth chipset. Uses SDIO interface. */ igep2_wlan_bt_init(); diff --git a/arch/arm/mach-omap2/board-igep0030.c b/arch/arm/mach-omap2/board-igep0030.c index b10db0e6ee62..2cf86c3cb1a3 100644 --- a/arch/arm/mach-omap2/board-igep0030.c +++ b/arch/arm/mach-omap2/board-igep0030.c @@ -440,7 +440,7 @@ static void __init igep3_init(void) igep3_leds_init(); /* - * WLAN-BT combo module from MuRata wich has a Marvell WLAN + * WLAN-BT combo module from MuRata which has a Marvell WLAN * (88W8686) + CSR Bluetooth chipset. Uses SDIO interface. */ igep3_wifi_bt_init(); diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c index ab878545bd9b..6cb6c03293df 100644 --- a/arch/arm/mach-omap2/clockdomain.c +++ b/arch/arm/mach-omap2/clockdomain.c @@ -258,7 +258,7 @@ static void _resolve_clkdm_deps(struct clockdomain *clkdm, * clkdm_init - set up the clockdomain layer * @clkdms: optional pointer to an array of clockdomains to register * @init_autodeps: optional pointer to an array of autodeps to register - * @custom_funcs: func pointers for arch specfic implementations + * @custom_funcs: func pointers for arch specific implementations * * Set up internal state. If a pointer to an array of clockdomains * @clkdms was supplied, loop through the list of clockdomains, diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h index 85b3dce65640..5823584d9cd7 100644 --- a/arch/arm/mach-omap2/clockdomain.h +++ b/arch/arm/mach-omap2/clockdomain.h @@ -125,7 +125,7 @@ struct clockdomain { }; /** - * struct clkdm_ops - Arch specfic function implementations + * struct clkdm_ops - Arch specific function implementations * @clkdm_add_wkdep: Add a wakeup dependency between clk domains * @clkdm_del_wkdep: Delete a wakeup dependency between clk domains * @clkdm_read_wkdep: Read wakeup dependency state between clk domains diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index a44c52303405..1c240eff3918 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c @@ -297,8 +297,8 @@ DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev); /** * omap3_cpuidle_update_states() - Update the cpuidle states - * @mpu_deepest_state: Enable states upto and including this for mpu domain - * @core_deepest_state: Enable states upto and including this for core domain + * @mpu_deepest_state: Enable states up to and including this for mpu domain + * @core_deepest_state: Enable states up to and including this for core domain * * This goes through the list of states available and enables and disables the * validity of C states based on deepest state that can be achieved for the diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 84d1b735fe80..7b8558564591 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -253,7 +253,7 @@ int __init omap4_keyboard_init(struct omap4_keypad_platform_data ARRAY_SIZE(omap_keyboard_latency), 0); if (IS_ERR(od)) { - WARN(1, "Cant build omap_device for %s:%s.\n", + WARN(1, "Can't build omap_device for %s:%s.\n", name, oh->name); return PTR_ERR(od); } @@ -373,7 +373,7 @@ static int omap_mcspi_init(struct omap_hwmod *oh, void *unused) od = omap_device_build(name, spi_num, oh, pdata, sizeof(*pdata), omap_mcspi_latency, ARRAY_SIZE(omap_mcspi_latency), 0); - WARN(IS_ERR(od), "Cant build omap_device for %s:%s\n", + WARN(IS_ERR(od), "Can't build omap_device for %s:%s\n", name, oh->name); kfree(pdata); return 0; @@ -725,7 +725,7 @@ static int __init omap_init_wdt(void) od = omap_device_build(dev_name, id, oh, NULL, 0, omap_wdt_latency, ARRAY_SIZE(omap_wdt_latency), 0); - WARN(IS_ERR(od), "Cant build omap_device for %s:%s.\n", + WARN(IS_ERR(od), "Can't build omap_device for %s:%s.\n", dev_name, oh->name); return 0; } diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c index 34922b2d2e3f..c9ff0e79703d 100644 --- a/arch/arm/mach-omap2/dma.c +++ b/arch/arm/mach-omap2/dma.c @@ -262,7 +262,7 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused) omap2_dma_latency, ARRAY_SIZE(omap2_dma_latency), 0); kfree(p); if (IS_ERR(od)) { - pr_err("%s: Cant build omap_device for %s:%s.\n", + pr_err("%s: Can't build omap_device for %s:%s.\n", __func__, name, oh->name); return PTR_ERR(od); } diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c index 413de18c1d2b..9529842ae054 100644 --- a/arch/arm/mach-omap2/gpio.c +++ b/arch/arm/mach-omap2/gpio.c @@ -82,7 +82,7 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) kfree(pdata); if (IS_ERR(od)) { - WARN(1, "Cant build omap_device for %s:%s.\n", + WARN(1, "Can't build omap_device for %s:%s.\n", name, oh->name); return PTR_ERR(od); } diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c index 137e1a5f3d85..b2f30bed5a20 100644 --- a/arch/arm/mach-omap2/hsmmc.c +++ b/arch/arm/mach-omap2/hsmmc.c @@ -465,7 +465,7 @@ void __init omap_init_hsmmc(struct omap2_hsmmc_info *hsmmcinfo, int ctrl_nr) od = omap_device_build(name, ctrl_nr - 1, oh, mmc_data, sizeof(struct omap_mmc_platform_data), ohl, ohl_cnt, false); if (IS_ERR(od)) { - WARN(1, "Cant build omap_device for %s:%s.\n", name, oh->name); + WARN(1, "Can't build omap_device for %s:%s.\n", name, oh->name); kfree(mmc_data->slots[0].name); goto done; } diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c index 565b9064a328..4a6ef6ab8458 100644 --- a/arch/arm/mach-omap2/mcbsp.c +++ b/arch/arm/mach-omap2/mcbsp.c @@ -149,7 +149,7 @@ static int omap_init_mcbsp(struct omap_hwmod *oh, void *unused) ARRAY_SIZE(omap2_mcbsp_latency), false); kfree(pdata); if (IS_ERR(od)) { - pr_err("%s: Cant build omap_device for %s:%s.\n", __func__, + pr_err("%s: Can't build omap_device for %s:%s.\n", __func__, name, oh->name); return PTR_ERR(od); } diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index bb043cbb3886..a4ab1e364313 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c @@ -518,7 +518,7 @@ static int omap_mux_dbg_board_show(struct seq_file *s, void *unused) seq_printf(s, "/* %s */\n", m->muxnames[mode]); /* - * XXX: Might be revisited to support differences accross + * XXX: Might be revisited to support differences across * same OMAP generation. */ seq_printf(s, "OMAP%d_MUX(%s, ", omap_gen, m0_def); diff --git a/arch/arm/mach-omap2/mux2430.h b/arch/arm/mach-omap2/mux2430.h index adbea0d03e08..9fd93149ebd9 100644 --- a/arch/arm/mach-omap2/mux2430.h +++ b/arch/arm/mach-omap2/mux2430.h @@ -22,7 +22,7 @@ * absolute addresses. The name in the macro is the mode-0 name of * the pin. NOTE: These registers are 8-bits wide. * - * Note that these defines use SDMMC instead of MMC for compability + * Note that these defines use SDMMC instead of MMC for compatibility * with signal names used in 3630. */ #define OMAP2430_CONTROL_PADCONF_GPMC_CLK_OFFSET 0x000 diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c index a860fb5024c2..e6e3810db77f 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c @@ -1559,7 +1559,7 @@ static struct omap_hwmod omap2430_i2c1_hwmod = { * I2CHS IP's do not follow the usual pattern. * prcm_reg_id alone cannot be used to program * the iclk and fclk. Needs to be handled using - * additonal flags when clk handling is moved + * additional flags when clk handling is moved * to hwmod framework. */ .module_offs = CORE_MOD, diff --git a/arch/arm/mach-omap2/omap_phy_internal.c b/arch/arm/mach-omap2/omap_phy_internal.c index e2e605fe9138..05f6abc96b0d 100644 --- a/arch/arm/mach-omap2/omap_phy_internal.c +++ b/arch/arm/mach-omap2/omap_phy_internal.c @@ -112,12 +112,12 @@ int omap4430_phy_power(struct device *dev, int ID, int on) else /* * Enable VBUS Valid, AValid and IDDIG - * high impedence + * high impedance */ __raw_writel(IDDIG | AVALID | VBUSVALID, ctrl_base + USBOTGHS_CONTROL); } else { - /* Enable session END and IDIG to high impedence. */ + /* Enable session END and IDIG to high impedance. */ __raw_writel(SESSEND | IDDIG, ctrl_base + USBOTGHS_CONTROL); } diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c index 0a8e74e3e811..07d6140baa9d 100644 --- a/arch/arm/mach-omap2/omap_twl.c +++ b/arch/arm/mach-omap2/omap_twl.c @@ -308,7 +308,7 @@ int __init omap3_twl_init(void) * Strategy Software Scaling Mode (ENABLE_VMODE=0), for setting the voltages, * in those scenarios this bit is to be cleared (enable = false). * - * Returns 0 on sucess, error is returned if I2C read/write fails. + * Returns 0 on success, error is returned if I2C read/write fails. */ int __init omap3_twl_set_sr_bit(bool enable) { diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c index 49c6513e90d8..9af08473bf10 100644 --- a/arch/arm/mach-omap2/powerdomain.c +++ b/arch/arm/mach-omap2/powerdomain.c @@ -196,7 +196,7 @@ static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused) /** * pwrdm_init - set up the powerdomain layer * @pwrdm_list: array of struct powerdomain pointers to register - * @custom_funcs: func pointers for arch specfic implementations + * @custom_funcs: func pointers for arch specific implementations * * Loop through the array of powerdomains @pwrdm_list, registering all * that are available on the current CPU. If pwrdm_list is supplied diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h index 027f40bd235d..d23d979b9c34 100644 --- a/arch/arm/mach-omap2/powerdomain.h +++ b/arch/arm/mach-omap2/powerdomain.h @@ -121,7 +121,7 @@ struct powerdomain { }; /** - * struct pwrdm_ops - Arch specfic function implementations + * struct pwrdm_ops - Arch specific function implementations * @pwrdm_set_next_pwrst: Set the target power state for a pd * @pwrdm_read_next_pwrst: Read the target power state set for a pd * @pwrdm_read_pwrst: Read the current power state of a pd diff --git a/arch/arm/mach-omap2/powerdomains3xxx_data.c b/arch/arm/mach-omap2/powerdomains3xxx_data.c index 9c9c113788b9..469a920a74dc 100644 --- a/arch/arm/mach-omap2/powerdomains3xxx_data.c +++ b/arch/arm/mach-omap2/powerdomains3xxx_data.c @@ -72,7 +72,7 @@ static struct powerdomain mpu_3xxx_pwrdm = { /* * The USBTLL Save-and-Restore mechanism is broken on - * 3430s upto ES3.0 and 3630ES1.0. Hence this feature + * 3430s up to ES3.0 and 3630ES1.0. Hence this feature * needs to be disabled on these chips. * Refer: 3430 errata ID i459 and 3630 errata ID i579 * diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c index 8f674c9442bf..13e24f913dd4 100644 --- a/arch/arm/mach-omap2/smartreflex.c +++ b/arch/arm/mach-omap2/smartreflex.c @@ -247,7 +247,7 @@ static void sr_stop_vddautocomp(struct omap_sr *sr) * driver register and sr device intializtion API's. Only one call * will ultimately succeed. * - * Currenly this function registers interrrupt handler for a particular SR + * Currently this function registers interrrupt handler for a particular SR * if smartreflex class driver is already registered and has * requested for interrupts and the SR interrupt line in present. */ diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c index c6facf7becf8..6fb520999b6e 100644 --- a/arch/arm/mach-omap2/voltage.c +++ b/arch/arm/mach-omap2/voltage.c @@ -851,7 +851,7 @@ int omap_voltage_scale_vdd(struct voltagedomain *voltdm, * @voltdm: pointer to the VDD whose voltage is to be reset. * * This API finds out the correct voltage the voltage domain is supposed - * to be at and resets the voltage to that level. Should be used expecially + * to be at and resets the voltage to that level. Should be used especially * while disabling any voltage compensation modules. */ void omap_voltage_reset(struct voltagedomain *voltdm) @@ -912,7 +912,7 @@ void omap_voltage_get_volttable(struct voltagedomain *voltdm, * This API searches only through the non-compensated voltages int the * voltage table. * Returns pointer to the voltage table entry corresponding to volt on - * sucess. Returns -ENODATA if no voltage table exisits for the passed voltage + * success. Returns -ENODATA if no voltage table exisits for the passed voltage * domain or if there is no matching entry. */ struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm, diff --git a/arch/arm/mach-orion5x/addr-map.c b/arch/arm/mach-orion5x/addr-map.c index 1a5d6a0e2602..5ceafdccc456 100644 --- a/arch/arm/mach-orion5x/addr-map.c +++ b/arch/arm/mach-orion5x/addr-map.c @@ -19,7 +19,7 @@ #include "common.h" /* - * The Orion has fully programable address map. There's a separate address + * The Orion has fully programmable address map. There's a separate address * map for each of the device _master_ interfaces, e.g. CPU, PCI, PCIe, USB, * Gigabit Ethernet, DMA/XOR engines, etc. Each interface has its own * address decode windows that allow it to access any of the Orion resources. diff --git a/arch/arm/mach-orion5x/net2big-setup.c b/arch/arm/mach-orion5x/net2big-setup.c index 429ecafe9fdd..a5930f83958b 100644 --- a/arch/arm/mach-orion5x/net2big-setup.c +++ b/arch/arm/mach-orion5x/net2big-setup.c @@ -190,7 +190,7 @@ err_free_1: * The power front LEDs (blue and red) and SATA red LEDs are controlled via a * single GPIO line and are compatible with the leds-gpio driver. * - * The SATA blue LEDs have some hardware blink capabilities which are detailled + * The SATA blue LEDs have some hardware blink capabilities which are detailed * in the following array: * * SATAx blue LED | SATAx activity | LED state diff --git a/arch/arm/mach-orion5x/ts209-setup.c b/arch/arm/mach-orion5x/ts209-setup.c index f0f43e13ac87..e6d64494d3de 100644 --- a/arch/arm/mach-orion5x/ts209-setup.c +++ b/arch/arm/mach-orion5x/ts209-setup.c @@ -36,7 +36,7 @@ /**************************************************************************** * 8MiB NOR flash. The struct mtd_partition is not in the same order as the - * partitions on the device because we want to keep compatability with + * partitions on the device because we want to keep compatibility with * existing QNAP firmware. * * Layout as used by QNAP: diff --git a/arch/arm/mach-orion5x/ts409-setup.c b/arch/arm/mach-orion5x/ts409-setup.c index 92f393f08fa4..9eac8192d923 100644 --- a/arch/arm/mach-orion5x/ts409-setup.c +++ b/arch/arm/mach-orion5x/ts409-setup.c @@ -56,7 +56,7 @@ /**************************************************************************** * 8MiB NOR flash. The struct mtd_partition is not in the same order as the - * partitions on the device because we want to keep compatability with + * partitions on the device because we want to keep compatibility with * existing QNAP firmware. * * Layout as used by QNAP: diff --git a/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h b/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h index e4fb4668c26e..207ecb49a61b 100644 --- a/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h +++ b/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h @@ -38,7 +38,7 @@ #define PCMD(x) __REG(0x40F50110 + ((x) << 2)) /* - * Slave Power Managment Unit + * Slave Power Management Unit */ #define ASCR __REG(0x40f40000) /* Application Subsystem Power Status/Configuration */ #define ARSR __REG(0x40f40004) /* Application Subsystem Reset Status */ diff --git a/arch/arm/mach-pxa/include/mach/zeus.h b/arch/arm/mach-pxa/include/mach/zeus.h index faa408ab7ad7..0641f31a56b7 100644 --- a/arch/arm/mach-pxa/include/mach/zeus.h +++ b/arch/arm/mach-pxa/include/mach/zeus.h @@ -64,7 +64,7 @@ /* * CPLD registers: - * Only 4 registers, but spreaded over a 32MB address space. + * Only 4 registers, but spread over a 32MB address space. * Be gentle, and remap that over 32kB... */ diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c index dd13bb63259b..23925db8ff74 100644 --- a/arch/arm/mach-pxa/mioa701.c +++ b/arch/arm/mach-pxa/mioa701.c @@ -458,7 +458,7 @@ static struct platform_device strataflash = { /* * Suspend/Resume bootstrap management * - * MIO A701 reboot sequence is highly ROM dependant. From the one dissassembled, + * MIO A701 reboot sequence is highly ROM dependent. From the one dissassembled, * this sequence is as follows : * - disables interrupts * - initialize SDRAM (self refresh RAM into active RAM) diff --git a/arch/arm/mach-s3c2410/include/mach/dma.h b/arch/arm/mach-s3c2410/include/mach/dma.h index cf68136cc668..b2b2a5bb275e 100644 --- a/arch/arm/mach-s3c2410/include/mach/dma.h +++ b/arch/arm/mach-s3c2410/include/mach/dma.h @@ -19,7 +19,7 @@ #define MAX_DMA_TRANSFER_SIZE 0x100000 /* Data Unit is half word */ /* We use `virtual` dma channels to hide the fact we have only a limited - * number of DMA channels, and not of all of them (dependant on the device) + * number of DMA channels, and not of all of them (dependent on the device) * can be attached to any DMA source. We therefore let the DMA core handle * the allocation of hardware channels to clients. */ diff --git a/arch/arm/mach-s3c2410/include/mach/regs-mem.h b/arch/arm/mach-s3c2410/include/mach/regs-mem.h index 7f7c52947963..988a6863e54b 100644 --- a/arch/arm/mach-s3c2410/include/mach/regs-mem.h +++ b/arch/arm/mach-s3c2410/include/mach/regs-mem.h @@ -101,7 +101,7 @@ #define S3C2410_BANKCON_PMC16 (0x03) /* bank configurations for banks 0..7, note banks - * 6 and 7 have differnt configurations depending on + * 6 and 7 have different configurations depending on * the memory type bits */ #define S3C2410_BANKCON_Tacp2 (0x0 << 2) diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c index 66f44440d5d3..079dcaa602d3 100644 --- a/arch/arm/mach-s3c2410/mach-n30.c +++ b/arch/arm/mach-s3c2410/mach-n30.c @@ -252,7 +252,7 @@ static struct s3c24xx_led_platdata n30_blue_led_pdata = { .def_trigger = "", }; -/* This is the blue LED on the device. Originaly used to indicate GPS activity +/* This is the blue LED on the device. Originally used to indicate GPS activity * by flashing. */ static struct s3c24xx_led_platdata n35_blue_led_pdata = { .name = "blue_led", diff --git a/arch/arm/mach-s3c2440/mach-mini2440.c b/arch/arm/mach-s3c2440/mach-mini2440.c index dfedc9c9e005..dd3120df09fe 100644 --- a/arch/arm/mach-s3c2440/mach-mini2440.c +++ b/arch/arm/mach-s3c2440/mach-mini2440.c @@ -155,7 +155,7 @@ static struct s3c2410fb_display mini2440_lcd_cfg[] __initdata = { * the same timings, however, anything smaller than 1024x768 * will only be displayed in the top left corner of a 1024x768 * XGA output unless you add optional dip switches to the shield. - * Therefore timings for other resolutions have been ommited here. + * Therefore timings for other resolutions have been omitted here. */ [2] = { _LCD_DECLARE( diff --git a/arch/arm/mach-s3c64xx/dma.c b/arch/arm/mach-s3c64xx/dma.c index c35585cf8c4f..b197171e7d03 100644 --- a/arch/arm/mach-s3c64xx/dma.c +++ b/arch/arm/mach-s3c64xx/dma.c @@ -315,7 +315,7 @@ int s3c2410_dma_ctrl(unsigned int channel, enum s3c2410_chan_op op) case S3C2410_DMAOP_FLUSH: return s3c64xx_dma_flush(chan); - /* belive PAUSE/RESUME are no-ops */ + /* believe PAUSE/RESUME are no-ops */ case S3C2410_DMAOP_PAUSE: case S3C2410_DMAOP_RESUME: case S3C2410_DMAOP_STARTED: diff --git a/arch/arm/mach-s5pc100/include/mach/regs-fb.h b/arch/arm/mach-s5pc100/include/mach/regs-fb.h index 4be4cc9abf75..07aa4d6054fe 100644 --- a/arch/arm/mach-s5pc100/include/mach/regs-fb.h +++ b/arch/arm/mach-s5pc100/include/mach/regs-fb.h @@ -29,7 +29,7 @@ #define WPALCON_H (0x19c) #define WPALCON_L (0x1a0) -/* Pallete contro for WPAL0 and WPAL1 is the same as in S3C64xx, but +/* Palette control for WPAL0 and WPAL1 is the same as in S3C64xx, but * different for WPAL2-4 */ /* In WPALCON_L (aka WPALCON) */ diff --git a/arch/arm/mach-s5pc100/setup-sdhci.c b/arch/arm/mach-s5pc100/setup-sdhci.c index f16946e456e9..be25879bb2ee 100644 --- a/arch/arm/mach-s5pc100/setup-sdhci.c +++ b/arch/arm/mach-s5pc100/setup-sdhci.c @@ -40,7 +40,7 @@ void s5pc100_setup_sdhci0_cfg_card(struct platform_device *dev, { u32 ctrl2, ctrl3; - /* don't need to alter anything acording to card-type */ + /* don't need to alter anything according to card-type */ writel(S3C64XX_SDHCI_CONTROL4_DRIVE_9mA, r + S3C64XX_SDHCI_CONTROL4); diff --git a/arch/arm/mach-s5pv210/include/mach/gpio.h b/arch/arm/mach-s5pv210/include/mach/gpio.h index 1f4b595534c2..a5a1e331f8ed 100644 --- a/arch/arm/mach-s5pv210/include/mach/gpio.h +++ b/arch/arm/mach-s5pv210/include/mach/gpio.h @@ -18,7 +18,7 @@ #define gpio_cansleep __gpio_cansleep #define gpio_to_irq __gpio_to_irq -/* Practically, GPIO banks upto MP03 are the configurable gpio banks */ +/* Practically, GPIO banks up to MP03 are the configurable gpio banks */ /* GPIO bank sizes */ #define S5PV210_GPIO_A0_NR (8) diff --git a/arch/arm/mach-s5pv210/setup-sdhci-gpio.c b/arch/arm/mach-s5pv210/setup-sdhci-gpio.c index 746777d56df9..3e3ac05bb7b1 100644 --- a/arch/arm/mach-s5pv210/setup-sdhci-gpio.c +++ b/arch/arm/mach-s5pv210/setup-sdhci-gpio.c @@ -32,10 +32,10 @@ void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width) switch (width) { case 8: - /* GPG1[3:6] special-funtion 3 */ + /* GPG1[3:6] special-function 3 */ s3c_gpio_cfgrange_nopull(S5PV210_GPG1(3), 4, S3C_GPIO_SFN(3)); case 4: - /* GPG0[3:6] special-funtion 2 */ + /* GPG0[3:6] special-function 2 */ s3c_gpio_cfgrange_nopull(S5PV210_GPG0(3), 4, S3C_GPIO_SFN(2)); default: break; diff --git a/arch/arm/mach-s5pv210/setup-sdhci.c b/arch/arm/mach-s5pv210/setup-sdhci.c index c32e202731c1..a83b6c909f6b 100644 --- a/arch/arm/mach-s5pv210/setup-sdhci.c +++ b/arch/arm/mach-s5pv210/setup-sdhci.c @@ -38,7 +38,7 @@ void s5pv210_setup_sdhci_cfg_card(struct platform_device *dev, { u32 ctrl2, ctrl3; - /* don't need to alter anything acording to card-type */ + /* don't need to alter anything according to card-type */ writel(S3C64XX_SDHCI_CONTROL4_DRIVE_9mA, r + S3C64XX_SDHCI_CONTROL4); diff --git a/arch/arm/mach-sa1100/Makefile b/arch/arm/mach-sa1100/Makefile index e697691eed28..41252d22e659 100644 --- a/arch/arm/mach-sa1100/Makefile +++ b/arch/arm/mach-sa1100/Makefile @@ -50,7 +50,7 @@ led-$(CONFIG_SA1100_SIMPAD) += leds-simpad.o # LEDs support obj-$(CONFIG_LEDS) += $(led-y) -# Miscelaneous functions +# Miscellaneous functions obj-$(CONFIG_PM) += pm.o sleep.o obj-$(CONFIG_SA1100_SSP) += ssp.o diff --git a/arch/arm/mach-sa1100/cpu-sa1100.c b/arch/arm/mach-sa1100/cpu-sa1100.c index 07d4e8ba3719..aaa8acf76b7b 100644 --- a/arch/arm/mach-sa1100/cpu-sa1100.c +++ b/arch/arm/mach-sa1100/cpu-sa1100.c @@ -68,7 +68,7 @@ * clock change in ROM and jump to that code from the kernel. The main * disadvantage is that the ROM has to be modified, which is not * possible on all SA-1100 platforms. Another disadvantage is that - * jumping to ROM makes clock switching unecessary complicated. + * jumping to ROM makes clock switching unnecessary complicated. * * The idea behind this driver is that the memory configuration can be * changed while running from DRAM (even with interrupts turned on!) diff --git a/arch/arm/mach-sa1100/include/mach/SA-1100.h b/arch/arm/mach-sa1100/include/mach/SA-1100.h index 4f7ea012e1e5..bae8296f5dbf 100644 --- a/arch/arm/mach-sa1100/include/mach/SA-1100.h +++ b/arch/arm/mach-sa1100/include/mach/SA-1100.h @@ -1794,7 +1794,7 @@ (DDAR_DevRd + DDAR_Brst4 + DDAR_16BitDev + \ DDAR_Ser4SSPRc + DDAR_DevAdd (__PREG(Ser4SSDR))) -#define DCSR_RUN 0x00000001 /* DMA RUNing */ +#define DCSR_RUN 0x00000001 /* DMA running */ #define DCSR_IE 0x00000002 /* DMA Interrupt Enable */ #define DCSR_ERROR 0x00000004 /* DMA ERROR */ #define DCSR_DONEA 0x00000008 /* DONE DMA transfer buffer A */ diff --git a/arch/arm/mach-sa1100/jornada720_ssp.c b/arch/arm/mach-sa1100/jornada720_ssp.c index 9d490c66891c..f50b00bd18a0 100644 --- a/arch/arm/mach-sa1100/jornada720_ssp.c +++ b/arch/arm/mach-sa1100/jornada720_ssp.c @@ -29,7 +29,7 @@ static unsigned long jornada_ssp_flags; /** * jornada_ssp_reverse - reverses input byte * - * we need to reverse all data we recieve from the mcu due to its physical location + * we need to reverse all data we receive from the mcu due to its physical location * returns : 01110111 -> 11101110 */ u8 inline jornada_ssp_reverse(u8 byte) @@ -179,7 +179,7 @@ static int __devinit jornada_ssp_probe(struct platform_device *dev) static int jornada_ssp_remove(struct platform_device *dev) { - /* Note that this doesnt actually remove the driver, since theres nothing to remove + /* Note that this doesn't actually remove the driver, since theres nothing to remove * It just makes sure everything is turned off */ GPSR = GPIO_GPIO25; ssp_exit(); diff --git a/arch/arm/mach-tegra/dma.c b/arch/arm/mach-tegra/dma.c index e945ae28ee77..f4ef5eb317bd 100644 --- a/arch/arm/mach-tegra/dma.c +++ b/arch/arm/mach-tegra/dma.c @@ -223,7 +223,7 @@ int tegra_dma_dequeue_req(struct tegra_dma_channel *ch, * - Change the source selector to invalid to stop the DMA from * FIFO to memory. * - Read the status register to know the number of pending - * bytes to be transfered. + * bytes to be transferred. * - Finally stop or program the DMA to the next buffer in the * list. */ @@ -244,7 +244,7 @@ int tegra_dma_dequeue_req(struct tegra_dma_channel *ch, if (status & STA_BUSY) req->bytes_transferred -= to_transfer; - /* In continous transfer mode, DMA only tracks the count of the + /* In continuous transfer mode, DMA only tracks the count of the * half DMA buffer. So, if the DMA already finished half the DMA * then add the half buffer to the completed count. * diff --git a/arch/arm/mach-tegra/include/mach/dma.h b/arch/arm/mach-tegra/include/mach/dma.h index 39011bd9a925..d0132e8031a1 100644 --- a/arch/arm/mach-tegra/include/mach/dma.h +++ b/arch/arm/mach-tegra/include/mach/dma.h @@ -92,11 +92,11 @@ struct tegra_dma_req { /* This is a called from the DMA ISR context when the DMA is still in * progress and is actively filling same buffer. * - * In case of continous mode receive, this threshold is 1/2 the buffer + * In case of continuous mode receive, this threshold is 1/2 the buffer * size. In other cases, this will not even be called as there is no * hardware support for it. * - * In the case of continous mode receive, if there is next req already + * In the case of continuous mode receive, if there is next req already * queued, DMA programs the HW to use that req when this req is * completed. If there is no "next req" queued, then DMA ISR doesn't do * anything before calling this callback. diff --git a/arch/arm/mach-u300/clock.c b/arch/arm/mach-u300/clock.c index fabcc49abe80..5535dd0a78c9 100644 --- a/arch/arm/mach-u300/clock.c +++ b/arch/arm/mach-u300/clock.c @@ -263,7 +263,7 @@ static void disable_i2s0_vcxo(void) val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR); val &= ~U300_SYSCON_CCR_I2S0_USE_VCXO; writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR); - /* Deactivate VCXO if noone else is using VCXO */ + /* Deactivate VCXO if no one else is using VCXO */ if (!(val & U300_SYSCON_CCR_I2S1_USE_VCXO)) val &= ~U300_SYSCON_CCR_TURN_VCXO_ON; writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR); @@ -283,7 +283,7 @@ static void disable_i2s1_vcxo(void) val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR); val &= ~U300_SYSCON_CCR_I2S1_USE_VCXO; writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR); - /* Deactivate VCXO if noone else is using VCXO */ + /* Deactivate VCXO if no one else is using VCXO */ if (!(val & U300_SYSCON_CCR_I2S0_USE_VCXO)) val &= ~U300_SYSCON_CCR_TURN_VCXO_ON; writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR); @@ -649,7 +649,7 @@ static unsigned long clk_round_rate_cpuclk(struct clk *clk, unsigned long rate) */ long clk_round_rate(struct clk *clk, unsigned long rate) { - /* TODO: get apropriate switches for EMIFCLK, AHBCLK and MCLK */ + /* TODO: get appropriate switches for EMIFCLK, AHBCLK and MCLK */ /* Else default to fixed value */ if (clk->round_rate) { diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index dc8746d7826e..af913741e6ec 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -52,7 +52,7 @@ static struct ab8500_gpio_platform_data ab8500_gpio_pdata = { * on value present in GpioSel1 to GpioSel6 and AlternatFunction * register. This is the array of 7 configuration settings. * One has to compile time decide these settings. Below is the - * explaination of these setting + * explanation of these setting * GpioSel1 = 0x00 => Pins GPIO1 to GPIO8 are not used as GPIO * GpioSel2 = 0x1E => Pins GPIO10 to GPIO13 are configured as GPIO * GpioSel3 = 0x80 => Pin GPIO24 is configured as GPIO diff --git a/arch/arm/mach-ux500/include/mach/db8500-regs.h b/arch/arm/mach-ux500/include/mach/db8500-regs.h index 0fefb34c11e4..16647b255378 100644 --- a/arch/arm/mach-ux500/include/mach/db8500-regs.h +++ b/arch/arm/mach-ux500/include/mach/db8500-regs.h @@ -58,7 +58,7 @@ #define U8500_GPIO2_BASE (U8500_PER2_BASE + 0xE000) #define U8500_GPIO3_BASE (U8500_PER5_BASE + 0x1E000) -/* per7 base addressess */ +/* per7 base addresses */ #define U8500_CR_BASE_ED (U8500_PER7_BASE_ED + 0x8000) #define U8500_MTU0_BASE_ED (U8500_PER7_BASE_ED + 0xa000) #define U8500_MTU1_BASE_ED (U8500_PER7_BASE_ED + 0xb000) @@ -68,7 +68,7 @@ #define U8500_UART0_BASE (U8500_PER1_BASE + 0x0000) #define U8500_UART1_BASE (U8500_PER1_BASE + 0x1000) -/* per6 base addressess */ +/* per6 base addresses */ #define U8500_RNG_BASE (U8500_PER6_BASE + 0x0000) #define U8500_PKA_BASE (U8500_PER6_BASE + 0x1000) #define U8500_PKAM_BASE (U8500_PER6_BASE + 0x2000) @@ -79,11 +79,11 @@ #define U8500_CRYPTO1_BASE (U8500_PER6_BASE + 0xb000) #define U8500_CLKRST6_BASE (U8500_PER6_BASE + 0xf000) -/* per5 base addressess */ +/* per5 base addresses */ #define U8500_USBOTG_BASE (U8500_PER5_BASE + 0x00000) #define U8500_CLKRST5_BASE (U8500_PER5_BASE + 0x1f000) -/* per4 base addressess */ +/* per4 base addresses */ #define U8500_BACKUPRAM0_BASE (U8500_PER4_BASE + 0x00000) #define U8500_BACKUPRAM1_BASE (U8500_PER4_BASE + 0x01000) #define U8500_RTT0_BASE (U8500_PER4_BASE + 0x02000) @@ -106,7 +106,7 @@ #define U8500_SDI5_BASE (U8500_PER3_BASE + 0x8000) #define U8500_CLKRST3_BASE (U8500_PER3_BASE + 0xf000) -/* per2 base addressess */ +/* per2 base addresses */ #define U8500_I2C3_BASE (U8500_PER2_BASE + 0x0000) #define U8500_SPI2_BASE (U8500_PER2_BASE + 0x1000) #define U8500_SPI1_BASE (U8500_PER2_BASE + 0x2000) diff --git a/arch/arm/mm/cache-v4wb.S b/arch/arm/mm/cache-v4wb.S index d3644db467b7..f40c69656d8d 100644 --- a/arch/arm/mm/cache-v4wb.S +++ b/arch/arm/mm/cache-v4wb.S @@ -32,7 +32,7 @@ /* * This is the size at which it becomes more efficient to * clean the whole cache, rather than using the individual - * cache line maintainence instructions. + * cache line maintenance instructions. * * Size Clean (ticks) Dirty (ticks) * 4096 21 20 21 53 55 54 diff --git a/arch/arm/mm/cache-v4wt.S b/arch/arm/mm/cache-v4wt.S index 49c2b66cf3dd..a7b276dbda11 100644 --- a/arch/arm/mm/cache-v4wt.S +++ b/arch/arm/mm/cache-v4wt.S @@ -34,7 +34,7 @@ /* * This is the size at which it becomes more efficient to * clean the whole cache, rather than using the individual - * cache line maintainence instructions. + * cache line maintenance instructions. * * *** This needs benchmarking */ diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S index 6136e68ce953..dc18d81ef8ce 100644 --- a/arch/arm/mm/cache-v7.S +++ b/arch/arm/mm/cache-v7.S @@ -96,7 +96,7 @@ ENDPROC(v7_flush_dcache_all) * Flush the entire cache system. * The data cache flush is now achieved using atomic clean / invalidates * working outwards from L1 cache. This is done using Set/Way based cache - * maintainance instructions. + * maintenance instructions. * The instruction cache can still be invalidated back to the point of * unification in a single instruction. * diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S index 226e3d8351c2..6c4e7fd6c8af 100644 --- a/arch/arm/mm/proc-arm1020.S +++ b/arch/arm/mm/proc-arm1020.S @@ -64,7 +64,7 @@ /* * This is the size at which it becomes more efficient to * clean the whole cache, rather than using the individual - * cache line maintainence instructions. + * cache line maintenance instructions. */ #define CACHE_DLIMIT 32768 diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S index 86d9c2cf0bce..4ce947c19623 100644 --- a/arch/arm/mm/proc-arm1020e.S +++ b/arch/arm/mm/proc-arm1020e.S @@ -64,7 +64,7 @@ /* * This is the size at which it becomes more efficient to * clean the whole cache, rather than using the individual - * cache line maintainence instructions. + * cache line maintenance instructions. */ #define CACHE_DLIMIT 32768 diff --git a/arch/arm/mm/proc-arm1022.S b/arch/arm/mm/proc-arm1022.S index 83d3dd34f846..c8884c5413a2 100644 --- a/arch/arm/mm/proc-arm1022.S +++ b/arch/arm/mm/proc-arm1022.S @@ -53,7 +53,7 @@ /* * This is the size at which it becomes more efficient to * clean the whole cache, rather than using the individual - * cache line maintainence instructions. + * cache line maintenance instructions. */ #define CACHE_DLIMIT 32768 diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S index 686043ee7281..413684660aad 100644 --- a/arch/arm/mm/proc-arm1026.S +++ b/arch/arm/mm/proc-arm1026.S @@ -53,7 +53,7 @@ /* * This is the size at which it becomes more efficient to * clean the whole cache, rather than using the individual - * cache line maintainence instructions. + * cache line maintenance instructions. */ #define CACHE_DLIMIT 32768 diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S index 665266da143c..7a06e5964f59 100644 --- a/arch/arm/mm/proc-arm720.S +++ b/arch/arm/mm/proc-arm720.S @@ -63,7 +63,7 @@ ENTRY(cpu_arm720_proc_fin) /* * Function: arm720_proc_do_idle(void) * Params : r0 = unused - * Purpose : put the processer in proper idle mode + * Purpose : put the processor in proper idle mode */ ENTRY(cpu_arm720_do_idle) mov pc, lr diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S index 219980ec8b6e..b46eb21f05c7 100644 --- a/arch/arm/mm/proc-arm920.S +++ b/arch/arm/mm/proc-arm920.S @@ -53,7 +53,7 @@ /* * This is the size at which it becomes more efficient to * clean the whole cache, rather than using the individual - * cache line maintainence instructions. + * cache line maintenance instructions. */ #define CACHE_DLIMIT 65536 diff --git a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S index 36154b1e792a..95ba1fc56e4d 100644 --- a/arch/arm/mm/proc-arm922.S +++ b/arch/arm/mm/proc-arm922.S @@ -54,7 +54,7 @@ /* * This is the size at which it becomes more efficient to * clean the whole cache, rather than using the individual - * cache line maintainence instructions. (I think this should + * cache line maintenance instructions. (I think this should * be 32768). */ #define CACHE_DLIMIT 8192 diff --git a/arch/arm/mm/proc-arm925.S b/arch/arm/mm/proc-arm925.S index 89c5e0009c4c..541e4774eea1 100644 --- a/arch/arm/mm/proc-arm925.S +++ b/arch/arm/mm/proc-arm925.S @@ -77,7 +77,7 @@ /* * This is the size at which it becomes more efficient to * clean the whole cache, rather than using the individual - * cache line maintainence instructions. + * cache line maintenance instructions. */ #define CACHE_DLIMIT 8192 diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S index e32fa499194c..34261f9486b9 100644 --- a/arch/arm/mm/proc-macros.S +++ b/arch/arm/mm/proc-macros.S @@ -85,7 +85,7 @@ /* * Sanity check the PTE configuration for the code below - which makes - * certain assumptions about how these bits are layed out. + * certain assumptions about how these bits are laid out. */ #ifdef CONFIG_MMU #if L_PTE_SHARED != PTE_EXT_SHARED diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index 832b6bdc192c..bfa0c9f611c5 100644 --- a/arch/arm/mm/proc-v6.S +++ b/arch/arm/mm/proc-v6.S @@ -132,7 +132,7 @@ ENTRY(cpu_v6_do_suspend) mrc p15, 0, r6, c3, c0, 0 @ Domain ID mrc p15, 0, r7, c2, c0, 0 @ Translation table base 0 mrc p15, 0, r8, c2, c0, 1 @ Translation table base 1 - mrc p15, 0, r9, c1, c0, 1 @ auxillary control register + mrc p15, 0, r9, c1, c0, 1 @ auxiliary control register mrc p15, 0, r10, c1, c0, 2 @ co-processor access control mrc p15, 0, r11, c1, c0, 0 @ control register stmia r0, {r4 - r11} @@ -151,7 +151,7 @@ ENTRY(cpu_v6_do_resume) mcr p15, 0, r6, c3, c0, 0 @ Domain ID mcr p15, 0, r7, c2, c0, 0 @ Translation table base 0 mcr p15, 0, r8, c2, c0, 1 @ Translation table base 1 - mcr p15, 0, r9, c1, c0, 1 @ auxillary control register + mcr p15, 0, r9, c1, c0, 1 @ auxiliary control register mcr p15, 0, r10, c1, c0, 2 @ co-processor access control mcr p15, 0, ip, c2, c0, 2 @ TTB control register mcr p15, 0, ip, c7, c5, 4 @ ISB diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index 262fa88a7439..c35618e42f6f 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S @@ -237,7 +237,7 @@ ENTRY(cpu_v7_do_resume) mcr p15, 0, r7, c2, c0, 0 @ TTB 0 mcr p15, 0, r8, c2, c0, 1 @ TTB 1 mcr p15, 0, ip, c2, c0, 2 @ TTB control register - mcr p15, 0, r10, c1, c0, 1 @ Auxillary control register + mcr p15, 0, r10, c1, c0, 1 @ Auxiliary control register mcr p15, 0, r11, c1, c0, 2 @ Co-processor access control ldr r4, =PRRR @ PRRR ldr r5, =NMRR @ NMRR diff --git a/arch/arm/plat-mxc/cpufreq.c b/arch/arm/plat-mxc/cpufreq.c index ce81481becf1..4268a2bdf145 100644 --- a/arch/arm/plat-mxc/cpufreq.c +++ b/arch/arm/plat-mxc/cpufreq.c @@ -13,7 +13,7 @@ /* * A driver for the Freescale Semiconductor i.MXC CPUfreq module. - * The CPUFREQ driver is for controling CPU frequency. It allows you to change + * The CPUFREQ driver is for controlling CPU frequency. It allows you to change * the CPU clock speed on the fly. */ diff --git a/arch/arm/plat-mxc/include/mach/entry-macro.S b/arch/arm/plat-mxc/include/mach/entry-macro.S index bd9bb9799141..2e49e71b1b98 100644 --- a/arch/arm/plat-mxc/include/mach/entry-macro.S +++ b/arch/arm/plat-mxc/include/mach/entry-macro.S @@ -33,9 +33,9 @@ .macro arch_ret_to_user, tmp1, tmp2 .endm - @ this macro checks which interrupt occured + @ this macro checks which interrupt occurred @ and returns its number in irqnr - @ and returns if an interrupt occured in irqstat + @ and returns if an interrupt occurred in irqstat .macro get_irqnr_and_base, irqnr, irqstat, base, tmp #ifndef CONFIG_MXC_TZIC @ Load offset & priority of the highest priority diff --git a/arch/arm/plat-mxc/include/mach/mxc_nand.h b/arch/arm/plat-mxc/include/mach/mxc_nand.h index 04c0d060d814..6bb96ef1600b 100644 --- a/arch/arm/plat-mxc/include/mach/mxc_nand.h +++ b/arch/arm/plat-mxc/include/mach/mxc_nand.h @@ -24,7 +24,7 @@ struct mxc_nand_platform_data { unsigned int width; /* data bus width in bytes */ - unsigned int hw_ecc:1; /* 0 if supress hardware ECC */ + unsigned int hw_ecc:1; /* 0 if suppress hardware ECC */ unsigned int flash_bbt:1; /* set to 1 to use a flash based bbt */ struct mtd_partition *parts; /* partition table */ int nr_parts; /* size of parts */ diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c index 7d9f815cedec..ea28f98d5d6a 100644 --- a/arch/arm/plat-omap/devices.c +++ b/arch/arm/plat-omap/devices.c @@ -280,7 +280,7 @@ EXPORT_SYMBOL(omap_dsp_get_mempool_base); * Claiming GPIOs, and setting their direction and initial values, is the * responsibility of the device drivers. So is responding to probe(). * - * Board-specific knowlege like creating devices or pin setup is to be + * Board-specific knowledge like creating devices or pin setup is to be * kept out of drivers as much as possible. In particular, pin setup * may be handled by the boot loader, and drivers should expect it will * normally have been done by the time they're probed. diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index 2ec3b5d9f214..c22217c2ee5f 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -1019,7 +1019,7 @@ EXPORT_SYMBOL(omap_set_dma_callback); * If the channel is running the caller must disable interrupts prior calling * this function and process the returned value before re-enabling interrupt to * prevent races with the interrupt handler. Note that in continuous mode there - * is a chance for CSSA_L register overflow inbetween the two reads resulting + * is a chance for CSSA_L register overflow between the two reads resulting * in incorrect return value. */ dma_addr_t omap_get_dma_src_pos(int lch) @@ -1046,7 +1046,7 @@ EXPORT_SYMBOL(omap_get_dma_src_pos); * If the channel is running the caller must disable interrupts prior calling * this function and process the returned value before re-enabling interrupt to * prevent races with the interrupt handler. Note that in continuous mode there - * is a chance for CDSA_L register overflow inbetween the two reads resulting + * is a chance for CDSA_L register overflow between the two reads resulting * in incorrect return value. */ dma_addr_t omap_get_dma_dst_pos(int lch) diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h index d6f9fa0f62af..cac2e8ac6968 100644 --- a/arch/arm/plat-omap/include/plat/gpio.h +++ b/arch/arm/plat-omap/include/plat/gpio.h @@ -93,7 +93,7 @@ extern void omap_gpio_restore_context(void); /* Wrappers for "new style" GPIO calls, using the new infrastructure * which lets us plug in FPGA, I2C, and other implementations. * * - * The original OMAP-specfic calls should eventually be removed. + * The original OMAP-specific calls should eventually be removed. */ #include diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index 12b316165037..1527929b445a 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -90,7 +90,7 @@ enum omap_ecc { /* 1-bit ecc: stored at end of spare area */ OMAP_ECC_HAMMING_CODE_DEFAULT = 0, /* Default, s/w method */ OMAP_ECC_HAMMING_CODE_HW, /* gpmc to detect the error */ - /* 1-bit ecc: stored at begining of spare area as romcode */ + /* 1-bit ecc: stored at beginning of spare area as romcode */ OMAP_ECC_HAMMING_CODE_HW_ROMCODE, /* gpmc method & romcode layout */ }; diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index d598d9fd65ac..5587acf0eb2c 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c @@ -1103,7 +1103,7 @@ int omap_mcbsp_pollread(unsigned int id, u16 *buf) /* resend */ return -1; } else { - /* wait for recieve confirmation */ + /* wait for receive confirmation */ int attemps = 0; while (!(MCBSP_READ(mcbsp, SPCR1) & RRDY)) { if (attemps++ > 1000) { diff --git a/arch/arm/plat-pxa/include/plat/mfp.h b/arch/arm/plat-pxa/include/plat/mfp.h index 75f656471240..89e68e07b0a8 100644 --- a/arch/arm/plat-pxa/include/plat/mfp.h +++ b/arch/arm/plat-pxa/include/plat/mfp.h @@ -434,7 +434,7 @@ typedef unsigned long mfp_cfg_t; * * mfp_init_addr() - accepts a table of "mfp_addr_map" structure, which * represents a range of MFP pins from "start" to "end", with the offset - * begining at "offset", to define a single pin, let "end" = -1. + * beginning at "offset", to define a single pin, let "end" = -1. * * use * diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile index c2064c308719..0291bd6e236e 100644 --- a/arch/arm/plat-s3c24xx/Makefile +++ b/arch/arm/plat-s3c24xx/Makefile @@ -23,7 +23,7 @@ obj-$(CONFIG_S3C24XX_DCLK) += clock-dclk.o obj-$(CONFIG_CPU_FREQ_S3C24XX) += cpu-freq.o obj-$(CONFIG_CPU_FREQ_S3C24XX_DEBUGFS) += cpu-freq-debugfs.o -# Architecture dependant builds +# Architecture dependent builds obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o obj-$(CONFIG_PM) += pm.o diff --git a/arch/arm/plat-s3c24xx/cpu-freq.c b/arch/arm/plat-s3c24xx/cpu-freq.c index eea75ff81d15..b3d3d0278997 100644 --- a/arch/arm/plat-s3c24xx/cpu-freq.c +++ b/arch/arm/plat-s3c24xx/cpu-freq.c @@ -455,7 +455,7 @@ static int s3c_cpufreq_resume(struct cpufreq_policy *policy) /* whilst we will be called later on, we try and re-set the * cpu frequencies as soon as possible so that we do not end - * up resuming devices and then immediatley having to re-set + * up resuming devices and then immediately having to re-set * a number of settings once these devices have restarted. * * as a note, it is expected devices are not used until they diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c index 6ad274e7593d..27ea852e3370 100644 --- a/arch/arm/plat-s3c24xx/dma.c +++ b/arch/arm/plat-s3c24xx/dma.c @@ -557,7 +557,7 @@ s3c2410_dma_lastxfer(struct s3c2410_dma_chan *chan) break; case S3C2410_DMALOAD_1LOADED_1RUNNING: - /* I belive in this case we do not have anything to do + /* I believe in this case we do not have anything to do * until the next buffer comes along, and we turn off the * reload */ return; diff --git a/arch/arm/plat-s5p/irq-gpioint.c b/arch/arm/plat-s5p/irq-gpioint.c index 46dd078147d8..cd6d67c8382a 100644 --- a/arch/arm/plat-s5p/irq-gpioint.c +++ b/arch/arm/plat-s5p/irq-gpioint.c @@ -208,7 +208,7 @@ static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip) } /* - * chained GPIO irq has been sucessfully registered, allocate new gpio + * chained GPIO irq has been successfully registered, allocate new gpio * int group and assign irq nubmers */ diff --git a/arch/arm/plat-samsung/include/plat/clock.h b/arch/arm/plat-samsung/include/plat/clock.h index 9a82b8874918..983c578b8276 100644 --- a/arch/arm/plat-samsung/include/plat/clock.h +++ b/arch/arm/plat-samsung/include/plat/clock.h @@ -21,7 +21,7 @@ struct clk; * @set_parent: set the clock's parent, see clk_set_parent(). * * Group the common clock implementations together so that we - * don't have to keep setting the same fiels again. We leave + * don't have to keep setting the same fields again. We leave * enable in struct clk. * * Adding an extra layer of indirection into the process should diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h index 5603db0b79bc..3ad8386599c3 100644 --- a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h +++ b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h @@ -114,7 +114,7 @@ extern unsigned s3c_gpio_getcfg_s3c24xx_a(struct s3c_gpio_chip *chip, * of control per GPIO, generally in the form of: * 0000 = Input * 0001 = Output - * others = Special functions (dependant on bank) + * others = Special functions (dependent on bank) * * Note, since the code to deal with the case where there are two control * registers instead of one, we do not have a separate set of functions for diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg.h b/arch/arm/plat-samsung/include/plat/gpio-cfg.h index 5e04fa6eda74..1762dcb4cb9e 100644 --- a/arch/arm/plat-samsung/include/plat/gpio-cfg.h +++ b/arch/arm/plat-samsung/include/plat/gpio-cfg.h @@ -125,7 +125,7 @@ extern int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr, * * These values control the state of the weak pull-{up,down} resistors * available on most pins on the S3C series. Not all chips support both - * up or down settings, and it may be dependant on the chip that is being + * up or down settings, and it may be dependent on the chip that is being * used to whether the particular mode is available. */ #define S3C_GPIO_PULL_NONE ((__force s3c_gpio_pull_t)0x00) @@ -138,7 +138,7 @@ extern int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr, * @pull: The configuration for the pull resistor. * * This function sets the state of the pull-{up,down} resistor for the - * specified pin. It will return 0 if successfull, or a negative error + * specified pin. It will return 0 if successful, or a negative error * code if the pin cannot support the requested pull setting. * * @pull is one of S3C_GPIO_PULL_NONE, S3C_GPIO_PULL_DOWN or S3C_GPIO_PULL_UP. @@ -202,7 +202,7 @@ extern s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin); * @drvstr: The new value of the driver strength * * This function sets the driver strength value for the specified pin. - * It will return 0 if successfull, or a negative error code if the pin + * It will return 0 if successful, or a negative error code if the pin * cannot support the requested setting. */ extern int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr); diff --git a/arch/arm/plat-samsung/include/plat/gpio-core.h b/arch/arm/plat-samsung/include/plat/gpio-core.h index dac35d0a711d..8cad4cf19c3c 100644 --- a/arch/arm/plat-samsung/include/plat/gpio-core.h +++ b/arch/arm/plat-samsung/include/plat/gpio-core.h @@ -108,7 +108,7 @@ extern void s3c_gpiolib_add(struct s3c_gpio_chip *chip); * of control per GPIO, generally in the form of: * 0000 = Input * 0001 = Output - * others = Special functions (dependant on bank) + * others = Special functions (dependent on bank) * * Note, since the code to deal with the case where there are two control * registers instead of one, we do not have a separate set of function diff --git a/arch/arm/plat-samsung/include/plat/sdhci.h b/arch/arm/plat-samsung/include/plat/sdhci.h index b0bdf16549d5..058e09654fe8 100644 --- a/arch/arm/plat-samsung/include/plat/sdhci.h +++ b/arch/arm/plat-samsung/include/plat/sdhci.h @@ -57,7 +57,7 @@ enum clk_types { * @cfg_gpio: Configure the GPIO for a specific card bit-width * @cfg_card: Configure the interface for a specific card and speed. This * is necessary the controllers and/or GPIO blocks require the - * changing of driver-strength and other controls dependant on + * changing of driver-strength and other controls dependent on * the card and speed of operation. * * Initialisation data specific to either the machine or the platform @@ -108,7 +108,7 @@ extern struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata; extern struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata; extern struct s3c_sdhci_platdata s3c_hsmmc3_def_platdata; -/* Helper function availablity */ +/* Helper function availability */ extern void s3c2416_setup_sdhci0_cfg_gpio(struct platform_device *, int w); extern void s3c2416_setup_sdhci1_cfg_gpio(struct platform_device *, int w); diff --git a/arch/arm/plat-samsung/s3c-pl330.c b/arch/arm/plat-samsung/s3c-pl330.c index b4ff8d74ac40..f85638c6f5ae 100644 --- a/arch/arm/plat-samsung/s3c-pl330.c +++ b/arch/arm/plat-samsung/s3c-pl330.c @@ -68,7 +68,7 @@ struct s3c_pl330_xfer { * @req: Two requests to communicate with the PL330 engine. * @callback_fn: Callback function to the client. * @rqcfg: Channel configuration for the xfers. - * @xfer_head: Pointer to the xfer to be next excecuted. + * @xfer_head: Pointer to the xfer to be next executed. * @dmac: Pointer to the DMAC that manages this channel, NULL if the * channel is available to be acquired. * @client: Client of this channel. NULL if the diff --git a/arch/arm/plat-spear/include/plat/clock.h b/arch/arm/plat-spear/include/plat/clock.h index 2ae6606930a6..fcc0d0ad4a1f 100644 --- a/arch/arm/plat-spear/include/plat/clock.h +++ b/arch/arm/plat-spear/include/plat/clock.h @@ -89,7 +89,7 @@ struct rate_config { * @sibling: node for list of clocks having same parents * @private_data: clock specific private data * @node: list to maintain clocks linearly - * @cl: clocklook up assoicated with this clock + * @cl: clocklook up associated with this clock * @dent: object for debugfs */ struct clk { diff --git a/arch/blackfin/Kconfig.debug b/arch/blackfin/Kconfig.debug index acb83799a215..2641731f24cd 100644 --- a/arch/blackfin/Kconfig.debug +++ b/arch/blackfin/Kconfig.debug @@ -59,7 +59,7 @@ config EXACT_HWERR be reported multiple cycles after the error happens. This delay can cause the wrong application, or even the kernel to receive a signal to be killed. If you are getting HW errors in your system, - try turning this on to ensure they are at least comming from the + try turning this on to ensure they are at least coming from the proper thread. On production systems, it is safe (and a small optimization) to say N. diff --git a/arch/blackfin/include/asm/traps.h b/arch/blackfin/include/asm/traps.h index 9fe0da612c09..70c4e511cae6 100644 --- a/arch/blackfin/include/asm/traps.h +++ b/arch/blackfin/include/asm/traps.h @@ -57,7 +57,7 @@ #define HWC_x3(level) \ "External Memory Addressing Error\n" #define EXC_0x04(level) \ - "Unimplmented exception occured\n" \ + "Unimplmented exception occurred\n" \ level " - Maybe you forgot to install a custom exception handler?\n" #define HWC_x12(level) \ "Performance Monitor Overflow\n" diff --git a/arch/blackfin/kernel/kgdb.c b/arch/blackfin/kernel/kgdb.c index b8cfe34989e4..9b80b152435e 100644 --- a/arch/blackfin/kernel/kgdb.c +++ b/arch/blackfin/kernel/kgdb.c @@ -181,7 +181,7 @@ static int bfin_set_hw_break(unsigned long addr, int len, enum kgdb_bptype type) return -ENOSPC; } - /* Becasue hardware data watchpoint impelemented in current + /* Because hardware data watchpoint impelemented in current * Blackfin can not trigger an exception event as the hardware * instrction watchpoint does, we ignaore all data watch point here. * They can be turned on easily after future blackfin design diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index 59c1df75e4de..655f25d139a7 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c @@ -98,7 +98,7 @@ asmlinkage notrace void trap_c(struct pt_regs *fp) /* send the appropriate signal to the user program */ switch (trapnr) { - /* This table works in conjuction with the one in ./mach-common/entry.S + /* This table works in conjunction with the one in ./mach-common/entry.S * Some exceptions are handled there (in assembly, in exception space) * Some are handled here, (in C, in interrupt space) * Some, like CPLB, are handled in both, where the normal path is diff --git a/arch/blackfin/lib/ins.S b/arch/blackfin/lib/ins.S index 3edbd8db6598..79caccea85ca 100644 --- a/arch/blackfin/lib/ins.S +++ b/arch/blackfin/lib/ins.S @@ -67,7 +67,7 @@ * - DMA version, which do not suffer from this issue. DMA versions have * different name (prefixed by dma_ ), and are located in * ../kernel/bfin_dma_5xx.c - * Using the dma related functions are recommended for transfering large + * Using the dma related functions are recommended for transferring large * buffers in/out of FIFOs. */ diff --git a/arch/blackfin/lib/memmove.S b/arch/blackfin/lib/memmove.S index 80c240acac60..4eca566237a4 100644 --- a/arch/blackfin/lib/memmove.S +++ b/arch/blackfin/lib/memmove.S @@ -60,7 +60,7 @@ ENTRY(_memmove) [P0++] = R1; CC = P2 == 0; /* any remaining bytes? */ - P3 = I0; /* Ammend P3 to updated ptr. */ + P3 = I0; /* Amend P3 to updated ptr. */ IF !CC JUMP .Lbytes; P3 = I1; RTS; diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 2c69785a7bbe..3fa335405b31 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -2530,7 +2530,7 @@ static struct resource bfin_pata_resources[] = { static struct pata_platform_info bfin_pata_platform_data = { .ioport_shift = 0, }; -/* CompactFlash Storage Card Memory Mapped Adressing +/* CompactFlash Storage Card Memory Mapped Addressing * /REG = A11 = 1 */ static struct resource bfin_pata_resources[] = { diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index 46ab45704c89..f96933f48a7f 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S @@ -268,7 +268,7 @@ ENTRY(_handle_bad_cplb) /* To get here, we just tried and failed to change a CPLB * so, handle things in trap_c (C code), by lowering to * IRQ5, just like we normally do. Since this is not a - * "normal" return path, we have a do alot of stuff to + * "normal" return path, we have a do a lot of stuff to * the stack to get ready so, we can fall through - we * need to make a CPLB exception look like a normal exception */ @@ -817,7 +817,7 @@ _new_old_task: rets = [sp++]; /* - * When we come out of resume, r0 carries "old" task, becuase we are + * When we come out of resume, r0 carries "old" task, because we are * in "new" task. */ rts; diff --git a/arch/blackfin/mach-common/head.S b/arch/blackfin/mach-common/head.S index 581e2b0a71ac..76de5724c1e3 100644 --- a/arch/blackfin/mach-common/head.S +++ b/arch/blackfin/mach-common/head.S @@ -174,7 +174,7 @@ ENTRY(__start) sp.l = lo(KERNEL_CLOCK_STACK); sp.h = hi(KERNEL_CLOCK_STACK); call _init_clocks; - sp = usp; /* usp hasnt been touched, so restore from there */ + sp = usp; /* usp hasn't been touched, so restore from there */ #endif /* This section keeps the processor in supervisor mode diff --git a/arch/cris/arch-v10/README.mm b/arch/cris/arch-v10/README.mm index 517d1f027fe8..67731d75cb51 100644 --- a/arch/cris/arch-v10/README.mm +++ b/arch/cris/arch-v10/README.mm @@ -38,7 +38,7 @@ space. We also use it to keep the user-mode virtual mapping in the same map during kernel-mode, so that the kernel easily can access the corresponding user-mode process' data. -As a comparision, the Linux/i386 2.0 puts the kernel and physical RAM at +As a comparison, the Linux/i386 2.0 puts the kernel and physical RAM at address 0, overlapping with the user-mode virtual space, so that descriptor registers are needed for each memory access to specify which MMU space to map through. That changed in 2.2, putting the kernel/physical RAM at diff --git a/arch/cris/arch-v10/drivers/sync_serial.c b/arch/cris/arch-v10/drivers/sync_serial.c index 399dc1ec8e6f..850265373611 100644 --- a/arch/cris/arch-v10/drivers/sync_serial.c +++ b/arch/cris/arch-v10/drivers/sync_serial.c @@ -31,7 +31,7 @@ #include #include -/* The receiver is a bit tricky beacuse of the continuous stream of data.*/ +/* The receiver is a bit tricky because of the continuous stream of data.*/ /* */ /* Three DMA descriptors are linked together. Each DMA descriptor is */ /* responsible for port->bufchunk of a common buffer. */ diff --git a/arch/cris/arch-v32/drivers/axisflashmap.c b/arch/cris/arch-v32/drivers/axisflashmap.c index 3d751250271b..7b155f8203b8 100644 --- a/arch/cris/arch-v32/drivers/axisflashmap.c +++ b/arch/cris/arch-v32/drivers/axisflashmap.c @@ -215,7 +215,7 @@ static struct mtd_partition main_partition = { }; #endif -/* Auxilliary partition if we find another flash */ +/* Auxiliary partition if we find another flash */ static struct mtd_partition aux_partition = { .name = "aux", .size = 0, diff --git a/arch/cris/arch-v32/drivers/mach-a3/nandflash.c b/arch/cris/arch-v32/drivers/mach-a3/nandflash.c index 25d6f2b3a721..f58f2c1c5295 100644 --- a/arch/cris/arch-v32/drivers/mach-a3/nandflash.c +++ b/arch/cris/arch-v32/drivers/mach-a3/nandflash.c @@ -165,7 +165,7 @@ struct mtd_info *__init crisv32_nand_flash_probe(void) /* Enable the following for a flash based bad block table */ /* this->options = NAND_USE_FLASH_BBT; */ - /* Scan to find existance of the device */ + /* Scan to find existence of the device */ if (nand_scan(crisv32_mtd, 1)) { err = -ENXIO; goto out_mtd; diff --git a/arch/cris/arch-v32/drivers/mach-fs/nandflash.c b/arch/cris/arch-v32/drivers/mach-fs/nandflash.c index c5a0f54763cc..d5b0cc9f976b 100644 --- a/arch/cris/arch-v32/drivers/mach-fs/nandflash.c +++ b/arch/cris/arch-v32/drivers/mach-fs/nandflash.c @@ -156,7 +156,7 @@ struct mtd_info *__init crisv32_nand_flash_probe(void) /* Enable the following for a flash based bad block table */ /* this->options = NAND_USE_FLASH_BBT; */ - /* Scan to find existance of the device */ + /* Scan to find existence of the device */ if (nand_scan(crisv32_mtd, 1)) { err = -ENXIO; goto out_ior; diff --git a/arch/cris/arch-v32/drivers/sync_serial.c b/arch/cris/arch-v32/drivers/sync_serial.c index c8637a9195ea..a6a180bc566f 100644 --- a/arch/cris/arch-v32/drivers/sync_serial.c +++ b/arch/cris/arch-v32/drivers/sync_serial.c @@ -33,7 +33,7 @@ #include -/* The receiver is a bit tricky beacuse of the continuous stream of data.*/ +/* The receiver is a bit tricky because of the continuous stream of data.*/ /* */ /* Three DMA descriptors are linked together. Each DMA descriptor is */ /* responsible for port->bufchunk of a common buffer. */ diff --git a/arch/cris/arch-v32/kernel/entry.S b/arch/cris/arch-v32/kernel/entry.S index 0ecb50b8f0d9..3abf12c23e5f 100644 --- a/arch/cris/arch-v32/kernel/entry.S +++ b/arch/cris/arch-v32/kernel/entry.S @@ -182,7 +182,7 @@ _syscall_traced: move.d $r0, [$sp] ;; The registers carrying parameters (R10-R13) are intact. The optional - ;; fifth and sixth parameters is in MOF and SRP respectivly. Put them + ;; fifth and sixth parameters is in MOF and SRP respectively. Put them ;; back on the stack. subq 4, $sp move $srp, [$sp] diff --git a/arch/cris/arch-v32/kernel/irq.c b/arch/cris/arch-v32/kernel/irq.c index 8023176e19b2..68a1a5901ca5 100644 --- a/arch/cris/arch-v32/kernel/irq.c +++ b/arch/cris/arch-v32/kernel/irq.c @@ -374,7 +374,7 @@ crisv32_do_multiple(struct pt_regs* regs) irq_enter(); for (i = 0; i < NBR_REGS; i++) { - /* Get which IRQs that happend. */ + /* Get which IRQs that happened. */ masked[i] = REG_RD_INT_VECT(intr_vect, irq_regs[cpu], r_masked_vect, i); diff --git a/arch/cris/arch-v32/kernel/kgdb.c b/arch/cris/arch-v32/kernel/kgdb.c index 6b653323d796..c0343c3ea7f8 100644 --- a/arch/cris/arch-v32/kernel/kgdb.c +++ b/arch/cris/arch-v32/kernel/kgdb.c @@ -925,7 +925,7 @@ stub_is_stopped(int sigval) if (reg.eda >= bp_d_regs[bp * 2] && reg.eda <= bp_d_regs[bp * 2 + 1]) { - /* EDA withing range for this BP; it must be the one + /* EDA within range for this BP; it must be the one we're looking for. */ stopped_data_address = reg.eda; break; diff --git a/arch/cris/arch-v32/kernel/process.c b/arch/cris/arch-v32/kernel/process.c index 562f84718906..0570e8ce603d 100644 --- a/arch/cris/arch-v32/kernel/process.c +++ b/arch/cris/arch-v32/kernel/process.c @@ -149,7 +149,7 @@ copy_thread(unsigned long clone_flags, unsigned long usp, childregs->r10 = 0; /* Child returns 0 after a fork/clone. */ /* Set a new TLS ? - * The TLS is in $mof beacuse it is the 5th argument to sys_clone. + * The TLS is in $mof because it is the 5th argument to sys_clone. */ if (p->mm && (clone_flags & CLONE_SETTLS)) { task_thread_info(p)->tls = regs->mof; diff --git a/arch/cris/arch-v32/kernel/signal.c b/arch/cris/arch-v32/kernel/signal.c index b3a05ae56214..ce4ab1a5552c 100644 --- a/arch/cris/arch-v32/kernel/signal.c +++ b/arch/cris/arch-v32/kernel/signal.c @@ -610,7 +610,7 @@ ugdb_trap_user(struct thread_info *ti, int sig) user_regs(ti)->spc = 0; } /* FIXME: Filter out false h/w breakpoint hits (i.e. EDA - not withing any configured h/w breakpoint range). Synchronize with + not within any configured h/w breakpoint range). Synchronize with what already exists for kernel debugging. */ if (((user_regs(ti)->exs & 0xff00) >> 8) == BREAK_8_INTR_VECT) { /* Break 8: subtract 2 from ERP unless in a delay slot. */ diff --git a/arch/cris/arch-v32/mach-a3/arbiter.c b/arch/cris/arch-v32/mach-a3/arbiter.c index 8b924db71c9a..15f5c9de2639 100644 --- a/arch/cris/arch-v32/mach-a3/arbiter.c +++ b/arch/cris/arch-v32/mach-a3/arbiter.c @@ -568,7 +568,7 @@ crisv32_foo_arbiter_irq(int irq, void *dev_id) REG_WR(marb_foo_bp, watch->instance, rw_ack, ack); REG_WR(marb_foo, regi_marb_foo, rw_ack_intr, ack_intr); - printk(KERN_DEBUG "IRQ occured at %X\n", (unsigned)get_irq_regs()); + printk(KERN_DEBUG "IRQ occurred at %X\n", (unsigned)get_irq_regs()); if (watch->cb) watch->cb(); @@ -624,7 +624,7 @@ crisv32_bar_arbiter_irq(int irq, void *dev_id) REG_WR(marb_bar_bp, watch->instance, rw_ack, ack); REG_WR(marb_bar, regi_marb_bar, rw_ack_intr, ack_intr); - printk(KERN_DEBUG "IRQ occured at %X\n", (unsigned)get_irq_regs()->erp); + printk(KERN_DEBUG "IRQ occurred at %X\n", (unsigned)get_irq_regs()->erp); if (watch->cb) watch->cb(); diff --git a/arch/cris/arch-v32/mach-fs/arbiter.c b/arch/cris/arch-v32/mach-fs/arbiter.c index 82ef293c4c81..3f8ebb5c1477 100644 --- a/arch/cris/arch-v32/mach-fs/arbiter.c +++ b/arch/cris/arch-v32/mach-fs/arbiter.c @@ -395,7 +395,7 @@ static irqreturn_t crisv32_arbiter_irq(int irq, void *dev_id) REG_WR(marb_bp, watch->instance, rw_ack, ack); REG_WR(marb, regi_marb, rw_ack_intr, ack_intr); - printk(KERN_INFO "IRQ occured at %lX\n", get_irq_regs()->erp); + printk(KERN_INFO "IRQ occurred at %lX\n", get_irq_regs()->erp); if (watch->cb) watch->cb(); diff --git a/arch/cris/boot/rescue/head_v10.S b/arch/cris/boot/rescue/head_v10.S index 2fafe247a25b..af55df0994b3 100644 --- a/arch/cris/boot/rescue/head_v10.S +++ b/arch/cris/boot/rescue/head_v10.S @@ -7,7 +7,7 @@ * for each partition that this code should check. * * If any of the checksums fail, we assume the flash is so - * corrupt that we cant use it to boot into the ftp flash + * corrupt that we can't use it to boot into the ftp flash * loader, and instead we initialize the serial port to * receive a flash-loader and new flash image. we dont include * any flash code here, but just accept a certain amount of diff --git a/arch/cris/include/arch-v32/arch/hwregs/Makefile b/arch/cris/include/arch-v32/arch/hwregs/Makefile index f9a05d2aa061..b8b3f8d666e4 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/Makefile +++ b/arch/cris/include/arch-v32/arch/hwregs/Makefile @@ -1,6 +1,6 @@ # Makefile to generate or copy the latest register definitions # and related datastructures and helpermacros. -# The offical place for these files is at: +# The official place for these files is at: RELEASE ?= r1_alfa5 OFFICIAL_INCDIR = /n/asic/projects/guinness/releases/$(RELEASE)/design/top/sw/include/ diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/Makefile b/arch/cris/include/arch-v32/arch/hwregs/iop/Makefile index a90056a095e3..0747a22e3c07 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/Makefile +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/Makefile @@ -1,7 +1,7 @@ # $Id: Makefile,v 1.3 2004/01/07 20:34:55 johana Exp $ # Makefile to generate or copy the latest register definitions # and related datastructures and helpermacros. -# The offical place for these files is probably at: +# The official place for these files is probably at: RELEASE ?= r1_alfa5 IOPOFFICIAL_INCDIR = /n/asic/projects/guinness/releases/$(RELEASE)/design/top/sw/include/ diff --git a/arch/cris/include/asm/pgtable.h b/arch/cris/include/asm/pgtable.h index 9eaae217b21b..7df430138355 100644 --- a/arch/cris/include/asm/pgtable.h +++ b/arch/cris/include/asm/pgtable.h @@ -97,7 +97,7 @@ extern unsigned long empty_zero_page; #define pte_clear(mm,addr,xp) do { pte_val(*(xp)) = 0; } while (0) #define pmd_none(x) (!pmd_val(x)) -/* by removing the _PAGE_KERNEL bit from the comparision, the same pmd_bad +/* by removing the _PAGE_KERNEL bit from the comparison, the same pmd_bad * works for both _PAGE_TABLE and _KERNPG_TABLE pmd entries. */ #define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_KERNEL)) != _PAGE_TABLE) diff --git a/arch/cris/kernel/traps.c b/arch/cris/kernel/traps.c index 541efbf09371..8da53f34c7a7 100644 --- a/arch/cris/kernel/traps.c +++ b/arch/cris/kernel/traps.c @@ -183,7 +183,7 @@ __initcall(oops_nmi_register); /* * This gets called from entry.S when the watchdog has bitten. Show something - * similiar to an Oops dump, and if the kernel is configured to be a nice + * similar to an Oops dump, and if the kernel is configured to be a nice * doggy, then halt instead of reboot. */ void diff --git a/arch/frv/include/asm/pci.h b/arch/frv/include/asm/pci.h index 0d5997909850..ef03baf5d89d 100644 --- a/arch/frv/include/asm/pci.h +++ b/arch/frv/include/asm/pci.h @@ -54,7 +54,7 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, #endif /* - * These are pretty much arbitary with the CoMEM implementation. + * These are pretty much arbitrary with the CoMEM implementation. * We have the whole address space to ourselves. */ #define PCIBIOS_MIN_IO 0x100 diff --git a/arch/frv/include/asm/spr-regs.h b/arch/frv/include/asm/spr-regs.h index 01e6af5e99b8..d3883021f236 100644 --- a/arch/frv/include/asm/spr-regs.h +++ b/arch/frv/include/asm/spr-regs.h @@ -274,7 +274,7 @@ #define MSR0_RD 0xc0000000 /* rounding mode */ #define MSR0_RD_NEAREST 0x00000000 /* - nearest */ #define MSR0_RD_ZERO 0x40000000 /* - zero */ -#define MSR0_RD_POS_INF 0x80000000 /* - postive infinity */ +#define MSR0_RD_POS_INF 0x80000000 /* - positive infinity */ #define MSR0_RD_NEG_INF 0xc0000000 /* - negative infinity */ /* diff --git a/arch/frv/include/asm/virtconvert.h b/arch/frv/include/asm/virtconvert.h index 59788fa2a813..b26d70ab9111 100644 --- a/arch/frv/include/asm/virtconvert.h +++ b/arch/frv/include/asm/virtconvert.h @@ -1,4 +1,4 @@ -/* virtconvert.h: virtual/physical/page address convertion +/* virtconvert.h: virtual/physical/page address conversion * * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) diff --git a/arch/frv/kernel/entry-table.S b/arch/frv/kernel/entry-table.S index bf35f33e48c9..06c5ae191e59 100644 --- a/arch/frv/kernel/entry-table.S +++ b/arch/frv/kernel/entry-table.S @@ -86,7 +86,7 @@ __break_usertrap_fixup_table: .globl __break_kerneltrap_fixup_table __break_kerneltrap_fixup_table: - # handler declaration for a sofware or program interrupt + # handler declaration for a software or program interrupt .macro VECTOR_SOFTPROG tbr_tt, vec .section .trap.user .org \tbr_tt @@ -145,7 +145,7 @@ __break_kerneltrap_fixup_table: .long \vec .endm - # handler declaration for an MMU only sofware or program interrupt + # handler declaration for an MMU only software or program interrupt .macro VECTOR_SP_MMU tbr_tt, vec #ifdef CONFIG_MMU VECTOR_SOFTPROG \tbr_tt, \vec diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index c4ea0925cdbd..e5cc56ae6ce3 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -414,11 +414,11 @@ config PERMIT_BSP_REMOVE support. config FORCE_CPEI_RETARGET - bool "Force assumption that CPEI can be re-targetted" + bool "Force assumption that CPEI can be re-targeted" depends on PERMIT_BSP_REMOVE default n ---help--- - Say Y if you need to force the assumption that CPEI can be re-targetted to + Say Y if you need to force the assumption that CPEI can be re-targeted to any cpu in the system. This hint is available via ACPI 3.0 specifications. Tiger4 systems are capable of re-directing CPEI to any CPU other than BSP. This option it useful to enable this feature on older BIOS's as well. diff --git a/arch/ia64/include/asm/pal.h b/arch/ia64/include/asm/pal.h index 6a292505b396..2e69284df8e7 100644 --- a/arch/ia64/include/asm/pal.h +++ b/arch/ia64/include/asm/pal.h @@ -1669,7 +1669,7 @@ typedef union pal_vp_info_u { } pal_vp_info_u_t; /* - * Returns infomation about virtual processor features + * Returns information about virtual processor features */ static inline s64 ia64_pal_vp_info (u64 feature_set, u64 vp_buffer, u64 *vp_info, u64 *vmm_id) diff --git a/arch/ia64/include/asm/perfmon_default_smpl.h b/arch/ia64/include/asm/perfmon_default_smpl.h index 74724b24c2b7..a2d560c67230 100644 --- a/arch/ia64/include/asm/perfmon_default_smpl.h +++ b/arch/ia64/include/asm/perfmon_default_smpl.h @@ -67,8 +67,8 @@ typedef struct { unsigned long ip; /* where did the overflow interrupt happened */ unsigned long tstamp; /* ar.itc when entering perfmon intr. handler */ - unsigned short cpu; /* cpu on which the overflow occured */ - unsigned short set; /* event set active when overflow ocurred */ + unsigned short cpu; /* cpu on which the overflow occurred */ + unsigned short set; /* event set active when overflow occurred */ int tgid; /* thread group id (for NPTL, this is getpid()) */ } pfm_default_smpl_entry_t; diff --git a/arch/ia64/include/asm/sn/bte.h b/arch/ia64/include/asm/sn/bte.h index 96798d2da7c2..cc6c4dbf53af 100644 --- a/arch/ia64/include/asm/sn/bte.h +++ b/arch/ia64/include/asm/sn/bte.h @@ -216,7 +216,7 @@ extern void bte_error_handler(unsigned long); bte_copy(0, dest, len, ((mode) | BTE_ZERO_FILL), notification) /* - * The following is the prefered way of calling bte_unaligned_copy + * The following is the preferred way of calling bte_unaligned_copy * If the copy is fully cache line aligned, then bte_copy is * used instead. Since bte_copy is inlined, this saves a call * stack. NOTE: bte_copy is called synchronously and does block diff --git a/arch/ia64/include/asm/sn/shub_mmr.h b/arch/ia64/include/asm/sn/shub_mmr.h index 7de1d1d4b71a..a84d870f4294 100644 --- a/arch/ia64/include/asm/sn/shub_mmr.h +++ b/arch/ia64/include/asm/sn/shub_mmr.h @@ -459,7 +459,7 @@ /* ==================================================================== */ /* Some MMRs are functionally identical (or close enough) on both SHUB1 */ /* and SHUB2 that it makes sense to define a geberic name for the MMR. */ -/* It is acceptible to use (for example) SH_IPI_INT to reference the */ +/* It is acceptable to use (for example) SH_IPI_INT to reference the */ /* the IPI MMR. The value of SH_IPI_INT is determined at runtime based */ /* on the type of the SHUB. Do not use these #defines in performance */ /* critical code or loops - there is a small performance penalty. */ diff --git a/arch/ia64/include/asm/sn/shubio.h b/arch/ia64/include/asm/sn/shubio.h index 6052422a22b3..ecb8a49476b6 100644 --- a/arch/ia64/include/asm/sn/shubio.h +++ b/arch/ia64/include/asm/sn/shubio.h @@ -1383,7 +1383,7 @@ typedef union ii_ibcr_u { * response is capture in IXSM and IXSS, and IXSS[VALID] is set. The * * errant header is thereby captured, and no further spurious read * * respones are captured until IXSS[VALID] is cleared by setting the * - * appropriate bit in IECLR.Everytime a spurious read response is * + * appropriate bit in IECLR. Every time a spurious read response is * * detected, the SPUR_RD bit of the PRB corresponding to the incoming * * message's SIDN field is set. This always happens, regarless of * * whether a header is captured. The programmer should check * @@ -2738,7 +2738,7 @@ typedef union ii_ippr_u { /************************************************************************ * * * The following defines which were not formed into structures are * - * probably indentical to another register, and the name of the * + * probably identical to another register, and the name of the * * register is provided against each of these registers. This * * information needs to be checked carefully * * * diff --git a/arch/ia64/kernel/cyclone.c b/arch/ia64/kernel/cyclone.c index d52f1f78eff2..1b811c61bdc6 100644 --- a/arch/ia64/kernel/cyclone.c +++ b/arch/ia64/kernel/cyclone.c @@ -31,7 +31,7 @@ static struct clocksource clocksource_cyclone = { .rating = 300, .read = read_cyclone, .mask = (1LL << 40) - 1, - .mult = 0, /*to be caluclated*/ + .mult = 0, /*to be calculated*/ .shift = 16, .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; diff --git a/arch/ia64/kernel/perfmon_default_smpl.c b/arch/ia64/kernel/perfmon_default_smpl.c index 5f637bbfcccd..30c644ea44c9 100644 --- a/arch/ia64/kernel/perfmon_default_smpl.c +++ b/arch/ia64/kernel/perfmon_default_smpl.c @@ -150,7 +150,7 @@ default_handler(struct task_struct *task, void *buf, pfm_ovfl_arg_t *arg, struct * current = task running at the time of the overflow. * * per-task mode: - * - this is ususally the task being monitored. + * - this is usually the task being monitored. * Under certain conditions, it might be a different task * * system-wide: diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index 44f11ee411c0..14ec641003da 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c @@ -703,7 +703,7 @@ int migrate_platform_irqs(unsigned int cpu) data->chip->irq_disable(data); data->chip->irq_set_affinity(data, mask, false); data->chip->irq_enable(data); - printk ("Re-targetting CPEI to cpu %d\n", new_cpei_cpu); + printk ("Re-targeting CPEI to cpu %d\n", new_cpei_cpu); } } if (!data) { diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c index 0baa1bbb65fe..0e0e0cc9e392 100644 --- a/arch/ia64/kernel/topology.c +++ b/arch/ia64/kernel/topology.c @@ -43,7 +43,7 @@ int __ref arch_register_cpu(int num) { #ifdef CONFIG_ACPI /* - * If CPEI can be re-targetted or if this is not + * If CPEI can be re-targeted or if this is not * CPEI target, then it is hotpluggable */ if (can_cpei_retarget() || !is_cpu_cpei_target(num)) diff --git a/arch/ia64/kvm/process.c b/arch/ia64/kvm/process.c index bb862fb224f2..b0398740b48d 100644 --- a/arch/ia64/kvm/process.c +++ b/arch/ia64/kvm/process.c @@ -987,7 +987,7 @@ static void vmm_sanity_check(struct kvm_vcpu *vcpu) static void kvm_do_resume_op(struct kvm_vcpu *vcpu) { - vmm_sanity_check(vcpu); /*Guarantee vcpu runing on healthy vmm!*/ + vmm_sanity_check(vcpu); /*Guarantee vcpu running on healthy vmm!*/ if (test_and_clear_bit(KVM_REQ_RESUME, &vcpu->requests)) { vcpu_do_resume(vcpu); diff --git a/arch/ia64/lib/do_csum.S b/arch/ia64/lib/do_csum.S index 6bec2fc9f5b2..1a431a5cf86f 100644 --- a/arch/ia64/lib/do_csum.S +++ b/arch/ia64/lib/do_csum.S @@ -201,7 +201,7 @@ GLOBAL_ENTRY(do_csum) ;; (p6) adds result1[0]=1,result1[0] (p9) br.cond.sptk .do_csum_exit // if (count == 1) exit - // Fall through to caluculate the checksum, feeding result1[0] as + // Fall through to calculate the checksum, feeding result1[0] as // the initial value in result1[0]. // // Calculate the checksum loading two 8-byte words per loop. diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c index 7f399f9d99c7..1c50e4cd63ed 100644 --- a/arch/ia64/sn/kernel/irq.c +++ b/arch/ia64/sn/kernel/irq.c @@ -227,7 +227,7 @@ void sn_set_err_irq_affinity(unsigned int irq) { /* * On systems which support CPU disabling (SHub2), all error interrupts - * are targetted at the boot CPU. + * are targeted at the boot CPU. */ if (is_shub2() && sn_prom_feature_available(PRF_CPU_DISABLE_SUPPORT)) set_irq_affinity_info(irq, cpu_physical_id(0), 0); @@ -435,7 +435,7 @@ static void sn_check_intr(int irq, struct sn_irq_info *sn_irq_info) /* * Bridge types attached to TIO (anything but PIC) do not need this WAR * since they do not target Shub II interrupt registers. If that - * ever changes, this check needs to accomodate. + * ever changes, this check needs to accommodate. */ if (sn_irq_info->irq_bridge_type != PCIIO_ASIC_TYPE_PIC) return; diff --git a/arch/ia64/sn/pci/pcibr/pcibr_dma.c b/arch/ia64/sn/pci/pcibr/pcibr_dma.c index c659ad5613a0..33def666a664 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_dma.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_dma.c @@ -227,7 +227,7 @@ pcibr_dma_unmap(struct pci_dev *hwdev, dma_addr_t dma_handle, int direction) * after doing the read. For PIC this routine then forces a fake interrupt * on another line, which is logically associated with the slot that the PIO * is addressed to. It then spins while watching the memory location that - * the interrupt is targetted to. When the interrupt response arrives, we + * the interrupt is targeted to. When the interrupt response arrives, we * are sure that the DMA has landed in memory and it is safe for the driver * to proceed. For TIOCP use the Device(x) Write Request Buffer Flush * Bridge register since it ensures the data has entered the coherence domain, diff --git a/arch/m32r/include/asm/m32104ut/m32104ut_pld.h b/arch/m32r/include/asm/m32104ut/m32104ut_pld.h index 2dc89d68b6d9..1feae9709f24 100644 --- a/arch/m32r/include/asm/m32104ut/m32104ut_pld.h +++ b/arch/m32r/include/asm/m32104ut/m32104ut_pld.h @@ -4,7 +4,7 @@ /* * include/asm-m32r/m32104ut/m32104ut_pld.h * - * Definitions for Programable Logic Device(PLD) on M32104UT board. + * Definitions for Programmable Logic Device(PLD) on M32104UT board. * Based on m32700ut_pld.h * * Copyright (c) 2002 Takeo Takahashi diff --git a/arch/m32r/include/asm/m32700ut/m32700ut_pld.h b/arch/m32r/include/asm/m32700ut/m32700ut_pld.h index 57623beb44cb..35294670b187 100644 --- a/arch/m32r/include/asm/m32700ut/m32700ut_pld.h +++ b/arch/m32r/include/asm/m32700ut/m32700ut_pld.h @@ -4,7 +4,7 @@ /* * include/asm-m32r/m32700ut/m32700ut_pld.h * - * Definitions for Programable Logic Device(PLD) on M32700UT board. + * Definitions for Programmable Logic Device(PLD) on M32700UT board. * * Copyright (c) 2002 Takeo Takahashi * diff --git a/arch/m32r/include/asm/opsput/opsput_pld.h b/arch/m32r/include/asm/opsput/opsput_pld.h index 3f11ea1aac2d..6901401fe9eb 100644 --- a/arch/m32r/include/asm/opsput/opsput_pld.h +++ b/arch/m32r/include/asm/opsput/opsput_pld.h @@ -4,7 +4,7 @@ /* * include/asm-m32r/opsput/opsput_pld.h * - * Definitions for Programable Logic Device(PLD) on OPSPUT board. + * Definitions for Programmable Logic Device(PLD) on OPSPUT board. * * Copyright (c) 2002 Takeo Takahashi * diff --git a/arch/m32r/include/asm/pgtable-2level.h b/arch/m32r/include/asm/pgtable-2level.h index bca3475f9595..9cdaf7350ef6 100644 --- a/arch/m32r/include/asm/pgtable-2level.h +++ b/arch/m32r/include/asm/pgtable-2level.h @@ -44,7 +44,7 @@ static inline int pgd_present(pgd_t pgd) { return 1; } #define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval) /* - * (pmds are folded into pgds so this doesnt get actually called, + * (pmds are folded into pgds so this doesn't get actually called, * but the define is needed for a generic inline function.) */ #define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval) diff --git a/arch/m32r/mm/fault.c b/arch/m32r/mm/fault.c index b8ec002aef8e..2c9aeb453847 100644 --- a/arch/m32r/mm/fault.c +++ b/arch/m32r/mm/fault.c @@ -120,7 +120,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code, /* When running in the kernel we expect faults to occur only to * addresses in user space. All other faults represent errors in the - * kernel and should generate an OOPS. Unfortunatly, in the case of an + * kernel and should generate an OOPS. Unfortunately, in the case of an * erroneous fault occurring in a code path which already holds mmap_sem * we will deadlock attempting to validate the fault against the * address space. Luckily the kernel only validly references user @@ -128,7 +128,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code, * exceptions table. * * As the vast majority of faults will be valid we will only perform - * the source reference check when there is a possibilty of a deadlock. + * the source reference check when there is a possibility of a deadlock. * Attempt to lock the address space, if we cannot we then validate the * source. If this is invalid we can skip the address space check, * thus avoiding the deadlock. diff --git a/arch/m68k/atari/atakeyb.c b/arch/m68k/atari/atakeyb.c index 5890897d28bf..b995513d527f 100644 --- a/arch/m68k/atari/atakeyb.c +++ b/arch/m68k/atari/atakeyb.c @@ -130,7 +130,7 @@ KEYBOARD_STATE kb_state; * it's really hard to decide whether they're mouse or keyboard bytes. Since * overruns usually occur when moving the Atari mouse rapidly, they're seen as * mouse bytes here. If this is wrong, only a make code of the keyboard gets - * lost, which isn't too bad. Loosing a break code would be disastrous, + * lost, which isn't too bad. Losing a break code would be disastrous, * because then the keyboard repeat strikes... */ diff --git a/arch/m68k/fpsp040/bindec.S b/arch/m68k/fpsp040/bindec.S index 72f1159cb804..f2e795231046 100644 --- a/arch/m68k/fpsp040/bindec.S +++ b/arch/m68k/fpsp040/bindec.S @@ -609,7 +609,7 @@ do_fint: | A6. This test occurs only on the first pass. If the | result is exactly 10^LEN, decrement ILOG and divide | the mantissa by 10. The calculation of 10^LEN cannot -| be inexact, since all powers of ten upto 10^27 are exact +| be inexact, since all powers of ten up to 10^27 are exact | in extended precision, so the use of a previous power-of-ten | table will introduce no error. | diff --git a/arch/m68k/ifpsp060/src/fpsp.S b/arch/m68k/ifpsp060/src/fpsp.S index 26e85e2b7a5e..78cb60f5bb4d 100644 --- a/arch/m68k/ifpsp060/src/fpsp.S +++ b/arch/m68k/ifpsp060/src/fpsp.S @@ -11813,7 +11813,7 @@ fmul_unfl_ena: bne.b fmul_unfl_ena_sd # no, sgl or dbl # if the rnd mode is anything but RZ, then we have to re-do the above -# multiplication becuase we used RZ for all. +# multiplication because we used RZ for all. fmov.l L_SCR3(%a6),%fpcr # set FPCR fmul_unfl_ena_cont: @@ -18095,7 +18095,7 @@ fscc_mem_op: rts -# addresing mode is post-increment. write the result byte. if the write +# addressing mode is post-increment. write the result byte. if the write # fails then don't update the address register. if write passes then # call inc_areg() to update the address register. fscc_mem_inc: @@ -20876,7 +20876,7 @@ dst_get_dupper: swap %d0 # d0 now in upper word lsl.l &0x4,%d0 # d0 in proper place for dbl prec exp tst.b FTEMP_EX(%a0) # test sign - bpl.b dst_get_dman # if postive, go process mantissa + bpl.b dst_get_dman # if positive, go process mantissa bset &0x1f,%d0 # if negative, set sign dst_get_dman: mov.l FTEMP_HI(%a0),%d1 # get ms mantissa @@ -22943,7 +22943,7 @@ tbl_ovfl_result: # FP_SRC(a6) = packed operand now as a binary FP number # # # # ALGORITHM *********************************************************** # -# Get the correct whihc is the value on the exception stack # +# Get the correct which is the value on the exception stack # # frame w/ maybe a correction factor if the is -(an) or (an)+. # # Then, fetch the operand from memory. If the fetch fails, exit # # through facc_in_x(). # @@ -24096,7 +24096,7 @@ do_fint12: # A6. This test occurs only on the first pass. If the # result is exactly 10^LEN, decrement ILOG and divide # the mantissa by 10. The calculation of 10^LEN cannot -# be inexact, since all powers of ten upto 10^27 are exact +# be inexact, since all powers of ten up to 10^27 are exact # in extended precision, so the use of a previous power-of-ten # table will introduce no error. # diff --git a/arch/m68k/ifpsp060/src/pfpsp.S b/arch/m68k/ifpsp060/src/pfpsp.S index e71ba0ab013c..4aedef973cf6 100644 --- a/arch/m68k/ifpsp060/src/pfpsp.S +++ b/arch/m68k/ifpsp060/src/pfpsp.S @@ -7777,7 +7777,7 @@ dst_get_dupper: swap %d0 # d0 now in upper word lsl.l &0x4,%d0 # d0 in proper place for dbl prec exp tst.b FTEMP_EX(%a0) # test sign - bpl.b dst_get_dman # if postive, go process mantissa + bpl.b dst_get_dman # if positive, go process mantissa bset &0x1f,%d0 # if negative, set sign dst_get_dman: mov.l FTEMP_HI(%a0),%d1 # get ms mantissa @@ -8244,7 +8244,7 @@ fmul_unfl_ena: bne.b fmul_unfl_ena_sd # no, sgl or dbl # if the rnd mode is anything but RZ, then we have to re-do the above -# multiplication becuase we used RZ for all. +# multiplication because we used RZ for all. fmov.l L_SCR3(%a6),%fpcr # set FPCR fmul_unfl_ena_cont: @@ -12903,7 +12903,7 @@ store_fpreg_7: # FP_SRC(a6) = packed operand now as a binary FP number # # # # ALGORITHM *********************************************************** # -# Get the correct whihc is the value on the exception stack # +# Get the correct which is the value on the exception stack # # frame w/ maybe a correction factor if the is -(an) or (an)+. # # Then, fetch the operand from memory. If the fetch fails, exit # # through facc_in_x(). # @@ -14056,7 +14056,7 @@ do_fint12: # A6. This test occurs only on the first pass. If the # result is exactly 10^LEN, decrement ILOG and divide # the mantissa by 10. The calculation of 10^LEN cannot -# be inexact, since all powers of ten upto 10^27 are exact +# be inexact, since all powers of ten up to 10^27 are exact # in extended precision, so the use of a previous power-of-ten # table will introduce no error. # diff --git a/arch/m68k/include/asm/atariints.h b/arch/m68k/include/asm/atariints.h index f597892e43a0..656bbbf5a6ff 100644 --- a/arch/m68k/include/asm/atariints.h +++ b/arch/m68k/include/asm/atariints.h @@ -146,7 +146,7 @@ static inline void clear_mfp_bit( unsigned irq, int type ) /* * {en,dis}able_irq have the usual semantics of temporary blocking the - * interrupt, but not loosing requests that happen between disabling and + * interrupt, but not losing requests that happen between disabling and * enabling. This is done with the MFP mask registers. */ diff --git a/arch/m68k/include/asm/bootstd.h b/arch/m68k/include/asm/bootstd.h index bdc1a4ac4fe9..e518f5a575b7 100644 --- a/arch/m68k/include/asm/bootstd.h +++ b/arch/m68k/include/asm/bootstd.h @@ -31,7 +31,7 @@ #define __BN_flash_write_range 20 /* Calling conventions compatible to (uC)linux/68k - * We use simmilar macros to call into the bootloader as for uClinux + * We use similar macros to call into the bootloader as for uClinux */ #define __bsc_return(type, res) \ diff --git a/arch/m68k/include/asm/commproc.h b/arch/m68k/include/asm/commproc.h index edf5eb6c08d2..a73998528d26 100644 --- a/arch/m68k/include/asm/commproc.h +++ b/arch/m68k/include/asm/commproc.h @@ -88,7 +88,7 @@ typedef struct cpm_buf_desc { /* rx bd status/control bits */ -#define BD_SC_EMPTY ((ushort)0x8000) /* Recieve is empty */ +#define BD_SC_EMPTY ((ushort)0x8000) /* Receive is empty */ #define BD_SC_WRAP ((ushort)0x2000) /* Last buffer descriptor in table */ #define BD_SC_INTRPT ((ushort)0x1000) /* Interrupt on change */ #define BD_SC_LAST ((ushort)0x0800) /* Last buffer in frame OR control char */ @@ -96,7 +96,7 @@ typedef struct cpm_buf_desc { #define BD_SC_FIRST ((ushort)0x0400) /* 1st buffer in an HDLC frame */ #define BD_SC_ADDR ((ushort)0x0400) /* 1st byte is a multidrop address */ -#define BD_SC_CM ((ushort)0x0200) /* Continous mode */ +#define BD_SC_CM ((ushort)0x0200) /* Continuous mode */ #define BD_SC_ID ((ushort)0x0100) /* Received too many idles */ #define BD_SC_AM ((ushort)0x0080) /* Multidrop address match */ diff --git a/arch/m68k/include/asm/delay_no.h b/arch/m68k/include/asm/delay_no.h index 55cbd6294ab6..c3a0edc90f21 100644 --- a/arch/m68k/include/asm/delay_no.h +++ b/arch/m68k/include/asm/delay_no.h @@ -16,7 +16,7 @@ static inline void __delay(unsigned long loops) * long word alignment which is the faster version. * The 0x4a8e is of course a 'tstl %fp' instruction. This is better * than using a NOP (0x4e71) instruction because it executes in one - * cycle not three and doesn't allow for an arbitary delay waiting + * cycle not three and doesn't allow for an arbitrary delay waiting * for bus cycles to finish. Also fp/a6 isn't likely to cause a * stall waiting for the register to become valid if such is added * to the coldfire at some stage. diff --git a/arch/m68k/include/asm/gpio.h b/arch/m68k/include/asm/gpio.h index c64c7b74cf86..b2046839f4b2 100644 --- a/arch/m68k/include/asm/gpio.h +++ b/arch/m68k/include/asm/gpio.h @@ -31,7 +31,7 @@ * GPIOs in a single control area, others have some GPIOs implemented in * different modules. * - * This implementation attempts accomodate the differences while presenting + * This implementation attempts accommodate the differences while presenting * a generic interface that will optimize to as few instructions as possible. */ #if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \ diff --git a/arch/m68k/include/asm/m520xsim.h b/arch/m68k/include/asm/m520xsim.h index 55d5a4c5fe0b..b6bf2c518bac 100644 --- a/arch/m68k/include/asm/m520xsim.h +++ b/arch/m68k/include/asm/m520xsim.h @@ -157,7 +157,7 @@ #define MCFFEC_SIZE 0x800 /* Register set size */ /* - * Reset Controll Unit. + * Reset Control Unit. */ #define MCF_RCR 0xFC0A0000 #define MCF_RSR 0xFC0A0001 diff --git a/arch/m68k/include/asm/m523xsim.h b/arch/m68k/include/asm/m523xsim.h index 8996df62ede4..6235921eca4e 100644 --- a/arch/m68k/include/asm/m523xsim.h +++ b/arch/m68k/include/asm/m523xsim.h @@ -48,7 +48,7 @@ #define MCFSIM_DMR1 (MCF_IPSBAR + 0x54) /* Address mask 1 */ /* - * Reset Controll Unit (relative to IPSBAR). + * Reset Control Unit (relative to IPSBAR). */ #define MCF_RCR 0x110000 #define MCF_RSR 0x110001 diff --git a/arch/m68k/include/asm/m527xsim.h b/arch/m68k/include/asm/m527xsim.h index 74855a66c050..758810ef91ec 100644 --- a/arch/m68k/include/asm/m527xsim.h +++ b/arch/m68k/include/asm/m527xsim.h @@ -283,7 +283,7 @@ #endif /* - * Reset Controll Unit (relative to IPSBAR). + * Reset Control Unit (relative to IPSBAR). */ #define MCF_RCR 0x110000 #define MCF_RSR 0x110001 diff --git a/arch/m68k/include/asm/m5307sim.h b/arch/m68k/include/asm/m5307sim.h index 4c94c01f36c4..8f8609fcc9b8 100644 --- a/arch/m68k/include/asm/m5307sim.h +++ b/arch/m68k/include/asm/m5307sim.h @@ -29,7 +29,7 @@ #define MCFSIM_SWSR 0x03 /* SW Watchdog service (r/w) */ #define MCFSIM_PAR 0x04 /* Pin Assignment reg (r/w) */ #define MCFSIM_IRQPAR 0x06 /* Interrupt Assignment reg (r/w) */ -#define MCFSIM_PLLCR 0x08 /* PLL Controll Reg*/ +#define MCFSIM_PLLCR 0x08 /* PLL Control Reg*/ #define MCFSIM_MPARK 0x0C /* BUS Master Control Reg*/ #define MCFSIM_IPR 0x40 /* Interrupt Pend reg (r/w) */ #define MCFSIM_IMR 0x44 /* Interrupt Mask reg (r/w) */ diff --git a/arch/m68k/include/asm/m5407sim.h b/arch/m68k/include/asm/m5407sim.h index 762c58c89050..51e00b00b8a6 100644 --- a/arch/m68k/include/asm/m5407sim.h +++ b/arch/m68k/include/asm/m5407sim.h @@ -29,7 +29,7 @@ #define MCFSIM_SWSR 0x03 /* SW Watchdog service (r/w) */ #define MCFSIM_PAR 0x04 /* Pin Assignment reg (r/w) */ #define MCFSIM_IRQPAR 0x06 /* Interrupt Assignment reg (r/w) */ -#define MCFSIM_PLLCR 0x08 /* PLL Controll Reg*/ +#define MCFSIM_PLLCR 0x08 /* PLL Control Reg*/ #define MCFSIM_MPARK 0x0C /* BUS Master Control Reg*/ #define MCFSIM_IPR 0x40 /* Interrupt Pend reg (r/w) */ #define MCFSIM_IMR 0x44 /* Interrupt Mask reg (r/w) */ diff --git a/arch/m68k/include/asm/m68360_quicc.h b/arch/m68k/include/asm/m68360_quicc.h index 6d40f4d18e10..59414cc108d3 100644 --- a/arch/m68k/include/asm/m68360_quicc.h +++ b/arch/m68k/include/asm/m68360_quicc.h @@ -32,7 +32,7 @@ struct user_data { /* BASE + 0x000: user data memory */ volatile unsigned char udata_bd_ucode[0x400]; /*user data bd's Ucode*/ volatile unsigned char udata_bd[0x200]; /*user data Ucode */ - volatile unsigned char ucode_ext[0x100]; /*Ucode Extention ram */ + volatile unsigned char ucode_ext[0x100]; /*Ucode Extension ram */ volatile unsigned char RESERVED1[0x500]; /* Reserved area */ }; #else diff --git a/arch/m68k/include/asm/mac_oss.h b/arch/m68k/include/asm/mac_oss.h index 7221f7251934..3cf2b6ed685a 100644 --- a/arch/m68k/include/asm/mac_oss.h +++ b/arch/m68k/include/asm/mac_oss.h @@ -61,7 +61,7 @@ /* * OSS Interrupt levels for various sub-systems * - * This mapping is layed out with two things in mind: first, we try to keep + * This mapping is laid out with two things in mind: first, we try to keep * things on their own levels to avoid having to do double-dispatches. Second, * the levels match as closely as possible the alternate IRQ mapping mode (aka * "A/UX mode") available on some VIA machines. diff --git a/arch/m68k/include/asm/mac_via.h b/arch/m68k/include/asm/mac_via.h index 39afb438b656..a59665e1d41b 100644 --- a/arch/m68k/include/asm/mac_via.h +++ b/arch/m68k/include/asm/mac_via.h @@ -204,7 +204,7 @@ #define vT2CL 0x1000 /* [VIA only] Timer two counter low. */ #define vT2CH 0x1200 /* [VIA only] Timer two counter high. */ #define vSR 0x1400 /* [VIA only] Shift register. */ -#define vACR 0x1600 /* [VIA only] Auxilary control register. */ +#define vACR 0x1600 /* [VIA only] Auxiliary control register. */ #define vPCR 0x1800 /* [VIA only] Peripheral control register. */ /* CHRP sez never ever to *write* this. * Mac family says never to *change* this. diff --git a/arch/m68k/include/asm/macintosh.h b/arch/m68k/include/asm/macintosh.h index 50db3591ca15..c2a1c5eac1a6 100644 --- a/arch/m68k/include/asm/macintosh.h +++ b/arch/m68k/include/asm/macintosh.h @@ -14,7 +14,7 @@ extern void mac_init_IRQ(void); extern int mac_irq_pending(unsigned int); /* - * Floppy driver magic hook - probably shouldnt be here + * Floppy driver magic hook - probably shouldn't be here */ extern void via1_set_head(int); diff --git a/arch/m68k/include/asm/mcftimer.h b/arch/m68k/include/asm/mcftimer.h index 92b276fe8240..351c27237874 100644 --- a/arch/m68k/include/asm/mcftimer.h +++ b/arch/m68k/include/asm/mcftimer.h @@ -27,7 +27,7 @@ /* * Bit definitions for the Timer Mode Register (TMR). - * Register bit flags are common accross ColdFires. + * Register bit flags are common across ColdFires. */ #define MCFTIMER_TMR_PREMASK 0xff00 /* Prescalar mask */ #define MCFTIMER_TMR_DISCE 0x0000 /* Disable capture */ diff --git a/arch/m68k/kernel/head.S b/arch/m68k/kernel/head.S index ef54128baa0b..27622b3273c1 100644 --- a/arch/m68k/kernel/head.S +++ b/arch/m68k/kernel/head.S @@ -134,7 +134,7 @@ * Thanks to a small helping routine enabling the mmu got quite simple * and there is only one way left. mmu_engage makes a complete a new mapping * that only includes the absolute necessary to be able to jump to the final - * postion and to restore the original mapping. + * position and to restore the original mapping. * As this code doesn't need a transparent translation register anymore this * means all registers are free to be used by machines that needs them for * other purposes. @@ -969,7 +969,7 @@ L(mmu_init_amiga): is_not_040_or_060(1f) /* - * 040: Map the 16Meg range physical 0x0 upto logical 0x8000.0000 + * 040: Map the 16Meg range physical 0x0 up to logical 0x8000.0000 */ mmu_map #0x80000000,#0,#0x01000000,#_PAGE_NOCACHE_S /* @@ -982,7 +982,7 @@ L(mmu_init_amiga): 1: /* - * 030: Map the 32Meg range physical 0x0 upto logical 0x8000.0000 + * 030: Map the 32Meg range physical 0x0 up to logical 0x8000.0000 */ mmu_map #0x80000000,#0,#0x02000000,#_PAGE_NOCACHE030 mmu_map_tt #1,#0x40000000,#0x20000000,#_PAGE_NOCACHE030 @@ -1074,7 +1074,7 @@ L(notq40): is_040(1f) /* - * 030: Map the 32Meg range physical 0x0 upto logical 0xf000.0000 + * 030: Map the 32Meg range physical 0x0 up to logical 0xf000.0000 */ mmu_map #0xf0000000,#0,#0x02000000,#_PAGE_NOCACHE030 @@ -1082,7 +1082,7 @@ L(notq40): 1: /* - * 040: Map the 16Meg range physical 0x0 upto logical 0xf000.0000 + * 040: Map the 16Meg range physical 0x0 up to logical 0xf000.0000 */ mmu_map #0xf0000000,#0,#0x01000000,#_PAGE_NOCACHE_S @@ -3078,7 +3078,7 @@ func_start serial_putc,%d0/%d1/%a0/%a1 /* * If the loader gave us a board type then we can use that to * select an appropriate output routine; otherwise we just use - * the Bug code. If we haev to use the Bug that means the Bug + * the Bug code. If we have to use the Bug that means the Bug * workspace has to be valid, which means the Bug has to use * the SRAM, which is non-standard. */ diff --git a/arch/m68k/kernel/vmlinux.lds_no.S b/arch/m68k/kernel/vmlinux.lds_no.S index 47e15ebfd893..f4d715cdca0e 100644 --- a/arch/m68k/kernel/vmlinux.lds_no.S +++ b/arch/m68k/kernel/vmlinux.lds_no.S @@ -3,7 +3,7 @@ * * (C) Copyright 2002-2006, Greg Ungerer * - * This linker script is equiped to build either ROM loaded or RAM + * This linker script is equipped to build either ROM loaded or RAM * run kernels. */ diff --git a/arch/m68k/platform/523x/config.c b/arch/m68k/platform/523x/config.c index 418a76feb1e3..71f4436ec809 100644 --- a/arch/m68k/platform/523x/config.c +++ b/arch/m68k/platform/523x/config.c @@ -3,7 +3,7 @@ /* * linux/arch/m68knommu/platform/523x/config.c * - * Sub-architcture dependant initialization code for the Freescale + * Sub-architcture dependent initialization code for the Freescale * 523x CPUs. * * Copyright (C) 1999-2005, Greg Ungerer (gerg@snapgear.com) diff --git a/arch/m68k/platform/5272/intc.c b/arch/m68k/platform/5272/intc.c index 43e6e96f087f..7e715dfe2819 100644 --- a/arch/m68k/platform/5272/intc.c +++ b/arch/m68k/platform/5272/intc.c @@ -33,7 +33,7 @@ * * Note that the external interrupts are edge triggered (unlike the * internal interrupt sources which are level triggered). Which means - * they also need acknowledgeing via acknowledge bits. + * they also need acknowledging via acknowledge bits. */ struct irqmap { unsigned char icr; diff --git a/arch/m68k/platform/527x/config.c b/arch/m68k/platform/527x/config.c index fa359593b613..3ebc769cefda 100644 --- a/arch/m68k/platform/527x/config.c +++ b/arch/m68k/platform/527x/config.c @@ -3,7 +3,7 @@ /* * linux/arch/m68knommu/platform/527x/config.c * - * Sub-architcture dependant initialization code for the Freescale + * Sub-architcture dependent initialization code for the Freescale * 5270/5271 CPUs. * * Copyright (C) 1999-2004, Greg Ungerer (gerg@snapgear.com) diff --git a/arch/m68k/platform/528x/config.c b/arch/m68k/platform/528x/config.c index ac39fc661219..7abe77a2f3e3 100644 --- a/arch/m68k/platform/528x/config.c +++ b/arch/m68k/platform/528x/config.c @@ -3,7 +3,7 @@ /* * linux/arch/m68knommu/platform/528x/config.c * - * Sub-architcture dependant initialization code for the Freescale + * Sub-architcture dependent initialization code for the Freescale * 5280, 5281 and 5282 CPUs. * * Copyright (C) 1999-2003, Greg Ungerer (gerg@snapgear.com) diff --git a/arch/m68k/platform/coldfire/cache.c b/arch/m68k/platform/coldfire/cache.c index 235d3c4f4f0f..71beeaf0c5c4 100644 --- a/arch/m68k/platform/coldfire/cache.c +++ b/arch/m68k/platform/coldfire/cache.c @@ -1,7 +1,7 @@ /***************************************************************************/ /* - * cache.c -- general ColdFire Cache maintainence code + * cache.c -- general ColdFire Cache maintenance code * * Copyright (C) 2010, Greg Ungerer (gerg@snapgear.com) */ diff --git a/arch/m68k/platform/coldfire/entry.S b/arch/m68k/platform/coldfire/entry.S index 5837cf080b6d..eab63f09965b 100644 --- a/arch/m68k/platform/coldfire/entry.S +++ b/arch/m68k/platform/coldfire/entry.S @@ -163,7 +163,7 @@ Lsignal_return: /* * This is the generic interrupt handler (for all hardware interrupt - * sources). Calls upto high level code to do all the work. + * sources). Calls up to high level code to do all the work. */ ENTRY(inthandler) SAVE_ALL diff --git a/arch/m68k/platform/coldfire/head.S b/arch/m68k/platform/coldfire/head.S index 129bff4956b5..6ae91a499184 100644 --- a/arch/m68k/platform/coldfire/head.S +++ b/arch/m68k/platform/coldfire/head.S @@ -20,7 +20,7 @@ /* * If we don't have a fixed memory size, then lets build in code - * to auto detect the DRAM size. Obviously this is the prefered + * to auto detect the DRAM size. Obviously this is the preferred * method, and should work for most boards. It won't work for those * that do not have their RAM starting at address 0, and it only * works on SDRAM (not boards fitted with SRAM). diff --git a/arch/m68k/platform/coldfire/intc.c b/arch/m68k/platform/coldfire/intc.c index c28a6ed6cb23..0bbb414856eb 100644 --- a/arch/m68k/platform/coldfire/intc.c +++ b/arch/m68k/platform/coldfire/intc.c @@ -37,7 +37,7 @@ unsigned char mcf_irq2imr[NR_IRQS]; /* * In the early version 2 core ColdFire parts the IMR register was 16 bits * in size. Version 3 (and later version 2) core parts have a 32 bit - * sized IMR register. Provide some size independant methods to access the + * sized IMR register. Provide some size independent methods to access the * IMR register. */ #ifdef MCFSIM_IMR_IS_16BITS diff --git a/arch/m68k/platform/coldfire/sltimers.c b/arch/m68k/platform/coldfire/sltimers.c index 0a1b937c3e18..6a85daf9a7fd 100644 --- a/arch/m68k/platform/coldfire/sltimers.c +++ b/arch/m68k/platform/coldfire/sltimers.c @@ -106,7 +106,7 @@ static cycle_t mcfslt_read_clk(struct clocksource *cs) cycles = mcfslt_cnt; local_irq_restore(flags); - /* substract because slice timers count down */ + /* subtract because slice timers count down */ return cycles - scnt; } diff --git a/arch/m68k/q40/README b/arch/m68k/q40/README index f877b7249790..b26d5f55e91d 100644 --- a/arch/m68k/q40/README +++ b/arch/m68k/q40/README @@ -89,7 +89,7 @@ The main interrupt register IIRQ_REG will indicate whether an IRQ was internal or from some ISA devices, EIRQ_REG can distinguish up to 8 ISA IRQs. The Q40 custom chip is programmable to provide 2 periodic timers: - - 50 or 200 Hz - level 2, !!THIS CANT BE DISABLED!! + - 50 or 200 Hz - level 2, !!THIS CAN'T BE DISABLED!! - 10 or 20 KHz - level 4, used for dma-sound Linux uses the 200 Hz interrupt for timer and beep by default. diff --git a/arch/microblaze/Makefile b/arch/microblaze/Makefile index 6f432e6df9af..b23c40eb7a52 100644 --- a/arch/microblaze/Makefile +++ b/arch/microblaze/Makefile @@ -18,7 +18,7 @@ export CPU_VER CPU_MAJOR CPU_MINOR CPU_REV # rather than bools y/n # Work out HW multipler support. This is tricky. -# 1. Spartan2 has no HW multiplers. +# 1. Spartan2 has no HW multipliers. # 2. MicroBlaze v3.x always uses them, except in Spartan 2 # 3. All other FPGa/CPU ver combos, we can trust the CONFIG_ settings ifeq (,$(findstring spartan2,$(CONFIG_XILINX_MICROBLAZE0_FAMILY))) diff --git a/arch/microblaze/include/asm/io.h b/arch/microblaze/include/asm/io.h index eae32220f447..8cdac14b55b0 100644 --- a/arch/microblaze/include/asm/io.h +++ b/arch/microblaze/include/asm/io.h @@ -70,7 +70,7 @@ static inline void __raw_writeq(unsigned long v, volatile void __iomem *addr) /* * read (readb, readw, readl, readq) and write (writeb, writew, - * writel, writeq) accessors are for PCI and thus littel endian. + * writel, writeq) accessors are for PCI and thus little endian. * Linux 2.4 for Microblaze had this wrong. */ static inline unsigned char readb(const volatile void __iomem *addr) diff --git a/arch/microblaze/include/asm/pci-bridge.h b/arch/microblaze/include/asm/pci-bridge.h index 10717669e0c2..746df91e5796 100644 --- a/arch/microblaze/include/asm/pci-bridge.h +++ b/arch/microblaze/include/asm/pci-bridge.h @@ -76,7 +76,7 @@ struct pci_controller { * Used for variants of PCI indirect handling and possible quirks: * SET_CFG_TYPE - used on 4xx or any PHB that does explicit type0/1 * EXT_REG - provides access to PCI-e extended registers - * SURPRESS_PRIMARY_BUS - we surpress the setting of PCI_PRIMARY_BUS + * SURPRESS_PRIMARY_BUS - we suppress the setting of PCI_PRIMARY_BUS * on Freescale PCI-e controllers since they used the PCI_PRIMARY_BUS * to determine which bus number to match on when generating type0 * config cycles diff --git a/arch/microblaze/include/asm/pci.h b/arch/microblaze/include/asm/pci.h index 2232ff942ba9..ba65cf472544 100644 --- a/arch/microblaze/include/asm/pci.h +++ b/arch/microblaze/include/asm/pci.h @@ -158,7 +158,7 @@ extern void pci_resource_to_user(const struct pci_dev *dev, int bar, extern void pcibios_setup_bus_devices(struct pci_bus *bus); extern void pcibios_setup_bus_self(struct pci_bus *bus); -/* This part of code was originaly in xilinx-pci.h */ +/* This part of code was originally in xilinx-pci.h */ #ifdef CONFIG_PCI_XILINX extern void __init xilinx_pci_init(void); #else diff --git a/arch/microblaze/kernel/cpu/cache.c b/arch/microblaze/kernel/cpu/cache.c index cf0afd90a2c0..4b7d8a3f4aef 100644 --- a/arch/microblaze/kernel/cpu/cache.c +++ b/arch/microblaze/kernel/cpu/cache.c @@ -129,7 +129,7 @@ do { \ * to use for simple wdc or wic. * * start address is cache aligned - * end address is not aligned, if end is aligned then I have to substract + * end address is not aligned, if end is aligned then I have to subtract * cacheline length because I can't flush/invalidate the next cacheline. * If is not, I align it because I will flush/invalidate whole line. */ diff --git a/arch/microblaze/lib/memcpy.c b/arch/microblaze/lib/memcpy.c index cc495d7d99cc..52746e718dfa 100644 --- a/arch/microblaze/lib/memcpy.c +++ b/arch/microblaze/lib/memcpy.c @@ -63,8 +63,8 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c) if (likely(c >= 4)) { unsigned value, buf_hold; - /* Align the dstination to a word boundry. */ - /* This is done in an endian independant manner. */ + /* Align the destination to a word boundary. */ + /* This is done in an endian independent manner. */ switch ((unsigned long)dst & 3) { case 1: *dst++ = *src++; @@ -80,7 +80,7 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c) i_dst = (void *)dst; /* Choose a copy scheme based on the source */ - /* alignment relative to dstination. */ + /* alignment relative to destination. */ switch ((unsigned long)src & 3) { case 0x0: /* Both byte offsets are aligned */ i_src = (const void *)src; @@ -173,7 +173,7 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c) } /* Finish off any remaining bytes */ - /* simple fast copy, ... unless a cache boundry is crossed */ + /* simple fast copy, ... unless a cache boundary is crossed */ switch (c) { case 3: *dst++ = *src++; diff --git a/arch/microblaze/lib/memmove.c b/arch/microblaze/lib/memmove.c index 810fd68775e3..2146c3752a80 100644 --- a/arch/microblaze/lib/memmove.c +++ b/arch/microblaze/lib/memmove.c @@ -83,8 +83,8 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c) if (c >= 4) { unsigned value, buf_hold; - /* Align the destination to a word boundry. */ - /* This is done in an endian independant manner. */ + /* Align the destination to a word boundary. */ + /* This is done in an endian independent manner. */ switch ((unsigned long)dst & 3) { case 3: @@ -193,7 +193,7 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c) dst = (void *)i_dst; } - /* simple fast copy, ... unless a cache boundry is crossed */ + /* simple fast copy, ... unless a cache boundary is crossed */ /* Finish off any remaining bytes */ switch (c) { case 4: diff --git a/arch/microblaze/lib/memset.c b/arch/microblaze/lib/memset.c index 834565d1607e..ddf67939576d 100644 --- a/arch/microblaze/lib/memset.c +++ b/arch/microblaze/lib/memset.c @@ -64,7 +64,7 @@ void *memset(void *v_src, int c, __kernel_size_t n) if (likely(n >= 4)) { /* Align the destination to a word boundary */ - /* This is done in an endian independant manner */ + /* This is done in an endian independent manner */ switch ((unsigned) src & 3) { case 1: *src++ = c; diff --git a/arch/microblaze/pci/indirect_pci.c b/arch/microblaze/pci/indirect_pci.c index 25f18f017f21..4196eb6bd764 100644 --- a/arch/microblaze/pci/indirect_pci.c +++ b/arch/microblaze/pci/indirect_pci.c @@ -108,7 +108,7 @@ indirect_write_config(struct pci_bus *bus, unsigned int devfn, int offset, out_le32(hose->cfg_addr, (0x80000000 | (bus_no << 16) | (devfn << 8) | reg | cfg_type)); - /* surpress setting of PCI_PRIMARY_BUS */ + /* suppress setting of PCI_PRIMARY_BUS */ if (hose->indirect_type & INDIRECT_TYPE_SURPRESS_PRIMARY_BUS) if ((offset == PCI_PRIMARY_BUS) && (bus->number == hose->first_busno)) diff --git a/arch/microblaze/platform/generic/Kconfig.auto b/arch/microblaze/platform/generic/Kconfig.auto index 5d86fc19029d..25a6f019e94d 100644 --- a/arch/microblaze/platform/generic/Kconfig.auto +++ b/arch/microblaze/platform/generic/Kconfig.auto @@ -29,7 +29,7 @@ config KERNEL_BASE_ADDR BASE Address for kernel config XILINX_MICROBLAZE0_FAMILY - string "Targetted FPGA family" + string "Targeted FPGA family" default "virtex5" config XILINX_MICROBLAZE0_USE_MSR_INSTR diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 83aa5fb8e8f1..8e256cc5dcd9 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1135,7 +1135,7 @@ config CPU_LOONGSON2E The Loongson 2E processor implements the MIPS III instruction set with many extensions. - It has an internal FPGA northbridge, which is compatiable to + It has an internal FPGA northbridge, which is compatible to bonito64. config CPU_LOONGSON2F diff --git a/arch/mips/Makefile b/arch/mips/Makefile index ac1d5b611a27..53e3514ba10e 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -101,7 +101,7 @@ cflags-y += -ffreestanding # carefully avoid to add it redundantly because gcc 3.3/3.4 complains # when fed the toolchain default! # -# Certain gcc versions upto gcc 4.1.1 (probably 4.2-subversion as of +# Certain gcc versions up to gcc 4.1.1 (probably 4.2-subversion as of # 2006-10-10 don't properly change the predefined symbols if -EB / -EL # are used, so we kludge that here. A bug has been filed at # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29413. @@ -314,5 +314,5 @@ define archhelp echo ' vmlinuz.bin - Raw binary zboot image' echo ' vmlinuz.srec - SREC zboot image' echo - echo ' These will be default as apropriate for a configured platform.' + echo ' These will be default as appropriate for a configured platform.' endef diff --git a/arch/mips/alchemy/common/clocks.c b/arch/mips/alchemy/common/clocks.c index af0fe41055af..f38298a8b98c 100644 --- a/arch/mips/alchemy/common/clocks.c +++ b/arch/mips/alchemy/common/clocks.c @@ -75,7 +75,7 @@ void set_au1x00_uart_baud_base(unsigned long new_baud_base) * counter, if it exists. If we don't have an accurate processor * speed, all of the peripherals that derive their clocks based on * this advertised speed will introduce error and sometimes not work - * properly. This function is futher convoluted to still allow configurations + * properly. This function is further convoluted to still allow configurations * to do that in case they have really, really old silicon with a * write-only PLL register. -- Dan */ diff --git a/arch/mips/cavium-octeon/executive/octeon-model.c b/arch/mips/cavium-octeon/executive/octeon-model.c index 9afc3794ed1b..c8d35684504e 100644 --- a/arch/mips/cavium-octeon/executive/octeon-model.c +++ b/arch/mips/cavium-octeon/executive/octeon-model.c @@ -75,7 +75,7 @@ const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer) num_cores = cvmx_octeon_num_cores(); - /* Make sure the non existant devices look disabled */ + /* Make sure the non existent devices look disabled */ switch ((chip_id >> 8) & 0xff) { case 6: /* CN50XX */ case 2: /* CN30XX */ diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c index cecaf62aef32..cd61d7281d91 100644 --- a/arch/mips/cavium-octeon/octeon-platform.c +++ b/arch/mips/cavium-octeon/octeon-platform.c @@ -75,7 +75,7 @@ static int __init octeon_cf_device_init(void) * zero. */ - /* Asume that CS1 immediately follows. */ + /* Assume that CS1 immediately follows. */ mio_boot_reg_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(i + 1)); region_base = mio_boot_reg_cfg.s.base << 16; diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c index 8b139bf4a1b5..0707fae3f0ee 100644 --- a/arch/mips/cavium-octeon/setup.c +++ b/arch/mips/cavium-octeon/setup.c @@ -662,7 +662,7 @@ void __init plat_mem_setup(void) * some memory vectors. When SPARSEMEM is in use, it doesn't * verify that the size is big enough for the final * vectors. Making the smallest chuck 4MB seems to be enough - * to consistantly work. + * to consistently work. */ mem_alloc_size = 4 << 20; if (mem_alloc_size > MAX_MEMORY) diff --git a/arch/mips/fw/arc/promlib.c b/arch/mips/fw/arc/promlib.c index c508c00dbb64..b7f9dd3c93c6 100644 --- a/arch/mips/fw/arc/promlib.c +++ b/arch/mips/fw/arc/promlib.c @@ -4,7 +4,7 @@ * for more details. * * Copyright (C) 1996 David S. Miller (dm@sgi.com) - * Compability with board caches, Ulf Carlsson + * Compatibility with board caches, Ulf Carlsson */ #include #include diff --git a/arch/mips/include/asm/dec/prom.h b/arch/mips/include/asm/dec/prom.h index b9c8203688d5..c0ead6313845 100644 --- a/arch/mips/include/asm/dec/prom.h +++ b/arch/mips/include/asm/dec/prom.h @@ -108,7 +108,7 @@ extern int (*__pmax_close)(int); /* * On MIPS64 we have to call PROM functions via a helper - * dispatcher to accomodate ABI incompatibilities. + * dispatcher to accommodate ABI incompatibilities. */ #define __DEC_PROM_O32(fun, arg) fun arg __asm__(#fun); \ __asm__(#fun " = call_o32") diff --git a/arch/mips/include/asm/floppy.h b/arch/mips/include/asm/floppy.h index 992d232adc83..c5c7c0e6064c 100644 --- a/arch/mips/include/asm/floppy.h +++ b/arch/mips/include/asm/floppy.h @@ -24,7 +24,7 @@ static inline void fd_cacheflush(char * addr, long size) * And on Mips's the CMOS info fails also ... * * FIXME: This information should come from the ARC configuration tree - * or whereever a particular machine has stored this ... + * or wherever a particular machine has stored this ... */ #define FLOPPY0_TYPE fd_drive_type(0) #define FLOPPY1_TYPE fd_drive_type(1) diff --git a/arch/mips/include/asm/hw_irq.h b/arch/mips/include/asm/hw_irq.h index aca05a43a97b..77adda297ad9 100644 --- a/arch/mips/include/asm/hw_irq.h +++ b/arch/mips/include/asm/hw_irq.h @@ -13,7 +13,7 @@ extern atomic_t irq_err_count; /* - * interrupt-retrigger: NOP for now. This may not be apropriate for all + * interrupt-retrigger: NOP for now. This may not be appropriate for all * machines, we'll see ... */ diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h index 5b017f23e243..b04e4de5dd2e 100644 --- a/arch/mips/include/asm/io.h +++ b/arch/mips/include/asm/io.h @@ -242,7 +242,7 @@ static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size, * This version of ioremap ensures that the memory is marked uncachable * on the CPU as well as honouring existing caching rules from things like * the PCI bus. Note that there are other caches and buffers on many - * busses. In paticular driver authors should read up on PCI writes + * busses. In particular driver authors should read up on PCI writes * * It's useful if some control registers are in such an area and * write combining or read caching is not desirable: diff --git a/arch/mips/include/asm/irqflags.h b/arch/mips/include/asm/irqflags.h index 9ef3b0d17896..309cbcd6909c 100644 --- a/arch/mips/include/asm/irqflags.h +++ b/arch/mips/include/asm/irqflags.h @@ -174,7 +174,7 @@ __asm__( "mtc0 \\flags, $2, 1 \n" #elif defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU) /* - * Slow, but doesn't suffer from a relativly unlikely race + * Slow, but doesn't suffer from a relatively unlikely race * condition we're having since days 1. */ " beqz \\flags, 1f \n" diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h b/arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h index 5325084d5c48..32978d32561a 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h @@ -4,7 +4,7 @@ #define TAGVER_LEN 4 /* Length of Tag Version */ #define TAGLAYOUT_LEN 4 /* Length of FlashLayoutVer */ #define SIG1_LEN 20 /* Company Signature 1 Length */ -#define SIG2_LEN 14 /* Company Signature 2 Lenght */ +#define SIG2_LEN 14 /* Company Signature 2 Length */ #define BOARDID_LEN 16 /* Length of BoardId */ #define ENDIANFLAG_LEN 2 /* Endian Flag Length */ #define CHIPID_LEN 6 /* Chip Id Length */ diff --git a/arch/mips/include/asm/mach-ip32/mc146818rtc.h b/arch/mips/include/asm/mach-ip32/mc146818rtc.h index c28ba8d84076..6b6bab43d5c1 100644 --- a/arch/mips/include/asm/mach-ip32/mc146818rtc.h +++ b/arch/mips/include/asm/mach-ip32/mc146818rtc.h @@ -26,7 +26,7 @@ static inline void CMOS_WRITE(unsigned char data, unsigned long addr) } /* - * FIXME: Do it right. For now just assume that noone lives in 20th century + * FIXME: Do it right. For now just assume that no one lives in 20th century * and no O2 user in 22th century ;-) */ #define mc146818_decode_year(year) ((year) + 2000) diff --git a/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h b/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h index 021f77ca59ec..2a8e2bb5d539 100644 --- a/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h +++ b/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h @@ -1,5 +1,5 @@ /* - * The header file of cs5536 sourth bridge. + * The header file of cs5536 south bridge. * * Copyright (C) 2007 Lemote, Inc. * Author : jlliu diff --git a/arch/mips/include/asm/mach-pb1x00/pb1000.h b/arch/mips/include/asm/mach-pb1x00/pb1000.h index 6d1ff9060e44..65059255dc1e 100644 --- a/arch/mips/include/asm/mach-pb1x00/pb1000.h +++ b/arch/mips/include/asm/mach-pb1x00/pb1000.h @@ -1,5 +1,5 @@ /* - * Alchemy Semi Pb1000 Referrence Board + * Alchemy Semi Pb1000 Reference Board * * Copyright 2001, 2008 MontaVista Software Inc. * Author: MontaVista Software, Inc. diff --git a/arch/mips/include/asm/mach-pb1x00/pb1200.h b/arch/mips/include/asm/mach-pb1x00/pb1200.h index 962eb55dc880..fce4332ebb7f 100644 --- a/arch/mips/include/asm/mach-pb1x00/pb1200.h +++ b/arch/mips/include/asm/mach-pb1x00/pb1200.h @@ -1,5 +1,5 @@ /* - * AMD Alchemy Pb1200 Referrence Board + * AMD Alchemy Pb1200 Reference Board * Board Registers defines. * * ######################################################################## diff --git a/arch/mips/include/asm/mach-pb1x00/pb1550.h b/arch/mips/include/asm/mach-pb1x00/pb1550.h index fc4d766641ce..f835c88e9593 100644 --- a/arch/mips/include/asm/mach-pb1x00/pb1550.h +++ b/arch/mips/include/asm/mach-pb1x00/pb1550.h @@ -1,5 +1,5 @@ /* - * AMD Alchemy Semi PB1550 Referrence Board + * AMD Alchemy Semi PB1550 Reference Board * Board Registers defines. * * Copyright 2004 Embedded Edge LLC. diff --git a/arch/mips/include/asm/mach-powertv/dma-coherence.h b/arch/mips/include/asm/mach-powertv/dma-coherence.h index f76029c2406e..a8e72cf12142 100644 --- a/arch/mips/include/asm/mach-powertv/dma-coherence.h +++ b/arch/mips/include/asm/mach-powertv/dma-coherence.h @@ -48,7 +48,7 @@ static inline unsigned long virt_to_phys_from_pte(void *addr) /* check for a valid page */ if (pte_present(pte)) { /* get the physical address the page is - * refering to */ + * referring to */ phys_addr = (unsigned long) page_to_phys(pte_page(pte)); /* add the offset within the page */ diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index 4d9870975382..6a6f8a8f542d 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -922,7 +922,7 @@ do { \ #define write_c0_config7(val) __write_32bit_c0_register($16, 7, val) /* - * The WatchLo register. There may be upto 8 of them. + * The WatchLo register. There may be up to 8 of them. */ #define read_c0_watchlo0() __read_ulong_c0_register($18, 0) #define read_c0_watchlo1() __read_ulong_c0_register($18, 1) @@ -942,7 +942,7 @@ do { \ #define write_c0_watchlo7(val) __write_ulong_c0_register($18, 7, val) /* - * The WatchHi register. There may be upto 8 of them. + * The WatchHi register. There may be up to 8 of them. */ #define read_c0_watchhi0() __read_32bit_c0_register($19, 0) #define read_c0_watchhi1() __read_32bit_c0_register($19, 1) diff --git a/arch/mips/include/asm/octeon/cvmx-bootinfo.h b/arch/mips/include/asm/octeon/cvmx-bootinfo.h index f3c23a43f845..4e4c3a8282d6 100644 --- a/arch/mips/include/asm/octeon/cvmx-bootinfo.h +++ b/arch/mips/include/asm/octeon/cvmx-bootinfo.h @@ -200,7 +200,7 @@ enum cvmx_chip_types_enum { CVMX_CHIP_TYPE_MAX, }; -/* Compatability alias for NAC38 name change, planned to be removed +/* Compatibility alias for NAC38 name change, planned to be removed * from SDK 1.7 */ #define CVMX_BOARD_TYPE_NAO38 CVMX_BOARD_TYPE_NAC38 diff --git a/arch/mips/include/asm/octeon/cvmx-bootmem.h b/arch/mips/include/asm/octeon/cvmx-bootmem.h index 8e708bdb43f7..877845b84b14 100644 --- a/arch/mips/include/asm/octeon/cvmx-bootmem.h +++ b/arch/mips/include/asm/octeon/cvmx-bootmem.h @@ -67,7 +67,7 @@ struct cvmx_bootmem_block_header { /* * Structure for named memory blocks. Number of descriptors available - * can be changed without affecting compatiblity, but name length + * can be changed without affecting compatibility, but name length * changes require a bump in the bootmem descriptor version Note: This * structure must be naturally 64 bit aligned, as a single memory * image will be used by both 32 and 64 bit programs. diff --git a/arch/mips/include/asm/octeon/cvmx-l2c.h b/arch/mips/include/asm/octeon/cvmx-l2c.h index 0b32c5b118e2..2c8ff9e33ec3 100644 --- a/arch/mips/include/asm/octeon/cvmx-l2c.h +++ b/arch/mips/include/asm/octeon/cvmx-l2c.h @@ -157,7 +157,7 @@ enum cvmx_l2c_tad_event { /** * Configure one of the four L2 Cache performance counters to capture event - * occurences. + * occurrences. * * @counter: The counter to configure. Range 0..3. * @event: The type of L2 Cache event occurrence to count. diff --git a/arch/mips/include/asm/octeon/cvmx.h b/arch/mips/include/asm/octeon/cvmx.h index 9d9381e2e3d8..7e1286706d46 100644 --- a/arch/mips/include/asm/octeon/cvmx.h +++ b/arch/mips/include/asm/octeon/cvmx.h @@ -151,7 +151,7 @@ enum cvmx_mips_space { #endif /** - * Convert a memory pointer (void*) into a hardware compatable + * Convert a memory pointer (void*) into a hardware compatible * memory address (uint64_t). Octeon hardware widgets don't * understand logical addresses. * diff --git a/arch/mips/include/asm/paccess.h b/arch/mips/include/asm/paccess.h index c2394f8b0fe1..9ce5a1e7e14c 100644 --- a/arch/mips/include/asm/paccess.h +++ b/arch/mips/include/asm/paccess.h @@ -7,7 +7,7 @@ * Copyright (C) 1999, 2000 Silicon Graphics, Inc. * * Protected memory access. Used for everything that might take revenge - * by sending a DBE error like accessing possibly non-existant memory or + * by sending a DBE error like accessing possibly non-existent memory or * devices. */ #ifndef _ASM_PACCESS_H diff --git a/arch/mips/include/asm/pci/bridge.h b/arch/mips/include/asm/pci/bridge.h index f1f508e4f971..be44fb0266da 100644 --- a/arch/mips/include/asm/pci/bridge.h +++ b/arch/mips/include/asm/pci/bridge.h @@ -262,7 +262,7 @@ typedef volatile struct bridge_s { } bridge_t; /* - * Field formats for Error Command Word and Auxillary Error Command Word + * Field formats for Error Command Word and Auxiliary Error Command Word * of bridge. */ typedef struct bridge_err_cmdword_s { diff --git a/arch/mips/include/asm/pmc-sierra/msp71xx/msp_regops.h b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_regops.h index 60a5a38dd5b2..7d41474e5488 100644 --- a/arch/mips/include/asm/pmc-sierra/msp71xx/msp_regops.h +++ b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_regops.h @@ -205,7 +205,7 @@ static inline u32 blocking_read_reg32(volatile u32 *const addr) * custom_read_reg32(address, tmp); <-- Reads the address and put the value * in the 'tmp' variable given * - * From here on out, you are (basicly) atomic, so don't do anything too + * From here on out, you are (basically) atomic, so don't do anything too * fancy! * Also, this code may loop if the end of this block fails to write * everything back safely due do the other CPU, so do NOT do anything diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h index ead6928fa6b8..c104f1039a69 100644 --- a/arch/mips/include/asm/processor.h +++ b/arch/mips/include/asm/processor.h @@ -337,7 +337,7 @@ unsigned long get_wchan(struct task_struct *p); /* * Return_address is a replacement for __builtin_return_address(count) * which on certain architectures cannot reasonably be implemented in GCC - * (MIPS, Alpha) or is unuseable with -fomit-frame-pointer (i386). + * (MIPS, Alpha) or is unusable with -fomit-frame-pointer (i386). * Note that __builtin_return_address(x>=1) is forbidden because GCC * aborts compilation on some CPUs. It's simply not possible to unwind * some CPU's stackframes. diff --git a/arch/mips/include/asm/sgi/ioc.h b/arch/mips/include/asm/sgi/ioc.h index 57a971904cfe..380347b648e2 100644 --- a/arch/mips/include/asm/sgi/ioc.h +++ b/arch/mips/include/asm/sgi/ioc.h @@ -17,7 +17,7 @@ #include /* - * All registers are 8-bit wide alligned on 32-bit boundary. Bad things + * All registers are 8-bit wide aligned on 32-bit boundary. Bad things * happen if you try word access them. You have been warned. */ diff --git a/arch/mips/include/asm/sibyte/sb1250_mac.h b/arch/mips/include/asm/sibyte/sb1250_mac.h index 591b9061fd8e..77f787284235 100644 --- a/arch/mips/include/asm/sibyte/sb1250_mac.h +++ b/arch/mips/include/asm/sibyte/sb1250_mac.h @@ -520,7 +520,7 @@ #define G_MAC_RX_EOP_COUNTER(x) _SB_GETVALUE(x, S_MAC_RX_EOP_COUNTER, M_MAC_RX_EOP_COUNTER) /* - * MAC Recieve Address Filter Exact Match Registers (Table 9-21) + * MAC Receive Address Filter Exact Match Registers (Table 9-21) * Registers: MAC_ADDR0_0 through MAC_ADDR7_0 * Registers: MAC_ADDR0_1 through MAC_ADDR7_1 * Registers: MAC_ADDR0_2 through MAC_ADDR7_2 @@ -538,7 +538,7 @@ /* No bitfields */ /* - * MAC Recieve Address Filter Hash Match Registers (Table 9-22) + * MAC Receive Address Filter Hash Match Registers (Table 9-22) * Registers: MAC_HASH0_0 through MAC_HASH7_0 * Registers: MAC_HASH0_1 through MAC_HASH7_1 * Registers: MAC_HASH0_2 through MAC_HASH7_2 diff --git a/arch/mips/include/asm/siginfo.h b/arch/mips/include/asm/siginfo.h index 1ca64b4d33d9..20ebeb875ee6 100644 --- a/arch/mips/include/asm/siginfo.h +++ b/arch/mips/include/asm/siginfo.h @@ -101,7 +101,7 @@ typedef struct siginfo { /* * si_code values - * Again these have been choosen to be IRIX compatible. + * Again these have been chosen to be IRIX compatible. */ #undef SI_ASYNCIO #undef SI_TIMER diff --git a/arch/mips/include/asm/sn/klconfig.h b/arch/mips/include/asm/sn/klconfig.h index 09e590daca17..fe02900b930d 100644 --- a/arch/mips/include/asm/sn/klconfig.h +++ b/arch/mips/include/asm/sn/klconfig.h @@ -78,7 +78,7 @@ typedef s32 klconf_off_t; */ #define MAX_SLOTS_PER_NODE (1 + 2 + 6 + 2) -/* XXX if each node is guranteed to have some memory */ +/* XXX if each node is guaranteed to have some memory */ #define MAX_PCI_DEVS 8 @@ -539,7 +539,7 @@ typedef struct klinfo_s { /* Generic info */ #define KLSTRUCT_IOC3_TTY 24 /* Early Access IO proms are compatible - only with KLSTRUCT values upto 24. */ + only with KLSTRUCT values up to 24. */ #define KLSTRUCT_FIBERCHANNEL 25 #define KLSTRUCT_MOD_SERIAL_NUM 26 diff --git a/arch/mips/include/asm/sn/sn0/hubio.h b/arch/mips/include/asm/sn/sn0/hubio.h index 31c76c021bb6..46286d8302a7 100644 --- a/arch/mips/include/asm/sn/sn0/hubio.h +++ b/arch/mips/include/asm/sn/sn0/hubio.h @@ -622,7 +622,7 @@ typedef union h1_icrbb_u { */ #define IIO_ICRB_PROC0 0 /* Source of request is Proc 0 */ #define IIO_ICRB_PROC1 1 /* Source of request is Proc 1 */ -#define IIO_ICRB_GB_REQ 2 /* Source is Guranteed BW request */ +#define IIO_ICRB_GB_REQ 2 /* Source is Guaranteed BW request */ #define IIO_ICRB_IO_REQ 3 /* Source is Normal IO request */ /* diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h index 58730c5ce4bf..b4ba2449444b 100644 --- a/arch/mips/include/asm/stackframe.h +++ b/arch/mips/include/asm/stackframe.h @@ -346,7 +346,7 @@ * we can't dispatch it directly without trashing * some registers, so we'll try to detect this unlikely * case and program a software interrupt in the VPE, - * as would be done for a cross-VPE IPI. To accomodate + * as would be done for a cross-VPE IPI. To accommodate * the handling of that case, we're doing a DVPE instead * of just a DMT here to protect against other threads. * This is a lot of cruft to cover a tiny window. diff --git a/arch/mips/include/asm/war.h b/arch/mips/include/asm/war.h index 22361d5e3bf0..fa133c1bc1f9 100644 --- a/arch/mips/include/asm/war.h +++ b/arch/mips/include/asm/war.h @@ -227,7 +227,7 @@ #endif /* - * On the R10000 upto version 2.6 (not sure about 2.7) there is a bug that + * On the R10000 up to version 2.6 (not sure about 2.7) there is a bug that * may cause ll / sc and lld / scd sequences to execute non-atomically. */ #ifndef R10000_LLSC_WAR diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c index bc18daaa8f84..c3b04be3fb2b 100644 --- a/arch/mips/jz4740/board-qi_lb60.c +++ b/arch/mips/jz4740/board-qi_lb60.c @@ -65,7 +65,7 @@ static struct nand_ecclayout qi_lb60_ecclayout_1gb = { }; /* Early prototypes of the QI LB60 had only 1GB of NAND. - * In order to support these devices aswell the partition and ecc layout is + * In order to support these devices as well the partition and ecc layout is * initialized depending on the NAND size */ static struct mtd_partition qi_lb60_partitions_1gb[] = { { @@ -439,7 +439,7 @@ static struct platform_device *jz_platform_devices[] __initdata = { static void __init board_gpio_setup(void) { /* We only need to enable/disable pullup here for pins used in generic - * drivers. Everything else is done by the drivers themselfs. */ + * drivers. Everything else is done by the drivers themselves. */ jz_gpio_disable_pullup(QI_LB60_GPIO_SD_VCC_EN_N); jz_gpio_disable_pullup(QI_LB60_GPIO_SD_CD); } diff --git a/arch/mips/kernel/cpu-bugs64.c b/arch/mips/kernel/cpu-bugs64.c index b8bb8ba60869..f305ca14351b 100644 --- a/arch/mips/kernel/cpu-bugs64.c +++ b/arch/mips/kernel/cpu-bugs64.c @@ -73,7 +73,7 @@ static inline void mult_sh_align_mod(long *v1, long *v2, long *w, : "0" (5), "1" (8), "2" (5)); align_mod(align, mod); /* - * The trailing nop is needed to fullfill the two-instruction + * The trailing nop is needed to fulfill the two-instruction * requirement between reading hi/lo and staring a mult/div. * Leaving it out may cause gas insert a nop itself breaking * the desired alignment of the next chunk. diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c index d9a7db78ed62..75266ff4cc33 100644 --- a/arch/mips/kernel/perf_event_mipsxx.c +++ b/arch/mips/kernel/perf_event_mipsxx.c @@ -721,7 +721,7 @@ static void mipsxx_pmu_start(void) /* * MIPS performance counters can be per-TC. The control registers can - * not be directly accessed accross CPUs. Hence if we want to do global + * not be directly accessed across CPUs. Hence if we want to do global * control, we need cross CPU calls. on_each_cpu() can help us, but we * can not make sure this function is called with interrupts enabled. So * here we pause local counters and then grab a rwlock and leave the diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index ae167df73ddd..d2112d3cf115 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -410,7 +410,7 @@ unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, if (!kallsyms_lookup_size_offset(pc, &size, &ofs)) return 0; /* - * Return ra if an exception occured at the first instruction + * Return ra if an exception occurred at the first instruction */ if (unlikely(ofs == 0)) { pc = *ra; diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c index c0e81418ba21..1ec56e635d04 100644 --- a/arch/mips/kernel/smp-mt.c +++ b/arch/mips/kernel/smp-mt.c @@ -120,7 +120,7 @@ static void vsmp_send_ipi_single(int cpu, unsigned int action) local_irq_save(flags); - vpflags = dvpe(); /* cant access the other CPU's registers whilst MVPE enabled */ + vpflags = dvpe(); /* can't access the other CPU's registers whilst MVPE enabled */ switch (action) { case SMP_CALL_FUNCTION: diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index fb7497405510..1083ad4e1017 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c @@ -102,7 +102,7 @@ static __init int cpu_has_mfc0_count_bug(void) case CPU_R4400SC: case CPU_R4400MC: /* - * The published errata for the R4400 upto 3.0 say the CPU + * The published errata for the R4400 up to 3.0 say the CPU * has the mfc0 from count bug. */ if ((current_cpu_data.processor_id & 0xff) <= 0x30) diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index ab52b7cf3b6b..dbb6b408f001 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c @@ -19,7 +19,7 @@ * VPE support module * * Provides support for loading a MIPS SP program on VPE1. - * The SP enviroment is rather simple, no tlb's. It needs to be relocatable + * The SP environment is rather simple, no tlb's. It needs to be relocatable * (or partially linked). You should initialise your stack in the startup * code. This loader looks for the symbol __start and sets up * execution to resume from there. The MIPS SDE kit contains suitable examples. diff --git a/arch/mips/lib/strnlen_user.S b/arch/mips/lib/strnlen_user.S index c768e3000616..64457162f7e0 100644 --- a/arch/mips/lib/strnlen_user.S +++ b/arch/mips/lib/strnlen_user.S @@ -17,7 +17,7 @@ .previous /* - * Return the size of a string including the ending NUL character upto a + * Return the size of a string including the ending NUL character up to a * maximum of a1 or 0 in case of error. * * Note: for performance reasons we deliberately accept that a user may diff --git a/arch/mips/math-emu/dp_fsp.c b/arch/mips/math-emu/dp_fsp.c index 1dfbd92ba9d0..daed6834dc15 100644 --- a/arch/mips/math-emu/dp_fsp.c +++ b/arch/mips/math-emu/dp_fsp.c @@ -62,7 +62,7 @@ ieee754dp ieee754dp_fsp(ieee754sp x) break; } - /* CANT possibly overflow,underflow, or need rounding + /* CAN'T possibly overflow,underflow, or need rounding */ /* drop the hidden bit */ diff --git a/arch/mips/math-emu/dp_mul.c b/arch/mips/math-emu/dp_mul.c index aa566e785f5a..09175f461920 100644 --- a/arch/mips/math-emu/dp_mul.c +++ b/arch/mips/math-emu/dp_mul.c @@ -104,7 +104,7 @@ ieee754dp ieee754dp_mul(ieee754dp x, ieee754dp y) case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): break; } - /* rm = xm * ym, re = xe+ye basicly */ + /* rm = xm * ym, re = xe+ye basically */ assert(xm & DP_HIDDEN_BIT); assert(ym & DP_HIDDEN_BIT); { diff --git a/arch/mips/math-emu/dsemul.c b/arch/mips/math-emu/dsemul.c index 36d975ae08f8..3c4a8c5ba7f2 100644 --- a/arch/mips/math-emu/dsemul.c +++ b/arch/mips/math-emu/dsemul.c @@ -32,7 +32,7 @@ * not change cp0_epc due to the instruction * * According to the spec: - * 1) it shouldnt be a branch :-) + * 1) it shouldn't be a branch :-) * 2) it can be a COP instruction :-( * 3) if we are tring to run a protected memory space we must take * special care on memory access instructions :-( diff --git a/arch/mips/math-emu/sp_mul.c b/arch/mips/math-emu/sp_mul.c index c06bb4022be5..2722a2570ea4 100644 --- a/arch/mips/math-emu/sp_mul.c +++ b/arch/mips/math-emu/sp_mul.c @@ -104,7 +104,7 @@ ieee754sp ieee754sp_mul(ieee754sp x, ieee754sp y) case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): break; } - /* rm = xm * ym, re = xe+ye basicly */ + /* rm = xm * ym, re = xe+ye basically */ assert(xm & SP_HIDDEN_BIT); assert(ym & SP_HIDDEN_BIT); diff --git a/arch/mips/mm/cex-sb1.S b/arch/mips/mm/cex-sb1.S index 2d08268bb705..89c412bc4b64 100644 --- a/arch/mips/mm/cex-sb1.S +++ b/arch/mips/mm/cex-sb1.S @@ -79,7 +79,7 @@ LEAF(except_vec2_sb1) recovered_dcache: /* * Unlock CacheErr-D (which in turn unlocks CacheErr-DPA). - * Ought to log the occurence of this recovered dcache error. + * Ought to log the occurrence of this recovered dcache error. */ b recovered mtc0 $0,C0_CERR_D diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 04f9e17db9d0..5ef294fbb6e7 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -352,7 +352,7 @@ static void __cpuinit __maybe_unused build_tlb_probe_entry(u32 **p) /* * Write random or indexed TLB entry, and care about the hazards from - * the preceeding mtc0 and for the following eret. + * the preceding mtc0 and for the following eret. */ enum tlb_write_entry { tlb_random, tlb_indexed }; diff --git a/arch/mips/mti-malta/malta-smtc.c b/arch/mips/mti-malta/malta-smtc.c index e67891521ac1..49a38b09a488 100644 --- a/arch/mips/mti-malta/malta-smtc.c +++ b/arch/mips/mti-malta/malta-smtc.c @@ -130,7 +130,7 @@ int plat_set_irq_affinity(struct irq_data *d, const struct cpumask *affinity, * cleared in the affinity mask, there will never be any * interrupt forwarding. But as soon as a program or operator * sets affinity for one of the related IRQs, we need to make - * sure that we don't ever try to forward across the VPE boundry, + * sure that we don't ever try to forward across the VPE boundary, * at least not until we engineer a system where the interrupt * _ack() or _end() function can somehow know that it corresponds * to an interrupt taken on another VPE, and perform the appropriate diff --git a/arch/mips/pci/ops-pmcmsp.c b/arch/mips/pci/ops-pmcmsp.c index 68798f869c0f..8fbfbf2b931c 100644 --- a/arch/mips/pci/ops-pmcmsp.c +++ b/arch/mips/pci/ops-pmcmsp.c @@ -344,7 +344,7 @@ static irqreturn_t bpci_interrupt(int irq, void *dev_id) * PCI_ACCESS_WRITE and PCI_ACCESS_READ. * * bus - pointer to the bus number of the device to - * be targetted for the configuration cycle. + * be targeted for the configuration cycle. * The only element of the pci_bus structure * used is bus->number. This argument determines * if the configuration access will be Type 0 or @@ -354,7 +354,7 @@ static irqreturn_t bpci_interrupt(int irq, void *dev_id) * * devfn - this is an 8-bit field. The lower three bits * specify the function number of the device to - * be targetted for the configuration cycle, with + * be targeted for the configuration cycle, with * all three-bit combinations being legal. The * upper five bits specify the device number, * with legal values being 10 to 31. diff --git a/arch/mips/pci/pci-bcm1480.c b/arch/mips/pci/pci-bcm1480.c index 6f5e24c6ae67..af8c31996965 100644 --- a/arch/mips/pci/pci-bcm1480.c +++ b/arch/mips/pci/pci-bcm1480.c @@ -210,7 +210,7 @@ static int __init bcm1480_pcibios_init(void) PCIBIOS_MIN_IO = 0x00008000UL; PCIBIOS_MIN_MEM = 0x01000000UL; - /* Set I/O resource limits. - unlimited for now to accomodate HT */ + /* Set I/O resource limits. - unlimited for now to accommodate HT */ ioport_resource.end = 0xffffffffUL; iomem_resource.end = 0xffffffffUL; diff --git a/arch/mips/pci/pci-octeon.c b/arch/mips/pci/pci-octeon.c index 2d74fc9ae3ba..ed1c54284b8f 100644 --- a/arch/mips/pci/pci-octeon.c +++ b/arch/mips/pci/pci-octeon.c @@ -441,7 +441,7 @@ static void octeon_pci_initialize(void) /* * TDOMC must be set to one in PCI mode. TDOMC should be set to 4 - * in PCI-X mode to allow four oustanding splits. Otherwise, + * in PCI-X mode to allow four outstanding splits. Otherwise, * should not change from its reset value. Don't write PCI_CFG19 * in PCI mode (0x82000001 reset value), write it to 0x82000004 * after PCI-X mode is known. MRBCI,MDWE,MDRE -> must be zero. @@ -515,7 +515,7 @@ static void octeon_pci_initialize(void) #endif /* USE_OCTEON_INTERNAL_ARBITER */ /* - * Preferrably written to 1 to set MLTD. [RDSATI,TRTAE, + * Preferably written to 1 to set MLTD. [RDSATI,TRTAE, * TWTAE,TMAE,DPPMR -> must be zero. TILT -> must not be set to * 1..7. */ diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index 38bc28005b4a..33bba7bff258 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c @@ -125,7 +125,7 @@ void __devinit register_pci_controller(struct pci_controller *hose) hose_tail = &hose->next; /* - * Do not panic here but later - this might hapen before console init. + * Do not panic here but later - this might happen before console init. */ if (!hose->io_map_base) { printk(KERN_WARNING diff --git a/arch/mips/pmc-sierra/msp71xx/msp_setup.c b/arch/mips/pmc-sierra/msp71xx/msp_setup.c index fb37a10e0309..2413ea67877e 100644 --- a/arch/mips/pmc-sierra/msp71xx/msp_setup.c +++ b/arch/mips/pmc-sierra/msp71xx/msp_setup.c @@ -239,7 +239,7 @@ void __init prom_init(void) #ifdef CONFIG_PMCTWILED /* * Setup LED states before the subsys_initcall loads other - * dependant drivers/modules. + * dependent drivers/modules. */ pmctwiled_setup(); #endif diff --git a/arch/mips/pnx833x/common/platform.c b/arch/mips/pnx833x/common/platform.c index ce45df17fd09..87167dcc79fa 100644 --- a/arch/mips/pnx833x/common/platform.c +++ b/arch/mips/pnx833x/common/platform.c @@ -165,7 +165,7 @@ static struct i2c_pnx0105_dev pnx833x_i2c_dev[] = { { .base = PNX833X_I2C0_PORTS_START, .irq = -1, /* should be PNX833X_PIC_I2C0_INT but polling is faster */ - .clock = 6, /* 0 == 400 kHz, 4 == 100 kHz(Maximum HDMI), 6 = 50kHz(Prefered HDCP) */ + .clock = 6, /* 0 == 400 kHz, 4 == 100 kHz(Maximum HDMI), 6 = 50kHz(Preferred HDCP) */ .bus_addr = 0, /* no slave support */ }, { diff --git a/arch/mips/sgi-ip27/Kconfig b/arch/mips/sgi-ip27/Kconfig index 5e960ae9735a..bc5e9769bb73 100644 --- a/arch/mips/sgi-ip27/Kconfig +++ b/arch/mips/sgi-ip27/Kconfig @@ -1,7 +1,7 @@ #config SGI_SN0_XXL # bool "IP27 XXL" # depends on SGI_IP27 -# This options adds support for userspace processes upto 16TB size. +# This options adds support for userspace processes up to 16TB size. # Normally the limit is just .5TB. choice diff --git a/arch/mips/sgi-ip27/TODO b/arch/mips/sgi-ip27/TODO index 19f1512c8f2e..160857ff1483 100644 --- a/arch/mips/sgi-ip27/TODO +++ b/arch/mips/sgi-ip27/TODO @@ -13,7 +13,7 @@ being invoked on all nodes in ip27-memory.c. 9. start_thread must turn off UX64 ... and define tlb_refill_debug. 10. Need a bad pmd table, bad pte table. __bad_pmd_table/__bad_pagetable does not agree with pgd_bad/pmd_bad. -11. All intrs (ip27_do_irq handlers) are targetted at cpu A on the node. +11. All intrs (ip27_do_irq handlers) are targeted at cpu A on the node. This might need to change later. Only the timer intr is set up to be received on both Cpu A and B. (ip27_do_irq()/bridge_startup()) 13. Cache flushing (specially the SMP version) has to be investigated. diff --git a/arch/mips/sgi-ip27/ip27-init.c b/arch/mips/sgi-ip27/ip27-init.c index 51d3a4f2d7e1..923c080f77bd 100644 --- a/arch/mips/sgi-ip27/ip27-init.c +++ b/arch/mips/sgi-ip27/ip27-init.c @@ -93,7 +93,7 @@ static void __cpuinit per_hub_init(cnodeid_t cnode) /* * Some interrupts are reserved by hardware or by software convention. - * Mark these as reserved right away so they won't be used accidently + * Mark these as reserved right away so they won't be used accidentally * later. */ for (i = 0; i <= BASE_PCI_IRQ; i++) { diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c index 11488719dd97..0a04603d577c 100644 --- a/arch/mips/sgi-ip27/ip27-irq.c +++ b/arch/mips/sgi-ip27/ip27-irq.c @@ -41,7 +41,7 @@ * Linux has a controller-independent x86 interrupt architecture. * every controller has a 'controller-template', that is used * by the main code to do the right thing. Each driver-visible - * interrupt source is transparently wired to the apropriate + * interrupt source is transparently wired to the appropriate * controller. Thus drivers need not be aware of the * interrupt-controller. * diff --git a/arch/mn10300/include/asm/cpu-regs.h b/arch/mn10300/include/asm/cpu-regs.h index 90ed4a365c97..c54effae2202 100644 --- a/arch/mn10300/include/asm/cpu-regs.h +++ b/arch/mn10300/include/asm/cpu-regs.h @@ -49,7 +49,7 @@ asm(" .am33_2\n"); #define EPSW_IM_6 0x00000600 /* interrupt mode 6 */ #define EPSW_IM_7 0x00000700 /* interrupt mode 7 */ #define EPSW_IE 0x00000800 /* interrupt enable */ -#define EPSW_S 0x00003000 /* software auxilliary bits */ +#define EPSW_S 0x00003000 /* software auxiliary bits */ #define EPSW_T 0x00008000 /* trace enable */ #define EPSW_nSL 0x00010000 /* not supervisor level */ #define EPSW_NMID 0x00020000 /* nonmaskable interrupt disable */ diff --git a/arch/parisc/include/asm/eisa_eeprom.h b/arch/parisc/include/asm/eisa_eeprom.h index 9c9da980402a..8ce8b85ca588 100644 --- a/arch/parisc/include/asm/eisa_eeprom.h +++ b/arch/parisc/include/asm/eisa_eeprom.h @@ -27,7 +27,7 @@ struct eeprom_header u_int8_t ver_maj; u_int8_t ver_min; u_int8_t num_slots; /* number of EISA slots in system */ - u_int16_t csum; /* checksum, I don't know how to calulate this */ + u_int16_t csum; /* checksum, I don't know how to calculate this */ u_int8_t pad[10]; } __attribute__ ((packed)); diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index e5477092a5d4..ead8d2a1034c 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -187,8 +187,8 @@ /* Register definitions for tlb miss handler macros */ - va = r8 /* virtual address for which the trap occured */ - spc = r24 /* space for which the trap occured */ + va = r8 /* virtual address for which the trap occurred */ + spc = r24 /* space for which the trap occurred */ #ifndef CONFIG_64BIT @@ -882,7 +882,7 @@ ENTRY(syscall_exit_rfi) * (we don't store them in the sigcontext), so set them * to "proper" values now (otherwise we'll wind up restoring * whatever was last stored in the task structure, which might - * be inconsistent if an interrupt occured while on the gateway + * be inconsistent if an interrupt occurred while on the gateway * page). Note that we may be "trashing" values the user put in * them, but we don't support the user changing them. */ @@ -1156,11 +1156,11 @@ ENDPROC(intr_save) */ t0 = r1 /* temporary register 0 */ - va = r8 /* virtual address for which the trap occured */ + va = r8 /* virtual address for which the trap occurred */ t1 = r9 /* temporary register 1 */ pte = r16 /* pte/phys page # */ prot = r17 /* prot bits */ - spc = r24 /* space for which the trap occured */ + spc = r24 /* space for which the trap occurred */ ptp = r25 /* page directory/page table pointer */ #ifdef CONFIG_64BIT diff --git a/arch/parisc/kernel/head.S b/arch/parisc/kernel/head.S index 4dbdf0ed6fa0..145c5e4caaa0 100644 --- a/arch/parisc/kernel/head.S +++ b/arch/parisc/kernel/head.S @@ -131,7 +131,7 @@ $pgt_fill_loop: ldo THREAD_SZ_ALGN(%r6),%sp #ifdef CONFIG_SMP - /* Set the smp rendevous address into page zero. + /* Set the smp rendezvous address into page zero. ** It would be safer to do this in init_smp_config() but ** it's just way easier to deal with here because ** of 64-bit function ptrs and the address is local to this file. diff --git a/arch/parisc/kernel/inventory.c b/arch/parisc/kernel/inventory.c index d228d8237879..08324aac3544 100644 --- a/arch/parisc/kernel/inventory.c +++ b/arch/parisc/kernel/inventory.c @@ -93,7 +93,7 @@ void __init setup_pdc(void) case 0x6: /* 705, 710 */ case 0x7: /* 715, 725 */ case 0x8: /* 745, 747, 742 */ - case 0xA: /* 712 and similiar */ + case 0xA: /* 712 and similar */ case 0xC: /* 715/64, at least */ pdc_type = PDC_TYPE_SNAKE; diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c index 609a331878e7..12c1ed33dc18 100644 --- a/arch/parisc/kernel/signal.c +++ b/arch/parisc/kernel/signal.c @@ -291,7 +291,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, DBG(1,"setup_rt_frame: frame->uc = 0x%p\n", &frame->uc); DBG(1,"setup_rt_frame: frame->uc.uc_mcontext = 0x%p\n", &frame->uc.uc_mcontext); err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, in_syscall); - /* FIXME: Should probably be converted aswell for the compat case */ + /* FIXME: Should probably be converted as well for the compat case */ err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); } diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index 68e75ce838d6..82a52b2fb13f 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S @@ -605,7 +605,7 @@ cas_action: copy %r0, %r21 3: - /* Error occured on load or store */ + /* Error occurred on load or store */ /* Free lock */ stw %r20, 0(%sr2,%r20) #if ENABLE_LWS_DEBUG diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index 74867dfdabe5..4be85ee10b85 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S @@ -34,7 +34,7 @@ /* Use ENTRY_SAME for 32-bit syscalls which are the same on wide and * narrow palinux. Use ENTRY_DIFF for those where a 32-bit specific * implementation is required on wide palinux. Use ENTRY_COMP where - * the compatability layer has a useful 32-bit implementation. + * the compatibility layer has a useful 32-bit implementation. */ #define ENTRY_SAME(_name_) .dword sys_##_name_ #define ENTRY_DIFF(_name_) .dword sys32_##_name_ diff --git a/arch/parisc/math-emu/dfadd.c b/arch/parisc/math-emu/dfadd.c index e147d7d3b0f4..d37e2d2cb6fe 100644 --- a/arch/parisc/math-emu/dfadd.c +++ b/arch/parisc/math-emu/dfadd.c @@ -303,7 +303,7 @@ dbl_fadd( if(Dbl_iszero_hidden(resultp1)) { /* Handle normalization */ - /* A straight foward algorithm would now shift the result + /* A straight forward algorithm would now shift the result * and extension left until the hidden bit becomes one. Not * all of the extension bits need participate in the shift. * Only the two most significant bits (round and guard) are diff --git a/arch/parisc/math-emu/dfsub.c b/arch/parisc/math-emu/dfsub.c index 87ebc60d465b..2e8b5a79bff7 100644 --- a/arch/parisc/math-emu/dfsub.c +++ b/arch/parisc/math-emu/dfsub.c @@ -306,7 +306,7 @@ dbl_fsub( if(Dbl_iszero_hidden(resultp1)) { /* Handle normalization */ - /* A straight foward algorithm would now shift the result + /* A straight forward algorithm would now shift the result * and extension left until the hidden bit becomes one. Not * all of the extension bits need participate in the shift. * Only the two most significant bits (round and guard) are diff --git a/arch/parisc/math-emu/fmpyfadd.c b/arch/parisc/math-emu/fmpyfadd.c index 5dd7f93a89be..b067c45c872d 100644 --- a/arch/parisc/math-emu/fmpyfadd.c +++ b/arch/parisc/math-emu/fmpyfadd.c @@ -531,7 +531,7 @@ dbl_fmpyfadd( sign_save = Dbl_signextendedsign(resultp1); if (Dbl_iszero_hidden(resultp1)) { /* Handle normalization */ - /* A straight foward algorithm would now shift the + /* A straightforward algorithm would now shift the * result and extension left until the hidden bit * becomes one. Not all of the extension bits need * participate in the shift. Only the two most @@ -1191,7 +1191,7 @@ unsigned int *status; sign_save = Dbl_signextendedsign(resultp1); if (Dbl_iszero_hidden(resultp1)) { /* Handle normalization */ - /* A straight foward algorithm would now shift the + /* A straightforward algorithm would now shift the * result and extension left until the hidden bit * becomes one. Not all of the extension bits need * participate in the shift. Only the two most @@ -1841,7 +1841,7 @@ unsigned int *status; sign_save = Sgl_signextendedsign(resultp1); if (Sgl_iszero_hidden(resultp1)) { /* Handle normalization */ - /* A straight foward algorithm would now shift the + /* A straightforward algorithm would now shift the * result and extension left until the hidden bit * becomes one. Not all of the extension bits need * participate in the shift. Only the two most @@ -2483,7 +2483,7 @@ unsigned int *status; sign_save = Sgl_signextendedsign(resultp1); if (Sgl_iszero_hidden(resultp1)) { /* Handle normalization */ - /* A straight foward algorithm would now shift the + /* A straightforward algorithm would now shift the * result and extension left until the hidden bit * becomes one. Not all of the extension bits need * participate in the shift. Only the two most diff --git a/arch/parisc/math-emu/sfadd.c b/arch/parisc/math-emu/sfadd.c index 008d721b5d22..f802cd6c7869 100644 --- a/arch/parisc/math-emu/sfadd.c +++ b/arch/parisc/math-emu/sfadd.c @@ -298,7 +298,7 @@ sgl_fadd( if(Sgl_iszero_hidden(result)) { /* Handle normalization */ - /* A straight foward algorithm would now shift the result + /* A straightforward algorithm would now shift the result * and extension left until the hidden bit becomes one. Not * all of the extension bits need participate in the shift. * Only the two most significant bits (round and guard) are diff --git a/arch/parisc/math-emu/sfsub.c b/arch/parisc/math-emu/sfsub.c index 24eef61c8e3b..5f90d0f31a52 100644 --- a/arch/parisc/math-emu/sfsub.c +++ b/arch/parisc/math-emu/sfsub.c @@ -301,7 +301,7 @@ sgl_fsub( if(Sgl_iszero_hidden(result)) { /* Handle normalization */ - /* A straight foward algorithm would now shift the result + /* A straightforward algorithm would now shift the result * and extension left until the hidden bit becomes one. Not * all of the extension bits need participate in the shift. * Only the two most significant bits (round and guard) are diff --git a/arch/powerpc/include/asm/bitops.h b/arch/powerpc/include/asm/bitops.h index 2e561876fc89..f18c6d9b9510 100644 --- a/arch/powerpc/include/asm/bitops.h +++ b/arch/powerpc/include/asm/bitops.h @@ -209,8 +209,8 @@ static __inline__ unsigned long ffz(unsigned long x) return BITS_PER_LONG; /* - * Calculate the bit position of the least signficant '1' bit in x - * (since x has been changed this will actually be the least signficant + * Calculate the bit position of the least significant '1' bit in x + * (since x has been changed this will actually be the least significant * '0' bit in * the original x). Note: (x & -x) gives us a mask that * is the least significant * (RIGHT-most) 1-bit of the value in x. */ diff --git a/arch/powerpc/include/asm/compat.h b/arch/powerpc/include/asm/compat.h index 2296112e247b..91010e8f8479 100644 --- a/arch/powerpc/include/asm/compat.h +++ b/arch/powerpc/include/asm/compat.h @@ -140,7 +140,7 @@ static inline void __user *arch_compat_alloc_user_space(long len) unsigned long usp = regs->gpr[1]; /* - * We cant access below the stack pointer in the 32bit ABI and + * We can't access below the stack pointer in the 32bit ABI and * can access 288 bytes in the 64bit ABI */ if (!is_32bit_task()) diff --git a/arch/powerpc/include/asm/cpm.h b/arch/powerpc/include/asm/cpm.h index e50323fe941f..4398a6cdcf53 100644 --- a/arch/powerpc/include/asm/cpm.h +++ b/arch/powerpc/include/asm/cpm.h @@ -98,7 +98,7 @@ typedef struct cpm_buf_desc { #define BD_SC_INTRPT (0x1000) /* Interrupt on change */ #define BD_SC_LAST (0x0800) /* Last buffer in frame */ #define BD_SC_TC (0x0400) /* Transmit CRC */ -#define BD_SC_CM (0x0200) /* Continous mode */ +#define BD_SC_CM (0x0200) /* Continuous mode */ #define BD_SC_ID (0x0100) /* Rec'd too many idles */ #define BD_SC_P (0x0100) /* xmt preamble */ #define BD_SC_BR (0x0020) /* Break received */ diff --git a/arch/powerpc/include/asm/cpm1.h b/arch/powerpc/include/asm/cpm1.h index bd07650dca56..8ee4211ca0c6 100644 --- a/arch/powerpc/include/asm/cpm1.h +++ b/arch/powerpc/include/asm/cpm1.h @@ -4,7 +4,7 @@ * * This file contains structures and information for the communication * processor channels. Some CPM control and status is available - * throught the MPC8xx internal memory map. See immap.h for details. + * through the MPC8xx internal memory map. See immap.h for details. * This file only contains what I need for the moment, not the total * CPM capabilities. I (or someone else) will add definitions as they * are needed. -- Dan diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h index ec089acfa56b..8edec710cc6d 100644 --- a/arch/powerpc/include/asm/hvcall.h +++ b/arch/powerpc/include/asm/hvcall.h @@ -122,7 +122,7 @@ #define H_DABRX_KERNEL (1UL<<(63-62)) #define H_DABRX_USER (1UL<<(63-63)) -/* Each control block has to be on a 4K bondary */ +/* Each control block has to be on a 4K boundary */ #define H_CB_ALIGNMENT 4096 /* pSeries hypervisor opcodes */ diff --git a/arch/powerpc/include/asm/kprobes.h b/arch/powerpc/include/asm/kprobes.h index d0e7701fa1f6..be0171afdc0f 100644 --- a/arch/powerpc/include/asm/kprobes.h +++ b/arch/powerpc/include/asm/kprobes.h @@ -50,7 +50,7 @@ typedef unsigned int kprobe_opcode_t; * Handle cases where: * - User passes a <.symbol> or * - User passes a or - * - User passes a non-existant symbol, kallsyms_lookup_name + * - User passes a non-existent symbol, kallsyms_lookup_name * returns 0. Don't deref the NULL pointer in that case */ #define kprobe_lookup_name(name, addr) \ diff --git a/arch/powerpc/include/asm/lppaca.h b/arch/powerpc/include/asm/lppaca.h index 26b8c807f8f1..a077adc0b35e 100644 --- a/arch/powerpc/include/asm/lppaca.h +++ b/arch/powerpc/include/asm/lppaca.h @@ -105,7 +105,7 @@ struct lppaca { // processing of external interrupts. Note that PLIC will store the // XIRR directly into the xXirrValue field so that another XIRR will // not be presented until this one clears. The layout of the low - // 4-bytes of this Dword is upto SLIC - PLIC just checks whether the + // 4-bytes of this Dword is up to SLIC - PLIC just checks whether the // entire Dword is zero or not. A non-zero value in the low order // 2-bytes will result in SLIC being granted the highest thread // priority upon return. A 0 will return to SLIC as medium priority. diff --git a/arch/powerpc/include/asm/page_64.h b/arch/powerpc/include/asm/page_64.h index 932f88dcf6fa..812b2cd80aed 100644 --- a/arch/powerpc/include/asm/page_64.h +++ b/arch/powerpc/include/asm/page_64.h @@ -169,7 +169,7 @@ do { \ /* * This is the default if a program doesn't have a PT_GNU_STACK * program header entry. The PPC64 ELF ABI has a non executable stack - * stack by default, so in the absense of a PT_GNU_STACK program header + * stack by default, so in the absence of a PT_GNU_STACK program header * we turn execute permission off. */ #define VM_STACK_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \ diff --git a/arch/powerpc/include/asm/pasemi_dma.h b/arch/powerpc/include/asm/pasemi_dma.h index 19fd7933e2d9..eafa5a5f56de 100644 --- a/arch/powerpc/include/asm/pasemi_dma.h +++ b/arch/powerpc/include/asm/pasemi_dma.h @@ -522,7 +522,7 @@ extern void *pasemi_dma_alloc_buf(struct pasemi_dmachan *chan, int size, extern void pasemi_dma_free_buf(struct pasemi_dmachan *chan, int size, dma_addr_t *handle); -/* Routines to allocate flags (events) for channel syncronization */ +/* Routines to allocate flags (events) for channel synchronization */ extern int pasemi_dma_alloc_flag(void); extern void pasemi_dma_free_flag(int flag); extern void pasemi_dma_set_flag(int flag); diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h index 5e156e034fe2..b90dbf8e5cd9 100644 --- a/arch/powerpc/include/asm/pci-bridge.h +++ b/arch/powerpc/include/asm/pci-bridge.h @@ -106,7 +106,7 @@ struct pci_controller { * Used for variants of PCI indirect handling and possible quirks: * SET_CFG_TYPE - used on 4xx or any PHB that does explicit type0/1 * EXT_REG - provides access to PCI-e extended registers - * SURPRESS_PRIMARY_BUS - we surpress the setting of PCI_PRIMARY_BUS + * SURPRESS_PRIMARY_BUS - we suppress the setting of PCI_PRIMARY_BUS * on Freescale PCI-e controllers since they used the PCI_PRIMARY_BUS * to determine which bus number to match on when generating type0 * config cycles diff --git a/arch/powerpc/include/asm/pmac_feature.h b/arch/powerpc/include/asm/pmac_feature.h index 00eedc5a4e61..10902c9375d0 100644 --- a/arch/powerpc/include/asm/pmac_feature.h +++ b/arch/powerpc/include/asm/pmac_feature.h @@ -53,8 +53,8 @@ /* Here is the infamous serie of OHare based machines */ -#define PMAC_TYPE_COMET 0x20 /* Beleived to be PowerBook 2400 */ -#define PMAC_TYPE_HOOPER 0x21 /* Beleived to be PowerBook 3400 */ +#define PMAC_TYPE_COMET 0x20 /* Believed to be PowerBook 2400 */ +#define PMAC_TYPE_HOOPER 0x21 /* Believed to be PowerBook 3400 */ #define PMAC_TYPE_KANGA 0x22 /* PowerBook 3500 (first G3) */ #define PMAC_TYPE_ALCHEMY 0x23 /* Alchemy motherboard base */ #define PMAC_TYPE_GAZELLE 0x24 /* Spartacus, some 5xxx/6xxx */ diff --git a/arch/powerpc/include/asm/pte-common.h b/arch/powerpc/include/asm/pte-common.h index 76bb195e4f24..811f04ac3660 100644 --- a/arch/powerpc/include/asm/pte-common.h +++ b/arch/powerpc/include/asm/pte-common.h @@ -86,7 +86,7 @@ extern unsigned long bad_call_to_PMD_PAGE_SIZE(void); #define PTE_RPN_MASK (~((1UL< #include -/* The physical memory is layed out such that the secondary processor +/* The physical memory is laid out such that the secondary processor * spin code sits at 0x0000...0x00ff. On server, the vectors follow * using the layout described in exceptions-64s.S */ diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index 3e02710d9562..5ecf54cfa7d4 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -326,7 +326,7 @@ interrupt_base: NORMAL_EXCEPTION_PROLOG EXC_XFER_EE_LITE(0x0c00, DoSyscall) - /* Auxillary Processor Unavailable Interrupt */ + /* Auxiliary Processor Unavailable Interrupt */ EXCEPTION(0x2900, AuxillaryProcessorUnavailable, unknown_exception, EXC_XFER_EE) /* Decrementer Interrupt */ diff --git a/arch/powerpc/kernel/l2cr_6xx.S b/arch/powerpc/kernel/l2cr_6xx.S index 2a2f3c3f6d80..97ec8557f974 100644 --- a/arch/powerpc/kernel/l2cr_6xx.S +++ b/arch/powerpc/kernel/l2cr_6xx.S @@ -151,7 +151,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) /**** Might be a good idea to set L2DO here - to prevent instructions from getting into the cache. But since we invalidate the next time we enable the cache it doesn't really matter. - Don't do this unless you accomodate all processor variations. + Don't do this unless you accommodate all processor variations. The bit moved on the 7450..... ****/ diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c index 16468362ad57..301db65f05a1 100644 --- a/arch/powerpc/kernel/lparcfg.c +++ b/arch/powerpc/kernel/lparcfg.c @@ -262,7 +262,7 @@ static void parse_ppp_data(struct seq_file *m) seq_printf(m, "system_active_processors=%d\n", ppp_data.active_system_procs); - /* pool related entries are apropriate for shared configs */ + /* pool related entries are appropriate for shared configs */ if (lppaca_of(0).shared_proc) { unsigned long pool_idle_time, pool_procs; diff --git a/arch/powerpc/kernel/perf_event.c b/arch/powerpc/kernel/perf_event.c index 97e0ae414940..c4063b7f49a0 100644 --- a/arch/powerpc/kernel/perf_event.c +++ b/arch/powerpc/kernel/perf_event.c @@ -759,7 +759,7 @@ static int power_pmu_add(struct perf_event *event, int ef_flags) /* * If group events scheduling transaction was started, - * skip the schedulability test here, it will be peformed + * skip the schedulability test here, it will be performed * at commit time(->commit_txn) as a whole */ if (cpuhw->group_flag & PERF_EVENT_TXN) diff --git a/arch/powerpc/kernel/ppc_save_regs.S b/arch/powerpc/kernel/ppc_save_regs.S index e83ba3f078e4..1b1787d52896 100644 --- a/arch/powerpc/kernel/ppc_save_regs.S +++ b/arch/powerpc/kernel/ppc_save_regs.S @@ -15,7 +15,7 @@ /* * Grab the register values as they are now. - * This won't do a particularily good job because we really + * This won't do a particularly good job because we really * want our caller's caller's registers, and our caller has * already executed its prologue. * ToDo: We could reach back into the caller's save area to do diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 05b7139d6a27..e74fa12afc82 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -683,7 +683,7 @@ void __init early_init_devtree(void *params) #endif #ifdef CONFIG_PHYP_DUMP - /* scan tree to see if dump occured during last boot */ + /* scan tree to see if dump occurred during last boot */ of_scan_flat_dt(early_init_dt_scan_phyp_dump, NULL); #endif @@ -739,7 +739,7 @@ void __init early_init_devtree(void *params) DBG("Scanning CPUs ...\n"); - /* Retreive CPU related informations from the flat tree + /* Retrieve CPU related informations from the flat tree * (altivec support, boot CPU ID, ...) */ of_scan_flat_dt(early_init_dt_scan_cpus, NULL); diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index 895b082f1e48..55613e33e263 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c @@ -463,7 +463,7 @@ static int vr_set(struct task_struct *target, const struct user_regset *regset, #ifdef CONFIG_VSX /* * Currently to set and and get all the vsx state, you need to call - * the fp and VMX calls aswell. This only get/sets the lower 32 + * the fp and VMX calls as well. This only get/sets the lower 32 * 128bit VSX registers. */ diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c index 7980ec0e1e1a..67f6c3b51357 100644 --- a/arch/powerpc/kernel/rtasd.c +++ b/arch/powerpc/kernel/rtasd.c @@ -465,7 +465,7 @@ static void start_event_scan(void) pr_debug("rtasd: will sleep for %d milliseconds\n", (30000 / rtas_event_scan_rate)); - /* Retreive errors from nvram if any */ + /* Retrieve errors from nvram if any */ retreive_nvram_error_log(); schedule_delayed_work_on(cpumask_first(cpu_online_mask), diff --git a/arch/powerpc/kernel/swsusp_32.S b/arch/powerpc/kernel/swsusp_32.S index b0754e237438..ba4dee3d233f 100644 --- a/arch/powerpc/kernel/swsusp_32.S +++ b/arch/powerpc/kernel/swsusp_32.S @@ -143,7 +143,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) /* Disable MSR:DR to make sure we don't take a TLB or * hash miss during the copy, as our hash table will - * for a while be unuseable. For .text, we assume we are + * for a while be unusable. For .text, we assume we are * covered by a BAT. This works only for non-G5 at this * point. G5 will need a better approach, possibly using * a small temporary hash table filled with large mappings, diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index bd74fac169be..5ddb801bc154 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -959,7 +959,7 @@ void __kprobes program_check_exception(struct pt_regs *regs) * ESR_DST (!?) or 0. In the process of chasing this with the * hardware people - not sure if it can happen on any illegal * instruction or only on FP instructions, whether there is a - * pattern to occurences etc. -dgibson 31/Mar/2003 */ + * pattern to occurrences etc. -dgibson 31/Mar/2003 */ switch (do_mathemu(regs)) { case 0: emulate_single_step(regs); diff --git a/arch/powerpc/kernel/udbg_16550.c b/arch/powerpc/kernel/udbg_16550.c index b4b167b33643..baa33a7517bc 100644 --- a/arch/powerpc/kernel/udbg_16550.c +++ b/arch/powerpc/kernel/udbg_16550.c @@ -1,5 +1,5 @@ /* - * udbg for NS16550 compatable serial ports + * udbg for NS16550 compatible serial ports * * Copyright (C) 2001-2005 PPC 64 Team, IBM Corp * diff --git a/arch/powerpc/kernel/vdso32/sigtramp.S b/arch/powerpc/kernel/vdso32/sigtramp.S index 68d49dd71dcc..cf0c9c9c24f9 100644 --- a/arch/powerpc/kernel/vdso32/sigtramp.S +++ b/arch/powerpc/kernel/vdso32/sigtramp.S @@ -19,7 +19,7 @@ /* The nop here is a hack. The dwarf2 unwind routines subtract 1 from the return address to get an address in the middle of the presumed - call instruction. Since we don't have a call here, we artifically + call instruction. Since we don't have a call here, we artificially extend the range covered by the unwind info by adding a nop before the real start. */ nop diff --git a/arch/powerpc/kernel/vdso64/sigtramp.S b/arch/powerpc/kernel/vdso64/sigtramp.S index 59eb59bb4082..45ea281e9a21 100644 --- a/arch/powerpc/kernel/vdso64/sigtramp.S +++ b/arch/powerpc/kernel/vdso64/sigtramp.S @@ -20,7 +20,7 @@ /* The nop here is a hack. The dwarf2 unwind routines subtract 1 from the return address to get an address in the middle of the presumed - call instruction. Since we don't have a call here, we artifically + call instruction. Since we don't have a call here, we artificially extend the range covered by the unwind info by padding before the real start. */ nop diff --git a/arch/powerpc/mm/hash_low_64.S b/arch/powerpc/mm/hash_low_64.S index 3079f6b44cf5..5b7dd4ea02b5 100644 --- a/arch/powerpc/mm/hash_low_64.S +++ b/arch/powerpc/mm/hash_low_64.S @@ -192,8 +192,8 @@ htab_insert_pte: rldicr r3,r0,3,63-3 /* r3 = (hash & mask) << 3 */ /* Call ppc_md.hpte_insert */ - ld r6,STK_PARM(r4)(r1) /* Retreive new pp bits */ - mr r4,r29 /* Retreive va */ + ld r6,STK_PARM(r4)(r1) /* Retrieve new pp bits */ + mr r4,r29 /* Retrieve va */ li r7,0 /* !bolted, !secondary */ li r8,MMU_PAGE_4K /* page size */ ld r9,STK_PARM(r9)(r1) /* segment size */ @@ -215,8 +215,8 @@ _GLOBAL(htab_call_hpte_insert1) rldicr r3,r0,3,63-3 /* r0 = (~hash & mask) << 3 */ /* Call ppc_md.hpte_insert */ - ld r6,STK_PARM(r4)(r1) /* Retreive new pp bits */ - mr r4,r29 /* Retreive va */ + ld r6,STK_PARM(r4)(r1) /* Retrieve new pp bits */ + mr r4,r29 /* Retrieve va */ li r7,HPTE_V_SECONDARY /* !bolted, secondary */ li r8,MMU_PAGE_4K /* page size */ ld r9,STK_PARM(r9)(r1) /* segment size */ @@ -495,8 +495,8 @@ htab_special_pfn: rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */ /* Call ppc_md.hpte_insert */ - ld r6,STK_PARM(r4)(r1) /* Retreive new pp bits */ - mr r4,r29 /* Retreive va */ + ld r6,STK_PARM(r4)(r1) /* Retrieve new pp bits */ + mr r4,r29 /* Retrieve va */ li r7,0 /* !bolted, !secondary */ li r8,MMU_PAGE_4K /* page size */ ld r9,STK_PARM(r9)(r1) /* segment size */ @@ -522,8 +522,8 @@ _GLOBAL(htab_call_hpte_insert1) rldicr r3,r0,3,63-3 /* r0 = (~hash & mask) << 3 */ /* Call ppc_md.hpte_insert */ - ld r6,STK_PARM(r4)(r1) /* Retreive new pp bits */ - mr r4,r29 /* Retreive va */ + ld r6,STK_PARM(r4)(r1) /* Retrieve new pp bits */ + mr r4,r29 /* Retrieve va */ li r7,HPTE_V_SECONDARY /* !bolted, secondary */ li r8,MMU_PAGE_4K /* page size */ ld r9,STK_PARM(r9)(r1) /* segment size */ @@ -813,8 +813,8 @@ ht64_insert_pte: rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */ /* Call ppc_md.hpte_insert */ - ld r6,STK_PARM(r4)(r1) /* Retreive new pp bits */ - mr r4,r29 /* Retreive va */ + ld r6,STK_PARM(r4)(r1) /* Retrieve new pp bits */ + mr r4,r29 /* Retrieve va */ li r7,0 /* !bolted, !secondary */ li r8,MMU_PAGE_64K ld r9,STK_PARM(r9)(r1) /* segment size */ @@ -836,8 +836,8 @@ _GLOBAL(ht64_call_hpte_insert1) rldicr r3,r0,3,63-3 /* r0 = (~hash & mask) << 3 */ /* Call ppc_md.hpte_insert */ - ld r6,STK_PARM(r4)(r1) /* Retreive new pp bits */ - mr r4,r29 /* Retreive va */ + ld r6,STK_PARM(r4)(r1) /* Retrieve new pp bits */ + mr r4,r29 /* Retrieve va */ li r7,HPTE_V_SECONDARY /* !bolted, secondary */ li r8,MMU_PAGE_64K ld r9,STK_PARM(r9)(r1) /* segment size */ diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index a5991facddce..58a022d0f463 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -753,7 +753,7 @@ void __cpuinit early_init_mmu_secondary(void) mtspr(SPRN_SDR1, _SDR1); /* Initialize STAB/SLB. We use a virtual address as it works - * in real mode on pSeries and we want a virutal address on + * in real mode on pSeries and we want a virtual address on * iSeries anyway */ if (cpu_has_feature(CPU_FTR_SLB)) diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index a66499650909..57e545b84bf1 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -424,7 +424,7 @@ void clear_user_page(void *page, unsigned long vaddr, struct page *pg) clear_page(page); /* - * We shouldnt have to do this, but some versions of glibc + * We shouldn't have to do this, but some versions of glibc * require it (ld.so assumes zero filled pages are icache clean) * - Anton */ diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 0dc95c0aa3be..5ec1dad2a19d 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -440,11 +440,11 @@ static void read_drconf_cell(struct of_drconf_cell *drmem, const u32 **cellp) } /* - * Retreive and validate the ibm,dynamic-memory property of the device tree. + * Retrieve and validate the ibm,dynamic-memory property of the device tree. * * The layout of the ibm,dynamic-memory property is a number N of memblock * list entries followed by N memblock list entries. Each memblock list entry - * contains information as layed out in the of_drconf_cell struct above. + * contains information as laid out in the of_drconf_cell struct above. */ static int of_get_drconf_memory(struct device_node *memory, const u32 **dm) { @@ -468,7 +468,7 @@ static int of_get_drconf_memory(struct device_node *memory, const u32 **dm) } /* - * Retreive and validate the ibm,lmb-size property for drconf memory + * Retrieve and validate the ibm,lmb-size property for drconf memory * from the device tree. */ static u64 of_get_lmb_size(struct device_node *memory) @@ -490,7 +490,7 @@ struct assoc_arrays { }; /* - * Retreive and validate the list of associativity arrays for drconf + * Retrieve and validate the list of associativity arrays for drconf * memory from the ibm,associativity-lookup-arrays property of the * device tree.. * @@ -604,7 +604,7 @@ static int __cpuinit cpu_numa_callback(struct notifier_block *nfb, * Returns the size the region should have to enforce the memory limit. * This will either be the original value of size, a truncated value, * or zero. If the returned value of size is 0 the region should be - * discarded as it lies wholy above the memory limit. + * discarded as it lies wholly above the memory limit. */ static unsigned long __init numa_enforce_memory_limit(unsigned long start, unsigned long size) diff --git a/arch/powerpc/mm/tlb_low_64e.S b/arch/powerpc/mm/tlb_low_64e.S index 8526bd9d2aa3..33cf704e4e1b 100644 --- a/arch/powerpc/mm/tlb_low_64e.S +++ b/arch/powerpc/mm/tlb_low_64e.S @@ -192,7 +192,7 @@ normal_tlb_miss: or r10,r15,r14 BEGIN_MMU_FTR_SECTION - /* Set the TLB reservation and seach for existing entry. Then load + /* Set the TLB reservation and search for existing entry. Then load * the entry. */ PPC_TLBSRX_DOT(0,r16) @@ -425,7 +425,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_TLBRSRV) virt_page_table_tlb_miss_fault: /* If we fault here, things are a little bit tricky. We need to call - * either data or instruction store fault, and we need to retreive + * either data or instruction store fault, and we need to retrieve * the original fault address and ESR (for data). * * The thing is, we know that in normal circumstances, this is diff --git a/arch/powerpc/oprofile/op_model_cell.c b/arch/powerpc/oprofile/op_model_cell.c index c4d2b7167568..cb515cff745c 100644 --- a/arch/powerpc/oprofile/op_model_cell.c +++ b/arch/powerpc/oprofile/op_model_cell.c @@ -67,7 +67,7 @@ #define MAX_SPU_COUNT 0xFFFFFF /* maximum 24 bit LFSR value */ -/* Minumum HW interval timer setting to send value to trace buffer is 10 cycle. +/* Minimum HW interval timer setting to send value to trace buffer is 10 cycle. * To configure counter to send value every N cycles set counter to * 2^32 - 1 - N. */ @@ -1470,7 +1470,7 @@ static int cell_global_start(struct op_counter_config *ctr) * trace buffer at the maximum rate possible. The trace buffer is configured * to store the PCs, wrapping when it is full. The performance counter is * initialized to the max hardware count minus the number of events, N, between - * samples. Once the N events have occured, a HW counter overflow occurs + * samples. Once the N events have occurred, a HW counter overflow occurs * causing the generation of a HW counter interrupt which also stops the * writing of the SPU PC values to the trace buffer. Hence the last PC * written to the trace buffer is the SPU PC that we want. Unfortunately, @@ -1656,7 +1656,7 @@ static void cell_handle_interrupt_ppu(struct pt_regs *regs, * The counters were frozen by the interrupt. * Reenable the interrupt and restart the counters. * If there was a race between the interrupt handler and - * the virtual counter routine. The virutal counter + * the virtual counter routine. The virtual counter * routine may have cleared the interrupts. Hence must * use the virt_cntr_inter_mask to re-enable the interrupts. */ diff --git a/arch/powerpc/oprofile/op_model_power4.c b/arch/powerpc/oprofile/op_model_power4.c index 80774092db77..8ee51a252cf1 100644 --- a/arch/powerpc/oprofile/op_model_power4.c +++ b/arch/powerpc/oprofile/op_model_power4.c @@ -207,7 +207,7 @@ static unsigned long get_pc(struct pt_regs *regs) unsigned long mmcra; unsigned long slot; - /* Cant do much about it */ + /* Can't do much about it */ if (!cur_cpu_spec->oprofile_mmcra_sihv) return pc; diff --git a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c index 6385d883cb8d..9940ce8a2d4e 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c @@ -57,7 +57,7 @@ struct mpc52xx_lpbfifo { static struct mpc52xx_lpbfifo lpbfifo; /** - * mpc52xx_lpbfifo_kick - Trigger the next block of data to be transfered + * mpc52xx_lpbfifo_kick - Trigger the next block of data to be transferred */ static void mpc52xx_lpbfifo_kick(struct mpc52xx_lpbfifo_request *req) { @@ -179,7 +179,7 @@ static void mpc52xx_lpbfifo_kick(struct mpc52xx_lpbfifo_request *req) * * On transmit, the dma completion irq triggers before the fifo completion * triggers. Handle the dma completion here instead of the LPB FIFO Bestcomm - * task completion irq becuase everyting is not really done until the LPB FIFO + * task completion irq because everything is not really done until the LPB FIFO * completion irq triggers. * * In other words: @@ -195,7 +195,7 @@ static void mpc52xx_lpbfifo_kick(struct mpc52xx_lpbfifo_request *req) * Exit conditions: * 1) Transfer aborted * 2) FIFO complete without DMA; more data to do - * 3) FIFO complete without DMA; all data transfered + * 3) FIFO complete without DMA; all data transferred * 4) FIFO complete using DMA * * Condition 1 can occur regardless of whether or not DMA is used. diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c index 3ddea96273ca..1dd15400f6f0 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c @@ -512,7 +512,7 @@ void __init mpc52xx_init_irq(void) /** * mpc52xx_get_irq - Get pending interrupt number hook function * - * Called by the interupt handler to determine what IRQ handler needs to be + * Called by the interrupt handler to determine what IRQ handler needs to be * executed. * * Status of pending interrupts is determined by reading the encoded status diff --git a/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c b/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c index 3b894f585280..147069938cfe 100644 --- a/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c +++ b/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c @@ -90,7 +90,7 @@ int spu_alloc_lscsa(struct spu_state *csa) */ for (i = 0; i < SPU_LSCSA_NUM_BIG_PAGES; i++) { /* XXX This is likely to fail, we should use a special pool - * similiar to what hugetlbfs does. + * similar to what hugetlbfs does. */ csa->lscsa_pages[i] = alloc_pages(GFP_KERNEL, SPU_64K_PAGE_ORDER); diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c index 0b0466284932..65203857b0ce 100644 --- a/arch/powerpc/platforms/cell/spufs/sched.c +++ b/arch/powerpc/platforms/cell/spufs/sched.c @@ -846,7 +846,7 @@ static struct spu_context *grab_runnable_context(int prio, int node) struct list_head *rq = &spu_prio->runq[best]; list_for_each_entry(ctx, rq, rq) { - /* XXX(hch): check for affinity here aswell */ + /* XXX(hch): check for affinity here as well */ if (__node_allowed(ctx, node)) { __spu_del_from_rq(ctx); goto found; diff --git a/arch/powerpc/platforms/cell/spufs/spu_restore.c b/arch/powerpc/platforms/cell/spufs/spu_restore.c index 21a9c952d88b..72c905f1ee7a 100644 --- a/arch/powerpc/platforms/cell/spufs/spu_restore.c +++ b/arch/powerpc/platforms/cell/spufs/spu_restore.c @@ -284,7 +284,7 @@ static inline void restore_complete(void) exit_instrs[3] = BR_INSTR; break; default: - /* SPU_Status[R]=1. No additonal instructions. */ + /* SPU_Status[R]=1. No additional instructions. */ break; } spu_sync(); diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c index b5e026bdca21..62dabe3c2bfa 100644 --- a/arch/powerpc/platforms/iseries/mf.c +++ b/arch/powerpc/platforms/iseries/mf.c @@ -51,7 +51,7 @@ static int mf_initialized; /* - * This is the structure layout for the Machine Facilites LPAR event + * This is the structure layout for the Machine Facilities LPAR event * flows. */ struct vsp_cmd_data { diff --git a/arch/powerpc/platforms/iseries/viopath.c b/arch/powerpc/platforms/iseries/viopath.c index b5f05d943a90..2376069cdc14 100644 --- a/arch/powerpc/platforms/iseries/viopath.c +++ b/arch/powerpc/platforms/iseries/viopath.c @@ -396,7 +396,7 @@ static void vio_handleEvent(struct HvLpEvent *event) viopathStatus[remoteLp].mTargetInst)) { printk(VIOPATH_KERN_WARN "message from invalid partition. " - "int msg rcvd, source inst (%d) doesnt match (%d)\n", + "int msg rcvd, source inst (%d) doesn't match (%d)\n", viopathStatus[remoteLp].mTargetInst, event->xSourceInstanceId); return; @@ -407,7 +407,7 @@ static void vio_handleEvent(struct HvLpEvent *event) viopathStatus[remoteLp].mSourceInst)) { printk(VIOPATH_KERN_WARN "message from invalid partition. " - "int msg rcvd, target inst (%d) doesnt match (%d)\n", + "int msg rcvd, target inst (%d) doesn't match (%d)\n", viopathStatus[remoteLp].mSourceInst, event->xTargetInstanceId); return; @@ -418,7 +418,7 @@ static void vio_handleEvent(struct HvLpEvent *event) viopathStatus[remoteLp].mSourceInst) { printk(VIOPATH_KERN_WARN "message from invalid partition. " - "ack msg rcvd, source inst (%d) doesnt match (%d)\n", + "ack msg rcvd, source inst (%d) doesn't match (%d)\n", viopathStatus[remoteLp].mSourceInst, event->xSourceInstanceId); return; @@ -428,7 +428,7 @@ static void vio_handleEvent(struct HvLpEvent *event) viopathStatus[remoteLp].mTargetInst) { printk(VIOPATH_KERN_WARN "message from invalid partition. " - "viopath: ack msg rcvd, target inst (%d) doesnt match (%d)\n", + "viopath: ack msg rcvd, target inst (%d) doesn't match (%d)\n", viopathStatus[remoteLp].mTargetInst, event->xTargetInstanceId); return; diff --git a/arch/powerpc/platforms/pasemi/dma_lib.c b/arch/powerpc/platforms/pasemi/dma_lib.c index 09695ae50f91..321a9b3a2d00 100644 --- a/arch/powerpc/platforms/pasemi/dma_lib.c +++ b/arch/powerpc/platforms/pasemi/dma_lib.c @@ -379,9 +379,9 @@ void pasemi_dma_free_buf(struct pasemi_dmachan *chan, int size, } EXPORT_SYMBOL(pasemi_dma_free_buf); -/* pasemi_dma_alloc_flag - Allocate a flag (event) for channel syncronization +/* pasemi_dma_alloc_flag - Allocate a flag (event) for channel synchronization * - * Allocates a flag for use with channel syncronization (event descriptors). + * Allocates a flag for use with channel synchronization (event descriptors). * Returns allocated flag (0-63), < 0 on error. */ int pasemi_dma_alloc_flag(void) diff --git a/arch/powerpc/platforms/powermac/Makefile b/arch/powerpc/platforms/powermac/Makefile index 50f169392551..ea47df66fee5 100644 --- a/arch/powerpc/platforms/powermac/Makefile +++ b/arch/powerpc/platforms/powermac/Makefile @@ -11,7 +11,7 @@ obj-y += pic.o setup.o time.o feature.o pci.o \ obj-$(CONFIG_PMAC_BACKLIGHT) += backlight.o obj-$(CONFIG_CPU_FREQ_PMAC) += cpufreq_32.o obj-$(CONFIG_CPU_FREQ_PMAC64) += cpufreq_64.o -# CONFIG_NVRAM is an arch. independant tristate symbol, for pmac32 we really +# CONFIG_NVRAM is an arch. independent tristate symbol, for pmac32 we really # need this to be a bool. Cheat here and pretend CONFIG_NVRAM=m is really # CONFIG_NVRAM=y obj-$(CONFIG_NVRAM:m=y) += nvram.o diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c index 480567e5fa9a..e9c8a607268e 100644 --- a/arch/powerpc/platforms/powermac/low_i2c.c +++ b/arch/powerpc/platforms/powermac/low_i2c.c @@ -904,7 +904,7 @@ static void __init smu_i2c_probe(void) printk(KERN_INFO "SMU i2c %s\n", controller->full_name); /* Look for childs, note that they might not be of the right - * type as older device trees mix i2c busses and other thigns + * type as older device trees mix i2c busses and other things * at the same level */ for (busnode = NULL; diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c index ab6898942700..f33e08d573ce 100644 --- a/arch/powerpc/platforms/powermac/pci.c +++ b/arch/powerpc/platforms/powermac/pci.c @@ -299,7 +299,7 @@ static void __init setup_chaos(struct pci_controller *hose, * This function deals with some "special cases" devices. * * 0 -> No special case - * 1 -> Skip the device but act as if the access was successfull + * 1 -> Skip the device but act as if the access was successful * (return 0xff's on reads, eventually, cache config space * accesses in a later version) * -1 -> Hide the device (unsuccessful access) diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index b74a9230edc9..57ceb92b2288 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c @@ -74,7 +74,7 @@ static struct device_node *dlpar_parse_cc_node(struct cc_workarea *ccwa) return NULL; /* The configure connector reported name does not contain a - * preceeding '/', so we allocate a buffer large enough to + * preceding '/', so we allocate a buffer large enough to * prepend this to the full_name. */ name = (char *)ccwa + ccwa->name_offset; diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c index 3cc4d102b1f1..89649173d3a3 100644 --- a/arch/powerpc/platforms/pseries/eeh.c +++ b/arch/powerpc/platforms/pseries/eeh.c @@ -65,7 +65,7 @@ * with EEH. * * Ideally, a PCI device driver, when suspecting that an isolation - * event has occured (e.g. by reading 0xff's), will then ask EEH + * event has occurred (e.g. by reading 0xff's), will then ask EEH * whether this is the case, and then take appropriate steps to * reset the PCI slot, the PCI device, and then resume operations. * However, until that day, the checking is done here, with the diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index fd50ccd4bac1..ef8c45489e20 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -216,7 +216,7 @@ static void pseries_cpu_die(unsigned int cpu) cpu, pcpu, cpu_status); } - /* Isolation and deallocation are definatly done by + /* Isolation and deallocation are definitely done by * drslot_chrp_cpu. If they were not they would be * done here. Change isolate state to Isolate and * change allocation-state to Unusable. diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 154c464cdca5..6d5412a18b26 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -272,7 +272,7 @@ static unsigned long tce_get_pSeriesLP(struct iommu_table *tbl, long tcenum) return tce_ret; } -/* this is compatable with cells for the device tree property */ +/* this is compatible with cells for the device tree property */ struct dynamic_dma_window_prop { __be32 liobn; /* tce table number */ __be64 dma_base; /* address hi,lo */ @@ -976,7 +976,7 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev) pr_debug("pci_dma_dev_setup_pSeriesLP: %s\n", pci_name(dev)); /* dev setup for LPAR is a little tricky, since the device tree might - * contain the dma-window properties per-device and not neccesarily + * contain the dma-window properties per-device and not necessarily * for the bus. So we need to search upwards in the tree until we * either hit a dma-window property, OR find a parent with a table * already allocated. @@ -1033,7 +1033,7 @@ static int dma_set_mask_pSeriesLP(struct device *dev, u64 dma_mask) /* * the device tree might contain the dma-window properties - * per-device and not neccesarily for the bus. So we need to + * per-device and not necessarily for the bus. So we need to * search upwards in the tree until we either hit a dma-window * property, OR find a parent with a table already allocated. */ diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c index ec8fe22047b7..d6901334d66e 100644 --- a/arch/powerpc/platforms/pseries/xics.c +++ b/arch/powerpc/platforms/pseries/xics.c @@ -897,7 +897,7 @@ void xics_migrate_irqs_away(void) int status; unsigned long flags; - /* We cant set affinity on ISA interrupts */ + /* We can't set affinity on ISA interrupts */ if (virq < NUM_ISA_INTERRUPTS) continue; if (irq_map[virq].host != xics_host) diff --git a/arch/powerpc/sysdev/axonram.c b/arch/powerpc/sysdev/axonram.c index 27402c7d309d..1636dd896707 100644 --- a/arch/powerpc/sysdev/axonram.c +++ b/arch/powerpc/sysdev/axonram.c @@ -95,7 +95,7 @@ axon_ram_irq_handler(int irq, void *dev) BUG_ON(!bank); - dev_err(&device->dev, "Correctable memory error occured\n"); + dev_err(&device->dev, "Correctable memory error occurred\n"); bank->ecc_counter++; return IRQ_HANDLED; } diff --git a/arch/powerpc/sysdev/bestcomm/bestcomm.h b/arch/powerpc/sysdev/bestcomm/bestcomm.h index 23a95f80dfdb..a0e2e6b19b57 100644 --- a/arch/powerpc/sysdev/bestcomm/bestcomm.h +++ b/arch/powerpc/sysdev/bestcomm/bestcomm.h @@ -20,7 +20,7 @@ * struct bcom_bd - Structure describing a generic BestComm buffer descriptor * @status: The current status of this buffer. Exact meaning depends on the * task type - * @data: An array of u32 extra data. Size of array is task dependant. + * @data: An array of u32 extra data. Size of array is task dependent. * * Note: Don't dereference a bcom_bd pointer as an array. The size of the * bcom_bd is variable. Use bcom_get_bd() instead. diff --git a/arch/powerpc/sysdev/bestcomm/bestcomm_priv.h b/arch/powerpc/sysdev/bestcomm/bestcomm_priv.h index eb0d1c883c31..3b52f3ffbdf8 100644 --- a/arch/powerpc/sysdev/bestcomm/bestcomm_priv.h +++ b/arch/powerpc/sysdev/bestcomm/bestcomm_priv.h @@ -97,7 +97,7 @@ struct bcom_task_header { u8 reserved[8]; }; -/* Descriptors stucture & co */ +/* Descriptors structure & co */ #define BCOM_DESC_NOP 0x000001f8 #define BCOM_LCD_MASK 0x80000000 #define BCOM_DRD_EXTENDED 0x40000000 diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c index 8b5aba263323..e0bc944eb23f 100644 --- a/arch/powerpc/sysdev/cpm1.c +++ b/arch/powerpc/sysdev/cpm1.c @@ -223,7 +223,7 @@ void __init cpm_reset(void) /* Set SDMA Bus Request priority 5. * On 860T, this also enables FEC priority 6. I am not sure - * this is what we realy want for some applications, but the + * this is what we really want for some applications, but the * manual recommends it. * Bit 25, FAM can also be set to use FEC aggressive mode (860T). */ diff --git a/arch/powerpc/sysdev/indirect_pci.c b/arch/powerpc/sysdev/indirect_pci.c index 7ed809676642..82fdad885d20 100644 --- a/arch/powerpc/sysdev/indirect_pci.c +++ b/arch/powerpc/sysdev/indirect_pci.c @@ -117,7 +117,7 @@ indirect_write_config(struct pci_bus *bus, unsigned int devfn, int offset, out_le32(hose->cfg_addr, (0x80000000 | (bus_no << 16) | (devfn << 8) | reg | cfg_type)); - /* surpress setting of PCI_PRIMARY_BUS */ + /* suppress setting of PCI_PRIMARY_BUS */ if (hose->indirect_type & PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS) if ((offset == PCI_PRIMARY_BUS) && (bus->number == hose->first_busno)) diff --git a/arch/powerpc/sysdev/ppc4xx_pci.h b/arch/powerpc/sysdev/ppc4xx_pci.h index 56d9e5deccbf..c39a134e8684 100644 --- a/arch/powerpc/sysdev/ppc4xx_pci.h +++ b/arch/powerpc/sysdev/ppc4xx_pci.h @@ -324,7 +324,7 @@ #define PESDR0_460EX_IHS2 0x036D /* - * 460SX addtional DCRs + * 460SX additional DCRs */ #define PESDRn_460SX_RCEI 0x02 diff --git a/arch/s390/include/asm/atomic.h b/arch/s390/include/asm/atomic.h index 5c5ba10384c2..d9db13810d15 100644 --- a/arch/s390/include/asm/atomic.h +++ b/arch/s390/include/asm/atomic.h @@ -9,7 +9,7 @@ * * Atomic operations that C can't guarantee us. * Useful for resource counting etc. - * s390 uses 'Compare And Swap' for atomicity in SMP enviroment. + * s390 uses 'Compare And Swap' for atomicity in SMP environment. * */ diff --git a/arch/s390/include/asm/cio.h b/arch/s390/include/asm/cio.h index e34347d567a6..fc50a3342da3 100644 --- a/arch/s390/include/asm/cio.h +++ b/arch/s390/include/asm/cio.h @@ -183,7 +183,7 @@ struct esw3 { * The irb that is handed to the device driver when an interrupt occurs. For * solicited interrupts, the common I/O layer already performs checks whether * a field is valid; a field not being valid is always passed as %0. - * If a unit check occured, @ecw may contain sense data; this is retrieved + * If a unit check occurred, @ecw may contain sense data; this is retrieved * by the common I/O layer itself if the device doesn't support concurrent * sense (so that the device driver never needs to perform basic sene itself). * For unsolicited interrupts, the irb is passed as-is (expect for sense data, diff --git a/arch/s390/kernel/reipl64.S b/arch/s390/kernel/reipl64.S index 5e73dee63baa..9eabbc90795d 100644 --- a/arch/s390/kernel/reipl64.S +++ b/arch/s390/kernel/reipl64.S @@ -78,7 +78,7 @@ do_reipl_asm: basr %r13,0 * in the ESA psw. * Bit 31 of the addresses has to be 0 for the * 31bit lpswe instruction a fact they appear to have - * ommited from the pop. + * omitted from the pop. */ .Lnewpsw: .quad 0x0000000080000000 .quad .Lpg1 diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index ed183c2c6168..f5434d1ecb31 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -708,7 +708,7 @@ static void __init setup_hwcaps(void) * and 1ULL<<0 as bit 63. Bits 0-31 contain the same information * as stored by stfl, bits 32-xxx contain additional facilities. * How many facility words are stored depends on the number of - * doublewords passed to the instruction. The additional facilites + * doublewords passed to the instruction. The additional facilities * are: * Bit 42: decimal floating point facility is installed * Bit 44: perform floating point operation facility is installed diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index 9e7b039458da..87be655557aa 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -724,7 +724,7 @@ static void clock_sync_cpu(struct clock_sync_data *sync) } /* - * Sync the TOD clock using the port refered to by aibp. This port + * Sync the TOD clock using the port referred to by aibp. This port * has to be enabled and the other port has to be disabled. The * last eacr update has to be more than 1.6 seconds in the past. */ @@ -1012,7 +1012,7 @@ static void etr_work_fn(struct work_struct *work) eacr = etr_handle_update(&aib, eacr); /* - * Select ports to enable. The prefered synchronization mode is PPS. + * Select ports to enable. The preferred synchronization mode is PPS. * If a port can be enabled depends on a number of things: * 1) The port needs to be online and uptodate. A port is not * disabled just because it is not uptodate, but it is only @@ -1091,7 +1091,7 @@ static void etr_work_fn(struct work_struct *work) /* * Update eacr and try to synchronize the clock. If the update * of eacr caused a stepping port switch (or if we have to - * assume that a stepping port switch has occured) or the + * assume that a stepping port switch has occurred) or the * clock syncing failed, reset the sync check control bit * and set up a timer to try again after 0.5 seconds */ diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index 1ccdf4d8aa85..5e8ead4b4aba 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c @@ -44,7 +44,7 @@ static inline void set_vtimer(__u64 expires) __u64 timer; asm volatile (" STPT %0\n" /* Store current cpu timer value */ - " SPT %1" /* Set new value immediatly afterwards */ + " SPT %1" /* Set new value immediately afterwards */ : "=m" (timer) : "m" (expires) ); S390_lowcore.system_timer += S390_lowcore.last_update_timer - timer; S390_lowcore.last_update_timer = expires; diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index bade533ba288..30ca85cce314 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -721,7 +721,7 @@ static int __init kvm_s390_init(void) /* * guests can ask for up to 255+1 double words, we need a full page - * to hold the maximum amount of facilites. On the other hand, we + * to hold the maximum amount of facilities. On the other hand, we * only set facilities that are known to work in KVM. */ facilities = (unsigned long long *) get_zeroed_page(GFP_KERNEL|GFP_DMA); diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c index 9194a4b52b22..73c47bd95db3 100644 --- a/arch/s390/kvm/priv.c +++ b/arch/s390/kvm/priv.c @@ -311,7 +311,7 @@ int kvm_s390_handle_b2(struct kvm_vcpu *vcpu) /* * a lot of B2 instructions are priviledged. We first check for - * the priviledges ones, that we can handle in the kernel. If the + * the privileged ones, that we can handle in the kernel. If the * kernel can handle this instruction, we check for the problem * state bit and (a) handle the instruction or (b) send a code 2 * program check. diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 2c57806c0858..9217e332b118 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -392,7 +392,7 @@ void __kprobes do_protection_exception(struct pt_regs *regs, long pgm_int_code, { int fault; - /* Protection exception is supressing, decrement psw address. */ + /* Protection exception is suppressing, decrement psw address. */ regs->psw.addr -= (pgm_int_code >> 16); /* * Check for low-address protection. This needs to be treated diff --git a/arch/score/Makefile b/arch/score/Makefile index d77dc639d8e3..974aefe86123 100644 --- a/arch/score/Makefile +++ b/arch/score/Makefile @@ -40,5 +40,5 @@ archclean: define archhelp echo ' vmlinux.bin - Raw binary boot image' echo - echo ' These will be default as apropriate for a configured platform.' + echo ' These will be default as appropriate for a configured platform.' endef diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug index 12fec72fec5f..1553d56cf4e0 100644 --- a/arch/sh/Kconfig.debug +++ b/arch/sh/Kconfig.debug @@ -82,7 +82,7 @@ config SH_NO_BSS_INIT help If running in painfully slow environments, such as an RTL simulation or from remote memory via SHdebug, where the memory - can already be gauranteed to ber zeroed on boot, say Y. + can already be guaranteed to ber zeroed on boot, say Y. For all other cases, say N. If this option seems perplexing, or you aren't sure, say N. diff --git a/arch/sh/boards/mach-dreamcast/irq.c b/arch/sh/boards/mach-dreamcast/irq.c index 78cf2ab89d7a..f63d323f411f 100644 --- a/arch/sh/boards/mach-dreamcast/irq.c +++ b/arch/sh/boards/mach-dreamcast/irq.c @@ -51,7 +51,7 @@ */ #define LEVEL(event) (((event) - HW_EVENT_IRQ_BASE) / 32) -/* Return the hardware event's bit positon within the EMR/ESR */ +/* Return the hardware event's bit position within the EMR/ESR */ #define EVENT_BIT(event) (((event) - HW_EVENT_IRQ_BASE) & 31) /* diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index fd4ff25f23b2..30ae2e4283f0 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c @@ -936,7 +936,7 @@ static void __init sh_eth_init(struct sh_eth_plat_data *pd) return; } - /* read MAC address frome EEPROM */ + /* read MAC address from EEPROM */ for (i = 0; i < sizeof(pd->mac_addr); i++) { pd->mac_addr[i] = mac_read(a, 0x10 + i); msleep(10); diff --git a/arch/sh/drivers/pci/pci-sh7751.h b/arch/sh/drivers/pci/pci-sh7751.h index 4983a4d20355..5ede38c330d3 100644 --- a/arch/sh/drivers/pci/pci-sh7751.h +++ b/arch/sh/drivers/pci/pci-sh7751.h @@ -61,7 +61,7 @@ #define SH7751_PCICONF3_BIST7 0x80000000 /* Bist Supported */ #define SH7751_PCICONF3_BIST6 0x40000000 /* Bist Executing */ #define SH7751_PCICONF3_BIST3_0 0x0F000000 /* Bist Passed */ - #define SH7751_PCICONF3_HD7 0x00800000 /* Single Funtion device */ + #define SH7751_PCICONF3_HD7 0x00800000 /* Single Function device */ #define SH7751_PCICONF3_HD6_0 0x007F0000 /* Configuration Layout */ #define SH7751_PCICONF3_LAT 0x0000FF00 /* Latency Timer */ #define SH7751_PCICONF3_CLS 0x000000FF /* Cache Line Size */ diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index a09c77dd09db..194231cb5a70 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -84,7 +84,7 @@ int __devinit register_pci_controller(struct pci_channel *hose) hose_tail = &hose->next; /* - * Do not panic here but later - this might hapen before console init. + * Do not panic here but later - this might happen before console init. */ if (!hose->io_map_base) { printk(KERN_WARNING diff --git a/arch/sh/include/asm/page.h b/arch/sh/include/asm/page.h index c4e0b3d472b9..822d6084195b 100644 --- a/arch/sh/include/asm/page.h +++ b/arch/sh/include/asm/page.h @@ -186,7 +186,7 @@ typedef struct page *pgtable_t; /* * While BYTES_PER_WORD == 4 on the current sh64 ABI, GCC will still * happily generate {ld/st}.q pairs, requiring us to have 8-byte - * alignment to avoid traps. The kmalloc alignment is gauranteed by + * alignment to avoid traps. The kmalloc alignment is guaranteed by * virtue of L1_CACHE_BYTES, requiring this to only be special cased * for slab caches. */ diff --git a/arch/sh/include/asm/pgtable_32.h b/arch/sh/include/asm/pgtable_32.h index b799fe71114c..0bce3d81569e 100644 --- a/arch/sh/include/asm/pgtable_32.h +++ b/arch/sh/include/asm/pgtable_32.h @@ -167,7 +167,7 @@ static inline unsigned long copy_ptea_attributes(unsigned long x) #endif /* - * Mask of bits that are to be preserved accross pgprot changes. + * Mask of bits that are to be preserved across pgprot changes. */ #define _PAGE_CHG_MASK \ (PTE_MASK | _PAGE_ACCESSED | _PAGE_CACHABLE | \ diff --git a/arch/sh/include/asm/unaligned-sh4a.h b/arch/sh/include/asm/unaligned-sh4a.h index c48a9c3420da..95adc500cabc 100644 --- a/arch/sh/include/asm/unaligned-sh4a.h +++ b/arch/sh/include/asm/unaligned-sh4a.h @@ -9,7 +9,7 @@ * struct. * * The same note as with the movli.l/movco.l pair applies here, as long - * as the load is gauranteed to be inlined, nothing else will hook in to + * as the load is guaranteed to be inlined, nothing else will hook in to * r0 and we get the return value for free. * * NOTE: Due to the fact we require r0 encoding, care should be taken to diff --git a/arch/sh/include/mach-common/mach/highlander.h b/arch/sh/include/mach-common/mach/highlander.h index 5d9d4d5154be..6ce944e33e59 100644 --- a/arch/sh/include/mach-common/mach/highlander.h +++ b/arch/sh/include/mach-common/mach/highlander.h @@ -24,7 +24,7 @@ #define PA_OBLED (PA_BCR+0x001c) /* On Board LED control */ #define PA_OBSW (PA_BCR+0x001e) /* On Board Switch control */ #define PA_AUDIOSEL (PA_BCR+0x0020) /* Sound Interface Select control */ -#define PA_EXTPLR (PA_BCR+0x001e) /* Extention Pin Polarity control */ +#define PA_EXTPLR (PA_BCR+0x001e) /* Extension Pin Polarity control */ #define PA_TPCTL (PA_BCR+0x0100) /* Touch Panel Access control */ #define PA_TPDCKCTL (PA_BCR+0x0102) /* Touch Panel Access data control */ #define PA_TPCTLCLR (PA_BCR+0x0104) /* Touch Panel Access control */ @@ -89,7 +89,7 @@ #define PA_OBLED (PA_BCR+0x0018) /* On Board LED control */ #define PA_OBSW (PA_BCR+0x001a) /* On Board Switch control */ #define PA_AUDIOSEL (PA_BCR+0x001c) /* Sound Interface Select control */ -#define PA_EXTPLR (PA_BCR+0x001e) /* Extention Pin Polarity control */ +#define PA_EXTPLR (PA_BCR+0x001e) /* Extension Pin Polarity control */ #define PA_TPCTL (PA_BCR+0x0100) /* Touch Panel Access control */ #define PA_TPDCKCTL (PA_BCR+0x0102) /* Touch Panel Access data control */ #define PA_TPCTLCLR (PA_BCR+0x0104) /* Touch Panel Access control */ diff --git a/arch/sh/include/mach-common/mach/r2d.h b/arch/sh/include/mach-common/mach/r2d.h index 0a800157b826..e04f75eaa153 100644 --- a/arch/sh/include/mach-common/mach/r2d.h +++ b/arch/sh/include/mach-common/mach/r2d.h @@ -18,18 +18,18 @@ #define PA_DISPCTL 0xa4000008 /* Display Timing control */ #define PA_SDMPOW 0xa400000a /* SD Power control */ #define PA_RTCCE 0xa400000c /* RTC(9701) Enable control */ -#define PA_PCICD 0xa400000e /* PCI Extention detect control */ +#define PA_PCICD 0xa400000e /* PCI Extension detect control */ #define PA_VOYAGERRTS 0xa4000020 /* VOYAGER Reset control */ #define PA_R2D1_AXRST 0xa4000022 /* AX_LAN Reset control */ #define PA_R2D1_CFRST 0xa4000024 /* CF Reset control */ #define PA_R2D1_ADMRTS 0xa4000026 /* SD Reset control */ -#define PA_R2D1_EXTRST 0xa4000028 /* Extention Reset control */ +#define PA_R2D1_EXTRST 0xa4000028 /* Extension Reset control */ #define PA_R2D1_CFCDINTCLR 0xa400002a /* CF Insert Interrupt clear */ #define PA_R2DPLUS_CFRST 0xa4000022 /* CF Reset control */ #define PA_R2DPLUS_ADMRTS 0xa4000024 /* SD Reset control */ -#define PA_R2DPLUS_EXTRST 0xa4000026 /* Extention Reset control */ +#define PA_R2DPLUS_EXTRST 0xa4000026 /* Extension Reset control */ #define PA_R2DPLUS_CFCDINTCLR 0xa4000028 /* CF Insert Interrupt clear */ #define PA_R2DPLUS_KEYCTLCLR 0xa400002a /* Key Interrupt clear */ diff --git a/arch/sh/kernel/cpu/clock-cpg.c b/arch/sh/kernel/cpu/clock-cpg.c index dd0e0f211359..8f63a264a842 100644 --- a/arch/sh/kernel/cpu/clock-cpg.c +++ b/arch/sh/kernel/cpu/clock-cpg.c @@ -67,7 +67,7 @@ int __init __deprecated cpg_clk_init(void) } /* - * Placeholder for compatability, until the lazy CPUs do this + * Placeholder for compatibility, until the lazy CPUs do this * on their own. */ int __init __weak arch_clk_init(void) diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c index 1656b8c91faf..beba32beb6d9 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c @@ -648,7 +648,7 @@ static void __init sh7786_usb_setup(void) * The following settings are necessary * for using the USB modules. * - * see "USB Inital Settings" for detail + * see "USB Initial Settings" for detail */ __raw_writel(USBINITVAL1, USBINITREG1); __raw_writel(USBINITVAL2, USBINITREG2); diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index 64ea0b165399..91971103b62b 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c @@ -183,7 +183,7 @@ asmlinkage void do_softirq(void) ); /* - * Shouldnt happen, we returned above if in_interrupt(): + * Shouldn't happen, we returned above if in_interrupt(): */ WARN_ON_ONCE(softirq_count()); } diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 4f267160c515..58bff45d1156 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -150,7 +150,7 @@ void __init check_for_initrd(void) } /* - * If we got this far inspite of the boot loader's best efforts + * If we got this far in spite of the boot loader's best efforts * to the contrary, assume we actually have a valid initrd and * fix up the root dev. */ diff --git a/arch/sh/lib64/copy_user_memcpy.S b/arch/sh/lib64/copy_user_memcpy.S index 2a62816d2ddd..49aeabeba2c2 100644 --- a/arch/sh/lib64/copy_user_memcpy.S +++ b/arch/sh/lib64/copy_user_memcpy.S @@ -27,7 +27,7 @@ ! 2.: When there are two or three bytes in the last word of an 11-or-more ! bytes memory chunk to b copied, the rest of the word can be read ! without side effects. -! This could be easily changed by increasing the minumum size of +! This could be easily changed by increasing the minimum size of ! a fast memcpy and the amount subtracted from r7 before L_2l_loop be 2, ! however, this would cost a few extra cyles on average. ! For SHmedia, the assumption is that any quadword can be read in its diff --git a/arch/sh/lib64/memcpy.S b/arch/sh/lib64/memcpy.S index dd300c372ce1..5d682e0ee24f 100644 --- a/arch/sh/lib64/memcpy.S +++ b/arch/sh/lib64/memcpy.S @@ -29,7 +29,7 @@ ! 2.: When there are two or three bytes in the last word of an 11-or-more ! bytes memory chunk to b copied, the rest of the word can be read ! without side effects. -! This could be easily changed by increasing the minumum size of +! This could be easily changed by increasing the minimum size of ! a fast memcpy and the amount subtracted from r7 before L_2l_loop be 2, ! however, this would cost a few extra cyles on average. ! For SHmedia, the assumption is that any quadword can be read in its diff --git a/arch/sparc/include/asm/hypervisor.h b/arch/sparc/include/asm/hypervisor.h index bafe5a631b6d..75686409be24 100644 --- a/arch/sparc/include/asm/hypervisor.h +++ b/arch/sparc/include/asm/hypervisor.h @@ -654,7 +654,7 @@ extern unsigned long sun4v_mmu_tsb_ctx0(unsigned long num_descriptions, * ARG3: mmu context * ARG4: flags (HV_MMU_{IMMU,DMMU}) * RET0: status - * ERRORS: EINVAL Invalid virutal address, context, or + * ERRORS: EINVAL Invalid virtual address, context, or * flags value * ENOTSUPPORTED ARG0 or ARG1 is non-zero * @@ -721,7 +721,7 @@ extern void sun4v_mmu_demap_all(void); * ARG2: TTE * ARG3: flags (HV_MMU_{IMMU,DMMU}) * RET0: status - * ERRORS: EINVAL Invalid virutal address or flags value + * ERRORS: EINVAL Invalid virtual address or flags value * EBADPGSZ Invalid page size value * ENORADDR Invalid real address in TTE * ETOOMANY Too many mappings (max of 8 reached) @@ -800,7 +800,7 @@ extern unsigned long sun4v_mmu_map_perm_addr(unsigned long vaddr, * ARG1: reserved, must be zero * ARG2: flags (HV_MMU_{IMMU,DMMU}) * RET0: status - * ERRORS: EINVAL Invalid virutal address or flags value + * ERRORS: EINVAL Invalid virtual address or flags value * ENOMAP Specified mapping was not found * * Demaps any permanent page mapping (established via @@ -1205,7 +1205,7 @@ struct hv_trap_trace_control { * structure contents. Attempts to do so will result in undefined * behavior for the guest. * - * Each trap trace buffer entry is layed out as follows: + * Each trap trace buffer entry is laid out as follows: */ #ifndef __ASSEMBLY__ struct hv_trap_trace_entry { @@ -1300,7 +1300,7 @@ struct hv_trap_trace_entry { * state in RET1. Future systems may define various flags for the * enable argument (ARG0), for the moment a guest should pass * "(uint64_t) -1" to enable, and "(uint64_t) 0" to disable all - * tracing - which will ensure future compatability. + * tracing - which will ensure future compatibility. */ #define HV_FAST_TTRACE_ENABLE 0x92 @@ -1880,7 +1880,7 @@ extern unsigned long sun4v_vintr_set_target(unsigned long dev_handle, * pci_device, at pci_config_offset from the beginning of the device's * configuration space. If there was no error, RET1 is set to zero and * RET2 is set to the data read. Insignificant bits in RET2 are not - * guarenteed to have any specific value and therefore must be ignored. + * guaranteed to have any specific value and therefore must be ignored. * * The data returned in RET2 is size based byte swapped. * @@ -1941,9 +1941,9 @@ extern unsigned long sun4v_vintr_set_target(unsigned long dev_handle, * and return the actual data read in RET2. The data returned is size based * byte swapped. * - * Non-significant bits in RET2 are not guarenteed to have any specific value + * Non-significant bits in RET2 are not guaranteed to have any specific value * and therefore must be ignored. If RET1 is returned as non-zero, the data - * value is not guarenteed to have any specific value and should be ignored. + * value is not guaranteed to have any specific value and should be ignored. * * The caller must have permission to read from the given devhandle, real * address, which must be an IO address. The argument real address must be a @@ -2456,9 +2456,9 @@ extern unsigned long sun4v_vintr_set_target(unsigned long dev_handle, * * As receive queue configuration causes a reset of the queue's head and * tail pointers there is no way for a gues to determine how many entries - * have been received between a preceeding ldc_get_rx_state() API call + * have been received between a preceding ldc_get_rx_state() API call * and the completion of the configuration operation. It should be noted - * that datagram delivery is not guarenteed via domain channels anyway, + * that datagram delivery is not guaranteed via domain channels anyway, * and therefore any higher protocol should be resilient to datagram * loss if necessary. However, to overcome this specific race potential * it is recommended, for example, that a higher level protocol be employed diff --git a/arch/sparc/include/asm/ns87303.h b/arch/sparc/include/asm/ns87303.h index 686defe6aaa0..af755483e17d 100644 --- a/arch/sparc/include/asm/ns87303.h +++ b/arch/sparc/include/asm/ns87303.h @@ -37,7 +37,7 @@ /* Power and Test Register (PTR) bits */ #define PTR_LPTB_IRQ7 0x08 #define PTR_LEVEL_IRQ 0x80 /* When not ECP/EPP: Use level IRQ */ -#define PTR_LPT_REG_DIR 0x80 /* When ECP/EPP: LPT CTR controlls direction */ +#define PTR_LPT_REG_DIR 0x80 /* When ECP/EPP: LPT CTR controls direction */ /* of the parallel port */ /* Function Control Register (FCR) bits */ diff --git a/arch/sparc/include/asm/pcr.h b/arch/sparc/include/asm/pcr.h index 843e4faf6a50..288d7beba051 100644 --- a/arch/sparc/include/asm/pcr.h +++ b/arch/sparc/include/asm/pcr.h @@ -31,7 +31,7 @@ extern unsigned int picl_shift; /* In order to commonize as much of the implementation as * possible, we use PICH as our counter. Mostly this is - * to accomodate Niagara-1 which can only count insn cycles + * to accommodate Niagara-1 which can only count insn cycles * in PICH. */ static inline u64 picl_value(unsigned int nmi_hz) diff --git a/arch/sparc/include/asm/ptrace.h b/arch/sparc/include/asm/ptrace.h index 30b0b797dc0c..c7ad3fe2b252 100644 --- a/arch/sparc/include/asm/ptrace.h +++ b/arch/sparc/include/asm/ptrace.h @@ -33,7 +33,7 @@ struct pt_regs { * things like "in a system call" etc. for an arbitray * process. * - * The PT_REGS_MAGIC is choosen such that it can be + * The PT_REGS_MAGIC is chosen such that it can be * loaded completely using just a sethi instruction. */ unsigned int magic; diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index 1504df8ddf70..8e607b3b0ed9 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S @@ -801,7 +801,7 @@ vac_linesize_patch_32: subcc %l7, 32, %l7 .globl vac_hwflush_patch1_on, vac_hwflush_patch2_on /* - * Ugly, but we cant use hardware flushing on the sun4 and we'd require + * Ugly, but we can't use hardware flushing on the sun4 and we'd require * two instructions (Anton) */ vac_hwflush_patch1_on: addcc %l7, -PAGE_SIZE, %l7 @@ -851,7 +851,7 @@ sun4c_fault: sethi %hi(~((1 << SUN4C_REAL_PGDIR_SHIFT) - 1)), %l4 /* If the kernel references a bum kernel pointer, or a pte which - * points to a non existant page in ram, we will run this code + * points to a non existent page in ram, we will run this code * _forever_ and lock up the machine!!!!! So we must check for * this condition, the AC_SYNC_ERR bits are what we must examine. * Also a parity error would make this happen as well. So we just diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S index f8f21050448b..aa594c792d19 100644 --- a/arch/sparc/kernel/head_64.S +++ b/arch/sparc/kernel/head_64.S @@ -85,7 +85,7 @@ sparc_ramdisk_image64: sparc64_boot: mov %o4, %l7 - /* We need to remap the kernel. Use position independant + /* We need to remap the kernel. Use position independent * code to remap us to KERNBASE. * * SILO can invoke us with 32-bit address masking enabled, diff --git a/arch/sparc/kernel/init_task.c b/arch/sparc/kernel/init_task.c index 5fe3d65581f7..35f141a9f506 100644 --- a/arch/sparc/kernel/init_task.c +++ b/arch/sparc/kernel/init_task.c @@ -15,7 +15,7 @@ EXPORT_SYMBOL(init_task); /* .text section in head.S is aligned at 8k boundary and this gets linked * right after that so that the init_thread_union is aligned properly as well. - * If this is not aligned on a 8k boundry, then you should change code + * If this is not aligned on a 8k boundary, then you should change code * in etrap.S which assumes it. */ union thread_union init_thread_union __init_task_data = diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c index 63cd4e5d47c2..5c149689bb20 100644 --- a/arch/sparc/kernel/of_device_64.c +++ b/arch/sparc/kernel/of_device_64.c @@ -459,7 +459,7 @@ apply_interrupt_map(struct device_node *dp, struct device_node *pp, * * Handle this by deciding that, if we didn't get a * match in the parent's 'interrupt-map', and the - * parent is an IRQ translater, then use the parent as + * parent is an IRQ translator, then use the parent as * our IRQ controller. */ if (pp->irq_trans) diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c index 760578687e7c..ee8426ede7c7 100644 --- a/arch/sparc/kernel/perf_event.c +++ b/arch/sparc/kernel/perf_event.c @@ -1027,7 +1027,7 @@ static int sparc_pmu_add(struct perf_event *event, int ef_flags) /* * If group events scheduling transaction was started, - * skip the schedulability test here, it will be peformed + * skip the schedulability test here, it will be performed * at commit time(->commit_txn) as a whole */ if (cpuc->group_flag & PERF_EVENT_TXN) diff --git a/arch/sparc/math-emu/Makefile b/arch/sparc/math-emu/Makefile index b9085ecbb27b..825dbee94d84 100644 --- a/arch/sparc/math-emu/Makefile +++ b/arch/sparc/math-emu/Makefile @@ -2,7 +2,7 @@ # Makefile for the FPU instruction emulation. # -# supress all warnings - as math.c produces a lot! +# suppress all warnings - as math.c produces a lot! ccflags-y := -w obj-y := math_$(BITS).o diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig index 6e2cdd5ae96b..e32b0c23c4c8 100644 --- a/arch/tile/Kconfig +++ b/arch/tile/Kconfig @@ -51,7 +51,7 @@ config GENERIC_TIME config GENERIC_CLOCKEVENTS def_bool y -# FIXME: tilegx can implement a more efficent rwsem. +# FIXME: tilegx can implement a more efficient rwsem. config RWSEM_GENERIC_SPINLOCK def_bool y diff --git a/arch/tile/include/hv/drv_xgbe_intf.h b/arch/tile/include/hv/drv_xgbe_intf.h index 146e47d5334b..f13188ac281a 100644 --- a/arch/tile/include/hv/drv_xgbe_intf.h +++ b/arch/tile/include/hv/drv_xgbe_intf.h @@ -319,7 +319,7 @@ typedef union * is an error code, or zero if no error. The val0 member is the * updated value of seqno; it has been incremented by 1 for each * packet sent. That increment may be less than nentries if an - * error occured, or if some of the entries in the vector contain + * error occurred, or if some of the entries in the vector contain * handles equal to NETIO_PKT_HANDLE_NONE. The val1 member is the * updated value of nentries; it has been decremented by 1 for each * vector entry processed. Again, that decrement may be less than diff --git a/arch/tile/include/hv/hypervisor.h b/arch/tile/include/hv/hypervisor.h index 1b8bf03d62a0..ee41bca4c8c4 100644 --- a/arch/tile/include/hv/hypervisor.h +++ b/arch/tile/include/hv/hypervisor.h @@ -1340,7 +1340,7 @@ typedef struct * this operation. If any permanent delivery errors were encountered, * the routine returns HV_ERECIP. In the event of permanent delivery * errors, it may be the case that delivery was not attempted to all - * recipients; if any messages were succesfully delivered, however, + * recipients; if any messages were successfully delivered, however, * recipients' state values will be updated appropriately. * * It is explicitly legal to specify a recipient structure whose state @@ -1359,7 +1359,7 @@ typedef struct * never call hv_receive_message, or could register a different state * buffer, losing the message. * - * Specifiying the same recipient more than once in the recipient list + * Specifying the same recipient more than once in the recipient list * is an error, which will not result in an error return but which may * or may not result in more than one message being delivered to the * recipient tile. diff --git a/arch/tile/kernel/pci.c b/arch/tile/kernel/pci.c index a1ee25be9ad9..ea38f0c9ec7c 100644 --- a/arch/tile/kernel/pci.c +++ b/arch/tile/kernel/pci.c @@ -36,7 +36,7 @@ * Initialization flow and process * ------------------------------- * - * This files containes the routines to search for PCI buses, + * This files contains the routines to search for PCI buses, * enumerate the buses, and configure any attached devices. * * There are two entry points here: @@ -519,7 +519,7 @@ static int __devinit tile_cfg_read(struct pci_bus *bus, /* - * See tile_cfg_read() for relevent comments. + * See tile_cfg_read() for relevant comments. * Note that "val" is the value to write, not a pointer to that value. */ static int __devinit tile_cfg_write(struct pci_bus *bus, diff --git a/arch/tile/mm/fault.c b/arch/tile/mm/fault.c index 758f597f488c..51f8663bf074 100644 --- a/arch/tile/mm/fault.c +++ b/arch/tile/mm/fault.c @@ -290,7 +290,7 @@ static int handle_page_fault(struct pt_regs *regs, /* * Early on, we need to check for migrating PTE entries; * see homecache.c. If we find a migrating PTE, we wait until - * the backing page claims to be done migrating, then we procede. + * the backing page claims to be done migrating, then we proceed. * For kernel PTEs, we rewrite the PTE and return and retry. * Otherwise, we treat the fault like a normal "no PTE" fault, * rather than trying to patch up the existing PTE. diff --git a/arch/tile/mm/hugetlbpage.c b/arch/tile/mm/hugetlbpage.c index 201a582c4137..42cfcba4e1ef 100644 --- a/arch/tile/mm/hugetlbpage.c +++ b/arch/tile/mm/hugetlbpage.c @@ -219,7 +219,7 @@ try_again: if (mm->free_area_cache < len) goto fail; - /* either no address requested or cant fit in requested address hole */ + /* either no address requested or can't fit in requested address hole */ addr = (mm->free_area_cache - len) & huge_page_mask(h); do { /* diff --git a/arch/um/Kconfig.net b/arch/um/Kconfig.net index 9e9a4aaa703d..3160b1a5adb7 100644 --- a/arch/um/Kconfig.net +++ b/arch/um/Kconfig.net @@ -186,7 +186,7 @@ config UML_NET_SLIRP other transports, SLiRP works without the need of root level privleges, setuid binaries, or SLIP devices on the host. This also means not every type of connection is possible, but most - situations can be accomodated with carefully crafted slirp + situations can be accommodated with carefully crafted slirp commands that can be passed along as part of the network device's setup string. The effect of this transport on the UML is similar that of a host behind a firewall that masquerades all network diff --git a/arch/unicore32/include/mach/regs-umal.h b/arch/unicore32/include/mach/regs-umal.h index 885bb62fee71..aa22df74e11d 100644 --- a/arch/unicore32/include/mach/regs-umal.h +++ b/arch/unicore32/include/mach/regs-umal.h @@ -52,7 +52,7 @@ */ #define UMAL_MIISTATUS (PKUNITY_UMAL_BASE + 0x0030) /* - * MII Managment Indicator UMAL_MIIIDCT + * MII Management Indicator UMAL_MIIIDCT */ #define UMAL_MIIIDCT (PKUNITY_UMAL_BASE + 0x0034) /* @@ -91,7 +91,7 @@ #define UMAL_FIFORAM6 (PKUNITY_UMAL_BASE + 0x0078) #define UMAL_FIFORAM7 (PKUNITY_UMAL_BASE + 0x007c) -/* MAHBE MODUEL OF UMAL */ +/* MAHBE MODULE OF UMAL */ /* UMAL's MAHBE module interfaces to the host system through 32-bit AHB Master * and Slave ports.Registers within the M-AHBE provide Control and Status * information concerning these transfers. diff --git a/arch/unicore32/kernel/head.S b/arch/unicore32/kernel/head.S index 92255f3ab6a7..8caf322e110d 100644 --- a/arch/unicore32/kernel/head.S +++ b/arch/unicore32/kernel/head.S @@ -164,7 +164,7 @@ ENTRY(stext) ENDPROC(stext) /* - * Enable the MMU. This completely changes the stucture of the visible + * Enable the MMU. This completely changes the structure of the visible * memory space. You will not be able to trace execution through this. * * r0 = cp#0 control register diff --git a/arch/xtensa/include/asm/dma.h b/arch/xtensa/include/asm/dma.h index 137ca3945b07..bb099a373b5a 100644 --- a/arch/xtensa/include/asm/dma.h +++ b/arch/xtensa/include/asm/dma.h @@ -37,7 +37,7 @@ * the size of the statically mapped kernel segment * (XCHAL_KSEG_{CACHED,BYPASS}_SIZE), ie. 128 MB. * - * NOTE: When the entire KSEG area is DMA capable, we substract + * NOTE: When the entire KSEG area is DMA capable, we subtract * one from the max address so that the virt_to_phys() macro * works correctly on the address (otherwise the address * enters another area, and virt_to_phys() may not return diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index 5fd01f6aaf37..6223f3346b5c 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S @@ -1026,7 +1026,7 @@ ENTRY(fast_syscall_unrecoverable) * TRY adds an entry to the __ex_table fixup table for the immediately * following instruction. * - * CATCH catches any exception that occurred at one of the preceeding TRY + * CATCH catches any exception that occurred at one of the preceding TRY * statements and continues from there * * Usage TRY l32i a0, a1, 0 diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index 2bef5705ce24..f0605ab2a761 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c @@ -868,7 +868,7 @@ static void blkio_update_policy_rule(struct blkio_policy_node *oldpn, } /* - * Some rules/values in blkg have changed. Propogate those to respective + * Some rules/values in blkg have changed. Propagate those to respective * policies. */ static void blkio_update_blkg_policy(struct blkio_cgroup *blkcg, @@ -903,7 +903,7 @@ static void blkio_update_blkg_policy(struct blkio_cgroup *blkcg, } /* - * A policy node rule has been updated. Propogate this update to all the + * A policy node rule has been updated. Propagate this update to all the * block groups which might be affected by this update. */ static void blkio_update_policy_node_blkg(struct blkio_cgroup *blkcg, diff --git a/block/blk-core.c b/block/blk-core.c index e0a062363937..071ae6d2768b 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -1184,7 +1184,7 @@ static bool bio_attempt_front_merge(struct request_queue *q, /* * Attempts to merge with the plugged list in the current process. Returns - * true if merge was succesful, otherwise false. + * true if merge was successful, otherwise false. */ static bool attempt_plug_merge(struct task_struct *tsk, struct request_queue *q, struct bio *bio) diff --git a/block/blk-throttle.c b/block/blk-throttle.c index 5352bdafbcf0..c8b16c88b315 100644 --- a/block/blk-throttle.c +++ b/block/blk-throttle.c @@ -916,7 +916,7 @@ static void throtl_update_blkio_group_common(struct throtl_data *td, /* * For all update functions, key should be a valid pointer because these * update functions are called under blkcg_lock, that means, blkg is - * valid and in turn key is valid. queue exit path can not race becuase + * valid and in turn key is valid. queue exit path can not race because * of blkcg_lock * * Can not take queue lock in update functions as queue lock under blkcg_lock diff --git a/block/blk.h b/block/blk.h index c8db371a921d..61263463e38e 100644 --- a/block/blk.h +++ b/block/blk.h @@ -32,7 +32,7 @@ enum rq_atomic_flags { /* * EH timer and IO completion will both attempt to 'grab' the request, make - * sure that only one of them suceeds + * sure that only one of them succeeds */ static inline int blk_mark_rq_complete(struct request *rq) { diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 7785169f3c8f..3be881ec95ad 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -888,7 +888,7 @@ cfq_group_notify_queue_add(struct cfq_data *cfqd, struct cfq_group *cfqg) /* * Currently put the group at the end. Later implement something * so that groups get lesser vtime based on their weights, so that - * if group does not loose all if it was not continously backlogged. + * if group does not loose all if it was not continuously backlogged. */ n = rb_last(&st->rb); if (n) { diff --git a/block/genhd.c b/block/genhd.c index c91a2dac6b6b..b364bd038a18 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -739,7 +739,7 @@ void __init printk_all_partitions(void) /* * Don't show empty devices or things that have been - * surpressed + * suppressed */ if (get_capacity(disk) == 0 || (disk->flags & GENHD_FL_SUPPRESS_PARTITION_INFO)) diff --git a/crypto/ansi_cprng.c b/crypto/ansi_cprng.c index 2bc332142849..ffa0245e2abc 100644 --- a/crypto/ansi_cprng.c +++ b/crypto/ansi_cprng.c @@ -83,7 +83,7 @@ static void xor_vectors(unsigned char *in1, unsigned char *in2, } /* * Returns DEFAULT_BLK_SZ bytes of random data per call - * returns 0 if generation succeded, <0 if something went wrong + * returns 0 if generation succeeded, <0 if something went wrong */ static int _get_more_prng_bytes(struct prng_context *ctx, int cont_test) { diff --git a/crypto/async_tx/async_xor.c b/crypto/async_tx/async_xor.c index 079ae8ca590b..bc28337fded2 100644 --- a/crypto/async_tx/async_xor.c +++ b/crypto/async_tx/async_xor.c @@ -94,7 +94,7 @@ do_async_xor(struct dma_chan *chan, struct page *dest, struct page **src_list, if (unlikely(!tx)) async_tx_quiesce(&submit->depend_tx); - /* spin wait for the preceeding transactions to complete */ + /* spin wait for the preceding transactions to complete */ while (unlikely(!tx)) { dma_async_issue_pending(chan); tx = dma->device_prep_dma_xor(chan, dma_dest, diff --git a/crypto/gf128mul.c b/crypto/gf128mul.c index a90d260528d4..df35e4ccd07e 100644 --- a/crypto/gf128mul.c +++ b/crypto/gf128mul.c @@ -89,7 +89,7 @@ } /* Given the value i in 0..255 as the byte overflow when a field element - in GHASH is multipled by x^8, this function will return the values that + in GHASH is multiplied by x^8, this function will return the values that are generated in the lo 16-bit word of the field value by applying the modular polynomial. The values lo_byte and hi_byte are returned via the macro xp_fun(lo_byte, hi_byte) so that the values can be assembled into diff --git a/crypto/vmac.c b/crypto/vmac.c index 0999274a27ac..f35ff8a3926e 100644 --- a/crypto/vmac.c +++ b/crypto/vmac.c @@ -95,7 +95,7 @@ const u64 mpoly = UINT64_C(0x1fffffff1fffffff); /* Poly key mask */ /* * For highest performance the L1 NH and L2 polynomial hashes should be - * carefully implemented to take advantage of one's target architechture. + * carefully implemented to take advantage of one's target architecture. * Here these two hash functions are defined multiple time; once for * 64-bit architectures, once for 32-bit SSE2 architectures, and once * for the rest (32-bit) architectures. diff --git a/crypto/xts.c b/crypto/xts.c index 555ecaab1e54..851705446c82 100644 --- a/crypto/xts.c +++ b/crypto/xts.c @@ -45,7 +45,7 @@ static int setkey(struct crypto_tfm *parent, const u8 *key, return -EINVAL; } - /* we need two cipher instances: one to compute the inital 'tweak' + /* we need two cipher instances: one to compute the initial 'tweak' * by encrypting the IV (usually the 'plain' iv) and the other * one to encrypt and decrypt the data */ diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index d1d484d4a06a..f703b2881153 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -241,7 +241,7 @@ static inline int ghes_severity(int severity) case CPER_SEV_FATAL: return GHES_SEV_PANIC; default: - /* Unkown, go panic */ + /* Unknown, go panic */ return GHES_SEV_PANIC; } } diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index fa84e9744330..ad3501739563 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c @@ -1164,7 +1164,7 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, */ if (!match_pr->flags.throttling) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Throttling Controll is unsupported " + "Throttling Control is unsupported " "on CPU %d\n", i)); continue; } diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 31e9e10f657e..ec574fc8fbc6 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -1354,7 +1354,7 @@ acpi_video_bus_get_devices(struct acpi_video_bus *video, status = acpi_video_bus_get_one_device(dev, video); if (ACPI_FAILURE(status)) { printk(KERN_WARNING PREFIX - "Cant attach device\n"); + "Can't attach device\n"); continue; } } @@ -1373,7 +1373,7 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device) acpi_video_device_notify); if (ACPI_FAILURE(status)) { printk(KERN_WARNING PREFIX - "Cant remove video notify handler\n"); + "Can't remove video notify handler\n"); } if (device->backlight) { backlight_device_unregister(device->backlight); diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index 6d2bb2524b6e..821040503154 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c @@ -760,7 +760,7 @@ int amba_request_regions(struct amba_device *dev, const char *name) } /** - * amba_release_regions - release mem regions assoicated with device + * amba_release_regions - release mem regions associated with device * @dev: amba_device structure for device * * Release regions claimed by a successful call to amba_request_regions. diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index e62f693be8ea..39d829cd82dd 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -926,7 +926,7 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) /* * Acer eMachines G725 has the same problem. BIOS * V1.03 is known to be broken. V3.04 is known to - * work. Inbetween, there are V1.06, V2.06 and V3.03 + * work. Between, there are V1.06, V2.06 and V3.03 * that we don't have much idea about. For now, * blacklist anything older than V3.04. * diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index ccaf08122058..39865009c251 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h @@ -225,7 +225,7 @@ enum { /* em_ctl bits */ EM_CTL_RST = (1 << 9), /* Reset */ EM_CTL_TM = (1 << 8), /* Transmit Message */ - EM_CTL_MR = (1 << 0), /* Message Recieved */ + EM_CTL_MR = (1 << 0), /* Message Received */ EM_CTL_ALHD = (1 << 26), /* Activity LED */ EM_CTL_XMT = (1 << 25), /* Transmit Only */ EM_CTL_SMB = (1 << 24), /* Single Message Buffer */ @@ -281,7 +281,7 @@ struct ahci_port_priv { }; struct ahci_host_priv { - void __iomem * mmio; /* bus-independant mem map */ + void __iomem * mmio; /* bus-independent mem map */ unsigned int flags; /* AHCI_HFLAG_* */ u32 cap; /* cap to use */ u32 cap2; /* cap2 to use */ diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index cdec4ab3b159..0bc3fd6c3fdb 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -38,16 +38,16 @@ * Hardware documentation available at http://developer.intel.com/ * * Documentation - * Publically available from Intel web site. Errata documentation - * is also publically available. As an aide to anyone hacking on this + * Publicly available from Intel web site. Errata documentation + * is also publicly available. As an aide to anyone hacking on this * driver the list of errata that are relevant is below, going back to * PIIX4. Older device documentation is now a bit tricky to find. * * The chipsets all follow very much the same design. The original Triton - * series chipsets do _not_ support independant device timings, but this + * series chipsets do _not_ support independent device timings, but this * is fixed in Triton II. With the odd mobile exception the chips then * change little except in gaining more modes until SATA arrives. This - * driver supports only the chips with independant timing (that is those + * driver supports only the chips with independent timing (that is those * with SITRE and the 0x44 timing register). See pata_oldpiix and pata_mpiix * for the early chip drivers. * @@ -122,7 +122,7 @@ enum { P2 = 2, /* port 2 */ P3 = 3, /* port 3 */ IDE = -1, /* IDE */ - NA = -2, /* not avaliable */ + NA = -2, /* not available */ RV = -3, /* reserved */ PIIX_AHCI_DEVICE = 6, diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index b91e19cab102..423c0a6952b2 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -5340,7 +5340,7 @@ int ata_host_suspend(struct ata_host *host, pm_message_t mesg) * * Resume @host. Actual operation is performed by EH. This * function requests EH to perform PM operations and returns. - * Note that all resume operations are performed parallely. + * Note that all resume operations are performed parallelly. * * LOCKING: * Kernel thread context (may sleep). diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index df3f3140c9c7..88cd22fa65cd 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -771,7 +771,7 @@ void ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap) /* process port suspend request */ ata_eh_handle_port_suspend(ap); - /* Exception might have happend after ->error_handler + /* Exception might have happened after ->error_handler * recovered the port but before this point. Repeat * EH in such case. */ @@ -1742,7 +1742,7 @@ void ata_eh_analyze_ncq_error(struct ata_link *link) * * Analyze taskfile of @qc and further determine cause of * failure. This function also requests ATAPI sense data if - * avaliable. + * available. * * LOCKING: * Kernel thread context (may sleep). @@ -1893,7 +1893,7 @@ static int speed_down_verdict_cb(struct ata_ering_entry *ent, void *void_arg) * occurred during last 5 mins, NCQ_OFF. * * 3. If more than 8 ATA_BUS, TOUT_HSM or UNK_DEV errors - * ocurred during last 5 mins, FALLBACK_TO_PIO + * occurred during last 5 mins, FALLBACK_TO_PIO * * 4. If more than 3 TOUT_HSM or UNK_DEV errors occurred * during last 10 mins, NCQ_OFF. @@ -2577,7 +2577,7 @@ int ata_eh_reset(struct ata_link *link, int classify, if (link->flags & ATA_LFLAG_NO_SRST) softreset = NULL; - /* make sure each reset attemp is at least COOL_DOWN apart */ + /* make sure each reset attempt is at least COOL_DOWN apart */ if (ehc->i.flags & ATA_EHI_DID_RESET) { now = jiffies; WARN_ON(time_after(ehc->last_reset, now)); @@ -2736,7 +2736,7 @@ int ata_eh_reset(struct ata_link *link, int classify, if (!reset) { ata_link_printk(link, KERN_ERR, "follow-up softreset required " - "but no softreset avaliable\n"); + "but no softreset available\n"); failed_link = link; rc = -EINVAL; goto fail; diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index a83419991357..e2f57e9e12f0 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -999,7 +999,7 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc) * @qc: Command that we are erroring out * * Generate sense block for a failed ATA command @qc. Descriptor - * format is used to accomodate LBA48 block address. + * format is used to accommodate LBA48 block address. * * LOCKING: * None. diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index cf7acbc0cfcb..f8380ce0f4d1 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -2839,7 +2839,7 @@ unsigned int ata_bmdma_port_intr(struct ata_port *ap, struct ata_queued_cmd *qc) bmdma_stopped = true; if (unlikely(host_stat & ATA_DMA_ERR)) { - /* error when transfering data to/from memory */ + /* error when transferring data to/from memory */ qc->err_mask |= AC_ERR_HOST_BUS; ap->hsm_task_state = HSM_ST_ERR; } @@ -3032,7 +3032,7 @@ void ata_bmdma_start(struct ata_queued_cmd *qc) * Or maybe I'm just being paranoid. * * FIXME: The posting of this write means I/O starts are - * unneccessarily delayed for MMIO + * unnecessarily delayed for MMIO */ } EXPORT_SYMBOL_GPL(ata_bmdma_start); diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c index 620a07cabe31..b0975a5ad8c4 100644 --- a/drivers/ata/pata_amd.c +++ b/drivers/ata/pata_amd.c @@ -11,7 +11,7 @@ * Power management on ports * * - * Documentation publically available. + * Documentation publicly available. */ #include diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c index 65cee74605b4..719bb73a73e0 100644 --- a/drivers/ata/pata_arasan_cf.c +++ b/drivers/ata/pata_arasan_cf.c @@ -385,7 +385,7 @@ static inline int wait4buf(struct arasan_cf_dev *acdev) return -ETIMEDOUT; } - /* Check if PIO Error interrupt has occured */ + /* Check if PIO Error interrupt has occurred */ if (acdev->dma_status & ATA_DMA_ERR) return -EAGAIN; @@ -450,7 +450,7 @@ static int sg_xfer(struct arasan_cf_dev *acdev, struct scatterlist *sg) /* * For each sg: * MAX_XFER_COUNT data will be transferred before we get transfer - * complete interrupt. Inbetween after FIFO_SIZE data + * complete interrupt. Between after FIFO_SIZE data * buffer available interrupt will be generated. At this time we will * fill FIFO again: max FIFO_SIZE data. */ @@ -463,7 +463,7 @@ static int sg_xfer(struct arasan_cf_dev *acdev, struct scatterlist *sg) acdev->vbase + XFER_CTR); spin_unlock_irqrestore(&acdev->host->lock, flags); - /* continue dma xfers untill current sg is completed */ + /* continue dma xfers until current sg is completed */ while (xfer_cnt) { /* wait for read to complete */ if (!write) { @@ -563,7 +563,7 @@ static void data_xfer(struct work_struct *work) chan_request_fail: spin_lock_irqsave(&acdev->host->lock, flags); - /* error when transfering data to/from memory */ + /* error when transferring data to/from memory */ qc->err_mask |= AC_ERR_HOST_BUS; qc->ap->hsm_task_state = HSM_ST_ERR; diff --git a/drivers/ata/pata_bf54x.c b/drivers/ata/pata_bf54x.c index e0b58b8dfe6f..ea64967000ff 100644 --- a/drivers/ata/pata_bf54x.c +++ b/drivers/ata/pata_bf54x.c @@ -1342,7 +1342,7 @@ static unsigned int bfin_ata_host_intr(struct ata_port *ap, ap->ops->bmdma_stop(qc); if (unlikely(host_stat & ATA_DMA_ERR)) { - /* error when transfering data to/from memory */ + /* error when transferring data to/from memory */ qc->err_mask |= AC_ERR_HOST_BUS; ap->hsm_task_state = HSM_ST_ERR; } diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c index 030952f1f97c..e3254fcff0f1 100644 --- a/drivers/ata/pata_cs5520.c +++ b/drivers/ata/pata_cs5520.c @@ -29,7 +29,7 @@ * General Public License for more details. * * Documentation: - * Not publically available. + * Not publicly available. */ #include #include diff --git a/drivers/ata/pata_mpiix.c b/drivers/ata/pata_mpiix.c index b21f0021f54a..d8d9c5807740 100644 --- a/drivers/ata/pata_mpiix.c +++ b/drivers/ata/pata_mpiix.c @@ -15,7 +15,7 @@ * with PCI IDE and also that we do not disable the device when our driver is * unloaded (as it has many other functions). * - * The driver conciously keeps this logic internally to avoid pushing quirky + * The driver consciously keeps this logic internally to avoid pushing quirky * PATA history into the clean libata layer. * * Thinkpad specific note: If you boot an MPIIX using a thinkpad with a PCMCIA diff --git a/drivers/ata/pata_rz1000.c b/drivers/ata/pata_rz1000.c index 4a454a88aa9d..4d04471794b6 100644 --- a/drivers/ata/pata_rz1000.c +++ b/drivers/ata/pata_rz1000.c @@ -112,7 +112,7 @@ static int rz1000_reinit_one(struct pci_dev *pdev) if (rc) return rc; - /* If this fails on resume (which is a "cant happen" case), we + /* If this fails on resume (which is a "can't happen" case), we must stop as any progress risks data loss */ if (rz1000_fifo_disable(pdev)) panic("rz1000 fifo"); diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c index 00eefbd84b33..118787caa93f 100644 --- a/drivers/ata/pata_sil680.c +++ b/drivers/ata/pata_sil680.c @@ -11,7 +11,7 @@ * * May be copied or modified under the terms of the GNU General Public License * - * Documentation publically available. + * Documentation publicly available. * * If you have strange problems with nVidia chipset systems please * see the SI support documentation and update your system BIOS @@ -43,7 +43,7 @@ * * Turn a config register offset into the right address in either * PCI space or MMIO space to access the control register in question - * Thankfully this is a configuration operation so isnt performance + * Thankfully this is a configuration operation so isn't performance * criticial. */ diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c index c04abc393fc5..be08ff92db17 100644 --- a/drivers/ata/pata_sis.c +++ b/drivers/ata/pata_sis.c @@ -331,7 +331,7 @@ static void sis_old_set_dmamode (struct ata_port *ap, struct ata_device *adev) if (adev->dma_mode < XFER_UDMA_0) { /* bits 3-0 hold recovery timing bits 8-10 active timing and - the higher bits are dependant on the device */ + the higher bits are dependent on the device */ timing &= ~0x870F; timing |= mwdma_bits[speed]; } else { @@ -371,7 +371,7 @@ static void sis_66_set_dmamode (struct ata_port *ap, struct ata_device *adev) if (adev->dma_mode < XFER_UDMA_0) { /* bits 3-0 hold recovery timing bits 8-10 active timing and - the higher bits are dependant on the device, bit 15 udma */ + the higher bits are dependent on the device, bit 15 udma */ timing &= ~0x870F; timing |= mwdma_bits[speed]; } else { diff --git a/drivers/ata/pata_triflex.c b/drivers/ata/pata_triflex.c index 0d1f89e571dd..03b6d69d6197 100644 --- a/drivers/ata/pata_triflex.c +++ b/drivers/ata/pata_triflex.c @@ -30,7 +30,7 @@ * Loosely based on the piix & svwks drivers. * * Documentation: - * Not publically available. + * Not publicly available. */ #include diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index 0f91e583892e..35a71d875d0e 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -42,7 +42,7 @@ enum { /* * SATA-FSL host controller supports a max. of (15+1) direct PRDEs, and - * chained indirect PRDEs upto a max count of 63. + * chained indirect PRDEs up to a max count of 63. * We are allocating an array of 63 PRDEs contiguously, but PRDE#15 will * be setup as an indirect descriptor, pointing to it's next * (contiguous) PRDE. Though chained indirect PRDE arrays are @@ -907,7 +907,7 @@ static int sata_fsl_softreset(struct ata_link *link, unsigned int *class, ata_msleep(ap, 1); /* - * SATA device enters reset state after receving a Control register + * SATA device enters reset state after receiving a Control register * FIS with SRST bit asserted and it awaits another H2D Control reg. * FIS with SRST bit cleared, then the device does internal diags & * initialization, followed by indicating it's initialization status diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index cd40651e9b72..b52c0519ad0b 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -1352,7 +1352,7 @@ static int mv_scr_write(struct ata_link *link, unsigned int sc_reg_in, u32 val) /* * Workaround for 88SX60x1 FEr SATA#26: * - * COMRESETs have to take care not to accidently + * COMRESETs have to take care not to accidentally * put the drive to sleep when writing SCR_CONTROL. * Setting bits 12..15 prevents this problem. * @@ -2044,7 +2044,7 @@ static void mv_qc_prep(struct ata_queued_cmd *qc) cw = &pp->crqb[in_index].ata_cmd[0]; - /* Sadly, the CRQB cannot accomodate all registers--there are + /* Sadly, the CRQB cannot accommodate all registers--there are * only 11 bytes...so we must pick and choose required * registers based on the command. So, we drop feature and * hob_feature for [RW] DMA commands, but they are needed for diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index 42344e3c686d..f173ef3bfc10 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c @@ -2121,7 +2121,7 @@ static int nv_swncq_sdbfis(struct ata_port *ap) host_stat = ap->ops->bmdma_status(ap); if (unlikely(host_stat & ATA_DMA_ERR)) { - /* error when transfering data to/from memory */ + /* error when transferring data to/from memory */ ata_ehi_clear_desc(ehi); ata_ehi_push_desc(ehi, "BMDMA stat 0x%x", host_stat); ehi->err_mask |= AC_ERR_HOST_BUS; diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index 21242c5709a0..54434db15b12 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c @@ -582,7 +582,7 @@ static void svia_configure(struct pci_dev *pdev, int board_id) * When host issues HOLD, device may send up to 20DW of data * before acknowledging it with HOLDA and the host should be * able to buffer them in FIFO. Unfortunately, some WD drives - * send upto 40DW before acknowledging HOLD and, in the + * send up to 40DW before acknowledging HOLD and, in the * default configuration, this ends up overflowing vt6421's * FIFO, making the controller abort the transaction with * R_ERR. diff --git a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c index 9f47e8625266..a5fcb1eb862f 100644 --- a/drivers/atm/ambassador.c +++ b/drivers/atm/ambassador.c @@ -497,7 +497,7 @@ static void rx_complete (amb_dev * dev, rx_out * rx) { // VC layer stats atomic_inc(&atm_vcc->stats->rx); __net_timestamp(skb); - // end of our responsability + // end of our responsibility atm_vcc->push (atm_vcc, skb); return; diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c index 049650d42c88..ef7a658312a6 100644 --- a/drivers/atm/firestream.c +++ b/drivers/atm/firestream.c @@ -1782,7 +1782,7 @@ static int __devinit fs_init (struct fs_dev *dev) write_fs (dev, RAS0, RAS0_DCD_XHLT | (((1 << FS155_VPI_BITS) - 1) * RAS0_VPSEL) | (((1 << FS155_VCI_BITS) - 1) * RAS0_VCSEL)); - /* We can chose the split arbitarily. We might be able to + /* We can chose the split arbitrarily. We might be able to support more. Whatever. This should do for now. */ dev->atm_dev->ci_range.vpi_bits = FS155_VPI_BITS; dev->atm_dev->ci_range.vci_bits = FS155_VCI_BITS; diff --git a/drivers/atm/fore200e.h b/drivers/atm/fore200e.h index 7f97c09aaea5..ba34a02b717d 100644 --- a/drivers/atm/fore200e.h +++ b/drivers/atm/fore200e.h @@ -263,7 +263,7 @@ typedef enum opcode { } opcode_t; -/* virtual path / virtual channel identifers */ +/* virtual path / virtual channel identifiers */ typedef struct vpvc { BITFIELD3( @@ -926,7 +926,7 @@ typedef struct fore200e_vcc { #define PCA200E_PCI_LATENCY 0x40 /* maximum slave latenty */ #define PCA200E_PCI_MASTER_CTRL 0x41 /* master control */ -#define PCA200E_PCI_THRESHOLD 0x42 /* burst / continous req threshold */ +#define PCA200E_PCI_THRESHOLD 0x42 /* burst / continuous req threshold */ /* PBI master control register */ diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c index 24761e1d6642..d58e3fcb9db3 100644 --- a/drivers/atm/horizon.c +++ b/drivers/atm/horizon.c @@ -169,13 +169,13 @@ static inline void __init show_version (void) { Real Time (cdv and max CDT given) CBR(pcr) pcr bandwidth always available - rtVBR(pcr,scr,mbs) scr bandwidth always available, upto pcr at mbs too + rtVBR(pcr,scr,mbs) scr bandwidth always available, up to pcr at mbs too Non Real Time - nrtVBR(pcr,scr,mbs) scr bandwidth always available, upto pcr at mbs too + nrtVBR(pcr,scr,mbs) scr bandwidth always available, up to pcr at mbs too UBR() - ABR(mcr,pcr) mcr bandwidth always available, upto pcr (depending) too + ABR(mcr,pcr) mcr bandwidth always available, up to pcr (depending) too mbs is max burst size (bucket) pcr and scr have associated cdvt values @@ -944,7 +944,7 @@ static void hrz_close_rx (hrz_dev * dev, u16 vc) { // to be fixed soon, so do not define TAILRECUSRIONWORKS unless you // are sure it does as you may otherwise overflow the kernel stack. -// giving this fn a return value would help GCC, alledgedly +// giving this fn a return value would help GCC, allegedly static void rx_schedule (hrz_dev * dev, int irq) { unsigned int rx_bytes; @@ -1036,7 +1036,7 @@ static void rx_schedule (hrz_dev * dev, int irq) { // VC layer stats atomic_inc(&vcc->stats->rx); __net_timestamp(skb); - // end of our responsability + // end of our responsibility vcc->push (vcc, skb); } } diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c index bfb7feee0400..048f99fe6f83 100644 --- a/drivers/atm/idt77252.c +++ b/drivers/atm/idt77252.c @@ -3495,7 +3495,7 @@ init_card(struct atm_dev *dev) return -1; } if (dev->phy->ioctl == NULL) { - printk("%s: LT had no IOCTL funtion defined.\n", card->name); + printk("%s: LT had no IOCTL function defined.\n", card->name); deinit_card(card); return -1; } diff --git a/drivers/atm/idt77252.h b/drivers/atm/idt77252.h index f53a43ae2bbe..3a82cc23a053 100644 --- a/drivers/atm/idt77252.h +++ b/drivers/atm/idt77252.h @@ -766,7 +766,7 @@ struct idt77252_dev #define SAR_RCTE_BUFFSTAT_MASK 0x00003000 /* buffer status */ #define SAR_RCTE_EFCI 0x00000800 /* EFCI Congestion flag */ #define SAR_RCTE_CLP 0x00000400 /* Cell Loss Priority flag */ -#define SAR_RCTE_CRC 0x00000200 /* Recieved CRC Error */ +#define SAR_RCTE_CRC 0x00000200 /* Received CRC Error */ #define SAR_RCTE_CELLCNT_MASK 0x000001FF /* cell Count */ #define SAR_RCTE_AAL0 0x00000000 /* AAL types for ALL field */ diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c index d80d51b62a1a..1c674a91f146 100644 --- a/drivers/atm/iphase.c +++ b/drivers/atm/iphase.c @@ -1025,7 +1025,7 @@ static void desc_dbg(IADEV *iadev) { } -/*----------------------------- Recieving side stuff --------------------------*/ +/*----------------------------- Receiving side stuff --------------------------*/ static void rx_excp_rcvd(struct atm_dev *dev) { @@ -1195,7 +1195,7 @@ static void rx_intr(struct atm_dev *dev) if (status & RX_PKT_RCVD) { /* do something */ - /* Basically recvd an interrupt for receving a packet. + /* Basically recvd an interrupt for receiving a packet. A descriptor would have been written to the packet complete queue. Get all the descriptors and set up dma to move the packets till the packet complete queue is empty.. @@ -1855,7 +1855,7 @@ static int open_tx(struct atm_vcc *vcc) return -EINVAL; } if (vcc->qos.txtp.max_pcr > iadev->LineRate) { - IF_CBR(printk("PCR is not availble\n");) + IF_CBR(printk("PCR is not available\n");) return -1; } vc->type = CBR; diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c index 52880c8387d8..4e8ba56f75d3 100644 --- a/drivers/atm/lanai.c +++ b/drivers/atm/lanai.c @@ -1255,7 +1255,7 @@ static inline void lanai_endtx(struct lanai_dev *lanai, /* * Since the "butt register" is a shared resounce on the card we * serialize all accesses to it through this spinlock. This is - * mostly just paranoia sicne the register is rarely "busy" anyway + * mostly just paranoia since the register is rarely "busy" anyway * but is needed for correctness. */ spin_lock(&lanai->endtxlock); @@ -1990,7 +1990,7 @@ static int __devinit lanai_pci_start(struct lanai_dev *lanai) /* * We _can_ use VCI==0 for normal traffic, but only for UBR (or we'll - * get a CBRZERO interrupt), and we can use it only if noone is receiving + * get a CBRZERO interrupt), and we can use it only if no one is receiving * AAL0 traffic (since they will use the same queue) - according to the * docs we shouldn't even use it for AAL0 traffic */ diff --git a/drivers/auxdisplay/cfag12864b.c b/drivers/auxdisplay/cfag12864b.c index 49758593a5ba..41ce4bd96813 100644 --- a/drivers/auxdisplay/cfag12864b.c +++ b/drivers/auxdisplay/cfag12864b.c @@ -49,7 +49,7 @@ static unsigned int cfag12864b_rate = CONFIG_CFAG12864B_RATE; module_param(cfag12864b_rate, uint, S_IRUGO); MODULE_PARM_DESC(cfag12864b_rate, - "Refresh rate (hertzs)"); + "Refresh rate (hertz)"); unsigned int cfag12864b_getrate(void) { @@ -60,7 +60,7 @@ unsigned int cfag12864b_getrate(void) * cfag12864b Commands * * E = Enable signal - * Everytime E switch from low to high, + * Every time E switch from low to high, * cfag12864b/ks0108 reads the command/data. * * CS1 = First ks0108controller. diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 54597c859ecb..3172c60d23a9 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -443,7 +443,7 @@ static int rpm_suspend(struct device *dev, int rpmflags) * * Check if the device's run-time PM status allows it to be resumed. Cancel * any scheduled or pending requests. If another resume has been started - * earlier, either return imediately or wait for it to finish, depending on the + * earlier, either return immediately or wait for it to finish, depending on the * RPM_NOWAIT and RPM_ASYNC flags. Similarly, if there's a suspend running in * parallel with this function, either tell the other process to resume after * suspending (deferred_resume) or wait for it to finish. If the RPM_ASYNC diff --git a/drivers/base/sys.c b/drivers/base/sys.c index fbe72da6c414..acde9b5ee131 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c @@ -197,7 +197,7 @@ kset_put: } /** - * sysdev_driver_register - Register auxillary driver + * sysdev_driver_register - Register auxiliary driver * @cls: Device class driver belongs to. * @drv: Driver. * @@ -250,7 +250,7 @@ unlock: } /** - * sysdev_driver_unregister - Remove an auxillary driver. + * sysdev_driver_unregister - Remove an auxiliary driver. * @cls: Class driver belongs to. * @drv: Driver. */ @@ -302,7 +302,7 @@ int sysdev_register(struct sys_device *sysdev) * code that should have called us. */ - /* Notify class auxillary drivers */ + /* Notify class auxiliary drivers */ list_for_each_entry(drv, &cls->drivers, entry) { if (drv->add) drv->add(sysdev); @@ -335,7 +335,7 @@ void sysdev_unregister(struct sys_device *sysdev) * * Loop over each class of system devices, and the devices in each * of those classes. For each device, we call the shutdown method for - * each driver registered for the device - the auxillaries, + * each driver registered for the device - the auxiliaries, * and the class driver. * * Note: The list is iterated in reverse order, so that we shut down @@ -360,7 +360,7 @@ void sysdev_shutdown(void) struct sysdev_driver *drv; pr_debug(" %s\n", kobject_name(&sysdev->kobj)); - /* Call auxillary drivers first */ + /* Call auxiliary drivers first */ list_for_each_entry(drv, &cls->drivers, entry) { if (drv->shutdown) drv->shutdown(sysdev); @@ -385,7 +385,7 @@ static void __sysdev_resume(struct sys_device *dev) WARN_ONCE(!irqs_disabled(), "Interrupts enabled after %pF\n", cls->resume); - /* Call auxillary drivers next. */ + /* Call auxiliary drivers next. */ list_for_each_entry(drv, &cls->drivers, entry) { if (drv->resume) drv->resume(dev); @@ -432,7 +432,7 @@ int sysdev_suspend(pm_message_t state) list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) { pr_debug(" %s\n", kobject_name(&sysdev->kobj)); - /* Call auxillary drivers first */ + /* Call auxiliary drivers first */ list_for_each_entry(drv, &cls->drivers, entry) { if (drv->suspend) { ret = drv->suspend(sysdev, state); diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index 79882104e431..8066d086578a 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c @@ -1790,7 +1790,7 @@ static bool DAC960_V2_ReadControllerConfiguration(DAC960_Controller_T unsigned short LogicalDeviceNumber = 0; int ModelNameLength; - /* Get data into dma-able area, then copy into permanant location */ + /* Get data into dma-able area, then copy into permanent location */ if (!DAC960_V2_NewControllerInfo(Controller)) return DAC960_Failure(Controller, "GET CONTROLLER INFO"); memcpy(ControllerInfo, Controller->V2.NewControllerInformation, diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c index 2a1642bc451d..c6828b68d77b 100644 --- a/drivers/block/drbd/drbd_actlog.c +++ b/drivers/block/drbd/drbd_actlog.c @@ -30,7 +30,7 @@ /* We maintain a trivial check sum in our on disk activity log. * With that we can ensure correct operation even when the storage - * device might do a partial (last) sector write while loosing power. + * device might do a partial (last) sector write while losing power. */ struct __packed al_transaction { u32 magic; diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 81030d8d654b..b2699bb2e530 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -622,7 +622,7 @@ DCBP_set_pad_bits(struct p_compressed_bm *p, int n) /* one bitmap packet, including the p_header, * should fit within one _architecture independend_ page. * so we need to use the fixed size 4KiB page size - * most architechtures have used for a long time. + * most architectures have used for a long time. */ #define BM_PACKET_PAYLOAD_BYTES (4096 - sizeof(struct p_header80)) #define BM_PACKET_WORDS (BM_PACKET_PAYLOAD_BYTES/sizeof(long)) @@ -810,7 +810,7 @@ enum { /* global flag bits */ enum { - CREATE_BARRIER, /* next P_DATA is preceeded by a P_BARRIER */ + CREATE_BARRIER, /* next P_DATA is preceded by a P_BARRIER */ SIGNAL_ASENDER, /* whether asender wants to be interrupted */ SEND_PING, /* whether asender should send a ping asap */ @@ -1126,7 +1126,7 @@ struct drbd_conf { int c_sync_rate; /* current resync rate after syncer throttle magic */ struct fifo_buffer rs_plan_s; /* correction values of resync planer */ int rs_in_flight; /* resync sectors in flight (to proxy, in proxy and from proxy) */ - int rs_planed; /* resync sectors already planed */ + int rs_planed; /* resync sectors already planned */ atomic_t ap_in_flight; /* App sectors in flight (waiting for ack) */ }; @@ -1144,7 +1144,7 @@ static inline unsigned int mdev_to_minor(struct drbd_conf *mdev) return mdev->minor; } -/* returns 1 if it was successfull, +/* returns 1 if it was successful, * returns 0 if there was no data socket. * so wherever you are going to use the data.socket, e.g. do * if (!drbd_get_data_sock(mdev)) @@ -2079,7 +2079,7 @@ static inline void inc_ap_pending(struct drbd_conf *mdev) /* counts how many resync-related answers we still expect from the peer * increase decrease * C_SYNC_TARGET sends P_RS_DATA_REQUEST (and expects P_RS_DATA_REPLY) - * C_SYNC_SOURCE sends P_RS_DATA_REPLY (and expects P_WRITE_ACK whith ID_SYNCER) + * C_SYNC_SOURCE sends P_RS_DATA_REPLY (and expects P_WRITE_ACK with ID_SYNCER) * (or P_NEG_ACK with ID_SYNCER) */ static inline void inc_rs_pending(struct drbd_conf *mdev) diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index dfc85f32d317..5b525c179f39 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -1561,7 +1561,7 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os, if (drbd_send_state(mdev)) dev_warn(DEV, "Notified peer that I'm now diskless.\n"); /* corresponding get_ldev in __drbd_set_state - * this may finaly trigger drbd_ldev_destroy. */ + * this may finally trigger drbd_ldev_destroy. */ put_ldev(mdev); } @@ -3706,7 +3706,7 @@ int drbd_md_read(struct drbd_conf *mdev, struct drbd_backing_dev *bdev) buffer = (struct meta_data_on_disk *)page_address(mdev->md_io_page); if (!drbd_md_sync_page_io(mdev, bdev, bdev->md.md_offset, READ)) { - /* NOTE: cant do normal error processing here as this is + /* NOTE: can't do normal error processing here as this is called BEFORE disk is attached */ dev_err(DEV, "Error while reading metadata.\n"); rv = ERR_IO_MD_DISK; diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index fe1564c7d8b6..fd26666c0b08 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -862,7 +862,7 @@ retry: msock->sk->sk_rcvtimeo = mdev->net_conf->ping_int*HZ; /* we don't want delays. - * we use TCP_CORK where apropriate, though */ + * we use TCP_CORK where appropriate, though */ drbd_tcp_nodelay(sock); drbd_tcp_nodelay(msock); diff --git a/drivers/block/drbd/drbd_vli.h b/drivers/block/drbd/drbd_vli.h index fc824006e721..8cb1532a3816 100644 --- a/drivers/block/drbd/drbd_vli.h +++ b/drivers/block/drbd/drbd_vli.h @@ -32,7 +32,7 @@ * the bitmap transfer time can take much too long, * if transmitted in plain text. * - * We try to reduce the transfered bitmap information + * We try to reduce the transferred bitmap information * by encoding runlengths of bit polarity. * * We never actually need to encode a "zero" (runlengths are positive). diff --git a/drivers/block/hd.c b/drivers/block/hd.c index 30ec6b37424e..007c630904c1 100644 --- a/drivers/block/hd.c +++ b/drivers/block/hd.c @@ -733,7 +733,7 @@ static int __init hd_init(void) * the BIOS or CMOS. This doesn't work all that well, * since this assumes that this is a primary or secondary * drive, and if we're using this legacy driver, it's - * probably an auxilliary controller added to recover + * probably an auxiliary controller added to recover * legacy data off an ST-506 drive. Either way, it's * definitely safest to have the user explicitly specify * the information. diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c index e2ff697697c2..9a5b2a2d616d 100644 --- a/drivers/block/viodasd.c +++ b/drivers/block/viodasd.c @@ -94,7 +94,7 @@ static const struct vio_error_entry viodasd_err_table[] = { { 0x0204, EIO, "Use Error" }, { 0x0205, EIO, "Release Error" }, { 0x0206, EINVAL, "Invalid Disk" }, - { 0x0207, EBUSY, "Cant Lock" }, + { 0x0207, EBUSY, "Can't Lock" }, { 0x0208, EIO, "Already Locked" }, { 0x0209, EIO, "Already Unlocked" }, { 0x020A, EIO, "Invalid Arg" }, diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index 73354b081ed3..645ff765cd12 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c @@ -621,7 +621,7 @@ static void ace_fsm_dostate(struct ace_device *ace) ace_dump_mem(ace->cf_id, 512); /* Debug: Dump out disk ID */ if (ace->data_result) { - /* Error occured, disable the disk */ + /* Error occurred, disable the disk */ ace->media_change = 1; set_capacity(ace->gd, 0); dev_err(ace->dev, "error fetching CF id (%i)\n", @@ -801,7 +801,7 @@ static int ace_interrupt_checkstate(struct ace_device *ace) u32 sreg = ace_in32(ace, ACE_STATUS); u16 creg = ace_in(ace, ACE_CTRL); - /* Check for error occurance */ + /* Check for error occurrence */ if ((sreg & (ACE_STATUS_CFGERROR | ACE_STATUS_CFCERROR)) && (creg & ACE_CTRL_ERRORIRQ)) { dev_err(ace->dev, "transfer failure\n"); @@ -1169,7 +1169,7 @@ static int __devinit ace_probe(struct platform_device *dev) irq = dev->resource[i].start; } - /* Call the bus-independant setup code */ + /* Call the bus-independent setup code */ return ace_alloc(&dev->dev, id, physaddr, irq, bus_width); } @@ -1222,7 +1222,7 @@ static int __devinit ace_of_probe(struct platform_device *op) if (of_find_property(op->dev.of_node, "8-bit", NULL)) bus_width = ACE_BUS_WIDTH_8; - /* Call the bus-independant setup code */ + /* Call the bus-independent setup code */ return ace_alloc(&op->dev, id ? be32_to_cpup(id) : 0, physaddr, irq, bus_width); } diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c index 38595e782d02..7e4b435f79f0 100644 --- a/drivers/bluetooth/hci_ll.c +++ b/drivers/bluetooth/hci_ll.c @@ -207,7 +207,7 @@ static void ll_device_want_to_wakeup(struct hci_uart *hu) /* * This state means that both the host and the BRF chip * have simultaneously sent a wake-up-indication packet. - * Traditionaly, in this case, receiving a wake-up-indication + * Traditionally, in this case, receiving a wake-up-indication * was enough and an additional wake-up-ack wasn't needed. * This has changed with the BRF6350, which does require an * explicit wake-up-ack. Other BRF versions, which do not diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index e2c48a7eccff..514dd8efaf73 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c @@ -30,7 +30,7 @@ changelog for the 1.x series, David? 2.00 Dec 2, 1997 -- Erik Andersen - -- New maintainer! As David A. van Leeuwen has been too busy to activly + -- New maintainer! As David A. van Leeuwen has been too busy to actively maintain and improve this driver, I am now carrying on the torch. If you have a problem with this driver, please feel free to contact me. @@ -2520,7 +2520,7 @@ static int cdrom_ioctl_drive_status(struct cdrom_device_info *cdi, /* * Ok, this is where problems start. The current interface for the * CDROM_DISC_STATUS ioctl is flawed. It makes the false assumption that - * CDs are all CDS_DATA_1 or all CDS_AUDIO, etc. Unfortunatly, while this + * CDs are all CDS_DATA_1 or all CDS_AUDIO, etc. Unfortunately, while this * is often the case, it is also very common for CDs to have some tracks * with data, and some tracks with audio. Just because I feel like it, * I declare the following to be the best way to cope. If the CD has ANY diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h index 3e67ddde9e16..923f99df4f1c 100644 --- a/drivers/char/agp/agp.h +++ b/drivers/char/agp/agp.h @@ -237,7 +237,7 @@ extern int agp_try_unsupported_boot; long compat_agp_ioctl(struct file *file, unsigned int cmd, unsigned long arg); -/* Chipset independant registers (from AGP Spec) */ +/* Chipset independent registers (from AGP Spec) */ #define AGP_APBASE 0x10 #define AGPSTAT 0x4 diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c index 45681c0ff3b6..f7e88787af97 100644 --- a/drivers/char/agp/amd-k7-agp.c +++ b/drivers/char/agp/amd-k7-agp.c @@ -272,7 +272,7 @@ static void amd_irongate_cleanup(void) * This routine could be implemented by taking the addresses * written to the GATT, and flushing them individually. However * currently it just flushes the whole table. Which is probably - * more efficent, since agp_memory blocks can be a large number of + * more efficient, since agp_memory blocks can be a large number of * entries. */ diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c index 13acaaf64edb..f02f9b07fd4c 100644 --- a/drivers/char/agp/sworks-agp.c +++ b/drivers/char/agp/sworks-agp.c @@ -229,7 +229,7 @@ static int serverworks_fetch_size(void) * This routine could be implemented by taking the addresses * written to the GATT, and flushing them individually. However * currently it just flushes the whole table. Which is probably - * more efficent, since agp_memory blocks can be a large number of + * more efficient, since agp_memory blocks can be a large number of * entries. */ static void serverworks_tlbflush(struct agp_memory *temp) diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c index df67e80019d2..8bc384937401 100644 --- a/drivers/char/agp/via-agp.c +++ b/drivers/char/agp/via-agp.c @@ -400,7 +400,7 @@ static struct agp_device_ids via_agp_device_ids[] __devinitdata = * the traditional AGP which resides only in chipset. AGP is used * by 3D driver which wasn't available for the VT3336 and VT3364 * generation until now. Unfortunately, by testing, VT3364 works - * but VT3336 doesn't. - explaination from via, just leave this as + * but VT3336 doesn't. - explanation from via, just leave this as * as a placeholder to avoid future patches adding it back in. */ #if 0 diff --git a/drivers/char/ipmi/ipmi_poweroff.c b/drivers/char/ipmi/ipmi_poweroff.c index 0dec5da000ef..2efa176beab0 100644 --- a/drivers/char/ipmi/ipmi_poweroff.c +++ b/drivers/char/ipmi/ipmi_poweroff.c @@ -122,7 +122,7 @@ static struct ipmi_recv_msg halt_recv_msg = { /* - * Code to send a message and wait for the reponse. + * Code to send a message and wait for the response. */ static void receive_handler(struct ipmi_recv_msg *recv_msg, void *handler_data) diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index d28b484aee45..cc6c9b2546a3 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -339,7 +339,7 @@ static void return_hosed_msg(struct smi_info *smi_info, int cCode) cCode = IPMI_ERR_UNSPECIFIED; /* else use it as is */ - /* Make it a reponse */ + /* Make it a response */ msg->rsp[0] = msg->data[0] | 4; msg->rsp[1] = msg->data[1]; msg->rsp[2] = cCode; @@ -2927,7 +2927,7 @@ static void return_hosed_msg_badsize(struct smi_info *smi_info) { struct ipmi_smi_msg *msg = smi_info->curr_msg; - /* Make it a reponse */ + /* Make it a response */ msg->rsp[0] = msg->data[0] | 4; msg->rsp[1] = msg->data[1]; msg->rsp[2] = CANNOT_RETURN_REQUESTED_LENGTH; diff --git a/drivers/char/mbcs.h b/drivers/char/mbcs.h index ba671589f4cb..1a36884c48b5 100644 --- a/drivers/char/mbcs.h +++ b/drivers/char/mbcs.h @@ -36,13 +36,13 @@ #define MBCS_RD_DMA_CTRL 0x0110 /* Read DMA Control */ #define MBCS_RD_DMA_AMO_DEST 0x0118 /* Read DMA AMO Destination */ #define MBCS_RD_DMA_INT_DEST 0x0120 /* Read DMA Interrupt Destination */ -#define MBCS_RD_DMA_AUX_STAT 0x0130 /* Read DMA Auxillary Status */ +#define MBCS_RD_DMA_AUX_STAT 0x0130 /* Read DMA Auxiliary Status */ #define MBCS_WR_DMA_SYS_ADDR 0x0200 /* Write DMA System Address */ #define MBCS_WR_DMA_LOC_ADDR 0x0208 /* Write DMA Local Address */ #define MBCS_WR_DMA_CTRL 0x0210 /* Write DMA Control */ #define MBCS_WR_DMA_AMO_DEST 0x0218 /* Write DMA AMO Destination */ #define MBCS_WR_DMA_INT_DEST 0x0220 /* Write DMA Interrupt Destination */ -#define MBCS_WR_DMA_AUX_STAT 0x0230 /* Write DMA Auxillary Status */ +#define MBCS_WR_DMA_AUX_STAT 0x0230 /* Write DMA Auxiliary Status */ #define MBCS_ALG_AMO_DEST 0x0300 /* Algorithm AMO Destination */ #define MBCS_ALG_INT_DEST 0x0308 /* Algorithm Interrupt Destination */ #define MBCS_ALG_OFFSETS 0x0310 diff --git a/drivers/char/mwave/3780i.h b/drivers/char/mwave/3780i.h index 270431ca7dae..fba6ab1160ce 100644 --- a/drivers/char/mwave/3780i.h +++ b/drivers/char/mwave/3780i.h @@ -122,7 +122,7 @@ typedef struct { typedef struct { unsigned char Dma:3; /* RW: DMA channel selection */ unsigned char NumTransfers:2; /* RW: Maximum # of transfers once being granted the ISA bus */ - unsigned char ReRequest:2; /* RW: Minumum delay between releasing the ISA bus and requesting it again */ + unsigned char ReRequest:2; /* RW: Minimum delay between releasing the ISA bus and requesting it again */ unsigned char MEMCS16:1; /* RW: ISA signal MEMCS16: 0=disabled, 1=enabled */ } DSP_BUSMASTER_CFG_1; diff --git a/drivers/char/nwbutton.c b/drivers/char/nwbutton.c index 8994ce32e6c7..04a480f86c6c 100644 --- a/drivers/char/nwbutton.c +++ b/drivers/char/nwbutton.c @@ -75,7 +75,7 @@ int button_add_callback (void (*callback) (void), int count) * with -EINVAL. If there is more than one entry with the same address, * because it searches the list from end to beginning, it will unregister the * last one to be registered first (FILO- First In Last Out). - * Note that this is not neccessarily true if the entries are not submitted + * Note that this is not necessarily true if the entries are not submitted * at the same time, because another driver could have unregistered a callback * between the submissions creating a gap earlier in the list, which would * be filled first at submission time. diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index bcbbc71febb7..90bd01671c70 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c @@ -806,7 +806,7 @@ static void monitor_card(unsigned long p) dev->flags1 = 0x01; xoutb(dev->flags1, REG_FLAGS1(iobase)); - /* atr is present (which doesnt mean it's valid) */ + /* atr is present (which doesn't mean it's valid) */ set_bit(IS_ATR_PRESENT, &dev->flags); if (dev->atr[0] == 0x03) str_invert_revert(dev->atr, dev->atr_len); diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index beca80bb9bdb..b575411c69b2 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -1290,7 +1290,7 @@ static int startup(MGSLPC_INFO * info, struct tty_struct *tty) /* Allocate and claim adapter resources */ retval = claim_resources(info); - /* perform existance check and diagnostics */ + /* perform existence check and diagnostics */ if ( !retval ) retval = adapter_test(info); @@ -2680,7 +2680,7 @@ static void rx_free_buffers(MGSLPC_INFO *info) static int claim_resources(MGSLPC_INFO *info) { if (rx_alloc_buffers(info) < 0 ) { - printk( "Cant allocate rx buffer %s\n", info->device_name); + printk( "Can't allocate rx buffer %s\n", info->device_name); release_resources(info); return -ENODEV; } diff --git a/drivers/char/random.c b/drivers/char/random.c index 5e29e8031bbc..d4ddeba56682 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -732,7 +732,7 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf, size_t nbytes, int min, int rsvd); /* - * This utility inline function is responsible for transfering entropy + * This utility inline function is responsible for transferring entropy * from the primary pool to the secondary extraction pool. We make * sure we pull enough for a 'catastrophic reseed'. */ diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index 79e36c878a4c..1ee8ce7d2762 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c @@ -1241,7 +1241,7 @@ static int __devinit sonypi_setup_ioports(struct sonypi_device *dev, while (check_ioport && check->port1) { if (!request_region(check->port1, sonypi_device.region_size, - "Sony Programable I/O Device Check")) { + "Sony Programmable I/O Device Check")) { printk(KERN_ERR "sonypi: ioport 0x%.4x busy, using sony-laptop? " "if not use check_ioport=0\n", check->port1); @@ -1255,7 +1255,7 @@ static int __devinit sonypi_setup_ioports(struct sonypi_device *dev, if (request_region(ioport_list->port1, sonypi_device.region_size, - "Sony Programable I/O Device")) { + "Sony Programmable I/O Device")) { dev->ioport1 = ioport_list->port1; dev->ioport2 = ioport_list->port2; return 0; diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c index d3c9d755ed98..d6412c16385f 100644 --- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c +++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c @@ -67,7 +67,7 @@ * cp foo.bit /dev/icap0 * * Note that unless foo.bit is an appropriately constructed partial - * bitstream, this has a high likelyhood of overwriting the design + * bitstream, this has a high likelihood of overwriting the design * currently programmed in the FPGA. */ diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index b03771d4787c..2dafc5c38ae7 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1782,7 +1782,7 @@ error_out: * cpufreq_update_policy - re-evaluate an existing cpufreq policy * @cpu: CPU which shall be re-evaluated * - * Usefull for policy notifiers which have different necessities + * Useful for policy notifiers which have different necessities * at different times. */ int cpufreq_update_policy(unsigned int cpu) diff --git a/drivers/crypto/amcc/crypto4xx_sa.c b/drivers/crypto/amcc/crypto4xx_sa.c index 466fd94cd4a3..de8a7a48775a 100644 --- a/drivers/crypto/amcc/crypto4xx_sa.c +++ b/drivers/crypto/amcc/crypto4xx_sa.c @@ -17,7 +17,7 @@ * @file crypto4xx_sa.c * * This file implements the security context - * assoicate format. + * associate format. */ #include #include diff --git a/drivers/crypto/amcc/crypto4xx_sa.h b/drivers/crypto/amcc/crypto4xx_sa.h index 4b83ed7e5570..1352d58d4e34 100644 --- a/drivers/crypto/amcc/crypto4xx_sa.h +++ b/drivers/crypto/amcc/crypto4xx_sa.h @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * This file defines the security context - * assoicate format. + * associate format. */ #ifndef __CRYPTO4XX_SA_H__ diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c index 0d662213c066..4c20c5bf6058 100644 --- a/drivers/crypto/ixp4xx_crypto.c +++ b/drivers/crypto/ixp4xx_crypto.c @@ -1044,7 +1044,7 @@ static int aead_perform(struct aead_request *req, int encrypt, memcpy(crypt->iv, req->iv, ivsize); if (req->src != req->dst) { - BUG(); /* -ENOTSUP because of my lazyness */ + BUG(); /* -ENOTSUP because of my laziness */ } /* ASSOC data */ diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index 3d7d705f026f..235f53bf494e 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -167,7 +167,7 @@ static void atc_desc_put(struct at_dma_chan *atchan, struct at_desc *desc) /** * atc_assign_cookie - compute and assign new cookie * @atchan: channel we work on - * @desc: descriptor to asign cookie for + * @desc: descriptor to assign cookie for * * Called with atchan->lock held and bh disabled */ diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c index 00deabd9a04b..f48e54006518 100644 --- a/drivers/dma/coh901318.c +++ b/drivers/dma/coh901318.c @@ -529,7 +529,7 @@ static void coh901318_pause(struct dma_chan *chan) val = readl(virtbase + COH901318_CX_CFG + COH901318_CX_CFG_SPACING * channel); - /* Stopping infinit transfer */ + /* Stopping infinite transfer */ if ((val & COH901318_CX_CTRL_TC_ENABLE) == 0 && (val & COH901318_CX_CFG_CH_ENABLE)) cohc->stopped = 1; diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c index 798f46a4590d..3d4ec38b9b62 100644 --- a/drivers/dma/intel_mid_dma.c +++ b/drivers/dma/intel_mid_dma.c @@ -911,8 +911,8 @@ static int intel_mid_dma_alloc_chan_resources(struct dma_chan *chan) /** * midc_handle_error - Handle DMA txn error - * @mid: controller where error occured - * @midc: chan where error occured + * @mid: controller where error occurred + * @midc: chan where error occurred * * Scan the descriptor for error */ @@ -1099,7 +1099,7 @@ static int mid_setup_dma(struct pci_dev *pdev) dma->mask_reg = ioremap(LNW_PERIPHRAL_MASK_BASE, LNW_PERIPHRAL_MASK_SIZE); if (dma->mask_reg == NULL) { - pr_err("ERR_MDMA:Cant map periphral intr space !!\n"); + pr_err("ERR_MDMA:Can't map periphral intr space !!\n"); return -ENOMEM; } } else @@ -1373,7 +1373,7 @@ int dma_resume(struct pci_dev *pci) pci_restore_state(pci); ret = pci_enable_device(pci); if (ret) { - pr_err("MDMA: device cant be enabled for %x\n", pci->device); + pr_err("MDMA: device can't be enabled for %x\n", pci->device); return ret; } device->state = RUNNING; diff --git a/drivers/dma/intel_mid_dma_regs.h b/drivers/dma/intel_mid_dma_regs.h index 709fecbdde79..aea5ee88ce03 100644 --- a/drivers/dma/intel_mid_dma_regs.h +++ b/drivers/dma/intel_mid_dma_regs.h @@ -174,8 +174,8 @@ union intel_mid_dma_cfg_hi { * @dma: dma device struture pointer * @busy: bool representing if ch is busy (active txn) or not * @in_use: bool representing if ch is in use or not - * @raw_tfr: raw trf interrupt recieved - * @raw_block: raw block interrupt recieved + * @raw_tfr: raw trf interrupt received + * @raw_block: raw block interrupt received */ struct intel_mid_dma_chan { struct dma_chan chan; diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c index 4f95d31f5a20..b9bae94f2015 100644 --- a/drivers/dma/mpc512x_dma.c +++ b/drivers/dma/mpc512x_dma.c @@ -328,7 +328,7 @@ static irqreturn_t mpc_dma_irq(int irq, void *data) return IRQ_HANDLED; } -/* proccess completed descriptors */ +/* process completed descriptors */ static void mpc_dma_process_completed(struct mpc_dma *mdma) { dma_cookie_t last_cookie = 0; diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index af955de035f4..94ee15dd3aed 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -90,7 +90,7 @@ struct d40_lli_pool { * @lli_log: Same as above but for logical channels. * @lli_pool: The pool with two entries pre-allocated. * @lli_len: Number of llis of current descriptor. - * @lli_current: Number of transfered llis. + * @lli_current: Number of transferred llis. * @lcla_alloc: Number of LCLA entries allocated. * @txd: DMA engine struct. Used for among other things for communication * during a transfer. @@ -1214,7 +1214,7 @@ static void dma_tasklet(unsigned long data) return; err: - /* Rescue manouver if receiving double interrupts */ + /* Rescue manoeuvre if receiving double interrupts */ if (d40c->pending_tx > 0) d40c->pending_tx--; spin_unlock_irqrestore(&d40c->lock, flags); diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig index fac1a2002e67..af1a17d42bd7 100644 --- a/drivers/edac/Kconfig +++ b/drivers/edac/Kconfig @@ -45,7 +45,7 @@ config EDAC_DECODE_MCE default y ---help--- Enable this option if you want to decode Machine Check Exceptions - occuring on your machine in human-readable form. + occurring on your machine in human-readable form. You should definitely say Y here in case you want to decode MCEs which occur really early upon boot, before the module infrastructure diff --git a/drivers/edac/cpc925_edac.c b/drivers/edac/cpc925_edac.c index b9a781c47e3c..837ad8f85b48 100644 --- a/drivers/edac/cpc925_edac.c +++ b/drivers/edac/cpc925_edac.c @@ -817,7 +817,7 @@ static void cpc925_del_edac_devices(void) } } -/* Convert current back-ground scrub rate into byte/sec bandwith */ +/* Convert current back-ground scrub rate into byte/sec bandwidth */ static int cpc925_get_sdram_scrub_rate(struct mem_ctl_info *mci) { struct cpc925_mc_pdata *pdata = mci->pvt_info; diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h index 3d965347a673..eefa3501916b 100644 --- a/drivers/edac/edac_core.h +++ b/drivers/edac/edac_core.h @@ -164,7 +164,7 @@ enum mem_type { /* chipset Error Detection and Correction capabilities and mode */ enum edac_type { EDAC_UNKNOWN = 0, /* Unknown if ECC is available */ - EDAC_NONE, /* Doesnt support ECC */ + EDAC_NONE, /* Doesn't support ECC */ EDAC_RESERVED, /* Reserved ECC type */ EDAC_PARITY, /* Detects parity errors */ EDAC_EC, /* Error Checking - no correction */ @@ -233,7 +233,7 @@ enum scrub_type { * of these in parallel provides 64 bits which is common * for a memory stick. * - * Memory Stick: A printed circuit board that agregates multiple + * Memory Stick: A printed circuit board that aggregates multiple * memory devices in parallel. This is the atomic * memory component that is purchaseable by Joe consumer * and loaded into a memory socket. @@ -385,7 +385,7 @@ struct mem_ctl_info { /* Get the current sdram memory scrub rate from the internal representation and converts it to the closest matching - bandwith in bytes/sec. + bandwidth in bytes/sec. */ int (*get_sdram_scrub_rate) (struct mem_ctl_info * mci); @@ -823,7 +823,7 @@ extern int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, * There are a limited number of error logging registers that can * be exausted. When all registers are exhausted and an additional * error occurs then an error overflow register records that an - * error occured and the type of error, but doesn't have any + * error occurred and the type of error, but doesn't have any * further information. The ce/ue versions make for cleaner * reporting logic and function interface - reduces conditional * statement clutter and extra function arguments. diff --git a/drivers/edac/edac_device.c b/drivers/edac/edac_device.c index d5e13c94714f..a7408cf86f37 100644 --- a/drivers/edac/edac_device.c +++ b/drivers/edac/edac_device.c @@ -672,7 +672,7 @@ void edac_device_handle_ce(struct edac_device_ctl_info *edac_dev, block->counters.ce_count++; } - /* Propogate the count up the 'totals' tree */ + /* Propagate the count up the 'totals' tree */ instance->counters.ce_count++; edac_dev->counters.ce_count++; @@ -718,7 +718,7 @@ void edac_device_handle_ue(struct edac_device_ctl_info *edac_dev, block->counters.ue_count++; } - /* Propogate the count up the 'totals' tree */ + /* Propagate the count up the 'totals' tree */ instance->counters.ue_count++; edac_dev->counters.ue_count++; diff --git a/drivers/edac/edac_device_sysfs.c b/drivers/edac/edac_device_sysfs.c index 400de071cabc..86649df00285 100644 --- a/drivers/edac/edac_device_sysfs.c +++ b/drivers/edac/edac_device_sysfs.c @@ -533,7 +533,7 @@ static int edac_device_create_block(struct edac_device_ctl_info *edac_dev, memset(&block->kobj, 0, sizeof(struct kobject)); /* bump the main kobject's reference count for this controller - * and this instance is dependant on the main + * and this instance is dependent on the main */ main_kobj = kobject_get(&edac_dev->kobj); if (!main_kobj) { @@ -635,7 +635,7 @@ static int edac_device_create_instance(struct edac_device_ctl_info *edac_dev, instance->ctl = edac_dev; /* bump the main kobject's reference count for this controller - * and this instance is dependant on the main + * and this instance is dependent on the main */ main_kobj = kobject_get(&edac_dev->kobj); if (!main_kobj) { diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index a4e9db2d6524..1d8056049072 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c @@ -724,7 +724,7 @@ void edac_mc_handle_ce(struct mem_ctl_info *mci, * Some MC's can remap memory so that it is still available * at a different address when PCI devices map into memory. * MC's that can't do this lose the memory where PCI devices - * are mapped. This mapping is MC dependant and so we call + * are mapped. This mapping is MC dependent and so we call * back into the MC driver for it to map the MC page to * a physical (CPU) page which can then be mapped to a virtual * page - which can then be scrubbed. diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c index 73196f7b7229..26343fd46596 100644 --- a/drivers/edac/edac_mc_sysfs.c +++ b/drivers/edac/edac_mc_sysfs.c @@ -850,7 +850,7 @@ static void edac_remove_mci_instance_attributes(struct mem_ctl_info *mci, /* * loop if there are attributes and until we hit a NULL entry - * Remove first all the atributes + * Remove first all the attributes */ while (sysfs_attrib) { debugf4("%s() sysfs_attrib = %p\n",__func__, sysfs_attrib); diff --git a/drivers/edac/edac_pci_sysfs.c b/drivers/edac/edac_pci_sysfs.c index 023b01cb5175..495198ad059c 100644 --- a/drivers/edac/edac_pci_sysfs.c +++ b/drivers/edac/edac_pci_sysfs.c @@ -352,7 +352,7 @@ static int edac_pci_main_kobj_setup(void) return 0; /* First time, so create the main kobject and its - * controls and atributes + * controls and attributes */ edac_class = edac_get_sysfs_class(); if (edac_class == NULL) { @@ -551,7 +551,7 @@ static void edac_pci_dev_parity_clear(struct pci_dev *dev) /* * PCI Parity polling * - * Fucntion to retrieve the current parity status + * Function to retrieve the current parity status * and decode it * */ diff --git a/drivers/edac/i5000_edac.c b/drivers/edac/i5000_edac.c index a5cefab8d65d..87f427c2ce5c 100644 --- a/drivers/edac/i5000_edac.c +++ b/drivers/edac/i5000_edac.c @@ -1372,7 +1372,7 @@ static int i5000_probe1(struct pci_dev *pdev, int dev_idx) * actual number of slots/dimms per channel, we thus utilize the * resource as specified by the chipset. Thus, we might have * have more DIMMs per channel than actually on the mobo, but this - * allows the driver to support upto the chipset max, without + * allows the driver to support up to the chipset max, without * some fancy mobo determination. */ i5000_get_dimm_and_channel_counts(pdev, &num_dimms_per_channel, diff --git a/drivers/edac/i5100_edac.c b/drivers/edac/i5100_edac.c index 0448da0af75d..bcbdeeca48b8 100644 --- a/drivers/edac/i5100_edac.c +++ b/drivers/edac/i5100_edac.c @@ -11,7 +11,7 @@ * * The intel 5100 has two independent channels. EDAC core currently * can not reflect this configuration so instead the chip-select - * rows for each respective channel are layed out one after another, + * rows for each respective channel are laid out one after another, * the first half belonging to channel 0, the second half belonging * to channel 1. */ diff --git a/drivers/edac/i5400_edac.c b/drivers/edac/i5400_edac.c index 38a9be9e1c7c..80a465efbae8 100644 --- a/drivers/edac/i5400_edac.c +++ b/drivers/edac/i5400_edac.c @@ -648,7 +648,7 @@ static void i5400_process_nonfatal_error_info(struct mem_ctl_info *mci, return; } - /* Miscelaneous errors */ + /* Miscellaneous errors */ errnum = find_first_bit(&allErrors, ARRAY_SIZE(error_name)); branch = extract_fbdchan_indx(info->ferr_nf_fbd); @@ -1240,7 +1240,7 @@ static int i5400_probe1(struct pci_dev *pdev, int dev_idx) * actual number of slots/dimms per channel, we thus utilize the * resource as specified by the chipset. Thus, we might have * have more DIMMs per channel than actually on the mobo, but this - * allows the driver to support upto the chipset max, without + * allows the driver to support up to the chipset max, without * some fancy mobo determination. */ num_dimms_per_channel = MAX_DIMMS_PER_CHANNEL; diff --git a/drivers/edac/i7300_edac.c b/drivers/edac/i7300_edac.c index 76d1f576cdc8..363cc1602944 100644 --- a/drivers/edac/i7300_edac.c +++ b/drivers/edac/i7300_edac.c @@ -1065,7 +1065,7 @@ static int __devinit i7300_init_one(struct pci_dev *pdev, * actual number of slots/dimms per channel, we thus utilize the * resource as specified by the chipset. Thus, we might have * have more DIMMs per channel than actually on the mobo, but this - * allows the driver to support upto the chipset max, without + * allows the driver to support up to the chipset max, without * some fancy mobo determination. */ num_dimms_per_channel = MAX_SLOTS; diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 81154ab296b6..465cbc25149f 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -1772,7 +1772,7 @@ static void i7core_check_error(struct mem_ctl_info *mci) /* * MCE first step: Copy all mce errors into a temporary buffer * We use a double buffering here, to reduce the risk of - * loosing an error. + * losing an error. */ smp_rmb(); count = (pvt->mce_out + MCE_LOG_LEN - pvt->mce_in) diff --git a/drivers/edac/i82443bxgx_edac.c b/drivers/edac/i82443bxgx_edac.c index 678405ab04e4..4329d39f902c 100644 --- a/drivers/edac/i82443bxgx_edac.c +++ b/drivers/edac/i82443bxgx_edac.c @@ -203,7 +203,7 @@ static void i82443bxgx_init_csrows(struct mem_ctl_info *mci, row_high_limit = ((u32) drbar << 23); /* find the DRAM Chip Select Base address and mask */ debugf1("MC%d: %s: %s() Row=%d, " - "Boundry Address=%#0x, Last = %#0x\n", + "Boundary Address=%#0x, Last = %#0x\n", mci->mc_idx, __FILE__, __func__, index, row_high_limit, row_high_limit_last); @@ -305,7 +305,7 @@ static int i82443bxgx_edacmc_probe1(struct pci_dev *pdev, int dev_idx) i82443bxgx_init_csrows(mci, pdev, edac_mode, mtype); /* Many BIOSes don't clear error flags on boot, so do this - * here, or we get "phantom" errors occuring at module-load + * here, or we get "phantom" errors occurring at module-load * time. */ pci_write_bits32(pdev, I82443BXGX_EAP, (I82443BXGX_EAP_OFFSET_SBE | diff --git a/drivers/edac/mce_amd_inj.c b/drivers/edac/mce_amd_inj.c index 733a7e7a8d6f..a4987e03f59e 100644 --- a/drivers/edac/mce_amd_inj.c +++ b/drivers/edac/mce_amd_inj.c @@ -90,7 +90,7 @@ static ssize_t edac_inject_bank_store(struct kobject *kobj, if (value > 5) if (boot_cpu_data.x86 != 0x15 || value > 6) { - printk(KERN_ERR "Non-existant MCE bank: %lu\n", value); + printk(KERN_ERR "Non-existent MCE bank: %lu\n", value); return -EINVAL; } diff --git a/drivers/edac/r82600_edac.c b/drivers/edac/r82600_edac.c index 6a822c631ef5..678513738c33 100644 --- a/drivers/edac/r82600_edac.c +++ b/drivers/edac/r82600_edac.c @@ -120,7 +120,7 @@ * write 0=NOP */ -#define R82600_DRBA 0x60 /* + 0x60..0x63 SDRAM Row Boundry Address +#define R82600_DRBA 0x60 /* + 0x60..0x63 SDRAM Row Boundary Address * Registers * * 7:0 Address lines 30:24 - upper limit of @@ -217,7 +217,7 @@ static void r82600_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev, { struct csrow_info *csrow; int index; - u8 drbar; /* SDRAM Row Boundry Address Register */ + u8 drbar; /* SDRAM Row Boundary Address Register */ u32 row_high_limit, row_high_limit_last; u32 reg_sdram, ecc_on, row_base; @@ -236,7 +236,7 @@ static void r82600_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev, row_high_limit = ((u32) drbar << 24); /* row_high_limit = ((u32)drbar << 24) | 0xffffffUL; */ - debugf1("%s() Row=%d, Boundry Address=%#0x, Last = %#0x\n", + debugf1("%s() Row=%d, Boundary Address=%#0x, Last = %#0x\n", __func__, index, row_high_limit, row_high_limit_last); /* Empty row [p.57] */ diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index 7ed08fd1214e..3f04dd3681cf 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -453,7 +453,7 @@ static bool fwnet_pd_update(struct fwnet_peer *peer, memcpy(pd->pbuf + frag_off, frag_buf, frag_len); /* - * Move list entry to beginnig of list so that oldest partial + * Move list entry to beginning of list so that oldest partial * datagrams percolate to the end of the list */ list_move_tail(&pd->pd_link, &peer->pd_list); diff --git a/drivers/gpio/mc33880.c b/drivers/gpio/mc33880.c index 00f6d24c669d..4ec797593bdb 100644 --- a/drivers/gpio/mc33880.c +++ b/drivers/gpio/mc33880.c @@ -45,7 +45,7 @@ * To save time we cache them here in memory */ struct mc33880 { - struct mutex lock; /* protect from simultanous accesses */ + struct mutex lock; /* protect from simultaneous accesses */ u8 port_config; struct gpio_chip chip; struct spi_device *spi; diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 799e1490cf24..872747c5a544 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -1699,7 +1699,7 @@ int drm_mode_addfb(struct drm_device *dev, mutex_lock(&dev->mode_config.mutex); - /* TODO check buffer is sufficently large */ + /* TODO check buffer is sufficiently large */ /* TODO setup destructor callback */ fb = dev->mode_config.funcs->fb_create(dev, file_priv, r); @@ -1750,7 +1750,7 @@ int drm_mode_rmfb(struct drm_device *dev, mutex_lock(&dev->mode_config.mutex); obj = drm_mode_object_find(dev, *id, DRM_MODE_OBJECT_FB); - /* TODO check that we realy get a framebuffer back. */ + /* TODO check that we really get a framebuffer back. */ if (!obj) { DRM_ERROR("mode invalid framebuffer id\n"); ret = -EINVAL; diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index add1737dae0d..5d00b0fc0d91 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -551,7 +551,7 @@ EXPORT_SYMBOL(drm_mm_scan_add_block); * corrupted. * * When the scan list is empty, the selected memory nodes can be freed. An - * immediatly following drm_mm_search_free with best_match = 0 will then return + * immediately following drm_mm_search_free with best_match = 0 will then return * the just freed block (because its at the top of the free_stack list). * * Returns one if this block should be evicted, zero otherwise. Will always diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 5004724ea57e..1c1b27c97e5c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -630,7 +630,7 @@ typedef struct drm_i915_private { * Flag if the hardware appears to be wedged. * * This is set when attempts to idle the device timeout. - * It prevents command submission from occuring and makes + * It prevents command submission from occurring and makes * every pending request fail */ atomic_t wedged; diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 0daefca5cbb8..cb8578b7e443 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -213,7 +213,7 @@ intel_dp_mode_valid(struct drm_connector *connector, return MODE_PANEL; } - /* only refuse the mode on non eDP since we have seen some wierd eDP panels + /* only refuse the mode on non eDP since we have seen some weird eDP panels which are outside spec tolerances but somehow work by magic */ if (!is_edp(intel_dp) && (intel_dp_link_required(connector->dev, intel_dp, mode->clock) diff --git a/drivers/gpu/drm/i915/intel_sdvo_regs.h b/drivers/gpu/drm/i915/intel_sdvo_regs.h index a386b022e538..4f4e23bc2d16 100644 --- a/drivers/gpu/drm/i915/intel_sdvo_regs.h +++ b/drivers/gpu/drm/i915/intel_sdvo_regs.h @@ -230,7 +230,7 @@ struct intel_sdvo_set_target_input_args { } __attribute__((packed)); /** - * Takes a struct intel_sdvo_output_flags of which outputs are targetted by + * Takes a struct intel_sdvo_output_flags of which outputs are targeted by * future output commands. * * Affected commands inclue SET_OUTPUT_TIMINGS_PART[12], diff --git a/drivers/gpu/drm/mga/mga_dma.c b/drivers/gpu/drm/mga/mga_dma.c index 1e1eb1d7e971..5ccb65deb83c 100644 --- a/drivers/gpu/drm/mga/mga_dma.c +++ b/drivers/gpu/drm/mga/mga_dma.c @@ -426,7 +426,7 @@ int mga_driver_load(struct drm_device *dev, unsigned long flags) * Bootstrap the driver for AGP DMA. * * \todo - * Investigate whether there is any benifit to storing the WARP microcode in + * Investigate whether there is any benefit to storing the WARP microcode in * AGP memory. If not, the microcode may as well always be put in PCI * memory. * diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index 3837090d66af..4cea35c57d15 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c @@ -200,7 +200,7 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, /* disable the fifo caches */ pfifo->reassign(dev, false); - /* Construct inital RAMFC for new channel */ + /* Construct initial RAMFC for new channel */ ret = pfifo->create_context(chan); if (ret) { nouveau_channel_put(&chan); @@ -278,7 +278,7 @@ nouveau_channel_put_unlocked(struct nouveau_channel **pchan) return; } - /* noone wants the channel anymore */ + /* no one wants the channel anymore */ NV_DEBUG(dev, "freeing channel %d\n", chan->id); nouveau_debugfs_channel_fini(chan); diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index fff180a99867..57e5302503db 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -216,7 +216,7 @@ struct nouveau_channel { /* mapping of the fifo itself */ struct drm_local_map *map; - /* mapping of the regs controling the fifo */ + /* mapping of the regs controlling the fifo */ void __iomem *user; uint32_t user_get; uint32_t user_put; diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 4fcbd091a117..5bb2859001e2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -963,7 +963,7 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) if (ret) goto err_mmio; - /* Map PRAMIN BAR, or on older cards, the aperture withing BAR0 */ + /* Map PRAMIN BAR, or on older cards, the aperture within BAR0 */ if (dev_priv->card_type >= NV_40) { int ramin_bar = 2; if (pci_resource_len(dev->pdev, ramin_bar) == 0) diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c index a260fbbe3d9b..748b9d9c2949 100644 --- a/drivers/gpu/drm/nouveau/nv04_crtc.c +++ b/drivers/gpu/drm/nouveau/nv04_crtc.c @@ -164,7 +164,7 @@ nv_crtc_dpms(struct drm_crtc *crtc, int mode) NV_DEBUG_KMS(dev, "Setting dpms mode %d on CRTC %d\n", mode, nv_crtc->index); - if (nv_crtc->last_dpms == mode) /* Don't do unnecesary mode changes. */ + if (nv_crtc->last_dpms == mode) /* Don't do unnecessary mode changes. */ return; nv_crtc->last_dpms = mode; @@ -677,7 +677,7 @@ static void nv_crtc_prepare(struct drm_crtc *crtc) NVBlankScreen(dev, nv_crtc->index, true); - /* Some more preperation. */ + /* Some more preparation. */ NVWriteCRTC(dev, nv_crtc->index, NV_PCRTC_CONFIG, NV_PCRTC_CONFIG_START_ADDRESS_NON_VGA); if (dev_priv->card_type == NV_40) { uint32_t reg900 = NVReadRAMDAC(dev, nv_crtc->index, NV_PRAMDAC_900); diff --git a/drivers/gpu/drm/nouveau/nv40_graph.c b/drivers/gpu/drm/nouveau/nv40_graph.c index 18d30c2c1aa6..fceb44c0ec74 100644 --- a/drivers/gpu/drm/nouveau/nv40_graph.c +++ b/drivers/gpu/drm/nouveau/nv40_graph.c @@ -181,7 +181,7 @@ nv40_graph_load_context(struct nouveau_channel *chan) NV40_PGRAPH_CTXCTL_CUR_LOADED); /* 0x32E0 records the instance address of the active FIFO's PGRAPH * context. If at any time this doesn't match 0x40032C, you will - * recieve PGRAPH_INTR_CONTEXT_SWITCH + * receive PGRAPH_INTR_CONTEXT_SWITCH */ nv_wr32(dev, NV40_PFIFO_GRCTX_INSTANCE, inst); return 0; diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h index 04b269d14a59..7fd88497b930 100644 --- a/drivers/gpu/drm/radeon/atombios.h +++ b/drivers/gpu/drm/radeon/atombios.h @@ -738,13 +738,13 @@ typedef struct _ATOM_DIG_ENCODER_CONFIG_V3 { #if ATOM_BIG_ENDIAN UCHAR ucReserved1:1; - UCHAR ucDigSel:3; // =0/1/2/3/4/5: DIG0/1/2/3/4/5 (In register spec also refered as DIGA/B/C/D/E/F) + UCHAR ucDigSel:3; // =0/1/2/3/4/5: DIG0/1/2/3/4/5 (In register spec also referred as DIGA/B/C/D/E/F) UCHAR ucReserved:3; UCHAR ucDPLinkRate:1; // =0: 1.62Ghz, =1: 2.7Ghz #else UCHAR ucDPLinkRate:1; // =0: 1.62Ghz, =1: 2.7Ghz UCHAR ucReserved:3; - UCHAR ucDigSel:3; // =0/1/2/3/4/5: DIG0/1/2/3/4/5 (In register spec also refered as DIGA/B/C/D/E/F) + UCHAR ucDigSel:3; // =0/1/2/3/4/5: DIG0/1/2/3/4/5 (In register spec also referred as DIGA/B/C/D/E/F) UCHAR ucReserved1:1; #endif }ATOM_DIG_ENCODER_CONFIG_V3; @@ -785,13 +785,13 @@ typedef struct _ATOM_DIG_ENCODER_CONFIG_V4 { #if ATOM_BIG_ENDIAN UCHAR ucReserved1:1; - UCHAR ucDigSel:3; // =0/1/2/3/4/5: DIG0/1/2/3/4/5 (In register spec also refered as DIGA/B/C/D/E/F) + UCHAR ucDigSel:3; // =0/1/2/3/4/5: DIG0/1/2/3/4/5 (In register spec also referred as DIGA/B/C/D/E/F) UCHAR ucReserved:2; UCHAR ucDPLinkRate:2; // =0: 1.62Ghz, =1: 2.7Ghz, 2=5.4Ghz <= Changed comparing to previous version #else UCHAR ucDPLinkRate:2; // =0: 1.62Ghz, =1: 2.7Ghz, 2=5.4Ghz <= Changed comparing to previous version UCHAR ucReserved:2; - UCHAR ucDigSel:3; // =0/1/2/3/4/5: DIG0/1/2/3/4/5 (In register spec also refered as DIGA/B/C/D/E/F) + UCHAR ucDigSel:3; // =0/1/2/3/4/5: DIG0/1/2/3/4/5 (In register spec also referred as DIGA/B/C/D/E/F) UCHAR ucReserved1:1; #endif }ATOM_DIG_ENCODER_CONFIG_V4; @@ -2126,7 +2126,7 @@ typedef struct _ATOM_MULTIMEDIA_CONFIG_INFO // Structures used in FirmwareInfoTable /****************************************************************************/ -// usBIOSCapability Defintion: +// usBIOSCapability Definition: // Bit 0 = 0: Bios image is not Posted, =1:Bios image is Posted; // Bit 1 = 0: Dual CRTC is not supported, =1: Dual CRTC is supported; // Bit 2 = 0: Extended Desktop is not supported, =1: Extended Desktop is supported; @@ -3341,7 +3341,7 @@ typedef struct _ATOM_SPREAD_SPECTRUM_INFO /****************************************************************************/ // Structure used in AnalogTV_InfoTable (Top level) /****************************************************************************/ -//ucTVBootUpDefaultStd definiton: +//ucTVBootUpDefaultStd definition: //ATOM_TV_NTSC 1 //ATOM_TV_NTSCJ 2 @@ -3816,7 +3816,7 @@ typedef struct _ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO UCHAR Reserved [6]; // for potential expansion }ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO; -//Related definitions, all records are differnt but they have a commond header +//Related definitions, all records are different but they have a commond header typedef struct _ATOM_COMMON_RECORD_HEADER { UCHAR ucRecordType; //An emun to indicate the record type @@ -4365,14 +4365,14 @@ ucUMAChannelNumber: System memory channel numbers. ulCSR_M3_ARB_CNTL_DEFAULT[10]: Arrays with values for CSR M3 arbiter for default ulCSR_M3_ARB_CNTL_UVD[10]: Arrays with values for CSR M3 arbiter for UVD playback. ulCSR_M3_ARB_CNTL_FS3D[10]: Arrays with values for CSR M3 arbiter for Full Screen 3D applications. -sAvail_SCLK[5]: Arrays to provide availabe list of SLCK and corresponding voltage, order from low to high +sAvail_SCLK[5]: Arrays to provide available list of SLCK and corresponding voltage, order from low to high ulGMCRestoreResetTime: GMC power restore and GMC reset time to calculate data reconnection latency. Unit in ns. ulMinimumNClk: Minimum NCLK speed among all NB-Pstates to calcualte data reconnection latency. Unit in 10kHz. ulIdleNClk: NCLK speed while memory runs in self-refresh state. Unit in 10kHz. ulDDR_DLL_PowerUpTime: DDR PHY DLL power up time. Unit in ns. ulDDR_PLL_PowerUpTime: DDR PHY PLL power up time. Unit in ns. -usPCIEClkSSPercentage: PCIE Clock Spred Spectrum Percentage in unit 0.01%; 100 mean 1%. -usPCIEClkSSType: PCIE Clock Spred Spectrum Type. 0 for Down spread(default); 1 for Center spread. +usPCIEClkSSPercentage: PCIE Clock Spread Spectrum Percentage in unit 0.01%; 100 mean 1%. +usPCIEClkSSType: PCIE Clock Spread Spectrum Type. 0 for Down spread(default); 1 for Center spread. usLvdsSSPercentage: LVDS panel ( not include eDP ) Spread Spectrum Percentage in unit of 0.01%, =0, use VBIOS default setting. usLvdsSSpreadRateIn10Hz: LVDS panel ( not include eDP ) Spread Spectrum frequency in unit of 10Hz, =0, use VBIOS default setting. usHDMISSPercentage: HDMI Spread Spectrum Percentage in unit 0.01%; 100 mean 1%, =0, use VBIOS default setting. @@ -4555,7 +4555,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO_V3 #define ATOM_S0_SYSTEM_POWER_STATE_VALUE_LITEAC 3 #define ATOM_S0_SYSTEM_POWER_STATE_VALUE_LIT2AC 4 -//Byte aligned defintion for BIOS usage +//Byte aligned definition for BIOS usage #define ATOM_S0_CRT1_MONOb0 0x01 #define ATOM_S0_CRT1_COLORb0 0x02 #define ATOM_S0_CRT1_MASKb0 (ATOM_S0_CRT1_MONOb0+ATOM_S0_CRT1_COLORb0) @@ -4621,7 +4621,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO_V3 #define ATOM_S2_DISPLAY_ROTATION_ANGLE_MASK 0xC0000000L -//Byte aligned defintion for BIOS usage +//Byte aligned definition for BIOS usage #define ATOM_S2_TV1_STANDARD_MASKb0 0x0F #define ATOM_S2_CURRENT_BL_LEVEL_MASKb1 0xFF #define ATOM_S2_DEVICE_DPMS_STATEb2 0x01 @@ -4671,7 +4671,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO_V3 #define ATOM_S3_ALLOW_FAST_PWR_SWITCH 0x40000000L #define ATOM_S3_RQST_GPU_USE_MIN_PWR 0x80000000L -//Byte aligned defintion for BIOS usage +//Byte aligned definition for BIOS usage #define ATOM_S3_CRT1_ACTIVEb0 0x01 #define ATOM_S3_LCD1_ACTIVEb0 0x02 #define ATOM_S3_TV1_ACTIVEb0 0x04 @@ -4707,7 +4707,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO_V3 #define ATOM_S4_LCD1_REFRESH_MASK 0x0000FF00L #define ATOM_S4_LCD1_REFRESH_SHIFT 8 -//Byte aligned defintion for BIOS usage +//Byte aligned definition for BIOS usage #define ATOM_S4_LCD1_PANEL_ID_MASKb0 0x0FF #define ATOM_S4_LCD1_REFRESH_MASKb1 ATOM_S4_LCD1_PANEL_ID_MASKb0 #define ATOM_S4_VRAM_INFO_MASKb2 ATOM_S4_LCD1_PANEL_ID_MASKb0 @@ -4786,7 +4786,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO_V3 #define ATOM_S6_VRI_BRIGHTNESS_CHANGE 0x40000000L #define ATOM_S6_CONFIG_DISPLAY_CHANGE_MASK 0x80000000L -//Byte aligned defintion for BIOS usage +//Byte aligned definition for BIOS usage #define ATOM_S6_DEVICE_CHANGEb0 0x01 #define ATOM_S6_SCALER_CHANGEb0 0x02 #define ATOM_S6_LID_CHANGEb0 0x04 @@ -5027,7 +5027,7 @@ typedef struct _ENABLE_GRAPH_SURFACE_PS_ALLOCATION typedef struct _MEMORY_CLEAN_UP_PARAMETERS { - USHORT usMemoryStart; //in 8Kb boundry, offset from memory base address + USHORT usMemoryStart; //in 8Kb boundary, offset from memory base address USHORT usMemorySize; //8Kb blocks aligned }MEMORY_CLEAN_UP_PARAMETERS; #define MEMORY_CLEAN_UP_PS_ALLOCATION MEMORY_CLEAN_UP_PARAMETERS @@ -6855,7 +6855,7 @@ typedef struct _ATOM_PPLIB_Clock_Voltage_Limit_Table /**************************************************************************/ -// Following definitions are for compatiblity issue in different SW components. +// Following definitions are for compatibility issue in different SW components. #define ATOM_MASTER_DATA_TABLE_REVISION 0x01 #define Object_Info Object_Header #define AdjustARB_SEQ MC_InitParameter diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index edde90b37554..23d36417158d 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c @@ -442,7 +442,7 @@ static inline int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u3 } ib = p->ib->ptr; switch (reg) { - /* force following reg to 0 in an attemp to disable out buffer + /* force following reg to 0 in an attempt to disable out buffer * which will need us to better understand how it works to perform * security check on it (Jerome) */ diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 8713731fa014..55a7f190027e 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -437,7 +437,7 @@ int r300_asic_reset(struct radeon_device *rdev) status = RREG32(R_000E40_RBBM_STATUS); dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); /* resetting the CP seems to be problematic sometimes it end up - * hard locking the computer, but it's necessary for successfull + * hard locking the computer, but it's necessary for successful * reset more test & playing is needed on R3XX/R4XX to find a * reliable (if any solution) */ diff --git a/drivers/gpu/drm/radeon/r300_reg.h b/drivers/gpu/drm/radeon/r300_reg.h index f0bce399c9f3..00c0d2ba22d3 100644 --- a/drivers/gpu/drm/radeon/r300_reg.h +++ b/drivers/gpu/drm/radeon/r300_reg.h @@ -608,7 +608,7 @@ * My guess is that there are two bits for each zbias primitive * (FILL, LINE, POINT). * One to enable depth test and one for depth write. - * Yet this doesnt explain why depth writes work ... + * Yet this doesn't explain why depth writes work ... */ #define R300_RE_OCCLUSION_CNTL 0x42B4 # define R300_OCCLUSION_ON (1<<1) @@ -817,7 +817,7 @@ # define R300_TX_MIN_FILTER_LINEAR_MIP_NEAREST (6 << 11) # define R300_TX_MIN_FILTER_LINEAR_MIP_LINEAR (10 << 11) -/* NOTE: NEAREST doesnt seem to exist. +/* NOTE: NEAREST doesn't seem to exist. * Im not seting MAG_FILTER_MASK and (3 << 11) on for all * anisotropy modes because that would void selected mag filter */ diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 3324620b2db6..fd18be9871ab 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c @@ -921,7 +921,7 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx return 0; ib = p->ib->ptr; switch (reg) { - /* force following reg to 0 in an attemp to disable out buffer + /* force following reg to 0 in an attempt to disable out buffer * which will need us to better understand how it works to perform * security check on it (Jerome) */ diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index 50db6d62eec2..f5ac7e788d81 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -334,7 +334,7 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod r600_hdmi_videoinfoframe(encoder, RGB, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - /* it's unknown what these bits do excatly, but it's indeed quite usefull for debugging */ + /* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */ WREG32(offset+R600_HDMI_AUDIO_DEBUG_0, 0x00FFFFFF); WREG32(offset+R600_HDMI_AUDIO_DEBUG_1, 0x007FFFFF); WREG32(offset+R600_HDMI_AUDIO_DEBUG_2, 0x00000001); diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index cfe3af1a7935..93f536594c73 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -679,11 +679,11 @@ struct radeon_wb { * @sideport_bandwidth: sideport bandwidth the gpu has (MByte/s) (IGP) * @ht_bandwidth: ht bandwidth the gpu has (MByte/s) (IGP) * @core_bandwidth: core GPU bandwidth the gpu has (MByte/s) (IGP) - * @sclk: GPU clock Mhz (core bandwith depends of this clock) + * @sclk: GPU clock Mhz (core bandwidth depends of this clock) * @needed_bandwidth: current bandwidth needs * * It keeps track of various data needed to take powermanagement decision. - * Bandwith need is used to determine minimun clock of the GPU and memory. + * Bandwidth need is used to determine minimun clock of the GPU and memory. * Equation between gpu/memory clock and available bandwidth is hw dependent * (type of memory, bus size, efficiency, ...) */ diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c index 3d599e33b9cc..75867792a4e2 100644 --- a/drivers/gpu/drm/radeon/radeon_cp.c +++ b/drivers/gpu/drm/radeon/radeon_cp.c @@ -244,7 +244,7 @@ void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base) u32 agp_base_lo = agp_base & 0xffffffff; u32 r6xx_agp_base = (agp_base >> 22) & 0x3ffff; - /* R6xx/R7xx must be aligned to a 4MB boundry */ + /* R6xx/R7xx must be aligned to a 4MB boundary */ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) RADEON_WRITE(R700_MC_VM_AGP_BASE, r6xx_agp_base); else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c index 017ac54920fb..bdf2fa1189ae 100644 --- a/drivers/gpu/drm/radeon/radeon_cursor.c +++ b/drivers/gpu/drm/radeon/radeon_cursor.c @@ -226,7 +226,7 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc, y += crtc->y; DRM_DEBUG("x %d y %d c->x %d c->y %d\n", x, y, crtc->x, crtc->y); - /* avivo cursor image can't end on 128 pixel boundry or + /* avivo cursor image can't end on 128 pixel boundary or * go past the end of the frame if both crtcs are enabled */ list_for_each_entry(crtc_p, &crtc->dev->mode_config.crtc_list, head) { diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index f0209be7a34b..890217e678d3 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -262,7 +262,7 @@ int radeon_wb_init(struct radeon_device *rdev) * Note: GTT start, end, size should be initialized before calling this * function on AGP platform. * - * Note: We don't explictly enforce VRAM start to be aligned on VRAM size, + * Note: We don't explicitly enforce VRAM start to be aligned on VRAM size, * this shouldn't be a problem as we are using the PCI aperture as a reference. * Otherwise this would be needed for rv280, all r3xx, and all r4xx, but * not IGP. diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 4be58793dc17..bdbab5c43bdc 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -1492,7 +1492,7 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, * * \return Flags, or'ed together as follows: * - * DRM_SCANOUTPOS_VALID = Query successfull. + * DRM_SCANOUTPOS_VALID = Query successful. * DRM_SCANOUTPOS_INVBL = Inside vblank. * DRM_SCANOUTPOS_ACCURATE = Returned position is accurate. A lack of * this flag means that returned position may be offset by a constant but diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h index 5cba46b9779a..a1b59ca96d01 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.h +++ b/drivers/gpu/drm/radeon/radeon_drv.h @@ -271,7 +271,7 @@ typedef struct drm_radeon_private { int have_z_offset; - /* starting from here on, data is preserved accross an open */ + /* starting from here on, data is preserved across an open */ uint32_t flags; /* see radeon_chip_flags */ resource_size_t fb_aper_offset; diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h index 7f8e778dba46..ede6c13628f2 100644 --- a/drivers/gpu/drm/radeon/radeon_object.h +++ b/drivers/gpu/drm/radeon/radeon_object.h @@ -87,7 +87,7 @@ static inline void radeon_bo_unreserve(struct radeon_bo *bo) * Returns current GPU offset of the object. * * Note: object should either be pinned or reserved when calling this - * function, it might be usefull to add check for this for debugging. + * function, it might be useful to add check for this for debugging. */ static inline u64 radeon_bo_gpu_offset(struct radeon_bo *bo) { diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c index 4ae5a3d1074e..92e7ea73b7c5 100644 --- a/drivers/gpu/drm/radeon/radeon_state.c +++ b/drivers/gpu/drm/radeon/radeon_state.c @@ -980,7 +980,7 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev, } /* hyper z clear */ - /* no docs available, based on reverse engeneering by Stephane Marchesin */ + /* no docs available, based on reverse engineering by Stephane Marchesin */ if ((flags & (RADEON_DEPTH | RADEON_STENCIL)) && (flags & RADEON_CLEAR_FASTZ)) { diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index cceeb42789b6..dfe32e62bd90 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -245,7 +245,7 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf, /* TODO handle none page aligned offsets */ /* TODO handle partial uploads and pitch != 256 */ /* TODO handle more then one copy (size != 64) */ - DRM_ERROR("lazy programer, cant handle wierd stuff\n"); + DRM_ERROR("lazy programmer, can't handle weird stuff\n"); return; } diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c index ace2b1623b21..be8d4cb5861c 100644 --- a/drivers/gpu/vga/vgaarb.c +++ b/drivers/gpu/vga/vgaarb.c @@ -151,7 +151,7 @@ static inline void vga_irq_set_state(struct vga_device *vgadev, bool state) static void vga_check_first_use(void) { /* we should inform all GPUs in the system that - * VGA arb has occured and to try and disable resources + * VGA arb has occurred and to try and disable resources * if they can */ if (!vga_arbiter_used) { vga_arbiter_used = true; @@ -774,7 +774,7 @@ static ssize_t vga_arb_read(struct file *file, char __user * buf, */ spin_lock_irqsave(&vga_lock, flags); - /* If we are targetting the default, use it */ + /* If we are targeting the default, use it */ pdev = priv->target; if (pdev == NULL || pdev == PCI_INVALID_CARD) { spin_unlock_irqrestore(&vga_lock, flags); diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index e9687768a335..453e7e6da0c2 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -306,7 +306,7 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item) case HID_GLOBAL_ITEM_TAG_PUSH: if (parser->global_stack_ptr == HID_GLOBAL_STACK_SIZE) { - dbg_hid("global enviroment stack overflow\n"); + dbg_hid("global environment stack overflow\n"); return -1; } @@ -317,7 +317,7 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item) case HID_GLOBAL_ITEM_TAG_POP: if (!parser->global_stack_ptr) { - dbg_hid("global enviroment stack underflow\n"); + dbg_hid("global environment stack underflow\n"); return -1; } diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c index 555382fc7417..bae48745bb42 100644 --- a/drivers/hid/hid-debug.c +++ b/drivers/hid/hid-debug.c @@ -341,7 +341,7 @@ static const struct hid_usage_entry hid_usage_table[] = { { 0x85, 0x83, "DesignCapacity" }, { 0x85, 0x85, "ManufacturerDate" }, { 0x85, 0x89, "iDeviceChemistry" }, - { 0x85, 0x8b, "Rechargable" }, + { 0x85, 0x8b, "Rechargeable" }, { 0x85, 0x8f, "iOEMInformation" }, { 0x85, 0x8d, "CapacityGranularity1" }, { 0x85, 0xd0, "ACPresent" }, diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index 318cc40df92d..7a6137346097 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -76,7 +76,7 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie * This is true when single_touch_id is equal to NO_TOUCHES. If multiple touches * are down and the touch providing for single touch emulation is lifted, * single_touch_id is equal to SINGLE_TOUCH_UP. While single touch emulation is - * occuring, single_touch_id corresponds with the tracking id of the touch used. + * occurring, single_touch_id corresponds with the tracking id of the touch used. */ #define NO_TOUCHES -1 #define SINGLE_TOUCH_UP -2 diff --git a/drivers/hid/hid-picolcd.c b/drivers/hid/hid-picolcd.c index 657da5a3d5c6..b2f56a13bcf5 100644 --- a/drivers/hid/hid-picolcd.c +++ b/drivers/hid/hid-picolcd.c @@ -1806,13 +1806,13 @@ static ssize_t picolcd_debug_flash_write(struct file *f, const char __user *u, /* * Notes: * - concurrent writing is prevented by mutex and all writes must be - * n*64 bytes and 64-byte aligned, each write being preceeded by an + * n*64 bytes and 64-byte aligned, each write being preceded by an * ERASE which erases a 64byte block. * If less than requested was written or an error is returned for an * otherwise correct write request the next 64-byte block which should * have been written is in undefined state (mostly: original, erased, * (half-)written with write error) - * - reading can happend without special restriction + * - reading can happen without special restriction */ static const struct file_operations picolcd_debug_flash_fops = { .owner = THIS_MODULE, diff --git a/drivers/hid/hid-roccat-kone.h b/drivers/hid/hid-roccat-kone.h index 64abb5b8a59a..4109a028e138 100644 --- a/drivers/hid/hid-roccat-kone.h +++ b/drivers/hid/hid-roccat-kone.h @@ -166,7 +166,7 @@ enum kone_mouse_events { /* osd events are thought to be display on screen */ kone_mouse_event_osd_dpi = 0xa0, kone_mouse_event_osd_profile = 0xb0, - /* TODO clarify meaning and occurence of kone_mouse_event_calibration */ + /* TODO clarify meaning and occurrence of kone_mouse_event_calibration */ kone_mouse_event_calibration = 0xc0, kone_mouse_event_call_overlong_macro = 0xe0, /* switch events notify if user changed values with mousebutton click */ diff --git a/drivers/hwmon/abituguru.c b/drivers/hwmon/abituguru.c index 0e05aa179eaa..e7d4c4687f02 100644 --- a/drivers/hwmon/abituguru.c +++ b/drivers/hwmon/abituguru.c @@ -1422,7 +1422,7 @@ static int __init abituguru_detect(void) at DATA and 0xAC, when this driver has already been loaded once DATA will hold 0x08. For most uGuru's CMD will hold 0xAC in either scenario but some will hold 0x00. - Some uGuru's initally hold 0x09 at DATA and will only hold 0x08 + Some uGuru's initially hold 0x09 at DATA and will only hold 0x08 after reading CMD first, so CMD must be read first! */ u8 cmd_val = inb_p(ABIT_UGURU_BASE + ABIT_UGURU_CMD); u8 data_val = inb_p(ABIT_UGURU_BASE + ABIT_UGURU_DATA); diff --git a/drivers/hwmon/abituguru3.c b/drivers/hwmon/abituguru3.c index 034cebfcd273..e89d572e3320 100644 --- a/drivers/hwmon/abituguru3.c +++ b/drivers/hwmon/abituguru3.c @@ -151,7 +151,7 @@ struct abituguru3_data { /* Pointer to the sensors info for the detected motherboard */ const struct abituguru3_sensor_info *sensors; - /* The abituguru3 supports upto 48 sensors, and thus has registers + /* The abituguru3 supports up to 48 sensors, and thus has registers sets for 48 sensors, for convienence reasons / simplicity of the code we always read and store all registers for all 48 sensors */ diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index be0fdd58aa29..0531867484f4 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c @@ -175,7 +175,7 @@ static u16 ADM1026_REG_TEMP_OFFSET[] = { 0x1e, 0x6e, 0x6f }; * these macros are called: arguments may be evaluated more than once. */ -/* IN are scaled acording to built-in resistors. These are the +/* IN are scaled according to built-in resistors. These are the * voltages corresponding to 3/4 of full scale (192 or 0xc0) * NOTE: The -12V input needs an additional factor to account * for the Vref pullup resistor. diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c index cf47e6e476ed..250d099ca398 100644 --- a/drivers/hwmon/lm85.c +++ b/drivers/hwmon/lm85.c @@ -130,7 +130,7 @@ enum chips { these macros are called: arguments may be evaluated more than once. */ -/* IN are scaled acording to built-in resistors */ +/* IN are scaled according to built-in resistors */ static const int lm85_scaling[] = { /* .001 Volts */ 2500, 2250, 3300, 5000, 12000, 3300, 1500, 1800 /*EMC6D100*/ diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index 812781c655a7..c43b4e9f96a9 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c @@ -356,7 +356,7 @@ static int lm90_read16(struct i2c_client *client, u8 regh, u8 regl, u16 *value) /* * There is a trick here. We have to read two registers to have the * sensor temperature, but we have to beware a conversion could occur - * inbetween the readings. The datasheet says we should either use + * between the readings. The datasheet says we should either use * the one-shot conversion register, which we don't want to do * (disables hardware monitoring) or monitor the busy bit, which is * impossible (we can't read the values and monitor that bit at the diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c index 1a9c32d6893a..f4e617adb220 100644 --- a/drivers/hwmon/sht15.c +++ b/drivers/hwmon/sht15.c @@ -52,7 +52,7 @@ #define SHT15_TSU 150 /* data setup time */ /** - * struct sht15_temppair - elements of voltage dependant temp calc + * struct sht15_temppair - elements of voltage dependent temp calc * @vdd: supply voltage in microvolts * @d1: see data sheet */ @@ -251,7 +251,7 @@ static inline int sht15_update_single_val(struct sht15_data *data, enable_irq(gpio_to_irq(data->pdata->gpio_data)); if (gpio_get_value(data->pdata->gpio_data) == 0) { disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data)); - /* Only relevant if the interrupt hasn't occured. */ + /* Only relevant if the interrupt hasn't occurred. */ if (!atomic_read(&data->interrupt_handled)) schedule_work(&data->read_work); } @@ -452,7 +452,7 @@ static void sht15_bh_read_data(struct work_struct *work_s) */ atomic_set(&data->interrupt_handled, 0); enable_irq(gpio_to_irq(data->pdata->gpio_data)); - /* If still not occured or another handler has been scheduled */ + /* If still not occurred or another handler has been scheduled */ if (gpio_get_value(data->pdata->gpio_data) || atomic_read(&data->interrupt_handled)) return; diff --git a/drivers/hwmon/tmp102.c b/drivers/hwmon/tmp102.c index 93187c3cb5e7..5bd194968801 100644 --- a/drivers/hwmon/tmp102.c +++ b/drivers/hwmon/tmp102.c @@ -166,7 +166,7 @@ static int __devinit tmp102_probe(struct i2c_client *client, if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) { - dev_err(&client->dev, "adapter doesnt support SMBus word " + dev_err(&client->dev, "adapter doesn't support SMBus word " "transactions\n"); return -ENODEV; } diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c index 400a88bde278..17cf1ab95521 100644 --- a/drivers/hwmon/w83791d.c +++ b/drivers/hwmon/w83791d.c @@ -556,7 +556,7 @@ static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr, /* Note: we save and restore the fan minimum here, because its value is determined in part by the fan divisor. This follows the principle of - least suprise; the user doesn't expect the fan minimum to change just + least surprise; the user doesn't expect the fan minimum to change just because the divisor changed. */ static ssize_t store_fan_div(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c index 63841f8cec07..f3e7130c4cda 100644 --- a/drivers/hwmon/w83792d.c +++ b/drivers/hwmon/w83792d.c @@ -244,7 +244,7 @@ FAN_TO_REG(long rpm, int div) #define TEMP1_TO_REG(val) (SENSORS_LIMIT(((val) < 0 ? (val)+0x100*1000 \ : (val)) / 1000, 0, 0xff)) #define TEMP1_FROM_REG(val) (((val) & 0x80 ? (val)-0x100 : (val)) * 1000) -/* for temp2 and temp3, because they need addtional resolution */ +/* for temp2 and temp3, because they need additional resolution */ #define TEMP_ADD_FROM_REG(val1, val2) \ ((((val1) & 0x80 ? (val1)-0x100 \ : (val1)) * 1000) + ((val2 & 0x80) ? 500 : 0)) diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c index e3bdedfb5347..854f9117f1aa 100644 --- a/drivers/hwmon/w83793.c +++ b/drivers/hwmon/w83793.c @@ -1921,7 +1921,7 @@ static void w83793_update_nonvolatile(struct device *dev) struct w83793_data *data = i2c_get_clientdata(client); int i, j; /* - They are somewhat "stable" registers, and to update them everytime + They are somewhat "stable" registers, and to update them every time takes so much time, it's just not worthy. Update them in a long interval to avoid exception. */ diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c index 2b9a8f54bb2c..4ca9cf9cde73 100644 --- a/drivers/i2c/algos/i2c-algo-pca.c +++ b/drivers/i2c/algos/i2c-algo-pca.c @@ -343,7 +343,7 @@ static int pca_xfer(struct i2c_adapter *i2c_adap, ret = curmsg; out: - DEB1("}}} transfered %d/%d messages. " + DEB1("}}} transferred %d/%d messages. " "status is %#04x. control is %#04x\n", curmsg, num, pca_status(adap), pca_get_con(adap)); diff --git a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c index 906a3ca50db6..dd364171f9c5 100644 --- a/drivers/i2c/busses/i2c-ali1535.c +++ b/drivers/i2c/busses/i2c-ali1535.c @@ -295,7 +295,7 @@ static int ali1535_transaction(struct i2c_adapter *adap) } /* Unfortunately the ALI SMB controller maps "no response" and "bus - * collision" into a single bit. No reponse is the usual case so don't + * collision" into a single bit. No response is the usual case so don't * do a printk. This means that bus collisions go unreported. */ if (temp & ALI1535_STS_BUSERR) { diff --git a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c index b14f6d68221d..83e8a60cdc86 100644 --- a/drivers/i2c/busses/i2c-ali15x3.c +++ b/drivers/i2c/busses/i2c-ali15x3.c @@ -318,7 +318,7 @@ static int ali15x3_transaction(struct i2c_adapter *adap) /* Unfortunately the ALI SMB controller maps "no response" and "bus - collision" into a single bit. No reponse is the usual case so don't + collision" into a single bit. No response is the usual case so don't do a printk. This means that bus collisions go unreported. */ diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index 5795c8398c7c..a76d85fa3ad7 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -355,7 +355,7 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) /* * Write mode register first as needed for correct behaviour * on OMAP-L138, but don't set STT yet to avoid a race with XRDY - * occuring before we have loaded DXR + * occurring before we have loaded DXR */ davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); diff --git a/drivers/i2c/busses/i2c-designware.c b/drivers/i2c/busses/i2c-designware.c index b664ed8bbdb3..b7a51c43b185 100644 --- a/drivers/i2c/busses/i2c-designware.c +++ b/drivers/i2c/busses/i2c-designware.c @@ -178,7 +178,7 @@ static char *abort_sources[] = { * @lock: protect this struct and IO registers * @clk: input reference clock * @cmd_err: run time hadware error code - * @msgs: points to an array of messages currently being transfered + * @msgs: points to an array of messages currently being transferred * @msgs_num: the number of elements in msgs * @msg_write_idx: the element index of the current tx message in the msgs * array diff --git a/drivers/i2c/busses/i2c-elektor.c b/drivers/i2c/busses/i2c-elektor.c index e5b1a3bf5b80..37e2e82a9c88 100644 --- a/drivers/i2c/busses/i2c-elektor.c +++ b/drivers/i2c/busses/i2c-elektor.c @@ -22,7 +22,7 @@ /* With some changes from Kyösti Mälkki and even Frodo Looijaard */ -/* Partialy rewriten by Oleg I. Vdovikin for mmapped support of +/* Partially rewriten by Oleg I. Vdovikin for mmapped support of for Alpha Processor Inc. UP-2000(+) boards */ #include diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index ed2e0c5ea37c..72c0415f6f94 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -96,7 +96,7 @@ #define SMBHSTCFG_SMB_SMI_EN 2 #define SMBHSTCFG_I2C_EN 4 -/* Auxillary control register bits, ICH4+ only */ +/* Auxiliary control register bits, ICH4+ only */ #define SMBAUXCTL_CRC 1 #define SMBAUXCTL_E32B 2 diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index e4f88dca99b5..3c110fbc409b 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c @@ -494,7 +494,7 @@ static int iic_xfer_bytes(struct ibm_iic_private* dev, struct i2c_msg* pm, if (unlikely(ret < 0)) break; else if (unlikely(ret != count)){ - DBG("%d: xfer_bytes, requested %d, transfered %d\n", + DBG("%d: xfer_bytes, requested %d, transferred %d\n", dev->idx, count, ret); /* If it's not a last part of xfer, abort it */ @@ -593,7 +593,7 @@ static int iic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) if (unlikely((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE)){ DBG("%d: iic_xfer, bus is not free\n", dev->idx); - /* Usually it means something serious has happend. + /* Usually it means something serious has happened. * We *cannot* have unfinished previous transfer * so it doesn't make any sense to try to stop it. * Probably we were not able to recover from the diff --git a/drivers/i2c/busses/i2c-intel-mid.c b/drivers/i2c/busses/i2c-intel-mid.c index c71492782bbd..e828ac85cfa7 100644 --- a/drivers/i2c/busses/i2c-intel-mid.c +++ b/drivers/i2c/busses/i2c-intel-mid.c @@ -170,8 +170,8 @@ struct intel_mid_i2c_private { /* Raw Interrupt Status Register */ #define IC_RAW_INTR_STAT 0x34 /* Read Only */ #define GEN_CALL (1 << 11) /* General call */ -#define START_DET (1 << 10) /* (RE)START occured */ -#define STOP_DET (1 << 9) /* STOP occured */ +#define START_DET (1 << 10) /* (RE)START occurred */ +#define STOP_DET (1 << 9) /* STOP occurred */ #define ACTIVITY (1 << 8) /* Bus busy */ #define RX_DONE (1 << 7) /* Not used in Master mode */ #define TX_ABRT (1 << 6) /* Transmit Abort */ @@ -375,7 +375,7 @@ static int intel_mid_i2c_disable(struct i2c_adapter *adap) * I2C should be disabled prior to other register operation. If failed, an * errno is returned. Mask and Clear all interrpts, this should be done at * first. Set common registers which will not be modified during normal - * transfers, including: controll register, FIFO threshold and clock freq. + * transfers, including: control register, FIFO threshold and clock freq. * Check APB data width at last. */ static int intel_mid_i2c_hwinit(struct intel_mid_i2c_private *i2c) @@ -455,7 +455,7 @@ static inline bool intel_mid_i2c_address_neq(const struct i2c_msg *p1, * * By reading register IC_TX_ABRT_SOURCE, various transfer errors can be * distingushed. At present, no circumstances have been found out that - * multiple errors would be occured simutaneously, so we simply use the + * multiple errors would be occurred simutaneously, so we simply use the * register value directly. * * At last the error bits are cleared. (Note clear ABRT_SBYTE_NORSTRT bit need @@ -469,7 +469,7 @@ static void intel_mid_i2c_abort(struct intel_mid_i2c_private *i2c) /* Single transfer error check: * According to databook, TX/RX FIFOs would be flushed when - * the abort interrupt occured. + * the abort interrupt occurred. */ if (abort & ABRT_MASTER_DIS) dev_err(&adap->dev, @@ -569,7 +569,7 @@ static int xfer_read(struct i2c_adapter *adap, unsigned char *buf, int length) * Return Values: * 0 if the read transfer succeeds * -ETIMEDOUT if we cannot read the "raw" interrupt register - * -EINVAL if a transfer abort occured + * -EINVAL if a transfer abort occurred * * For every byte, a "WRITE" command will be loaded into IC_DATA_CMD prior to * data transfer. The actual "write" operation will be performed when the @@ -697,7 +697,7 @@ static int intel_mid_i2c_setup(struct i2c_adapter *adap, struct i2c_msg *pmsg) * @num: number of i2c_msg * * Return Values: - * + number of messages transfered + * + number of messages transferred * -ETIMEDOUT If cannot disable I2C controller or read IC_STATUS * -EINVAL If the address in i2c_msg is invalid * diff --git a/drivers/i2c/busses/i2c-isch.c b/drivers/i2c/busses/i2c-isch.c index ddc258edb34f..0682f8f277b0 100644 --- a/drivers/i2c/busses/i2c-isch.c +++ b/drivers/i2c/busses/i2c-isch.c @@ -141,7 +141,7 @@ static int sch_transaction(void) * This is the main access entry for i2c-sch access * adap is i2c_adapter pointer, addr is the i2c device bus address, read_write * (0 for read and 1 for write), size is i2c transaction type and data is the - * union of transaction for data to be transfered or data read from bus. + * union of transaction for data to be transferred or data read from bus. * return 0 for success and others for failure. */ static s32 sch_access(struct i2c_adapter *adap, u16 addr, diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c index caf96dc8ca1b..7e78f7c87857 100644 --- a/drivers/i2c/busses/i2c-mxs.c +++ b/drivers/i2c/busses/i2c-mxs.c @@ -149,7 +149,7 @@ static void mxs_i2c_pioq_setup_write(struct mxs_i2c_dev *i2c, * We have to copy the slave address (u8) and buffer (arbitrary number * of u8) into the data register (u32). To achieve that, the u8 are put * into the MSBs of 'data' which is then shifted for the next u8. When - * apropriate, 'data' is written to MXS_I2C_DATA. So, the first u32 + * appropriate, 'data' is written to MXS_I2C_DATA. So, the first u32 * looks like this: * * 3 2 1 0 diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c index 594ed5059c4a..e10e5cf3751a 100644 --- a/drivers/i2c/busses/i2c-nomadik.c +++ b/drivers/i2c/busses/i2c-nomadik.c @@ -126,9 +126,9 @@ enum i2c_operation { /** * struct i2c_nmk_client - client specific data * @slave_adr: 7-bit slave address - * @count: no. bytes to be transfered + * @count: no. bytes to be transferred * @buffer: client data buffer - * @xfer_bytes: bytes transfered till now + * @xfer_bytes: bytes transferred till now * @operation: current I2C operation */ struct i2c_nmk_client { @@ -330,7 +330,7 @@ static void setup_i2c_controller(struct nmk_i2c_dev *dev) * slsu defines the data setup time after SCL clock * stretching in terms of i2c clk cycles. The * needed setup time for the three modes are 250ns, - * 100ns, 10ns repectively thus leading to the values + * 100ns, 10ns respectively thus leading to the values * of 14, 6, 2 for a 48 MHz i2c clk. */ writel(dev->cfg.slsu << 16, dev->virtbase + I2C_SCR); @@ -364,7 +364,7 @@ static void setup_i2c_controller(struct nmk_i2c_dev *dev) /* * set the speed mode. Currently we support * only standard and fast mode of operation - * TODO - support for fast mode plus (upto 1Mb/s) + * TODO - support for fast mode plus (up to 1Mb/s) * and high speed (up to 3.4 Mb/s) */ if (dev->cfg.sm > I2C_FREQ_MODE_FAST) { diff --git a/drivers/i2c/busses/i2c-s6000.c b/drivers/i2c/busses/i2c-s6000.c index cadc0216e02f..cb5d01e279c6 100644 --- a/drivers/i2c/busses/i2c-s6000.c +++ b/drivers/i2c/busses/i2c-s6000.c @@ -318,7 +318,7 @@ static int __devinit s6i2c_probe(struct platform_device *dev) rc = request_irq(iface->irq, s6i2c_interrupt_entry, IRQF_SHARED, dev->name, iface); if (rc) { - dev_err(&p_adap->dev, "s6i2c: cant get IRQ %d\n", iface->irq); + dev_err(&p_adap->dev, "s6i2c: can't get IRQ %d\n", iface->irq); goto err_clk_dis; } diff --git a/drivers/i2c/busses/i2c-stu300.c b/drivers/i2c/busses/i2c-stu300.c index 266135ddf7fa..99879617e686 100644 --- a/drivers/i2c/busses/i2c-stu300.c +++ b/drivers/i2c/busses/i2c-stu300.c @@ -497,7 +497,7 @@ static int stu300_set_clk(struct stu300_dev *dev, unsigned long clkrate) u32 val; int i = 0; - /* Locate the apropriate clock setting */ + /* Locate the appropriate clock setting */ while (i < ARRAY_SIZE(stu300_clktable) - 1 && stu300_clktable[i].rate < clkrate) i++; @@ -644,7 +644,7 @@ static int stu300_send_address(struct stu300_dev *dev, ret = stu300_await_event(dev, STU300_EVENT_6); /* - * Clear any pending EVENT 6 no matter what happend during + * Clear any pending EVENT 6 no matter what happened during * await_event. */ val = stu300_r8(dev->virtbase + I2C_CR); diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index 3921f664c9c3..b4ab39b741eb 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -386,7 +386,7 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev_id) dvc_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, DVC_STATUS); return IRQ_HANDLED; err: - /* An error occured, mask all interrupts */ + /* An error occurred, mask all interrupts */ tegra_i2c_mask_irq(i2c_dev, I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST | I2C_INT_PACKET_XFER_COMPLETE | I2C_INT_TX_FIFO_DATA_REQ | I2C_INT_RX_FIFO_DATA_REQ); diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c index 9fbd7e6fe32e..e9d5ff4d1496 100644 --- a/drivers/i2c/busses/i2c-xiic.c +++ b/drivers/i2c/busses/i2c-xiic.c @@ -21,7 +21,7 @@ * to the automotive development board Russellville. The copyright holder * as seen in the header is Intel corporation. * Mocean Laboratories forked off the GNU/Linux platform work into a - * separate company called Pelagicore AB, which commited the code to the + * separate company called Pelagicore AB, which committed the code to the * kernel. */ diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index e5f76a0372fd..70c30e6bce0b 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -348,7 +348,7 @@ EXPORT_SYMBOL(i2c_verify_client); /* This is a permissive address validity check, I2C address map constraints - * are purposedly not enforced, except for the general call address. */ + * are purposely not enforced, except for the general call address. */ static int i2c_check_client_addr_validity(const struct i2c_client *client) { if (client->flags & I2C_CLIENT_TEN) { diff --git a/drivers/ide/cy82c693.c b/drivers/ide/cy82c693.c index 9383f67deae1..3be60da52123 100644 --- a/drivers/ide/cy82c693.c +++ b/drivers/ide/cy82c693.c @@ -67,7 +67,7 @@ static void cy82c693_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive) /* * note: below we set the value for Bus Master IDE TimeOut Register - * I'm not absolutly sure what this does, but it solved my problem + * I'm not absolutely sure what this does, but it solved my problem * with IDE DMA and sound, so I now can play sound and work with * my IDE driver at the same time :-) * diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 5406b6ea3ad1..5a702d02c848 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -107,7 +107,7 @@ static int ide_floppy_callback(ide_drive_t *drive, int dsc) static void ide_floppy_report_error(struct ide_disk_obj *floppy, struct ide_atapi_pc *pc) { - /* supress error messages resulting from Medium not present */ + /* suppress error messages resulting from Medium not present */ if (floppy->sense_key == 0x02 && floppy->asc == 0x3a && floppy->ascq == 0x00) diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 34b9872f35d1..600c89a3d137 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c @@ -201,7 +201,7 @@ static u8 wait_drive_not_busy(ide_drive_t *drive) u8 stat; /* - * Last sector was transfered, wait until device is ready. This can + * Last sector was transferred, wait until device is ready. This can * take up to 6 ms on some ATAPI devices, so we will wait max 10 ms. */ for (retries = 0; retries < 1000; retries++) { diff --git a/drivers/ide/piix.c b/drivers/ide/piix.c index 1bdca49e5a03..b59d04c72051 100644 --- a/drivers/ide/piix.c +++ b/drivers/ide/piix.c @@ -8,8 +8,8 @@ * * Documentation: * - * Publically available from Intel web site. Errata documentation - * is also publically available. As an aide to anyone hacking on this + * Publicly available from Intel web site. Errata documentation + * is also publicly available. As an aide to anyone hacking on this * driver the list of errata that are relevant is below.going back to * PIIX4. Older device documentation is now a bit tricky to find. * diff --git a/drivers/ide/sis5513.c b/drivers/ide/sis5513.c index db7f4e761dbc..4a0022567758 100644 --- a/drivers/ide/sis5513.c +++ b/drivers/ide/sis5513.c @@ -53,7 +53,7 @@ #define DRV_NAME "sis5513" -/* registers layout and init values are chipset family dependant */ +/* registers layout and init values are chipset family dependent */ #define ATA_16 0x01 #define ATA_33 0x02 @@ -406,7 +406,7 @@ static int __devinit sis_find_family(struct pci_dev *dev) pci_name(dev)); chipset_family = ATA_133; - /* Check for 5513 compability mapping + /* Check for 5513 compatibility mapping * We must use this, else the port enabled code will fail, * as it expects the enablebits at 0x4a. */ diff --git a/drivers/ide/triflex.c b/drivers/ide/triflex.c index 7953447eae0f..e53a1b78378b 100644 --- a/drivers/ide/triflex.c +++ b/drivers/ide/triflex.c @@ -22,7 +22,7 @@ * Loosely based on the piix & svwks drivers. * * Documentation: - * Not publically available. + * Not publicly available. */ #include diff --git a/drivers/ide/via82cxxx.c b/drivers/ide/via82cxxx.c index d2a0997b78f8..f46f49cfcc28 100644 --- a/drivers/ide/via82cxxx.c +++ b/drivers/ide/via82cxxx.c @@ -14,7 +14,7 @@ * Andre Hedrick * * Documentation: - * Obsolete device documentation publically available from via.com.tw + * Obsolete device documentation publicly available from via.com.tw * Current device documentation available under NDA only */ diff --git a/drivers/infiniband/hw/amso1100/c2_ae.c b/drivers/infiniband/hw/amso1100/c2_ae.c index 62af74295dbe..24f9e3a90e8e 100644 --- a/drivers/infiniband/hw/amso1100/c2_ae.c +++ b/drivers/infiniband/hw/amso1100/c2_ae.c @@ -157,7 +157,7 @@ void c2_ae_event(struct c2_dev *c2dev, u32 mq_index) int status; /* - * retreive the message + * retrieve the message */ wr = c2_mq_consume(mq); if (!wr) diff --git a/drivers/infiniband/hw/amso1100/c2_qp.c b/drivers/infiniband/hw/amso1100/c2_qp.c index d8f4bb8bf42e..0d7b6f23caff 100644 --- a/drivers/infiniband/hw/amso1100/c2_qp.c +++ b/drivers/infiniband/hw/amso1100/c2_qp.c @@ -612,7 +612,7 @@ void c2_free_qp(struct c2_dev *c2dev, struct c2_qp *qp) c2_unlock_cqs(send_cq, recv_cq); /* - * Destory qp in the rnic... + * Destroy qp in the rnic... */ destroy_qp(c2dev, qp); diff --git a/drivers/infiniband/hw/amso1100/c2_wr.h b/drivers/infiniband/hw/amso1100/c2_wr.h index c65fbdd6e469..8d4b4ca463ca 100644 --- a/drivers/infiniband/hw/amso1100/c2_wr.h +++ b/drivers/infiniband/hw/amso1100/c2_wr.h @@ -131,7 +131,7 @@ enum c2wr_ids { * All the preceding IDs are fixed, and must not change. * You can add new IDs, but must not remove or reorder * any IDs. If you do, YOU will ruin any hope of - * compatability between versions. + * compatibility between versions. */ CCWR_LAST, @@ -242,7 +242,7 @@ enum c2_acf { /* * to fix bug 1815 we define the max size allowable of the * terminate message (per the IETF spec).Refer to the IETF - * protocal specification, section 12.1.6, page 64) + * protocol specification, section 12.1.6, page 64) * The message is prefixed by 20 types of DDP info. * * Then the message has 6 bytes for the terminate control diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c index 47db4bf34628..58c0e417bc30 100644 --- a/drivers/infiniband/hw/ipath/ipath_driver.c +++ b/drivers/infiniband/hw/ipath/ipath_driver.c @@ -2392,7 +2392,7 @@ void ipath_shutdown_device(struct ipath_devdata *dd) /* * clear SerdesEnable and turn the leds off; do this here because * we are unloading, so don't count on interrupts to move along - * Turn the LEDs off explictly for the same reason. + * Turn the LEDs off explicitly for the same reason. */ dd->ipath_f_quiet_serdes(dd); diff --git a/drivers/infiniband/hw/ipath/ipath_file_ops.c b/drivers/infiniband/hw/ipath/ipath_file_ops.c index 6d4b29c4cd89..ee79a2d97b14 100644 --- a/drivers/infiniband/hw/ipath/ipath_file_ops.c +++ b/drivers/infiniband/hw/ipath/ipath_file_ops.c @@ -1972,7 +1972,7 @@ static int ipath_do_user_init(struct file *fp, * 0 to 1. So for those chips, we turn it off and then back on. * This will (very briefly) affect any other open ports, but the * duration is very short, and therefore isn't an issue. We - * explictly set the in-memory tail copy to 0 beforehand, so we + * explicitly set the in-memory tail copy to 0 beforehand, so we * don't have to wait to be sure the DMA update has happened * (chip resets head/tail to 0 on transition to enable). */ diff --git a/drivers/infiniband/hw/ipath/ipath_init_chip.c b/drivers/infiniband/hw/ipath/ipath_init_chip.c index fef0f4201257..7c1eebe8c7c9 100644 --- a/drivers/infiniband/hw/ipath/ipath_init_chip.c +++ b/drivers/infiniband/hw/ipath/ipath_init_chip.c @@ -335,7 +335,7 @@ done: * @dd: the infinipath device * * sanity check at least some of the values after reset, and - * ensure no receive or transmit (explictly, in case reset + * ensure no receive or transmit (explicitly, in case reset * failed */ static int init_chip_reset(struct ipath_devdata *dd) diff --git a/drivers/infiniband/hw/ipath/ipath_ud.c b/drivers/infiniband/hw/ipath/ipath_ud.c index 7420715256a9..e8a2a915251e 100644 --- a/drivers/infiniband/hw/ipath/ipath_ud.c +++ b/drivers/infiniband/hw/ipath/ipath_ud.c @@ -86,7 +86,7 @@ static void ipath_ud_loopback(struct ipath_qp *sqp, struct ipath_swqe *swqe) } /* - * A GRH is expected to preceed the data even if not + * A GRH is expected to precede the data even if not * present on the wire. */ length = swqe->length; @@ -515,7 +515,7 @@ void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, } /* - * A GRH is expected to preceed the data even if not + * A GRH is expected to precede the data even if not * present on the wire. */ wc.byte_len = tlen + sizeof(struct ib_grh); diff --git a/drivers/infiniband/hw/ipath/ipath_user_sdma.c b/drivers/infiniband/hw/ipath/ipath_user_sdma.c index be78f6643c06..f5cb13b21445 100644 --- a/drivers/infiniband/hw/ipath/ipath_user_sdma.c +++ b/drivers/infiniband/hw/ipath/ipath_user_sdma.c @@ -236,7 +236,7 @@ static int ipath_user_sdma_num_pages(const struct iovec *iov) return 1 + ((epage - spage) >> PAGE_SHIFT); } -/* truncate length to page boundry */ +/* truncate length to page boundary */ static int ipath_user_sdma_page_length(unsigned long addr, unsigned long len) { const unsigned long offset = addr & ~PAGE_MASK; diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index cfa3a2b22232..33c7eedaba6c 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c @@ -1397,7 +1397,7 @@ static void handle_fin_pkt(struct nes_cm_node *cm_node) cleanup_retrans_entry(cm_node); cm_node->state = NES_CM_STATE_CLOSING; send_ack(cm_node, NULL); - /* Wait for ACK as this is simultanous close.. + /* Wait for ACK as this is simultaneous close.. * After we receive ACK, do not send anything.. * Just rm the node.. Done.. */ break; diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c index 08c194861af5..10d0a5ec9add 100644 --- a/drivers/infiniband/hw/nes/nes_hw.c +++ b/drivers/infiniband/hw/nes/nes_hw.c @@ -80,7 +80,7 @@ static void nes_terminate_start_timer(struct nes_qp *nesqp); #ifdef CONFIG_INFINIBAND_NES_DEBUG static unsigned char *nes_iwarp_state_str[] = { - "Non-Existant", + "Non-Existent", "Idle", "RTS", "Closing", @@ -91,7 +91,7 @@ static unsigned char *nes_iwarp_state_str[] = { }; static unsigned char *nes_tcp_state_str[] = { - "Non-Existant", + "Non-Existent", "Closed", "Listen", "SYN Sent", diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c index 2c9c1933bbe3..e96b8fb5d44c 100644 --- a/drivers/infiniband/hw/nes/nes_nic.c +++ b/drivers/infiniband/hw/nes/nes_nic.c @@ -902,7 +902,7 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev) nes_write_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL, nic_active); } - nes_debug(NES_DBG_NIC_RX, "Number of MC entries = %d, Promiscous = %d, All Multicast = %d.\n", + nes_debug(NES_DBG_NIC_RX, "Number of MC entries = %d, Promiscuous = %d, All Multicast = %d.\n", mc_count, !!(netdev->flags & IFF_PROMISC), !!(netdev->flags & IFF_ALLMULTI)); if (!mc_all_on) { diff --git a/drivers/infiniband/hw/qib/qib.h b/drivers/infiniband/hw/qib/qib.h index 73225eee3cc6..769a1d9da4b7 100644 --- a/drivers/infiniband/hw/qib/qib.h +++ b/drivers/infiniband/hw/qib/qib.h @@ -653,7 +653,7 @@ struct diag_observer_list_elt; /* device data struct now contains only "general per-device" info. * fields related to a physical IB port are in a qib_pportdata struct, - * described above) while fields only used by a particualr chip-type are in + * described above) while fields only used by a particular chip-type are in * a qib_chipdata struct, whose contents are opaque to this file. */ struct qib_devdata { diff --git a/drivers/infiniband/hw/qib/qib_file_ops.c b/drivers/infiniband/hw/qib/qib_file_ops.c index 75bfad16c114..406fca50d036 100644 --- a/drivers/infiniband/hw/qib/qib_file_ops.c +++ b/drivers/infiniband/hw/qib/qib_file_ops.c @@ -1539,7 +1539,7 @@ done_chk_sdma: /* * If process has NOT already set it's affinity, select and - * reserve a processor for it, as a rendevous for all + * reserve a processor for it, as a rendezvous for all * users of the driver. If they don't actually later * set affinity to this cpu, or set it to some other cpu, * it just means that sooner or later we don't recommend @@ -1657,7 +1657,7 @@ static int qib_do_user_init(struct file *fp, * 0 to 1. So for those chips, we turn it off and then back on. * This will (very briefly) affect any other open ctxts, but the * duration is very short, and therefore isn't an issue. We - * explictly set the in-memory tail copy to 0 beforehand, so we + * explicitly set the in-memory tail copy to 0 beforehand, so we * don't have to wait to be sure the DMA update has happened * (chip resets head/tail to 0 on transition to enable). */ diff --git a/drivers/infiniband/hw/qib/qib_iba6120.c b/drivers/infiniband/hw/qib/qib_iba6120.c index 774dea897e9c..7de4b7ebffc5 100644 --- a/drivers/infiniband/hw/qib/qib_iba6120.c +++ b/drivers/infiniband/hw/qib/qib_iba6120.c @@ -1799,7 +1799,7 @@ static int qib_6120_setup_reset(struct qib_devdata *dd) /* * Keep chip from being accessed until we are ready. Use * writeq() directly, to allow the write even though QIB_PRESENT - * isnt' set. + * isn't' set. */ dd->flags &= ~(QIB_INITTED | QIB_PRESENT); dd->int_counter = 0; /* so we check interrupts work again */ @@ -2171,7 +2171,7 @@ static void rcvctrl_6120_mod(struct qib_pportdata *ppd, unsigned int op, * Init the context registers also; if we were * disabled, tail and head should both be zero * already from the enable, but since we don't - * know, we have to do it explictly. + * know, we have to do it explicitly. */ val = qib_read_ureg32(dd, ur_rcvegrindextail, ctxt); qib_write_ureg(dd, ur_rcvegrindexhead, val, ctxt); diff --git a/drivers/infiniband/hw/qib/qib_iba7220.c b/drivers/infiniband/hw/qib/qib_iba7220.c index de799f17cb9e..74fe0360bec7 100644 --- a/drivers/infiniband/hw/qib/qib_iba7220.c +++ b/drivers/infiniband/hw/qib/qib_iba7220.c @@ -2111,7 +2111,7 @@ static int qib_setup_7220_reset(struct qib_devdata *dd) /* * Keep chip from being accessed until we are ready. Use * writeq() directly, to allow the write even though QIB_PRESENT - * isnt' set. + * isn't' set. */ dd->flags &= ~(QIB_INITTED | QIB_PRESENT); dd->int_counter = 0; /* so we check interrupts work again */ @@ -2479,7 +2479,7 @@ static int qib_7220_set_ib_cfg(struct qib_pportdata *ppd, int which, u32 val) * we command the link down. As with width, only write the * actual register if the link is currently down, otherwise * takes effect on next link change. Since setting is being - * explictly requested (via MAD or sysfs), clear autoneg + * explicitly requested (via MAD or sysfs), clear autoneg * failure status if speed autoneg is enabled. */ ppd->link_speed_enabled = val; @@ -2778,7 +2778,7 @@ static void rcvctrl_7220_mod(struct qib_pportdata *ppd, unsigned int op, * Init the context registers also; if we were * disabled, tail and head should both be zero * already from the enable, but since we don't - * know, we have to do it explictly. + * know, we have to do it explicitly. */ val = qib_read_ureg32(dd, ur_rcvegrindextail, ctxt); qib_write_ureg(dd, ur_rcvegrindexhead, val, ctxt); diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c index 4a2d21e15a70..55de3cf3441c 100644 --- a/drivers/infiniband/hw/qib/qib_iba7322.c +++ b/drivers/infiniband/hw/qib/qib_iba7322.c @@ -3299,7 +3299,7 @@ static int qib_do_7322_reset(struct qib_devdata *dd) /* * Keep chip from being accessed until we are ready. Use * writeq() directly, to allow the write even though QIB_PRESENT - * isnt' set. + * isn't' set. */ dd->flags &= ~(QIB_INITTED | QIB_PRESENT | QIB_BADINTR); dd->flags |= QIB_DOING_RESET; @@ -3727,7 +3727,7 @@ static int qib_7322_set_ib_cfg(struct qib_pportdata *ppd, int which, u32 val) /* * As with width, only write the actual register if the * link is currently down, otherwise takes effect on next - * link change. Since setting is being explictly requested + * link change. Since setting is being explicitly requested * (via MAD or sysfs), clear autoneg failure status if speed * autoneg is enabled. */ @@ -4163,7 +4163,7 @@ static void rcvctrl_7322_mod(struct qib_pportdata *ppd, unsigned int op, * Init the context registers also; if we were * disabled, tail and head should both be zero * already from the enable, but since we don't - * know, we have to do it explictly. + * know, we have to do it explicitly. */ val = qib_read_ureg32(dd, ur_rcvegrindextail, ctxt); qib_write_ureg(dd, ur_rcvegrindexhead, val, ctxt); @@ -7483,7 +7483,7 @@ static int serdes_7322_init_new(struct qib_pportdata *ppd) /* Baseline Wander Correction Gain [13:4-0] (leave as default) */ /* Baseline Wander Correction Gain [3:7-5] (leave as default) */ /* Data Rate Select [5:7-6] (leave as default) */ - /* RX Parralel Word Width [3:10-8] (leave as default) */ + /* RX Parallel Word Width [3:10-8] (leave as default) */ /* RX REST */ /* Single- or Multi-channel reset */ diff --git a/drivers/infiniband/hw/qib/qib_init.c b/drivers/infiniband/hw/qib/qib_init.c index ffefb78b8949..a01f3fce8eb3 100644 --- a/drivers/infiniband/hw/qib/qib_init.c +++ b/drivers/infiniband/hw/qib/qib_init.c @@ -346,7 +346,7 @@ done: * @dd: the qlogic_ib device * * sanity check at least some of the values after reset, and - * ensure no receive or transmit (explictly, in case reset + * ensure no receive or transmit (explicitly, in case reset * failed */ static int init_after_reset(struct qib_devdata *dd) diff --git a/drivers/infiniband/hw/qib/qib_mad.h b/drivers/infiniband/hw/qib/qib_mad.h index 147aff9117d7..7840ab593bcf 100644 --- a/drivers/infiniband/hw/qib/qib_mad.h +++ b/drivers/infiniband/hw/qib/qib_mad.h @@ -73,7 +73,7 @@ struct ib_mad_notice_attr { struct { __be16 reserved; - __be16 lid; /* LID where change occured */ + __be16 lid; /* LID where change occurred */ u8 reserved2; u8 local_changes; /* low bit - local changes */ __be32 new_cap_mask; /* new capability mask */ diff --git a/drivers/infiniband/hw/qib/qib_twsi.c b/drivers/infiniband/hw/qib/qib_twsi.c index 6f31ca5039db..ddde72e11edb 100644 --- a/drivers/infiniband/hw/qib/qib_twsi.c +++ b/drivers/infiniband/hw/qib/qib_twsi.c @@ -41,7 +41,7 @@ * QLogic_IB "Two Wire Serial Interface" driver. * Originally written for a not-quite-i2c serial eeprom, which is * still used on some supported boards. Later boards have added a - * variety of other uses, most board-specific, so teh bit-boffing + * variety of other uses, most board-specific, so the bit-boffing * part has been split off to this file, while the other parts * have been moved to chip-specific files. * diff --git a/drivers/infiniband/hw/qib/qib_ud.c b/drivers/infiniband/hw/qib/qib_ud.c index 4a51fd1e9cb7..828609fa4d28 100644 --- a/drivers/infiniband/hw/qib/qib_ud.c +++ b/drivers/infiniband/hw/qib/qib_ud.c @@ -116,7 +116,7 @@ static void qib_ud_loopback(struct qib_qp *sqp, struct qib_swqe *swqe) } /* - * A GRH is expected to preceed the data even if not + * A GRH is expected to precede the data even if not * present on the wire. */ length = swqe->length; @@ -520,7 +520,7 @@ void qib_ud_rcv(struct qib_ibport *ibp, struct qib_ib_header *hdr, goto drop; /* - * A GRH is expected to preceed the data even if not + * A GRH is expected to precede the data even if not * present on the wire. */ wc.byte_len = tlen + sizeof(struct ib_grh); diff --git a/drivers/infiniband/hw/qib/qib_user_sdma.c b/drivers/infiniband/hw/qib/qib_user_sdma.c index 66208bcd7c13..82442085cbe6 100644 --- a/drivers/infiniband/hw/qib/qib_user_sdma.c +++ b/drivers/infiniband/hw/qib/qib_user_sdma.c @@ -239,7 +239,7 @@ static int qib_user_sdma_num_pages(const struct iovec *iov) } /* - * Truncate length to page boundry. + * Truncate length to page boundary. */ static int qib_user_sdma_page_length(unsigned long addr, unsigned long len) { diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h index f1df01567bb6..2f02ab0ccc1e 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.h +++ b/drivers/infiniband/ulp/iser/iscsi_iser.h @@ -91,7 +91,7 @@ #define SIZE_4K (1UL << SHIFT_4K) #define MASK_4K (~(SIZE_4K-1)) - /* support upto 512KB in one RDMA */ + /* support up to 512KB in one RDMA */ #define ISCSI_ISER_SG_TABLESIZE (0x80000 >> SHIFT_4K) #define ISER_DEF_CMD_PER_LUN 128 diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 3182c9cd1b0e..5688b5c88f24 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -758,7 +758,7 @@ static void joydev_remove_chrdev(struct joydev *joydev) } /* - * Mark device non-existant. This disables writes, ioctls and + * Mark device non-existent. This disables writes, ioctls and * prevents new users from opening the device. Already posted * blocking reads will stay, however new ones will fail. */ @@ -777,7 +777,7 @@ static void joydev_cleanup(struct joydev *joydev) joydev_hangup(joydev); joydev_remove_chrdev(joydev); - /* joydev is marked dead so noone else accesses joydev->open */ + /* joydev is marked dead so no one else accesses joydev->open */ if (joydev->open) input_close_device(handle); } diff --git a/drivers/input/joystick/a3d.c b/drivers/input/joystick/a3d.c index d259b41354b8..1639ab2b94b7 100644 --- a/drivers/input/joystick/a3d.c +++ b/drivers/input/joystick/a3d.c @@ -3,7 +3,7 @@ */ /* - * FP-Gaming Assasin 3D joystick driver for Linux + * FP-Gaming Assassin 3D joystick driver for Linux */ /* @@ -34,7 +34,7 @@ #include #include -#define DRIVER_DESC "FP-Gaming Assasin 3D joystick driver" +#define DRIVER_DESC "FP-Gaming Assassin 3D joystick driver" MODULE_AUTHOR("Vojtech Pavlik "); MODULE_DESCRIPTION(DRIVER_DESC); diff --git a/drivers/input/keyboard/davinci_keyscan.c b/drivers/input/keyboard/davinci_keyscan.c index a91ee941b5c1..cd89d17162a3 100644 --- a/drivers/input/keyboard/davinci_keyscan.c +++ b/drivers/input/keyboard/davinci_keyscan.c @@ -5,7 +5,7 @@ * * Author: Miguel Aguilar * - * Intial Code: Sandeep Paulraj + * Initial Code: Sandeep Paulraj * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/input/misc/adxl34x.c b/drivers/input/misc/adxl34x.c index de5900d50788..144ddbdeb9b3 100644 --- a/drivers/input/misc/adxl34x.c +++ b/drivers/input/misc/adxl34x.c @@ -716,7 +716,7 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq, pdata = dev->platform_data; if (!pdata) { dev_dbg(dev, - "No platfrom data: Using default initialization\n"); + "No platform data: Using default initialization\n"); pdata = &adxl34x_default_init; } diff --git a/drivers/input/misc/keyspan_remote.c b/drivers/input/misc/keyspan_remote.c index a93c525475c6..fc62256c963f 100644 --- a/drivers/input/misc/keyspan_remote.c +++ b/drivers/input/misc/keyspan_remote.c @@ -312,7 +312,7 @@ static void keyspan_check_data(struct usb_keyspan *remote) remote->data.tester = remote->data.tester >> 5; remote->data.bits_left -= 5; } else { - err("Bad message recieved, no stop bit found.\n"); + err("Bad message received, no stop bit found.\n"); } dev_dbg(&remote->udev->dev, diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index 12501de0c5cd..52b419348983 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c @@ -274,7 +274,7 @@ static struct key_entry keymap_fs_amilo_pro_v3505[] __initdata = { { KE_BLUETOOTH, 0x30 }, /* Fn+F10 */ { KE_KEY, 0x31, {KEY_MAIL} }, /* mail button */ { KE_KEY, 0x36, {KEY_WWW} }, /* www button */ - { KE_WIFI, 0x78 }, /* satelite dish button */ + { KE_WIFI, 0x78 }, /* satellite dish button */ { KE_END, 0 } }; diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index 3aead91bacc8..3126983c004a 100644 --- a/drivers/input/mouse/bcm5974.c +++ b/drivers/input/mouse/bcm5974.c @@ -639,7 +639,7 @@ exit: * device, resulting in trackpad malfunction under certain * circumstances. To get around this problem, there is at least one * example that utilizes the USB_QUIRK_RESET_RESUME quirk in order to - * recieve a reset_resume request rather than the normal resume. + * receive a reset_resume request rather than the normal resume. * Since the implementation of reset_resume is equal to mode switch * plus start_traffic, it seems easier to always do the switch when * starting traffic on the device. diff --git a/drivers/input/mouse/synaptics_i2c.c b/drivers/input/mouse/synaptics_i2c.c index f6aa26d305ed..cba3c84d2f21 100644 --- a/drivers/input/mouse/synaptics_i2c.c +++ b/drivers/input/mouse/synaptics_i2c.c @@ -462,7 +462,7 @@ static void synaptics_i2c_work_handler(struct work_struct *work) * While interrupt driven, there is no real need to poll the device. * But touchpads are very sensitive, so there could be errors * related to physical environment and the attention line isn't - * neccesarily asserted. In such case we can lose the touchpad. + * necessarily asserted. In such case we can lose the touchpad. * We poll the device once in THREAD_IRQ_SLEEP_SECS and * if error is detected, we try to reset and reconfigure the touchpad. */ diff --git a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c index bf2c0c80d6cc..eb9a3cfbeefa 100644 --- a/drivers/input/mouse/vsxxxaa.c +++ b/drivers/input/mouse/vsxxxaa.c @@ -334,7 +334,7 @@ static void vsxxxaa_handle_POR_packet(struct vsxxxaa *mouse) * M: manufacturer location code * R: revision code * E: Error code. If it's in the range of 0x00..0x1f, only some - * minor problem occured. Errors >= 0x20 are considered bad + * minor problem occurred. Errors >= 0x20 are considered bad * and the device may not work properly... * D: <0010> == mouse, <0100> == tablet */ diff --git a/drivers/input/serio/hp_sdc.c b/drivers/input/serio/hp_sdc.c index 8c0b51c31424..42206205e4f5 100644 --- a/drivers/input/serio/hp_sdc.c +++ b/drivers/input/serio/hp_sdc.c @@ -955,7 +955,7 @@ static int __init hp_sdc_init_hppa(struct parisc_device *d) INIT_DELAYED_WORK(&moduleloader_work, request_module_delayed); ret = hp_sdc_init(); - /* after successfull initialization give SDC some time to settle + /* after successful initialization give SDC some time to settle * and then load the hp_sdc_mlc upper layer driver */ if (!ret) schedule_delayed_work(&moduleloader_work, diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c index 7540bafc95cf..80baa53da5b1 100644 --- a/drivers/input/serio/xilinx_ps2.c +++ b/drivers/input/serio/xilinx_ps2.c @@ -225,7 +225,7 @@ static void sxps2_close(struct serio *pserio) /** * xps2_of_probe - probe method for the PS/2 device. * @of_dev: pointer to OF device structure - * @match: pointer to the stucture used for matching a device + * @match: pointer to the structure used for matching a device * * This function probes the PS/2 device in the device tree. * It initializes the driver data structure and the hardware. diff --git a/drivers/input/touchscreen/intel-mid-touch.c b/drivers/input/touchscreen/intel-mid-touch.c index c0307b22d86f..66c96bfc5522 100644 --- a/drivers/input/touchscreen/intel-mid-touch.c +++ b/drivers/input/touchscreen/intel-mid-touch.c @@ -542,7 +542,7 @@ static int __devinit mrstouch_adc_init(struct mrstouch_dev *tsdev) * ADC power on, start, enable PENDET and set loop delay * ADC loop delay is set to 4.5 ms approximately * Loop delay more than this results in jitter in adc readings - * Setting loop delay to 0 (continous loop) in MAXIM stops PENDET + * Setting loop delay to 0 (continuous loop) in MAXIM stops PENDET * interrupt generation sometimes. */ diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c index 028a5363eea1..3b5b5df04dd6 100644 --- a/drivers/input/touchscreen/ucb1400_ts.c +++ b/drivers/input/touchscreen/ucb1400_ts.c @@ -6,7 +6,7 @@ * Copyright: MontaVista Software, Inc. * * Spliting done by: Marek Vasut - * If something doesnt work and it worked before spliting, e-mail me, + * If something doesn't work and it worked before spliting, e-mail me, * dont bother Nicolas please ;-) * * This program is free software; you can redistribute it and/or modify diff --git a/drivers/input/touchscreen/wm9705.c b/drivers/input/touchscreen/wm9705.c index 6b5be742c27d..98e61175d3f5 100644 --- a/drivers/input/touchscreen/wm9705.c +++ b/drivers/input/touchscreen/wm9705.c @@ -306,7 +306,7 @@ static int wm9705_acc_enable(struct wm97xx *wm, int enable) dig2 = wm->dig[2]; if (enable) { - /* continous mode */ + /* continuous mode */ if (wm->mach_ops->acc_startup && (ret = wm->mach_ops->acc_startup(wm)) < 0) return ret; diff --git a/drivers/input/touchscreen/wm9712.c b/drivers/input/touchscreen/wm9712.c index 7490b05c3566..2bc2fb801009 100644 --- a/drivers/input/touchscreen/wm9712.c +++ b/drivers/input/touchscreen/wm9712.c @@ -419,7 +419,7 @@ static int wm9712_acc_enable(struct wm97xx *wm, int enable) dig2 = wm->dig[2]; if (enable) { - /* continous mode */ + /* continuous mode */ if (wm->mach_ops->acc_startup) { ret = wm->mach_ops->acc_startup(wm); if (ret < 0) diff --git a/drivers/input/touchscreen/wm9713.c b/drivers/input/touchscreen/wm9713.c index 238b5132712e..73ec99568f12 100644 --- a/drivers/input/touchscreen/wm9713.c +++ b/drivers/input/touchscreen/wm9713.c @@ -431,7 +431,7 @@ static int wm9713_acc_enable(struct wm97xx *wm, int enable) dig3 = wm->dig[2]; if (enable) { - /* continous mode */ + /* continuous mode */ if (wm->mach_ops->acc_startup && (ret = wm->mach_ops->acc_startup(wm)) < 0) return ret; diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c index 6b75c9f660ae..5dbe73af2f8f 100644 --- a/drivers/input/touchscreen/wm97xx-core.c +++ b/drivers/input/touchscreen/wm97xx-core.c @@ -335,7 +335,7 @@ static void wm97xx_pen_irq_worker(struct work_struct *work) */ if (!wm->mach_ops->acc_enabled || wm->mach_ops->acc_pen_down) { if (wm->pen_is_down && !pen_was_down) { - /* Data is not availiable immediately on pen down */ + /* Data is not available immediately on pen down */ queue_delayed_work(wm->ts_workq, &wm->ts_reader, 1); } @@ -354,7 +354,7 @@ static void wm97xx_pen_irq_worker(struct work_struct *work) * Codec PENDOWN irq handler * * We have to disable the codec interrupt in the handler because it - * can take upto 1ms to clear the interrupt source. We schedule a task + * can take up to 1ms to clear the interrupt source. We schedule a task * in a work queue to do the actual interaction with the chip. The * interrupt is then enabled again in the slow handler when the source * has been cleared. diff --git a/drivers/isdn/hardware/eicon/divacapi.h b/drivers/isdn/hardware/eicon/divacapi.h index 9f5b68037a26..e330da0c5fc0 100644 --- a/drivers/isdn/hardware/eicon/divacapi.h +++ b/drivers/isdn/hardware/eicon/divacapi.h @@ -673,7 +673,7 @@ struct async_s { /*------------------------------------------------------------------*/ -/* auxilliary states for supplementary services */ +/* auxiliary states for supplementary services */ /*------------------------------------------------------------------*/ #define IDLE 0 diff --git a/drivers/isdn/hardware/eicon/io.h b/drivers/isdn/hardware/eicon/io.h index 0c6c650d76bb..a6f175596364 100644 --- a/drivers/isdn/hardware/eicon/io.h +++ b/drivers/isdn/hardware/eicon/io.h @@ -60,7 +60,7 @@ typedef struct _diva_xdi_capi_cfg { -------------------------------------------------------------------------- */ struct _ISDN_ADAPTER { void (* DIRequest)(PISDN_ADAPTER, ENTITY *) ; - int State ; /* from NT4 1.srv, a good idea, but a poor achievment */ + int State ; /* from NT4 1.srv, a good idea, but a poor achievement */ int Initialized ; int RegisteredWithDidd ; int Unavailable ; /* callback function possible? */ diff --git a/drivers/isdn/hardware/eicon/message.c b/drivers/isdn/hardware/eicon/message.c index 341ef17c22ac..8c5c563c4f12 100644 --- a/drivers/isdn/hardware/eicon/message.c +++ b/drivers/isdn/hardware/eicon/message.c @@ -2639,7 +2639,7 @@ static byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a, } else { - /* local reply if assign unsuccessfull + /* local reply if assign unsuccessful or B3 protocol allows only one layer 3 connection and already connected or B2 protocol not any LAPD @@ -8189,7 +8189,7 @@ static word add_b23(PLCI *plci, API_PARSE *bp) dlc[ 0] = 15; if(b2_config->length >= 8) { /* PIAFS control abilities */ dlc[ 7] = 10; - dlc[16] = 2; /* Length of PIAFS extention */ + dlc[16] = 2; /* Length of PIAFS extension */ dlc[17] = PIAFS_UDATA_ABILITIES; /* control (UDATA) ability */ dlc[18] = b2_config_parms[4].info[0]; /* value */ dlc[ 0] = 18; diff --git a/drivers/isdn/hardware/eicon/pc.h b/drivers/isdn/hardware/eicon/pc.h index 1c6945768a35..bf6b01812400 100644 --- a/drivers/isdn/hardware/eicon/pc.h +++ b/drivers/isdn/hardware/eicon/pc.h @@ -701,7 +701,7 @@ Byte | 8 7 6 5 4 3 2 1 #define PROTCAP_FREE12 0x1000 /* not used */ #define PROTCAP_FREE13 0x2000 /* not used */ #define PROTCAP_FREE14 0x4000 /* not used */ -#define PROTCAP_EXTENSION 0x8000 /* used for future extentions */ +#define PROTCAP_EXTENSION 0x8000 /* used for future extensions */ /* -----------------------------------------------------------* */ /* Onhook data transmission ETS30065901 */ /* Message Type */ diff --git a/drivers/isdn/hardware/eicon/um_idi.c b/drivers/isdn/hardware/eicon/um_idi.c index 6563db998d06..ac0bdd1f23fa 100644 --- a/drivers/isdn/hardware/eicon/um_idi.c +++ b/drivers/isdn/hardware/eicon/um_idi.c @@ -363,7 +363,7 @@ int diva_um_idi_read(void *entity, if ((ret = (*cp_fn) (os_handle, dst, data, length)) >= 0) { /* - Acknowledge only if read was successfull + Acknowledge only if read was successful */ diva_data_q_ack_segment4read(q); } diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c index 4e3780d78ac7..f6f3c87cc7c2 100644 --- a/drivers/isdn/hardware/mISDN/hfcmulti.c +++ b/drivers/isdn/hardware/mISDN/hfcmulti.c @@ -118,7 +118,7 @@ * -> See hfc_multi.h for HFC_IO_MODE_* values * By default, the IO mode is pci memory IO (MEMIO). * Some cards require specific IO mode, so it cannot be changed. - * It may be usefull to set IO mode to register io (REGIO) to solve + * It may be useful to set IO mode to register io (REGIO) to solve * PCI bridge problems. * If unsure, don't give this parameter. * @@ -903,7 +903,7 @@ vpm_echocan_off(struct hfc_multi *hc, int ch) /* * Speech Design resync feature * NOTE: This is called sometimes outside interrupt handler. - * We must lock irqsave, so no other interrupt (other card) will occurr! + * We must lock irqsave, so no other interrupt (other card) will occur! * Also multiple interrupts may nest, so must lock each access (lists, card)! */ static inline void diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c index 15d323b8be60..4343abac0b13 100644 --- a/drivers/isdn/hardware/mISDN/hfcpci.c +++ b/drivers/isdn/hardware/mISDN/hfcpci.c @@ -272,7 +272,7 @@ reset_hfcpci(struct hfc_pci *hc) * D- and monitor/CI channel are not enabled * STIO1 is used as output for data, B1+B2 from ST->IOM+HFC * STIO2 is used as data input, B1+B2 from IOM->ST - * ST B-channel send disabled -> continous 1s + * ST B-channel send disabled -> continuous 1s * The IOM slots are always enabled */ if (test_bit(HFC_CFG_PCM, &hc->cfg)) { diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c index 3147020d188b..0cb0546ead88 100644 --- a/drivers/isdn/hisax/hfc_pci.c +++ b/drivers/isdn/hisax/hfc_pci.c @@ -146,7 +146,7 @@ reset_hfcpci(struct IsdnCardState *cs) /* D- and monitor/CI channel are not enabled */ /* STIO1 is used as output for data, B1+B2 from ST->IOM+HFC */ /* STIO2 is used as data input, B1+B2 from IOM->ST */ - /* ST B-channel send disabled -> continous 1s */ + /* ST B-channel send disabled -> continuous 1s */ /* The IOM slots are always enabled */ cs->hw.hfcpci.conn = 0x36; /* set data flow directions */ Write_hfc(cs, HFCPCI_CONNECT, cs->hw.hfcpci.conn); diff --git a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c index 1235b7131ae1..156d7c63d944 100644 --- a/drivers/isdn/hisax/hfc_sx.c +++ b/drivers/isdn/hisax/hfc_sx.c @@ -399,7 +399,7 @@ reset_hfcsx(struct IsdnCardState *cs) /* D- and monitor/CI channel are not enabled */ /* STIO1 is used as output for data, B1+B2 from ST->IOM+HFC */ /* STIO2 is used as data input, B1+B2 from IOM->ST */ - /* ST B-channel send disabled -> continous 1s */ + /* ST B-channel send disabled -> continuous 1s */ /* The IOM slots are always enabled */ cs->hw.hfcsx.conn = 0x36; /* set data flow directions */ Write_hfc(cs, HFCSX_CONNECT, cs->hw.hfcsx.conn); diff --git a/drivers/isdn/hisax/hfc_usb.h b/drivers/isdn/hisax/hfc_usb.h index e79f56568d30..2f581c0b4693 100644 --- a/drivers/isdn/hisax/hfc_usb.h +++ b/drivers/isdn/hisax/hfc_usb.h @@ -126,7 +126,7 @@ static struct hfcusb_symbolic_list urb_errlist[] = { /* - * device dependant information to support different + * device dependent information to support different * ISDN Ta's using the HFC-S USB chip */ diff --git a/drivers/isdn/hisax/l3dss1.c b/drivers/isdn/hisax/l3dss1.c index cc6ee2d39880..8e2fd02ecce0 100644 --- a/drivers/isdn/hisax/l3dss1.c +++ b/drivers/isdn/hisax/l3dss1.c @@ -1595,7 +1595,7 @@ l3dss1_setup(struct l3_process *pc, u_char pr, void *arg) * Bearer Capabilities */ p = skb->data; - /* only the first occurence 'll be detected ! */ + /* only the first occurrence 'll be detected ! */ if ((p = findie(p, skb->len, 0x04, 0))) { if ((p[1] < 2) || (p[1] > 11)) err = 1; @@ -2161,7 +2161,7 @@ static void l3dss1_redir_req_early(struct l3_process *pc, u_char pr, void *arg) /***********************************************/ /* handle special commands for this protocol. */ -/* Examples are call independant services like */ +/* Examples are call independent services like */ /* remote operations with dummy callref. */ /***********************************************/ static int l3dss1_cmd_global(struct PStack *st, isdn_ctrl *ic) diff --git a/drivers/isdn/hisax/l3ni1.c b/drivers/isdn/hisax/l3ni1.c index f9584491fe8e..7b229c0ce115 100644 --- a/drivers/isdn/hisax/l3ni1.c +++ b/drivers/isdn/hisax/l3ni1.c @@ -1449,7 +1449,7 @@ l3ni1_setup(struct l3_process *pc, u_char pr, void *arg) * Bearer Capabilities */ p = skb->data; - /* only the first occurence 'll be detected ! */ + /* only the first occurrence 'll be detected ! */ if ((p = findie(p, skb->len, 0x04, 0))) { if ((p[1] < 2) || (p[1] > 11)) err = 1; @@ -2017,7 +2017,7 @@ static void l3ni1_redir_req_early(struct l3_process *pc, u_char pr, void *arg) /***********************************************/ /* handle special commands for this protocol. */ -/* Examples are call independant services like */ +/* Examples are call independent services like */ /* remote operations with dummy callref. */ /***********************************************/ static int l3ni1_cmd_global(struct PStack *st, isdn_ctrl *ic) diff --git a/drivers/isdn/hisax/nj_s.c b/drivers/isdn/hisax/nj_s.c index 2344e7b33448..a1b89524b505 100644 --- a/drivers/isdn/hisax/nj_s.c +++ b/drivers/isdn/hisax/nj_s.c @@ -167,7 +167,7 @@ static int __devinit njs_pci_probe(struct pci_dev *dev_netjet, return(0); } /* the TJ300 and TJ320 must be detected, the IRQ handling is different - * unfortunatly the chips use the same device ID, but the TJ320 has + * unfortunately the chips use the same device ID, but the TJ320 has * the bit20 in status PCI cfg register set */ pci_read_config_dword(dev_netjet, 0x04, &cfg); diff --git a/drivers/isdn/hisax/st5481_b.c b/drivers/isdn/hisax/st5481_b.c index e56e5af889b6..ed4bc564dc63 100644 --- a/drivers/isdn/hisax/st5481_b.c +++ b/drivers/isdn/hisax/st5481_b.c @@ -124,7 +124,7 @@ static void usb_b_out(struct st5481_bcs *bcs,int buf_nr) } /* - * Start transfering (flags or data) on the B channel, since + * Start transferring (flags or data) on the B channel, since * FIFO counters has been set to a non-zero value. */ static void st5481B_start_xfer(void *context) diff --git a/drivers/isdn/hisax/st5481_usb.c b/drivers/isdn/hisax/st5481_usb.c index 10d41c5d73ed..159e8fa00fd6 100644 --- a/drivers/isdn/hisax/st5481_usb.c +++ b/drivers/isdn/hisax/st5481_usb.c @@ -470,7 +470,7 @@ void st5481_release_isocpipes(struct urb* urb[2]) /* * Decode frames received on the B/D channel. - * Note that this function will be called continously + * Note that this function will be called continuously * with 64Kbit/s / 16Kbit/s of data and hence it will be * called 50 times per second with 20 ISOC descriptors. * Called at interrupt. diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c index 282a4467ef19..aa25e183bf79 100644 --- a/drivers/isdn/hisax/teles_cs.c +++ b/drivers/isdn/hisax/teles_cs.c @@ -9,7 +9,7 @@ Also inspired by ELSA PCMCIA driver by Klaus Lichtenwalder - Extentions to new hisax_pcmcia by Karsten Keil + Extensions to new hisax_pcmcia by Karsten Keil minor changes to be compatible with kernel 2.4.x by Jan.Schubert@GMX.li diff --git a/drivers/isdn/hysdn/hysdn_sched.c b/drivers/isdn/hysdn/hysdn_sched.c index 81db4a190d41..3674d30d6a03 100644 --- a/drivers/isdn/hysdn/hysdn_sched.c +++ b/drivers/isdn/hysdn/hysdn_sched.c @@ -143,7 +143,7 @@ hysdn_sched_tx(hysdn_card *card, unsigned char *buf, /* send one config line to the card and return 0 if successful, otherwise a */ /* negative error code. */ /* The function works with timeouts perhaps not giving the greatest speed */ -/* sending the line, but this should be meaningless beacuse only some lines */ +/* sending the line, but this should be meaningless because only some lines */ /* are to be sent and this happens very seldom. */ /*****************************************************************************/ int diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c index afeede7ee295..2a7d17c19489 100644 --- a/drivers/isdn/i4l/isdn_net.c +++ b/drivers/isdn/i4l/isdn_net.c @@ -1530,7 +1530,7 @@ isdn_net_ciscohdlck_slarp_send_keepalive(unsigned long data) printk (KERN_WARNING "UPDOWN: Line protocol on Interface %s," " changed state to down\n", lp->netdev->dev->name); - /* should stop routing higher-level data accross */ + /* should stop routing higher-level data across */ } else if ((!lp->cisco_line_state) && (myseq_diff >= 0) && (myseq_diff <= 2)) { /* line down -> up */ @@ -1538,7 +1538,7 @@ isdn_net_ciscohdlck_slarp_send_keepalive(unsigned long data) printk (KERN_WARNING "UPDOWN: Line protocol on Interface %s," " changed state to up\n", lp->netdev->dev->name); - /* restart routing higher-level data accross */ + /* restart routing higher-level data across */ } if (lp->cisco_debserint) diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c index 9e8162c80bb0..1b002b0002a4 100644 --- a/drivers/isdn/i4l/isdn_ppp.c +++ b/drivers/isdn/i4l/isdn_ppp.c @@ -1514,7 +1514,7 @@ int isdn_ppp_autodial_filter(struct sk_buff *skb, isdn_net_local *lp) #define MP_LONGSEQ_MAXBIT ((MP_LONGSEQ_MASK+1)>>1) #define MP_SHORTSEQ_MAXBIT ((MP_SHORTSEQ_MASK+1)>>1) -/* sequence-wrap safe comparisions (for long sequence)*/ +/* sequence-wrap safe comparisons (for long sequence)*/ #define MP_LT(a,b) ((a-b)&MP_LONGSEQ_MAXBIT) #define MP_LE(a,b) !((b-a)&MP_LONGSEQ_MAXBIT) #define MP_GT(a,b) ((b-a)&MP_LONGSEQ_MAXBIT) @@ -1746,7 +1746,7 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, * then next fragment should be the start of new reassembly * if sequence is contiguous, but we haven't reassembled yet, * keep going. - * if sequence is not contiguous, either clear everyting + * if sequence is not contiguous, either clear everything * below low watermark and set start to the next frag or * clear start ptr. */ diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index 3d88f15aa218..607d846ae063 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c @@ -792,7 +792,7 @@ isdn_tty_suspend(char *id, modem_info * info, atemu * m) } /* isdn_tty_resume() tries to resume a suspended call - * setup of the lower levels before that. unfortunatly here is no + * setup of the lower levels before that. unfortunately here is no * checking for compatibility of used protocols implemented by Q931 * It does the same things like isdn_tty_dial, the last command * is different, may be we can merge it. diff --git a/drivers/isdn/isdnloop/isdnloop.c b/drivers/isdn/isdnloop/isdnloop.c index b8a1098b66ed..d497db0a26d0 100644 --- a/drivers/isdn/isdnloop/isdnloop.c +++ b/drivers/isdn/isdnloop/isdnloop.c @@ -954,7 +954,7 @@ isdnloop_parse_cmd(isdnloop_card * card) /* * Put command-strings into the of the 'card'. In reality, execute them * right in place by calling isdnloop_parse_cmd(). Also copy every - * command to the read message ringbuffer, preceeding it with a '>'. + * command to the read message ringbuffer, preceding it with a '>'. * These mesagges can be read at /dev/isdnctrl. * * Parameter: diff --git a/drivers/isdn/mISDN/dsp.h b/drivers/isdn/mISDN/dsp.h index 18af86879c05..8549431430f0 100644 --- a/drivers/isdn/mISDN/dsp.h +++ b/drivers/isdn/mISDN/dsp.h @@ -21,7 +21,7 @@ /* options may be: * * bit 0 = use ulaw instead of alaw - * bit 1 = enable hfc hardware accelleration for all channels + * bit 1 = enable hfc hardware acceleration for all channels * */ #define DSP_OPT_ULAW (1<<0) diff --git a/drivers/isdn/mISDN/dsp_cmx.c b/drivers/isdn/mISDN/dsp_cmx.c index 309bacf1fadc..4d395dea32f3 100644 --- a/drivers/isdn/mISDN/dsp_cmx.c +++ b/drivers/isdn/mISDN/dsp_cmx.c @@ -1513,7 +1513,7 @@ dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members) /* -> if echo is NOT enabled */ if (!dsp->echo.software) { /* - * -> substract rx-data from conf-data, + * -> subtract rx-data from conf-data, * if tx-data is available, mix */ while (r != rr && t != tt) { @@ -1572,7 +1572,7 @@ dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members) send_packet: /* * send tx-data if enabled - don't filter, - * becuase we want what we send, not what we filtered + * because we want what we send, not what we filtered */ if (dsp->tx_data) { if (tx_data_only) { diff --git a/drivers/isdn/mISDN/dsp_core.c b/drivers/isdn/mISDN/dsp_core.c index 6f5b54864283..2877291a9ed8 100644 --- a/drivers/isdn/mISDN/dsp_core.c +++ b/drivers/isdn/mISDN/dsp_core.c @@ -115,7 +115,7 @@ * * The CMX has special functions for conferences with one, two and more * members. It will allow different types of data flow. Receive and transmit - * data to/form upper layer may be swithed on/off individually without loosing + * data to/form upper layer may be swithed on/off individually without losing * features of CMX, Tones and DTMF. * * Echo Cancellation: Sometimes we like to cancel echo from the interface. @@ -127,9 +127,9 @@ * * If all used features can be realized in hardware, and if transmit and/or * receive data ist disabled, the card may not send/receive any data at all. - * Not receiving is usefull if only announcements are played. Not sending is - * usefull if an answering machine records audio. Not sending and receiving is - * usefull during most states of the call. If supported by hardware, tones + * Not receiving is useful if only announcements are played. Not sending is + * useful if an answering machine records audio. Not sending and receiving is + * useful during most states of the call. If supported by hardware, tones * will be played without cpu load. Small PBXs and NT-Mode applications will * not need expensive hardware when processing calls. * diff --git a/drivers/isdn/mISDN/dsp_dtmf.c b/drivers/isdn/mISDN/dsp_dtmf.c index 9ae2d33b06f7..5b484c3f4af6 100644 --- a/drivers/isdn/mISDN/dsp_dtmf.c +++ b/drivers/isdn/mISDN/dsp_dtmf.c @@ -106,7 +106,7 @@ void dsp_dtmf_hardware(struct dsp *dsp) * tested it allot. it even works with very short tones (40ms). the only * disadvantage is, that it doesn't work good with different volumes of both * tones. this will happen, if accoustically coupled dialers are used. - * it sometimes detects tones during speach, which is normal for decoders. + * it sometimes detects tones during speech, which is normal for decoders. * use sequences to given commands during calls. * * dtmf - points to a structure of the current dtmf state @@ -244,7 +244,7 @@ coefficients: if (result[i] < tresh) { lowgroup = -1; highgroup = -1; - break; /* noise inbetween */ + break; /* noise in between */ } /* good level found. This is allowed only one time per group */ if (i < NCOEFF/2) { diff --git a/drivers/isdn/mISDN/dsp_tones.c b/drivers/isdn/mISDN/dsp_tones.c index 7dbe54ed1deb..4e4440e8bae5 100644 --- a/drivers/isdn/mISDN/dsp_tones.c +++ b/drivers/isdn/mISDN/dsp_tones.c @@ -394,7 +394,7 @@ void dsp_tone_copy(struct dsp *dsp, u8 *data, int len) while (len) { /* find sample to start with */ while (42) { - /* warp arround */ + /* wrap around */ if (!pat->seq[index]) { count = 0; index = 0; diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c index bd526f664a39..22f8ec8b9247 100644 --- a/drivers/isdn/mISDN/l1oip_core.c +++ b/drivers/isdn/mISDN/l1oip_core.c @@ -179,7 +179,7 @@ NOTE: A value of 0 equals 256 bytes of data. - Time Base = Timestamp of first sample in frame The "Time Base" is used to rearange packets and to detect packet loss. The 16 bits are sent in network order (MSB first) and count 1/8000 th of a -second. This causes a wrap arround each 8,192 seconds. There is no requirement +second. This causes a wrap around each 8,192 seconds. There is no requirement for the initial "Time Base", but 0 should be used for the first packet. In case of HDLC data, this timestamp counts the packet or byte number. @@ -205,7 +205,7 @@ On Demand: If the ondemand parameter is given, the remote IP is set to 0 on timeout. This will stop keepalive traffic to remote. If the remote is online again, -traffic will continue to the remote address. This is usefull for road warriors. +traffic will continue to the remote address. This is useful for road warriors. This feature only works with ID set, otherwhise it is highly unsecure. @@ -590,7 +590,7 @@ multiframe: return; } } else - mlen = len-2; /* single frame, substract timebase */ + mlen = len-2; /* single frame, subtract timebase */ if (len < 2) { printk(KERN_WARNING "%s: packet error - packet too short, time " diff --git a/drivers/isdn/mISDN/layer2.c b/drivers/isdn/mISDN/layer2.c index 4ae75053c9d2..d0aeb44ee7c0 100644 --- a/drivers/isdn/mISDN/layer2.c +++ b/drivers/isdn/mISDN/layer2.c @@ -1864,7 +1864,7 @@ ph_data_indication(struct layer2 *l2, struct mISDNhead *hh, struct sk_buff *skb) psapi >>= 2; ptei >>= 1; if (psapi != l2->sapi) { - /* not our bussiness */ + /* not our business */ if (*debug & DEBUG_L2) printk(KERN_DEBUG "%s: sapi %d/%d mismatch\n", __func__, psapi, l2->sapi); @@ -1872,7 +1872,7 @@ ph_data_indication(struct layer2 *l2, struct mISDNhead *hh, struct sk_buff *skb) return 0; } if ((ptei != l2->tei) && (ptei != GROUP_TEI)) { - /* not our bussiness */ + /* not our business */ if (*debug & DEBUG_L2) printk(KERN_DEBUG "%s: tei %d/%d mismatch\n", __func__, ptei, l2->tei); diff --git a/drivers/leds/leds-pca9532.c b/drivers/leds/leds-pca9532.c index afac338d5025..5bf63af09ddf 100644 --- a/drivers/leds/leds-pca9532.c +++ b/drivers/leds/leds-pca9532.c @@ -58,7 +58,7 @@ static struct i2c_driver pca9532_driver = { .id_table = pca9532_id, }; -/* We have two pwm/blinkers, but 16 possible leds to drive. Additionaly, +/* We have two pwm/blinkers, but 16 possible leds to drive. Additionally, * the clever Thecus people are using one pwm to drive the beeper. So, * as a compromise we average one pwm to the values requested by all * leds that are not ON/OFF. diff --git a/drivers/leds/leds-wm8350.c b/drivers/leds/leds-wm8350.c index a04523273282..f14edd82cb00 100644 --- a/drivers/leds/leds-wm8350.c +++ b/drivers/leds/leds-wm8350.c @@ -215,13 +215,13 @@ static int wm8350_led_probe(struct platform_device *pdev) isink = regulator_get(&pdev->dev, "led_isink"); if (IS_ERR(isink)) { - printk(KERN_ERR "%s: cant get ISINK\n", __func__); + printk(KERN_ERR "%s: can't get ISINK\n", __func__); return PTR_ERR(isink); } dcdc = regulator_get(&pdev->dev, "led_vcc"); if (IS_ERR(dcdc)) { - printk(KERN_ERR "%s: cant get DCDC\n", __func__); + printk(KERN_ERR "%s: can't get DCDC\n", __func__); ret = PTR_ERR(dcdc); goto err_isink; } diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c index 3c781cdddda9..948c547b8e9e 100644 --- a/drivers/lguest/lguest_user.c +++ b/drivers/lguest/lguest_user.c @@ -130,7 +130,7 @@ static int add_eventfd(struct lguest *lg, unsigned long addr, int fd) rcu_assign_pointer(lg->eventfds, new); /* - * We're not in a big hurry. Wait until noone's looking at old + * We're not in a big hurry. Wait until no one's looking at old * version, then free it. */ synchronize_rcu(); diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c index 5396c67ba0a4..09d72bb00d12 100644 --- a/drivers/macintosh/adbhid.c +++ b/drivers/macintosh/adbhid.c @@ -328,7 +328,7 @@ adbhid_input_keycode(int id, int scancode, int repeat) switch (keycode) { case ADB_KEY_CAPSLOCK: if (!restore_capslock_events) { - /* Generate down/up events for CapsLock everytime. */ + /* Generate down/up events for CapsLock every time. */ input_report_key(ahid->input, KEY_CAPSLOCK, 1); input_sync(ahid->input); input_report_key(ahid->input, KEY_CAPSLOCK, 0); diff --git a/drivers/macintosh/macio-adb.c b/drivers/macintosh/macio-adb.c index bd6da7a9c55b..b6ef8f590764 100644 --- a/drivers/macintosh/macio-adb.c +++ b/drivers/macintosh/macio-adb.c @@ -147,7 +147,7 @@ static int macio_adb_reset_bus(void) /* Hrm... we may want to not lock interrupts for so * long ... oh well, who uses that chip anyway ? :) - * That function will be seldomly used during boot + * That function will be seldom used during boot * on rare machines, so... */ spin_lock_irqsave(&macio_lock, flags); diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c index 9e3e2c566598..02367308ff2e 100644 --- a/drivers/macintosh/therm_adt746x.c +++ b/drivers/macintosh/therm_adt746x.c @@ -662,7 +662,7 @@ static void thermostat_create_files(void) err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_fan_speed); if (err) printk(KERN_WARNING - "Failed to create tempertaure attribute file(s).\n"); + "Failed to create temperature attribute file(s).\n"); } static void thermostat_remove_files(void) diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index bca2af2e3760..d25df48b437b 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c @@ -91,7 +91,7 @@ * * Mar. 10, 2005 : 1.2 * - Add basic support for Xserve G5 - * - Retreive pumps min/max from EEPROM image in device-tree (broken) + * - Retrieve pumps min/max from EEPROM image in device-tree (broken) * - Use min/max macros here or there * - Latest darwin updated U3H min fan speed to 20% PWM * @@ -375,7 +375,7 @@ static int read_smon_adc(struct cpu_pid_state *state, int chan) rc = i2c_master_send(state->monitor, buf, 2); if (rc <= 0) goto error; - /* Wait for convertion */ + /* Wait for conversion */ msleep(1); /* Switch to data register */ buf[0] = 4; @@ -1192,7 +1192,7 @@ static int init_cpu_state(struct cpu_pid_state *state, int index) err |= device_create_file(&of_dev->dev, &dev_attr_cpu1_intake_fan_rpm); } if (err) - printk(KERN_WARNING "Failed to create some of the atribute" + printk(KERN_WARNING "Failed to create some of the attribute" "files for CPU %d\n", index); return 0; diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c index d37819fd5ad3..46c4e95f10d6 100644 --- a/drivers/macintosh/therm_windtunnel.c +++ b/drivers/macintosh/therm_windtunnel.c @@ -45,7 +45,7 @@ #include #include -#define LOG_TEMP 0 /* continously log temperature */ +#define LOG_TEMP 0 /* continuously log temperature */ static struct { volatile int running; diff --git a/drivers/md/bitmap.h b/drivers/md/bitmap.h index 931a7a7c3796..d0aeaf46d932 100644 --- a/drivers/md/bitmap.h +++ b/drivers/md/bitmap.h @@ -45,7 +45,7 @@ * * The counter counts pending write requests, plus the on-disk bit. * When the counter is '1' and the resync bits are clear, the on-disk - * bit can be cleared aswell, thus setting the counter to 0. + * bit can be cleared as well, thus setting the counter to 0. * When we set a bit, or in the counter (to start a write), if the fields is * 0, we first set the disk bit and set the counter to 1. * diff --git a/drivers/md/dm-region-hash.c b/drivers/md/dm-region-hash.c index dad011aed0c9..7771ed212182 100644 --- a/drivers/md/dm-region-hash.c +++ b/drivers/md/dm-region-hash.c @@ -419,7 +419,7 @@ void dm_rh_mark_nosync(struct dm_region_hash *rh, struct bio *bio) /* * Possible cases: * 1) DM_RH_DIRTY - * 2) DM_RH_NOSYNC: was dirty, other preceeding writes failed + * 2) DM_RH_NOSYNC: was dirty, other preceding writes failed * 3) DM_RH_RECOVERING: flushing pending writes * Either case, the region should have not been connected to list. */ diff --git a/drivers/md/faulty.c b/drivers/md/faulty.c index 339fdc670751..23078dabb6df 100644 --- a/drivers/md/faulty.c +++ b/drivers/md/faulty.c @@ -30,7 +30,7 @@ * * Different modes can be active at a time, but only * one can be set at array creation. Others can be added later. - * A mode can be one-shot or recurrent with the recurrance being + * A mode can be one-shot or recurrent with the recurrence being * once in every N requests. * The bottom 5 bits of the "layout" indicate the mode. The * remainder indicate a period, or 0 for one-shot. diff --git a/drivers/md/md.c b/drivers/md/md.c index 8b66e04c2ea6..b12b3776c0c0 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -6266,7 +6266,7 @@ static void status_resync(struct seq_file *seq, mddev_t * mddev) * rt is a sector_t, so could be 32bit or 64bit. * So we divide before multiply in case it is 32bit and close * to the limit. - * We scale the divisor (db) by 32 to avoid loosing precision + * We scale the divisor (db) by 32 to avoid losing precision * near the end of resync when the number of remaining sectors * is close to 'db'. * We then divide rt by 32 after multiplying by db to compensate. diff --git a/drivers/md/md.h b/drivers/md/md.h index 12215d437fcc..52b407369e13 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -94,7 +94,7 @@ struct mdk_rdev_s #define In_sync 2 /* device is in_sync with rest of array */ #define WriteMostly 4 /* Avoid reading if at all possible */ #define AutoDetected 7 /* added by auto-detect */ -#define Blocked 8 /* An error occured on an externally +#define Blocked 8 /* An error occurred on an externally * managed array, don't allow writes * until it is cleared */ wait_queue_head_t blocked_wait; diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index f7b62370b374..2da83d566592 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -5,7 +5,7 @@ * * RAID-10 support for md. * - * Base on code in raid1.c. See raid1.c for futher copyright information. + * Base on code in raid1.c. See raid1.c for further copyright information. * * * This program is free software; you can redistribute it and/or modify @@ -340,14 +340,14 @@ static void raid10_end_write_request(struct bio *bio, int error) /* * RAID10 layout manager - * Aswell as the chunksize and raid_disks count, there are two + * As well as the chunksize and raid_disks count, there are two * parameters: near_copies and far_copies. * near_copies * far_copies must be <= raid_disks. * Normally one of these will be 1. * If both are 1, we get raid0. * If near_copies == raid_disks, we get raid1. * - * Chunks are layed out in raid0 style with near_copies copies of the + * Chunks are laid out in raid0 style with near_copies copies of the * first chunk, followed by near_copies copies of the next chunk and * so on. * If far_copies > 1, then after 1/far_copies of the array has been assigned diff --git a/drivers/md/raid10.h b/drivers/md/raid10.h index 2316ac2e8e21..944b1104d3b4 100644 --- a/drivers/md/raid10.h +++ b/drivers/md/raid10.h @@ -17,8 +17,8 @@ struct r10_private_data_s { spinlock_t device_lock; /* geometry */ - int near_copies; /* number of copies layed out raid0 style */ - int far_copies; /* number of copies layed out + int near_copies; /* number of copies laid out raid0 style */ + int far_copies; /* number of copies laid out * at large strides across drives */ int far_offset; /* far_copies are offset by 1 stripe diff --git a/drivers/media/common/saa7146_i2c.c b/drivers/media/common/saa7146_i2c.c index 74ee172b5bc9..b2ba9dc0dd6d 100644 --- a/drivers/media/common/saa7146_i2c.c +++ b/drivers/media/common/saa7146_i2c.c @@ -161,7 +161,7 @@ static int saa7146_i2c_reset(struct saa7146_dev *dev) msleep(SAA7146_I2C_DELAY); } - /* if any error is still present, a fatal error has occured ... */ + /* if any error is still present, a fatal error has occurred ... */ status = saa7146_i2c_status(dev); if ( dev->i2c_bitrate != status ) { DEB_I2C(("fatal error. status:0x%08x\n",status)); @@ -326,9 +326,9 @@ static int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg *m if ( 0 != err) { /* this one is unsatisfying: some i2c slaves on some dvb cards don't acknowledge correctly, so the saa7146 - thinks that an address error occured. in that case, the + thinks that an address error occurred. in that case, the transaction should be retrying, even if an address error - occured. analog saa7146 based cards extensively rely on + occurred. analog saa7146 based cards extensively rely on i2c address probing, however, and address errors indicate that a device is really *not* there. retrying in that case increases the time the device needs to probe greatly, so @@ -365,7 +365,7 @@ static int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg *m DEB_I2C(("transmission successful. (msg:%d).\n",err)); out: /* another bug in revision 0: the i2c-registers get uploaded randomly by other - uploads, so we better clear them out before continueing */ + uploads, so we better clear them out before continuing */ if( 0 == dev->revision ) { __le32 zero = 0; saa7146_i2c_reset(dev); diff --git a/drivers/media/common/tuners/mxl5005s.c b/drivers/media/common/tuners/mxl5005s.c index 605e28b73263..0d6e09419044 100644 --- a/drivers/media/common/tuners/mxl5005s.c +++ b/drivers/media/common/tuners/mxl5005s.c @@ -106,7 +106,7 @@ enum { /* MXL5005 Tuner Register Struct */ struct TunerReg { u16 Reg_Num; /* Tuner Register Address */ - u16 Reg_Val; /* Current sw programmed value waiting to be writen */ + u16 Reg_Val; /* Current sw programmed value waiting to be written */ }; enum { diff --git a/drivers/media/common/tuners/tda18271.h b/drivers/media/common/tuners/tda18271.h index 3abb221f3d07..50cfa8cebb93 100644 --- a/drivers/media/common/tuners/tda18271.h +++ b/drivers/media/common/tuners/tda18271.h @@ -98,7 +98,7 @@ struct tda18271_config { /* output options that can be disabled */ enum tda18271_output_options output_opt; - /* some i2c providers cant write all 39 registers at once */ + /* some i2c providers can't write all 39 registers at once */ enum tda18271_small_i2c small_i2c; /* force rf tracking filter calibration on startup */ diff --git a/drivers/media/dvb/b2c2/flexcop-pci.c b/drivers/media/dvb/b2c2/flexcop-pci.c index 227c0200b70a..955254090a0e 100644 --- a/drivers/media/dvb/b2c2/flexcop-pci.c +++ b/drivers/media/dvb/b2c2/flexcop-pci.c @@ -58,7 +58,7 @@ struct flexcop_pci { int active_dma1_addr; /* 0 = addr0 of dma1; 1 = addr1 of dma1 */ u32 last_dma1_cur_pos; - /* position of the pointer last time the timer/packet irq occured */ + /* position of the pointer last time the timer/packet irq occurred */ int count; int count_prev; int stream_problem; diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c index 78fc469f0f69..1e1106dcd063 100644 --- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c +++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c @@ -427,10 +427,10 @@ static void or51211_reset(struct dvb_frontend * fe) struct dvb_bt8xx_card *bt = fe->dvb->priv; /* RESET DEVICE - * reset is controled by GPIO-0 + * reset is controlled by GPIO-0 * when set to 0 causes reset and when to 1 for normal op * must remain reset for 128 clock cycles on a 50Mhz clock - * also PRM1 PRM2 & PRM4 are controled by GPIO-1,GPIO-2 & GPIO-4 + * also PRM1 PRM2 & PRM4 are controlled by GPIO-1,GPIO-2 & GPIO-4 * We assume that the reset has be held low long enough or we * have been reset by a power on. When the driver is unloaded * reset set to 0 so if reloaded we have been reset. diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index cad6634610ea..31e2c0d45db3 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -1638,7 +1638,7 @@ static int dvb_frontend_ioctl_legacy(struct file *file, case FE_READ_STATUS: { fe_status_t* status = parg; - /* if retune was requested but hasn't occured yet, prevent + /* if retune was requested but hasn't occurred yet, prevent * that user get signal state from previous tuning */ if (fepriv->state == FESTATE_RETUNE || fepriv->state == FESTATE_ERROR) { @@ -1729,7 +1729,7 @@ static int dvb_frontend_ioctl_legacy(struct file *file, * Dish network legacy switches (as used by Dish500) * are controlled by sending 9-bit command words * spaced 8msec apart. - * the actual command word is switch/port dependant + * the actual command word is switch/port dependent * so it is up to the userspace application to send * the right command. * The command must always start with a '0' after diff --git a/drivers/media/dvb/dvb-usb/af9005-fe.c b/drivers/media/dvb/dvb-usb/af9005-fe.c index 199ece0d4883..6ad94745bbdd 100644 --- a/drivers/media/dvb/dvb-usb/af9005-fe.c +++ b/drivers/media/dvb/dvb-usb/af9005-fe.c @@ -580,7 +580,7 @@ static int af9005_fe_program_cfoe(struct dvb_usb_device *d, fe_bandwidth_t bw) NS_coeff2_8k = 0x724925; break; default: - err("Invalid bandwith %d.", bw); + err("Invalid bandwidth %d.", bw); return -EINVAL; } @@ -789,7 +789,7 @@ static int af9005_fe_select_bw(struct dvb_usb_device *d, fe_bandwidth_t bw) temp = 2; break; default: - err("Invalid bandwith %d.", bw); + err("Invalid bandwidth %d.", bw); return -EINVAL; } return af9005_write_register_bits(d, xd_g_reg_bw, reg_bw_pos, @@ -930,7 +930,7 @@ static int af9005_fe_init(struct dvb_frontend *fe) if (ret) return ret; - /* init other parameters: program cfoe and select bandwith */ + /* init other parameters: program cfoe and select bandwidth */ deb_info("program cfoe\n"); if ((ret = af9005_fe_program_cfoe(state->d, BANDWIDTH_6_MHZ))) return ret; @@ -1167,7 +1167,7 @@ static int af9005_fe_set_frontend(struct dvb_frontend *fe, if (ret) return ret; - /* select bandwith */ + /* select bandwidth */ deb_info("select bandwidth"); ret = af9005_fe_select_bw(state->d, fep->u.ofdm.bandwidth); if (ret) diff --git a/drivers/media/dvb/dvb-usb/friio.h b/drivers/media/dvb/dvb-usb/friio.h index af8d55e390fb..0f461ca10cb9 100644 --- a/drivers/media/dvb/dvb-usb/friio.h +++ b/drivers/media/dvb/dvb-usb/friio.h @@ -20,7 +20,7 @@ * Frontend: comtech JDVBT-90502 * (tuner PLL: tua6034, I2C addr:(0xC0 >> 1)) * (OFDM demodulator: TC90502, I2C addr:(0x30 >> 1)) - * LED x3 (+LNB) controll: PIC 16F676 + * LED x3 (+LNB) control: PIC 16F676 * EEPROM: 24C08 * * (USB smart card reader: AU9522) diff --git a/drivers/media/dvb/dvb-usb/lmedm04.c b/drivers/media/dvb/dvb-usb/lmedm04.c index cd26e7c1536a..f2db01212ca1 100644 --- a/drivers/media/dvb/dvb-usb/lmedm04.c +++ b/drivers/media/dvb/dvb-usb/lmedm04.c @@ -321,7 +321,7 @@ static int lme2510_int_read(struct dvb_usb_adapter *adap) lme_int->lme_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; usb_submit_urb(lme_int->lme_urb, GFP_ATOMIC); - info("INT Interupt Service Started"); + info("INT Interrupt Service Started"); return 0; } @@ -482,7 +482,7 @@ static int lme2510_msg(struct dvb_usb_device *d, break; } - deb_info(4, "I2C From Interupt Message out(%02x) in(%02x)", + deb_info(4, "I2C From Interrupt Message out(%02x) in(%02x)", wbuf[3], rbuf[1]); } @@ -632,11 +632,11 @@ static int lme2510_int_service(struct dvb_usb_adapter *adap) } d->rc_dev = rc; - /* Start the Interupt */ + /* Start the Interrupt */ ret = lme2510_int_read(adap); if (ret < 0) { rc_unregister_device(rc); - info("INT Unable to start Interupt Service"); + info("INT Unable to start Interrupt Service"); return -ENODEV; } @@ -1003,7 +1003,7 @@ static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap) return -ENODEV; } - /* Start the Interupt & Remote*/ + /* Start the Interrupt & Remote*/ ret = lme2510_int_service(adap); return ret; @@ -1171,7 +1171,7 @@ void *lme2510_exit_int(struct dvb_usb_device *d) usb_kill_urb(st->lme_urb); usb_free_coherent(d->udev, 5000, st->buffer, st->lme_urb->transfer_dma); - info("Interupt Service Stopped"); + info("Interrupt Service Stopped"); rc_unregister_device(d->rc_dev); info("Remote Stopped"); } diff --git a/drivers/media/dvb/frontends/atbm8830.h b/drivers/media/dvb/frontends/atbm8830.h index e8149f393300..024273374bd8 100644 --- a/drivers/media/dvb/frontends/atbm8830.h +++ b/drivers/media/dvb/frontends/atbm8830.h @@ -39,7 +39,7 @@ struct atbm8830_config { /* parallel or serial transport stream */ u8 serial_ts; - /* transport stream clock output only when receving valid stream */ + /* transport stream clock output only when receiving valid stream */ u8 ts_clk_gated; /* Decoder sample TS data at rising edge of clock */ diff --git a/drivers/media/dvb/frontends/au8522_dig.c b/drivers/media/dvb/frontends/au8522_dig.c index 65f6a36dfb21..1d572940e243 100644 --- a/drivers/media/dvb/frontends/au8522_dig.c +++ b/drivers/media/dvb/frontends/au8522_dig.c @@ -635,7 +635,7 @@ static int au8522_led_gpio_enable(struct au8522_state *state, int onoff) struct au8522_led_config *led_config = state->config->led_cfg; u8 val; - /* bail out if we cant control an LED */ + /* bail out if we can't control an LED */ if (!led_config || !led_config->gpio_output || !led_config->gpio_output_enable || !led_config->gpio_output_disable) return 0; @@ -665,7 +665,7 @@ static int au8522_led_ctrl(struct au8522_state *state, int led) struct au8522_led_config *led_config = state->config->led_cfg; int i, ret = 0; - /* bail out if we cant control an LED */ + /* bail out if we can't control an LED */ if (!led_config || !led_config->gpio_leds || !led_config->num_led_states || !led_config->led_states) return 0; @@ -803,7 +803,7 @@ static int au8522_led_status(struct au8522_state *state, const u16 *snr) int led; u16 strong; - /* bail out if we cant control an LED */ + /* bail out if we can't control an LED */ if (!led_config) return 0; diff --git a/drivers/media/dvb/frontends/bcm3510.c b/drivers/media/dvb/frontends/bcm3510.c index cf5e576dfdcf..8aff5868a5e1 100644 --- a/drivers/media/dvb/frontends/bcm3510.c +++ b/drivers/media/dvb/frontends/bcm3510.c @@ -155,7 +155,7 @@ static int bcm3510_hab_send_request(struct bcm3510_state *st, u8 *buf, int len) unsigned long t; /* Check if any previous HAB request still needs to be serviced by the - * Aquisition Processor before sending new request */ + * Acquisition Processor before sending new request */ if ((ret = bcm3510_readB(st,0xa8,&v)) < 0) return ret; if (v.HABSTAT_a8.HABR) { @@ -361,7 +361,7 @@ static int bcm3510_tuner_cmd(struct bcm3510_state* st,u8 bc, u16 n, u8 a) /* Set duration of the initial state of TUNCTL = 3.34 micro Sec */ c.TUNCTL_state = 0x40; -/* PRESCALER DEVIDE RATIO | BC1_2_3_4; (band switch), 1stosc REFERENCE COUNTER REF_S12 and REF_S11 */ +/* PRESCALER DIVIDE RATIO | BC1_2_3_4; (band switch), 1stosc REFERENCE COUNTER REF_S12 and REF_S11 */ c.ctl_dat[0].ctrl.size = BITS_8; c.ctl_dat[0].data = 0x80 | bc; @@ -397,7 +397,7 @@ static int bcm3510_tuner_cmd(struct bcm3510_state* st,u8 bc, u16 n, u8 a) c.ctl_dat[7].ctrl.cs0 = 1; c.ctl_dat[7].data = 0x40; -/* PRESCALER DEVIDE RATIO, 2ndosc REFERENCE COUNTER REF_S12 and REF_S11 */ +/* PRESCALER DIVIDE RATIO, 2ndosc REFERENCE COUNTER REF_S12 and REF_S11 */ c.ctl_dat[8].ctrl.size = BITS_8; c.ctl_dat[8].data = 0x80; diff --git a/drivers/media/dvb/frontends/cx22700.c b/drivers/media/dvb/frontends/cx22700.c index 5fbc0fc37ecd..0142214b0133 100644 --- a/drivers/media/dvb/frontends/cx22700.c +++ b/drivers/media/dvb/frontends/cx22700.c @@ -179,7 +179,7 @@ static int cx22700_set_tps (struct cx22700_state *state, struct dvb_ofdm_paramet cx22700_writereg (state, 0x06, val); cx22700_writereg (state, 0x08, 0x04 | 0x02); /* use user tps parameters */ - cx22700_writereg (state, 0x08, 0x04); /* restart aquisition */ + cx22700_writereg (state, 0x08, 0x04); /* restart acquisition */ return 0; } diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c index ff6c4983051c..3139558148ba 100644 --- a/drivers/media/dvb/frontends/cx22702.c +++ b/drivers/media/dvb/frontends/cx22702.c @@ -55,7 +55,7 @@ MODULE_PARM_DESC(debug, "Enable verbose debug messages"); /* Register values to initialise the demod */ static const u8 init_tab[] = { - 0x00, 0x00, /* Stop aquisition */ + 0x00, 0x00, /* Stop acquisition */ 0x0B, 0x06, 0x09, 0x01, 0x0D, 0x41, @@ -310,7 +310,7 @@ static int cx22702_set_tps(struct dvb_frontend *fe, & 0xfc); cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40); - cx22702_writereg(state, 0x00, 0x01); /* Begin aquisition */ + cx22702_writereg(state, 0x00, 0x01); /* Begin acquisition */ dprintk("%s: Autodetecting\n", __func__); return 0; } @@ -424,7 +424,7 @@ static int cx22702_set_tps(struct dvb_frontend *fe, cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40); - /* Begin channel aquisition */ + /* Begin channel acquisition */ cx22702_writereg(state, 0x00, 0x01); return 0; diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c index 7a1a5bc337d8..bf9c999aa470 100644 --- a/drivers/media/dvb/frontends/cx24110.c +++ b/drivers/media/dvb/frontends/cx24110.c @@ -544,7 +544,7 @@ static int cx24110_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par cx24110_set_inversion (state, p->inversion); cx24110_set_fec (state, p->u.qpsk.fec_inner); cx24110_set_symbolrate (state, p->u.qpsk.symbol_rate); - cx24110_writereg(state,0x04,0x05); /* start aquisition */ + cx24110_writereg(state,0x04,0x05); /* start acquisition */ return 0; } diff --git a/drivers/media/dvb/frontends/cx24113.h b/drivers/media/dvb/frontends/cx24113.h index 5de0f7ffd8d2..01eb7b9c28f4 100644 --- a/drivers/media/dvb/frontends/cx24113.h +++ b/drivers/media/dvb/frontends/cx24113.h @@ -1,5 +1,5 @@ /* - * Driver for Conexant CX24113/CX24128 Tuner (Satelite) + * Driver for Conexant CX24113/CX24128 Tuner (Satellite) * * Copyright (C) 2007-8 Patrick Boettcher * diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb/frontends/cx24123.c index fad6a990a39b..b1dd8acc607a 100644 --- a/drivers/media/dvb/frontends/cx24123.c +++ b/drivers/media/dvb/frontends/cx24123.c @@ -949,7 +949,7 @@ static int cx24123_set_frontend(struct dvb_frontend *fe, else err("it seems I don't have a tuner..."); - /* Enable automatic aquisition and reset cycle */ + /* Enable automatic acquisition and reset cycle */ cx24123_writereg(state, 0x03, (cx24123_readreg(state, 0x03) | 0x07)); cx24123_writereg(state, 0x00, 0x10); cx24123_writereg(state, 0x00, 0); diff --git a/drivers/media/dvb/frontends/drx397xD.c b/drivers/media/dvb/frontends/drx397xD.c index a05007c80985..536f02b17338 100644 --- a/drivers/media/dvb/frontends/drx397xD.c +++ b/drivers/media/dvb/frontends/drx397xD.c @@ -1097,7 +1097,7 @@ static int drx397x_init(struct dvb_frontend *fe) s->config.ifagc.w0A = 0x3ff; s->config.ifagc.w0C = 0x388; - /* for signal strenght calculations */ + /* for signal strength calculations */ s->config.ss76 = 820; s->config.ss78 = 2200; s->config.ss7A = 150; diff --git a/drivers/media/dvb/frontends/mb86a16.c b/drivers/media/dvb/frontends/mb86a16.c index 33b63235b86e..c283112051b1 100644 --- a/drivers/media/dvb/frontends/mb86a16.c +++ b/drivers/media/dvb/frontends/mb86a16.c @@ -1630,7 +1630,7 @@ static enum dvbfe_search mb86a16_search(struct dvb_frontend *fe, state->srate = p->u.qpsk.symbol_rate / 1000; if (!mb86a16_set_fe(state)) { - dprintk(verbose, MB86A16_ERROR, 1, "Succesfully acquired LOCK"); + dprintk(verbose, MB86A16_ERROR, 1, "Successfully acquired LOCK"); return DVBFE_ALGO_SEARCH_SUCCESS; } diff --git a/drivers/media/dvb/frontends/mb86a20s.c b/drivers/media/dvb/frontends/mb86a20s.c index cc4acd2f920d..0f867a5055fb 100644 --- a/drivers/media/dvb/frontends/mb86a20s.c +++ b/drivers/media/dvb/frontends/mb86a20s.c @@ -406,7 +406,7 @@ err: printk(KERN_INFO "mb86a20s: Init failed. Will try again later\n"); } else { state->need_init = false; - dprintk("Initialization succeded.\n"); + dprintk("Initialization succeeded.\n"); } return rc; } diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c index 472907d43460..83e6f1a1b700 100644 --- a/drivers/media/dvb/frontends/mt312.c +++ b/drivers/media/dvb/frontends/mt312.c @@ -670,7 +670,7 @@ static int mt312_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) if (ret < 0) goto error; - /* preserve this bit to not accidently shutdown ADC */ + /* preserve this bit to not accidentally shutdown ADC */ val &= 0x80; break; } diff --git a/drivers/media/dvb/frontends/s5h1420.c b/drivers/media/dvb/frontends/s5h1420.c index e87b747ea99c..17f8cdf8afef 100644 --- a/drivers/media/dvb/frontends/s5h1420.c +++ b/drivers/media/dvb/frontends/s5h1420.c @@ -225,7 +225,7 @@ static int s5h1420_recv_slave_reply (struct dvb_frontend* fe, unsigned long timeout; int result = 0; - /* setup for DISEQC recieve */ + /* setup for DISEQC receive */ val = s5h1420_readreg(state, 0x3b); s5h1420_writereg(state, 0x3b, 0x82); /* FIXME: guess - do we need to set DIS_RDY(0x08) in receive mode? */ msleep(15); diff --git a/drivers/media/dvb/frontends/stb6100.c b/drivers/media/dvb/frontends/stb6100.c index 64673b8b64a2..bc1a8af4f6e1 100644 --- a/drivers/media/dvb/frontends/stb6100.c +++ b/drivers/media/dvb/frontends/stb6100.c @@ -360,7 +360,7 @@ static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency) else odiv = 0; - /* VCO enabled, seach clock off as per LL3.7, 3.4.1 */ + /* VCO enabled, search clock off as per LL3.7, 3.4.1 */ regs[STB6100_VCO] = 0xe0 | (odiv << STB6100_VCO_ODIV_SHIFT); /* OSM */ diff --git a/drivers/media/dvb/frontends/stv0297.c b/drivers/media/dvb/frontends/stv0297.c index 4fd7479bb62b..84d88f33275e 100644 --- a/drivers/media/dvb/frontends/stv0297.c +++ b/drivers/media/dvb/frontends/stv0297.c @@ -435,7 +435,7 @@ static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par return -EINVAL; } - // determine inversion dependant parameters + // determine inversion dependent parameters inversion = p->inversion; if (state->config->invert) inversion = (inversion == INVERSION_ON) ? INVERSION_OFF : INVERSION_ON; diff --git a/drivers/media/dvb/frontends/stv0367.c b/drivers/media/dvb/frontends/stv0367.c index 4e0e6a873b8c..e57ab53e2e27 100644 --- a/drivers/media/dvb/frontends/stv0367.c +++ b/drivers/media/dvb/frontends/stv0367.c @@ -1328,7 +1328,7 @@ stv0367_ter_signal_type stv0367ter_lock_algo(struct stv0367_state *state) /*guard=stv0367_readbits(state,F367TER_SYR_GUARD); */ - /*supress EPQ auto for SYR_GARD 1/16 or 1/32 + /*suppress EPQ auto for SYR_GARD 1/16 or 1/32 and set channel predictor in automatic */ #if 0 switch (guard) { diff --git a/drivers/media/dvb/frontends/stv0900_priv.h b/drivers/media/dvb/frontends/stv0900_priv.h index b62b0f0a4fef..e0ea74c8e093 100644 --- a/drivers/media/dvb/frontends/stv0900_priv.h +++ b/drivers/media/dvb/frontends/stv0900_priv.h @@ -238,7 +238,7 @@ enum fe_stv0900_demod_mode { }; struct stv0900_init_params{ - u32 dmd_ref_clk;/* Refrence,Input clock for the demod in Hz */ + u32 dmd_ref_clk;/* Reference,Input clock for the demod in Hz */ /* Demodulator Type (single demod or dual demod) */ enum fe_stv0900_demod_mode demod_mode; diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c index 41d0f0a6655d..52d8712411e5 100644 --- a/drivers/media/dvb/frontends/stv090x.c +++ b/drivers/media/dvb/frontends/stv090x.c @@ -1424,7 +1424,7 @@ static int stv090x_start_search(struct stv090x_state *state) if (STV090x_WRITE_DEMOD(state, CFRLOW0, 0x00) < 0) goto err; - /*enlarge the timing bandwith for Low SR*/ + /*enlarge the timing bandwidth for Low SR*/ if (STV090x_WRITE_DEMOD(state, RTCS2, 0x68) < 0) goto err; } else { @@ -1432,17 +1432,17 @@ static int stv090x_start_search(struct stv090x_state *state) Set The carrier search up and low to auto mode */ if (STV090x_WRITE_DEMOD(state, CARCFG, 0xc4) < 0) goto err; - /*reduce the timing bandwith for high SR*/ + /*reduce the timing bandwidth for high SR*/ if (STV090x_WRITE_DEMOD(state, RTCS2, 0x44) < 0) goto err; } } else { /* >= Cut 3 */ if (state->srate <= 5000000) { - /* enlarge the timing bandwith for Low SR */ + /* enlarge the timing bandwidth for Low SR */ STV090x_WRITE_DEMOD(state, RTCS2, 0x68); } else { - /* reduce timing bandwith for high SR */ + /* reduce timing bandwidth for high SR */ STV090x_WRITE_DEMOD(state, RTCS2, 0x44); } @@ -2482,7 +2482,7 @@ static int stv090x_sw_algo(struct stv090x_state *state) dvbs2_fly_wheel = STV090x_GETFIELD_Px(reg, FLYWHEEL_CPT_FIELD); } if (dvbs2_fly_wheel < 0xd) { - /*FALSE lock, The demod is loosing lock */ + /*FALSE lock, The demod is losing lock */ lock = 0; if (trials < 2) { if (state->internal->dev_ver >= 0x20) { @@ -3202,7 +3202,7 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) goto err; if (STV090x_WRITE_DEMOD(state, CORRELMANT, 0x70) < 0) goto err; - if (stv090x_set_srate(state, 1000000) < 0) /* inital srate = 1Msps */ + if (stv090x_set_srate(state, 1000000) < 0) /* initial srate = 1Msps */ goto err; } else { /* known srate */ diff --git a/drivers/media/dvb/mantis/mantis_uart.c b/drivers/media/dvb/mantis/mantis_uart.c index 97b889e8a341..f807c8ba26e4 100644 --- a/drivers/media/dvb/mantis/mantis_uart.c +++ b/drivers/media/dvb/mantis/mantis_uart.c @@ -172,7 +172,7 @@ int mantis_uart_init(struct mantis_pci *mantis) mmwrite(mmread(MANTIS_UART_CTL) | MANTIS_UART_RXINT, MANTIS_UART_CTL); schedule_work(&mantis->uart_work); - dprintk(MANTIS_DEBUG, 1, "UART succesfully initialized"); + dprintk(MANTIS_DEBUG, 1, "UART successfully initialized"); return 0; } diff --git a/drivers/media/dvb/ngene/ngene-core.c b/drivers/media/dvb/ngene/ngene-core.c index 175a0f6c2a4c..ccc2d1af49d4 100644 --- a/drivers/media/dvb/ngene/ngene-core.c +++ b/drivers/media/dvb/ngene/ngene-core.c @@ -122,7 +122,7 @@ static void demux_tasklet(unsigned long data) Cur->ngeneBuffer.SR.Flags &= ~0x40; break; - /* Stop proccessing stream */ + /* Stop processing stream */ } } else { /* We got a valid buffer, @@ -133,7 +133,7 @@ static void demux_tasklet(unsigned long data) printk(KERN_ERR DEVICE_NAME ": OOPS\n"); if (chan->HWState == HWSTATE_RUN) { Cur->ngeneBuffer.SR.Flags &= ~0x40; - break; /* Stop proccessing stream */ + break; /* Stop processing stream */ } } if (chan->AudioDTOUpdated) { diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c index 6ca6713d527a..7cb79ec685f0 100644 --- a/drivers/media/dvb/pluto2/pluto2.c +++ b/drivers/media/dvb/pluto2/pluto2.c @@ -294,13 +294,13 @@ static void pluto_dma_end(struct pluto *pluto, unsigned int nbpackets) /* Workaround for broken hardware: * [1] On startup NBPACKETS seems to contain an uninitialized value, - * but no packets have been transfered. + * but no packets have been transferred. * [2] Sometimes (actually very often) NBPACKETS stays at zero - * although one packet has been transfered. + * although one packet has been transferred. * [3] Sometimes (actually rarely), the card gets into an erroneous * mode where it continuously generates interrupts, claiming it - * has recieved nbpackets>TS_DMA_PACKETS packets, but no packet - * has been transfered. Only a reset seems to solve this + * has received nbpackets>TS_DMA_PACKETS packets, but no packet + * has been transferred. Only a reset seems to solve this */ if ((nbpackets == 0) || (nbpackets > TS_DMA_PACKETS)) { unsigned int i = 0; @@ -332,7 +332,7 @@ static irqreturn_t pluto_irq(int irq, void *dev_id) struct pluto *pluto = dev_id; u32 tscr; - /* check whether an interrupt occured on this device */ + /* check whether an interrupt occurred on this device */ tscr = pluto_readreg(pluto, REG_TSCR); if (!(tscr & (TSCR_DE | TSCR_OVR))) return IRQ_NONE; diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c index b80d09b035a1..37c594f82782 100644 --- a/drivers/media/dvb/siano/smsdvb.c +++ b/drivers/media/dvb/siano/smsdvb.c @@ -650,7 +650,7 @@ static int smsdvb_dvbt_set_frontend(struct dvb_frontend *fe, if (status & FE_HAS_LOCK) return ret; - /* previous tune didnt lock - enable LNA and tune again */ + /* previous tune didn't lock - enable LNA and tune again */ sms_board_lna_control(client->coredev, 1); } diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index fc0a60f8a1e1..3d20719fce1a 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c @@ -2332,7 +2332,7 @@ static int frontend_init(struct av7110 *av7110) * increment. That's how the 7146 is programmed to do event * counting in this budget-patch.c * I *think* HPS setting has something to do with the phase - * of HS but I cant be 100% sure in that. + * of HS but I can't be 100% sure in that. * * hardware debug note: a working budget card (including budget patch) * with vpeirq() interrupt setup in mode "0x90" (every 64K) will diff --git a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/dvb/ttpci/budget-patch.c index 579835590690..3395d1a90516 100644 --- a/drivers/media/dvb/ttpci/budget-patch.c +++ b/drivers/media/dvb/ttpci/budget-patch.c @@ -539,7 +539,7 @@ static int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_exte ** increment. That's how the 7146 is programmed to do event ** counting in this budget-patch.c ** I *think* HPS setting has something to do with the phase -** of HS but I cant be 100% sure in that. +** of HS but I can't be 100% sure in that. ** hardware debug note: a working budget card (including budget patch) ** with vpeirq() interrupt setup in mode "0x90" (every 64K) will diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c index fe1b8037b247..f893bffa08a3 100644 --- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c +++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c @@ -234,7 +234,7 @@ static void ttusb_dec_handle_irq( struct urb *urb) * (with buffer[3] == 0x40) in an intervall of ~100ms. * But to handle this correctly we had to imlemenent some * kind of timer which signals a 'key up' event if no - * keyrepeat signal is recieved for lets say 200ms. + * keyrepeat signal is received for lets say 200ms. * this should/could be added later ... * for now lets report each signal as a key down and up*/ dprintk("%s:rc signal:%d\n", __func__, buffer[4]); diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index e6b2d085a449..b3a635b95820 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c @@ -99,7 +99,7 @@ devices, that would be 76 and 91. */ /* * Commands that device should understand - * List isnt full and will be updated with implementation of new functions + * List isn't full and will be updated with implementation of new functions */ #define AMRADIO_SET_FREQ 0xa4 #define AMRADIO_SET_MUTE 0xab diff --git a/drivers/media/radio/si4713-i2c.c b/drivers/media/radio/si4713-i2c.c index 0fab6f8f7e24..deca2e06ff22 100644 --- a/drivers/media/radio/si4713-i2c.c +++ b/drivers/media/radio/si4713-i2c.c @@ -481,7 +481,7 @@ unlock: } /* - * si4713_wait_stc - Waits STC interrupt and clears status bits. Usefull + * si4713_wait_stc - Waits STC interrupt and clears status bits. Useful * for TX_TUNE_POWER, TX_TUNE_FREQ and TX_TUNE_MEAS * @sdev: si4713_device structure for the device we are communicating * @usecs: timeout to wait for STC interrupt signal diff --git a/drivers/media/radio/wl128x/fmdrv_common.c b/drivers/media/radio/wl128x/fmdrv_common.c index 64454d39c0ca..26fb9cbd7530 100644 --- a/drivers/media/radio/wl128x/fmdrv_common.c +++ b/drivers/media/radio/wl128x/fmdrv_common.c @@ -352,7 +352,7 @@ static void send_tasklet(unsigned long arg) if (!atomic_read(&fmdev->tx_cnt)) return; - /* Check, is there any timeout happenned to last transmitted packet */ + /* Check, is there any timeout happened to last transmitted packet */ if ((jiffies - fmdev->last_tx_jiffies) > FM_DRV_TX_TIMEOUT) { fmerr("TX timeout occurred\n"); atomic_set(&fmdev->tx_cnt, 1); @@ -478,7 +478,7 @@ u32 fmc_send_cmd(struct fmdev *fmdev, u8 fm_op, u16 type, void *payload, return -ETIMEDOUT; } if (!fmdev->resp_skb) { - fmerr("Reponse SKB is missing\n"); + fmerr("Response SKB is missing\n"); return -EFAULT; } spin_lock_irqsave(&fmdev->resp_skb_lock, flags); @@ -1592,7 +1592,7 @@ u32 fmc_release(struct fmdev *fmdev) fmdbg("FM Core is already down\n"); return 0; } - /* Sevice pending read */ + /* Service pending read */ wake_up_interruptible(&fmdev->rx.rds.read_queue); tasklet_kill(&fmdev->tx_task); diff --git a/drivers/media/radio/wl128x/fmdrv_common.h b/drivers/media/radio/wl128x/fmdrv_common.h index 427c4164cece..aee243bb6630 100644 --- a/drivers/media/radio/wl128x/fmdrv_common.h +++ b/drivers/media/radio/wl128x/fmdrv_common.h @@ -362,7 +362,7 @@ struct fm_event_msg_hdr { #define FM_TX_PREEMPH_50US 0 #define FM_TX_PREEMPH_75US 2 -/* FM TX antenna impedence values */ +/* FM TX antenna impedance values */ #define FM_TX_ANT_IMP_50 0 #define FM_TX_ANT_IMP_200 1 #define FM_TX_ANT_IMP_500 2 diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c index 1ac49139158d..a43ed6c41bfc 100644 --- a/drivers/media/rc/ene_ir.c +++ b/drivers/media/rc/ene_ir.c @@ -520,7 +520,7 @@ static void ene_rx_disable(struct ene_device *dev) dev->rx_enabled = false; } -/* This resets the receiver. Usefull to stop stream of spaces at end of +/* This resets the receiver. Useful to stop stream of spaces at end of * transmission */ static void ene_rx_reset(struct ene_device *dev) @@ -1089,7 +1089,7 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) if (error < 0) goto error; - ene_notice("driver has been succesfully loaded"); + ene_notice("driver has been successfully loaded"); return 0; error: if (dev && dev->irq >= 0) diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c index f714e1a22c92..ebd68edf5b24 100644 --- a/drivers/media/rc/imon.c +++ b/drivers/media/rc/imon.c @@ -1293,7 +1293,7 @@ static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf) * contain a position coordinate (x,y), with each component ranging * from -14 to 14. We want to down-sample this to only 4 discrete values * for up/down/left/right arrow keys. Also, when you get too close to - * diagonals, it has a tendancy to jump back and forth, so lets try to + * diagonals, it has a tendency to jump back and forth, so lets try to * ignore when they get too close. */ if (ictx->product != 0xffdc) { diff --git a/drivers/media/rc/ir-raw.c b/drivers/media/rc/ir-raw.c index 01f258a2a57a..11c19d8d0ee0 100644 --- a/drivers/media/rc/ir-raw.c +++ b/drivers/media/rc/ir-raw.c @@ -153,7 +153,7 @@ EXPORT_SYMBOL_GPL(ir_raw_event_store_edge); * @type: the type of the event that has occurred * * This routine (which may be called from an interrupt context) works - * in similiar manner to ir_raw_event_store_edge. + * in similar manner to ir_raw_event_store_edge. * This routine is intended for devices with limited internal buffer * It automerges samples of same type, and handles timeouts */ diff --git a/drivers/media/rc/keymaps/rc-lme2510.c b/drivers/media/rc/keymaps/rc-lme2510.c index 3c1913926c1a..afae14fd152e 100644 --- a/drivers/media/rc/keymaps/rc-lme2510.c +++ b/drivers/media/rc/keymaps/rc-lme2510.c @@ -55,7 +55,7 @@ static struct rc_map_table lme2510_rc[] = { { 0xff40fb04, KEY_MEDIA_REPEAT}, /* Recall */ { 0xff40e51a, KEY_PAUSE }, /* Timeshift */ { 0xff40fd02, KEY_VOLUMEUP }, /* 2 x -/+ Keys not marked */ - { 0xff40f906, KEY_VOLUMEDOWN }, /* Volumne defined as right hand*/ + { 0xff40f906, KEY_VOLUMEDOWN }, /* Volume defined as right hand*/ { 0xff40fe01, KEY_CHANNELUP }, { 0xff40fa05, KEY_CHANNELDOWN }, { 0xff40eb14, KEY_ZOOM }, @@ -76,7 +76,7 @@ static struct rc_map_table lme2510_rc[] = { { 0xff00bb44, KEY_MEDIA_REPEAT}, /* Recall */ { 0xff00b54a, KEY_PAUSE }, /* Timeshift */ { 0xff00b847, KEY_VOLUMEUP }, /* 2 x -/+ Keys not marked */ - { 0xff00bc43, KEY_VOLUMEDOWN }, /* Volumne defined as right hand*/ + { 0xff00bc43, KEY_VOLUMEDOWN }, /* Volume defined as right hand*/ { 0xff00b946, KEY_CHANNELUP }, { 0xff00bf40, KEY_CHANNELDOWN }, { 0xff00f708, KEY_ZOOM }, diff --git a/drivers/media/rc/keymaps/rc-msi-tvanywhere.c b/drivers/media/rc/keymaps/rc-msi-tvanywhere.c index 18b37facb0dd..fdd213ff1adf 100644 --- a/drivers/media/rc/keymaps/rc-msi-tvanywhere.c +++ b/drivers/media/rc/keymaps/rc-msi-tvanywhere.c @@ -29,7 +29,7 @@ static struct rc_map_table msi_tvanywhere[] = { { 0x0c, KEY_MUTE }, { 0x0f, KEY_SCREEN }, /* Full Screen */ - { 0x10, KEY_FN }, /* Funtion */ + { 0x10, KEY_FN }, /* Function */ { 0x11, KEY_TIME }, /* Time shift */ { 0x12, KEY_POWER }, { 0x13, KEY_MEDIA }, /* MTS */ diff --git a/drivers/media/rc/keymaps/rc-norwood.c b/drivers/media/rc/keymaps/rc-norwood.c index f1c1281fbc17..f9f2fa2819b8 100644 --- a/drivers/media/rc/keymaps/rc-norwood.c +++ b/drivers/media/rc/keymaps/rc-norwood.c @@ -49,7 +49,7 @@ static struct rc_map_table norwood[] = { { 0x37, KEY_PLAY }, /* Play */ { 0x36, KEY_PAUSE }, /* Pause */ { 0x2b, KEY_STOP }, /* Stop */ - { 0x67, KEY_FASTFORWARD }, /* Foward */ + { 0x67, KEY_FASTFORWARD }, /* Forward */ { 0x66, KEY_REWIND }, /* Rewind */ { 0x3e, KEY_SEARCH }, /* Auto Scan */ { 0x2e, KEY_CAMERA }, /* Capture Video */ diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 5ac1baf45c8e..f53f9c68d38d 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -255,7 +255,7 @@ static unsigned int ir_update_mapping(struct rc_dev *dev, * @rc_map: scancode table to be searched * @scancode: the desired scancode * @resize: controls whether we allowed to resize the table to - * accomodate not yet present scancodes + * accommodate not yet present scancodes * @return: index of the mapping containing scancode in question * or -1U in case of failure. * @@ -1037,7 +1037,7 @@ int rc_register_device(struct rc_dev *dev) goto out_table; /* - * Default delay of 250ms is too short for some protocols, expecially + * Default delay of 250ms is too short for some protocols, especially * since the timeout is currently set to 250ms. Increase it to 500ms, * to avoid wrong repetition of the keycodes. Note that this must be * set after the call to input_register_device(). diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c index 6ad83a15d073..c03eb29a9ee6 100644 --- a/drivers/media/video/au0828/au0828-video.c +++ b/drivers/media/video/au0828/au0828-video.c @@ -502,7 +502,7 @@ static inline void vbi_get_next_buf(struct au0828_dmaqueue *dma_q, /* Get the next buffer */ *buf = list_entry(dma_q->active.next, struct au0828_buffer, vb.queue); - /* Cleans up buffer - Usefull for testing for frame/URB loss */ + /* Cleans up buffer - Useful for testing for frame/URB loss */ outp = videobuf_to_vmalloc(&(*buf)->vb); memset(outp, 0x00, (*buf)->vb.size); diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c index 242f0d512238..3c9e6c7e7b52 100644 --- a/drivers/media/video/bt8xx/bttv-cards.c +++ b/drivers/media/video/bt8xx/bttv-cards.c @@ -2244,8 +2244,8 @@ struct tvcard bttv_tvcards[] = { }, [BTTV_BOARD_PICOLO_TETRA_CHIP] = { /*Eric DEBIEF */ - /*EURESYS Picolo Tetra : 4 Conexant Fusion 878A, no audio, video input set with analog multiplexers GPIO controled*/ - /* adds picolo_tetra_muxsel(), picolo_tetra_init(), the folowing declaration strucure, and #define BTTV_BOARD_PICOLO_TETRA_CHIP*/ + /*EURESYS Picolo Tetra : 4 Conexant Fusion 878A, no audio, video input set with analog multiplexers GPIO controlled*/ + /* adds picolo_tetra_muxsel(), picolo_tetra_init(), the following declaration strucure, and #define BTTV_BOARD_PICOLO_TETRA_CHIP*/ /*0x79 in bttv.h*/ .name = "Euresys Picolo Tetra", .video_inputs = 4, @@ -4567,7 +4567,7 @@ static void picolo_tetra_muxsel (struct bttv* btv, unsigned int input) * at one input while the monitor is looking at another. * * Since I've couldn't be bothered figuring out how to add an - * independant muxsel for the monitor bus, I've just set it to + * independent muxsel for the monitor bus, I've just set it to * whatever the card is looking at. * * OUT0 of the TDA8540's is connected to MUX0 (0x03) diff --git a/drivers/media/video/bt8xx/bttv-gpio.c b/drivers/media/video/bt8xx/bttv-gpio.c index fd604d32bbb9..13ce72c04b33 100644 --- a/drivers/media/video/bt8xx/bttv-gpio.c +++ b/drivers/media/video/bt8xx/bttv-gpio.c @@ -3,7 +3,7 @@ bttv-gpio.c -- gpio sub drivers sysfs-based sub driver interface for bttv - mainly intented for gpio access + mainly intended for gpio access Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index 55ffd60ffa7f..664703398493 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c @@ -383,7 +383,7 @@ static int cafe_smbus_write_data(struct cafe_camera *cam, * causes the device to die. * Use a busy-wait because we often send a large quantity of small * commands at-once; using msleep() would cause a lot of context - * switches which take longer than 2ms, resulting in a noticable + * switches which take longer than 2ms, resulting in a noticeable * boot-time and capture-start delays. */ mdelay(2); diff --git a/drivers/media/video/cx18/cx18-av-core.h b/drivers/media/video/cx18/cx18-av-core.h index 188c9c3d2db1..e9c69d9c9e4a 100644 --- a/drivers/media/video/cx18/cx18-av-core.h +++ b/drivers/media/video/cx18/cx18-av-core.h @@ -109,7 +109,7 @@ struct cx18_av_state { int is_initialized; /* - * The VBI slicer starts operating and counting lines, begining at + * The VBI slicer starts operating and counting lines, beginning at * slicer line count of 1, at D lines after the deassertion of VRESET. * This staring field line, S, is 6 (& 319) or 10 (& 273) for 625 or 525 * line systems respectively. Sliced ancillary data captured on VBI diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c index 86c30b9963e5..4f041c033c54 100644 --- a/drivers/media/video/cx18/cx18-ioctl.c +++ b/drivers/media/video/cx18/cx18-ioctl.c @@ -312,7 +312,7 @@ static int cx18_s_fmt_vbi_cap(struct file *file, void *fh, /* * Set the digitizer registers for raw active VBI. - * Note cx18_av_vbi_wipes out alot of the passed in fmt under valid + * Note cx18_av_vbi_wipes out a lot of the passed in fmt under valid * calling conditions */ ret = v4l2_subdev_call(cx->sd_av, vbi, s_raw_fmt, &fmt->fmt.vbi); diff --git a/drivers/media/video/cx18/cx18-vbi.c b/drivers/media/video/cx18/cx18-vbi.c index 582227522cf0..6d3121ff45a2 100644 --- a/drivers/media/video/cx18/cx18-vbi.c +++ b/drivers/media/video/cx18/cx18-vbi.c @@ -29,7 +29,7 @@ /* * Raster Reference/Protection (RP) bytes, used in Start/End Active * Video codes emitted from the digitzer in VIP 1.x mode, that flag the start - * of VBI sample or VBI ancilliary data regions in the digitial ratser line. + * of VBI sample or VBI ancillary data regions in the digitial ratser line. * * Task FieldEven VerticalBlank HorizontalBlank 0 0 0 0 */ diff --git a/drivers/media/video/cx231xx/cx231xx-avcore.c b/drivers/media/video/cx231xx/cx231xx-avcore.c index 62843d39817c..280df43ca446 100644 --- a/drivers/media/video/cx231xx/cx231xx-avcore.c +++ b/drivers/media/video/cx231xx/cx231xx-avcore.c @@ -2577,7 +2577,7 @@ int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type) break; case 6: /* ts1 parallel mode */ - cx231xx_info("%s: set ts1 parrallel mode registers\n", + cx231xx_info("%s: set ts1 parallel mode registers\n", __func__); status = cx231xx_mode_register(dev, TS_MODE_REG, 0x100); status = cx231xx_mode_register(dev, TS1_CFG_REG, 0x400); diff --git a/drivers/media/video/cx231xx/cx231xx-vbi.c b/drivers/media/video/cx231xx/cx231xx-vbi.c index 1d914488dbb3..1c7a4daafecf 100644 --- a/drivers/media/video/cx231xx/cx231xx-vbi.c +++ b/drivers/media/video/cx231xx/cx231xx-vbi.c @@ -631,7 +631,7 @@ static inline void get_next_vbi_buf(struct cx231xx_dmaqueue *dma_q, /* Get the next buffer */ *buf = list_entry(dma_q->active.next, struct cx231xx_buffer, vb.queue); - /* Cleans up buffer - Usefull for testing for frame/URB loss */ + /* Cleans up buffer - Useful for testing for frame/URB loss */ outp = videobuf_to_vmalloc(&(*buf)->vb); memset(outp, 0, (*buf)->vb.size); diff --git a/drivers/media/video/cx231xx/cx231xx-video.c b/drivers/media/video/cx231xx/cx231xx-video.c index ffd5af914c44..a69c24d8db06 100644 --- a/drivers/media/video/cx231xx/cx231xx-video.c +++ b/drivers/media/video/cx231xx/cx231xx-video.c @@ -309,7 +309,7 @@ static inline void get_next_buf(struct cx231xx_dmaqueue *dma_q, /* Get the next buffer */ *buf = list_entry(dma_q->active.next, struct cx231xx_buffer, vb.queue); - /* Cleans up buffer - Usefull for testing for frame/URB loss */ + /* Cleans up buffer - Useful for testing for frame/URB loss */ outp = videobuf_to_vmalloc(&(*buf)->vb); memset(outp, 0, (*buf)->vb.size); diff --git a/drivers/media/video/cx23885/cimax2.c b/drivers/media/video/cx23885/cimax2.c index 209b971bd267..c9f15d6dec40 100644 --- a/drivers/media/video/cx23885/cimax2.c +++ b/drivers/media/video/cx23885/cimax2.c @@ -449,7 +449,7 @@ int netup_ci_init(struct cx23885_tsport *port) 0x04, /* ack active low */ 0x00, /* LOCK = 0 */ 0x33, /* serial mode, rising in, rising out, MSB first*/ - 0x31, /* syncronization */ + 0x31, /* synchronization */ }; int ret; diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h index 8db2797bc7c3..c186473fc570 100644 --- a/drivers/media/video/cx23885/cx23885.h +++ b/drivers/media/video/cx23885/cx23885.h @@ -214,7 +214,7 @@ struct cx23885_board { /* Vendors can and do run the PCIe bridge at different * clock rates, driven physically by crystals on the PCBs. - * The core has to accomodate this. This allows the user + * The core has to accommodate this. This allows the user * to add new boards with new frequencys. The value is * expressed in Hz. * diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index 35796e035247..b7ee2ae70583 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c @@ -2,7 +2,7 @@ * * Copyright (C) 2004 Ulf Eklund * - * Based on the saa7115 driver and on the first verison of Chris Kennedy's + * Based on the saa7115 driver and on the first version of Chris Kennedy's * cx25840 driver. * * Changes by Tyler Trafford @@ -445,7 +445,7 @@ static void cx25840_initialize(struct i2c_client *client) cx25840_write(client, 0x918, 0xa0); cx25840_write(client, 0x919, 0x01); - /* stereo prefered */ + /* stereo preferred */ cx25840_write(client, 0x809, 0x04); /* AC97 shift */ cx25840_write(client, 0x8cf, 0x0f); @@ -546,7 +546,7 @@ static void cx23885_initialize(struct i2c_client *client) * Aux PLL * Initial setup for audio sample clock: * 48 ksps, 16 bits/sample, x160 multiplier = 122.88 MHz - * Intial I2S output/master clock(?): + * Initial I2S output/master clock(?): * 48 ksps, 16 bits/sample, x16 multiplier = 12.288 MHz */ switch (state->id) { @@ -903,7 +903,7 @@ static void input_change(struct i2c_client *client) } else if (std & V4L2_STD_PAL) { /* Autodetect audio standard and audio system */ cx25840_write(client, 0x808, 0xff); - /* Since system PAL-L is pretty much non-existant and + /* Since system PAL-L is pretty much non-existent and not used by any public broadcast network, force 6.5 MHz carrier to be interpreted as System DK, this avoids DK audio detection instability */ @@ -1851,7 +1851,7 @@ static u32 get_cx2388x_ident(struct i2c_client *client) ret = V4L2_IDENT_CX23885_AV; } else { /* CX23887 has a broken DIF, but the registers - * appear valid (but unsed), good enough to detect. */ + * appear valid (but unused), good enough to detect. */ ret = V4L2_IDENT_CX23887_AV; } } else if (cx25840_read4(client, 0x300) & 0x0fffffff) { diff --git a/drivers/media/video/davinci/dm644x_ccdc.c b/drivers/media/video/davinci/dm644x_ccdc.c index 490aafb34e2f..c8b32c1c7386 100644 --- a/drivers/media/video/davinci/dm644x_ccdc.c +++ b/drivers/media/video/davinci/dm644x_ccdc.c @@ -258,7 +258,7 @@ static int ccdc_update_raw_params(struct ccdc_config_params_raw *raw_params) /* * Allocate memory for FPC table if current * FPC table buffer is not big enough to - * accomodate FPC Number requested + * accommodate FPC Number requested */ if (raw_params->fault_pxl.fp_num != config_params->fault_pxl.fp_num) { if (fpc_physaddr != NULL) { @@ -436,7 +436,7 @@ void ccdc_config_ycbcr(void) /* * configure the horizontal line offset. This should be a - * on 32 byte bondary. So clear LSB 5 bits + * on 32 byte boundary. So clear LSB 5 bits */ regw(((params->win.width * 2 + 31) & ~0x1f), CCDC_HSIZE_OFF); diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c index 71e961e53a56..5b38fc93ff28 100644 --- a/drivers/media/video/davinci/vpfe_capture.c +++ b/drivers/media/video/davinci/vpfe_capture.c @@ -1691,7 +1691,7 @@ static int vpfe_s_crop(struct file *file, void *priv, goto unlock_out; } - /* adjust the width to 16 pixel boundry */ + /* adjust the width to 16 pixel boundary */ crop->c.width = ((crop->c.width + 15) & ~0xf); /* make sure parameters are valid */ diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index a83131bd00b2..7b6461d2d1ff 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c @@ -377,7 +377,7 @@ static inline void get_next_buf(struct em28xx_dmaqueue *dma_q, /* Get the next buffer */ *buf = list_entry(dma_q->active.next, struct em28xx_buffer, vb.queue); - /* Cleans up buffer - Usefull for testing for frame/URB loss */ + /* Cleans up buffer - Useful for testing for frame/URB loss */ outp = videobuf_to_vmalloc(&(*buf)->vb); memset(outp, 0, (*buf)->vb.size); @@ -404,7 +404,7 @@ static inline void vbi_get_next_buf(struct em28xx_dmaqueue *dma_q, /* Get the next buffer */ *buf = list_entry(dma_q->active.next, struct em28xx_buffer, vb.queue); - /* Cleans up buffer - Usefull for testing for frame/URB loss */ + /* Cleans up buffer - Useful for testing for frame/URB loss */ outp = videobuf_to_vmalloc(&(*buf)->vb); memset(outp, 0x00, (*buf)->vb.size); diff --git a/drivers/media/video/gspca/gl860/gl860-mi1320.c b/drivers/media/video/gspca/gl860/gl860-mi1320.c index c276a7debdec..b57160e04866 100644 --- a/drivers/media/video/gspca/gl860/gl860-mi1320.c +++ b/drivers/media/video/gspca/gl860/gl860-mi1320.c @@ -201,7 +201,7 @@ void mi1320_init_settings(struct gspca_dev *gspca_dev) sd->vmax.backlight = 2; sd->vmax.brightness = 8; sd->vmax.sharpness = 7; - sd->vmax.contrast = 0; /* 10 but not working with tihs driver */ + sd->vmax.contrast = 0; /* 10 but not working with this driver */ sd->vmax.gamma = 40; sd->vmax.hue = 5 + 1; sd->vmax.saturation = 8; diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 9c6a643caf01..e526aa3dedaf 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -857,7 +857,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) } /* the bandwidth is not wide enough - * negociate or try a lower alternate setting */ + * negotiate or try a lower alternate setting */ PDEBUG(D_ERR|D_STREAM, "bandwidth not wide enough - trying again"); msleep(20); /* wait for kill complete */ @@ -2346,7 +2346,7 @@ void gspca_disconnect(struct usb_interface *intf) usb_set_intfdata(intf, NULL); /* release the device */ - /* (this will call gspca_release() immediatly or on last close) */ + /* (this will call gspca_release() immediately or on last close) */ video_unregister_device(&gspca_dev->vdev); /* PDEBUG(D_PROBE, "disconnect complete"); */ diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c index cb4d0bf0d784..0196209a948a 100644 --- a/drivers/media/video/gspca/mars.c +++ b/drivers/media/video/gspca/mars.c @@ -361,7 +361,7 @@ static int sd_start(struct gspca_dev *gspca_dev) mi_w(gspca_dev, i + 1, mi_data[i]); data[0] = 0x00; - data[1] = 0x4d; /* ISOC transfering enable... */ + data[1] = 0x4d; /* ISOC transferring enable... */ reg_w(gspca_dev, 2); gspca_dev->ctrl_inac = 0; /* activate the illuminator controls */ diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c index 3884c9d300c5..97e507967434 100644 --- a/drivers/media/video/gspca/mr97310a.c +++ b/drivers/media/video/gspca/mr97310a.c @@ -469,7 +469,7 @@ static void lcd_stop(struct gspca_dev *gspca_dev) static int isoc_enable(struct gspca_dev *gspca_dev) { gspca_dev->usb_buf[0] = 0x00; - gspca_dev->usb_buf[1] = 0x4d; /* ISOC transfering enable... */ + gspca_dev->usb_buf[1] = 0x4d; /* ISOC transferring enable... */ return mr_write(gspca_dev, 2); } diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index fd1b6082c96d..36a46fc78734 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c @@ -381,7 +381,7 @@ static const struct v4l2_pix_format ov519_sif_mode[] = { larger then necessary, however they need to be this big as the ov511 / ov518 always fills the entire isoc frame, using 0 padding bytes when it doesn't have any data. So with low framerates the amount of data - transfered can become quite large (libv4l will remove all the 0 padding + transferred can become quite large (libv4l will remove all the 0 padding in userspace). */ static const struct v4l2_pix_format ov518_vga_mode[] = { {320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE, @@ -4368,7 +4368,7 @@ static void ov511_pkt_scan(struct gspca_dev *gspca_dev, gspca_dev->last_packet_type = DISCARD_PACKET; return; } - /* Add 11 byte footer to frame, might be usefull */ + /* Add 11 byte footer to frame, might be useful */ gspca_frame_add(gspca_dev, LAST_PACKET, in, 11); return; } else { diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 5a08738fba30..146b459b08d5 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -827,7 +827,7 @@ static void setexposure(struct gspca_dev *gspca_dev) possible to use less exposure then what the fps maximum allows by setting register 10. register 10 configures the actual exposure as quotient of the full exposure, with 0 - being no exposure at all (not very usefull) and reg10_max + being no exposure at all (not very useful) and reg10_max being max exposure possible at that framerate. The code maps our 0 - 510 ms exposure ctrl to these 2 diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c index 45552c3ff8d9..3e76951e3c19 100644 --- a/drivers/media/video/gspca/spca500.c +++ b/drivers/media/video/gspca/spca500.c @@ -607,7 +607,7 @@ static void spca500_reinit(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0x00, 0x8880, 2); /* family cam Quicksmart stuff */ reg_w(gspca_dev, 0x00, 0x800a, 0x00); - /* Set agc transfer: synced inbetween frames */ + /* Set agc transfer: synced between frames */ reg_w(gspca_dev, 0x00, 0x820f, 0x01); /* Init SDRAM - needed for SDRAM access */ reg_w(gspca_dev, 0x00, 0x870a, 0x04); @@ -831,7 +831,7 @@ static int sd_start(struct gspca_dev *gspca_dev) /* familycam Quicksmart pocketDV stuff */ reg_w(gspca_dev, 0x00, 0x800a, 0x00); - /* Set agc transfer: synced inbetween frames */ + /* Set agc transfer: synced between frames */ reg_w(gspca_dev, 0x00, 0x820f, 0x01); /* Init SDRAM - needed for SDRAM access */ reg_w(gspca_dev, 0x00, 0x870a, 0x04); diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c index 348319371523..41dce49fb43d 100644 --- a/drivers/media/video/gspca/spca508.c +++ b/drivers/media/video/gspca/spca508.c @@ -592,7 +592,7 @@ static const u16 spca508_sightcam_init_data[][2] = { /* This line seems to setup the frame/canvas */ {0x000f, 0x8402}, -/* Theese 6 lines are needed to startup the webcam */ +/* These 6 lines are needed to startup the webcam */ {0x0090, 0x8110}, {0x0001, 0x8114}, {0x0001, 0x8114}, diff --git a/drivers/media/video/gspca/sq905.c b/drivers/media/video/gspca/sq905.c index 2e9c06175192..5ba96aff2252 100644 --- a/drivers/media/video/gspca/sq905.c +++ b/drivers/media/video/gspca/sq905.c @@ -22,7 +22,7 @@ * History and Acknowledgments * * The original Linux driver for SQ905 based cameras was written by - * Marcell Lengyel and furter developed by many other contributers + * Marcell Lengyel and furter developed by many other contributors * and is available from http://sourceforge.net/projects/sqcam/ * * This driver takes advantage of the reverse engineering work done for diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c index 17531b41a073..b8156855f2b7 100644 --- a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c +++ b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c @@ -569,7 +569,7 @@ static int hdcs_init(struct sd *sd) if (err < 0) return err; - /* Enable continous frame capture, bit 2: stop when frame complete */ + /* Enable continuous frame capture, bit 2: stop when frame complete */ err = stv06xx_write_sensor(sd, HDCS_REG_CONFIG(sd), BIT(3)); if (err < 0) return err; diff --git a/drivers/media/video/hexium_gemini.c b/drivers/media/video/hexium_gemini.c index cdf8b191f710..cbc505a2fc29 100644 --- a/drivers/media/video/hexium_gemini.c +++ b/drivers/media/video/hexium_gemini.c @@ -261,7 +261,7 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input) /* the saa7146 provides some controls (brightness, contrast, saturation) which gets registered *after* this function. because of this we have - to return with a value != 0 even if the function succeded.. */ + to return with a value != 0 even if the function succeeded.. */ static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qc) { struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; diff --git a/drivers/media/video/ivtv/ivtv-firmware.c b/drivers/media/video/ivtv/ivtv-firmware.c index 4df01947a7df..14a1cea1d70d 100644 --- a/drivers/media/video/ivtv/ivtv-firmware.c +++ b/drivers/media/video/ivtv/ivtv-firmware.c @@ -179,7 +179,7 @@ static volatile struct ivtv_mailbox __iomem *ivtv_search_mailbox(const volatile { int i; - /* mailbox is preceeded by a 16 byte 'magic cookie' starting at a 256-byte + /* mailbox is preceded by a 16 byte 'magic cookie' starting at a 256-byte address boundary */ for (i = 0; i < size; i += 0x100) { if (readl(mem + i) == 0x12345678 && @@ -377,7 +377,7 @@ int ivtv_firmware_check(struct ivtv *itv, char *where) "Reloading\n", where); res = ivtv_firmware_restart(itv); /* - * Even if restarted ok, still signal a problem had occured. + * Even if restarted ok, still signal a problem had occurred. * The caller can come through this function again to check * if things are really ok after the restart. */ diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c index f0316d02f09f..17247451c693 100644 --- a/drivers/media/video/ivtv/ivtvfb.c +++ b/drivers/media/video/ivtv/ivtvfb.c @@ -1080,7 +1080,7 @@ static int ivtvfb_init_vidmode(struct ivtv *itv) kmalloc(sizeof(u32) * 16, GFP_KERNEL|__GFP_NOWARN); if (!oi->ivtvfb_info.pseudo_palette) { - IVTVFB_ERR("abort, unable to alloc pseudo pallete\n"); + IVTVFB_ERR("abort, unable to alloc pseudo palette\n"); return -ENOMEM; } diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c index b1763ac93ab3..8126622fb4f5 100644 --- a/drivers/media/video/msp3400-driver.c +++ b/drivers/media/video/msp3400-driver.c @@ -69,7 +69,7 @@ MODULE_LICENSE("GPL"); /* module parameters */ static int opmode = OPMODE_AUTO; int msp_debug; /* msp_debug output */ -int msp_once; /* no continous stereo monitoring */ +int msp_once; /* no continuous stereo monitoring */ int msp_amsound; /* hard-wire AM sound at 6.5 Hz (france), the autoscan seems work well only with FM... */ int msp_standard = 1; /* Override auto detect of audio msp_standard, @@ -551,7 +551,7 @@ static int msp_log_status(struct v4l2_subdev *sd) switch (state->mode) { case MSP_MODE_AM_DETECT: p = "AM (for carrier detect)"; break; case MSP_MODE_FM_RADIO: p = "FM Radio"; break; - case MSP_MODE_FM_TERRA: p = "Terrestial FM-mono/stereo"; break; + case MSP_MODE_FM_TERRA: p = "Terrestrial FM-mono/stereo"; break; case MSP_MODE_FM_SAT: p = "Satellite FM-mono"; break; case MSP_MODE_FM_NICAM1: p = "NICAM/FM (B/G, D/K)"; break; case MSP_MODE_FM_NICAM2: p = "NICAM/FM (I)"; break; diff --git a/drivers/media/video/msp3400-kthreads.c b/drivers/media/video/msp3400-kthreads.c index b376fcdee652..80387e2c3eca 100644 --- a/drivers/media/video/msp3400-kthreads.c +++ b/drivers/media/video/msp3400-kthreads.c @@ -87,7 +87,7 @@ static struct msp3400c_init_data_dem { {-8, -8, 4, 6, 78, 107}, MSP_CARRIER(10.7), MSP_CARRIER(10.7), 0x00d0, 0x0480, 0x0020, 0x3000 - }, { /* Terrestial FM-mono + FM-stereo */ + }, { /* Terrestrial FM-mono + FM-stereo */ {3, 18, 27, 48, 66, 72}, {3, 18, 27, 48, 66, 72}, MSP_CARRIER(5.5), MSP_CARRIER(5.5), diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index 029a4babfd61..d4fe7bc92a1d 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -473,7 +473,7 @@ static int omap_vout_vrfb_buffer_setup(struct omap_vout_device *vout, /* * Convert V4L2 rotation to DSS rotation * V4L2 understand 0, 90, 180, 270. - * Convert to 0, 1, 2 and 3 repsectively for DSS + * Convert to 0, 1, 2 and 3 respectively for DSS */ static int v4l2_rot_to_dss_rot(int v4l2_rotation, enum dss_rotation *rotation, bool mirror) @@ -1142,7 +1142,7 @@ static int omap_vout_buffer_prepare(struct videobuf_queue *q, } /* - * Buffer queue funtion will be called from the videobuf layer when _QBUF + * Buffer queue function will be called from the videobuf layer when _QBUF * ioctl is called. It is used to enqueue buffer, which is ready to be * displayed. */ diff --git a/drivers/media/video/omap/omap_voutlib.c b/drivers/media/video/omap/omap_voutlib.c index b941c761eef9..2aa6a76c5e59 100644 --- a/drivers/media/video/omap/omap_voutlib.c +++ b/drivers/media/video/omap/omap_voutlib.c @@ -53,7 +53,7 @@ EXPORT_SYMBOL_GPL(omap_vout_default_crop); /* Given a new render window in new_win, adjust the window to the * nearest supported configuration. The adjusted window parameters are * returned in new_win. - * Returns zero if succesful, or -EINVAL if the requested window is + * Returns zero if successful, or -EINVAL if the requested window is * impossible and cannot reasonably be adjusted. */ int omap_vout_try_window(struct v4l2_framebuffer *fbuf, @@ -101,7 +101,7 @@ EXPORT_SYMBOL_GPL(omap_vout_try_window); * will also be adjusted if necessary. Preference is given to keeping the * the window as close to the requested configuration as possible. If * successful, new_win, vout->win, and crop are updated. - * Returns zero if succesful, or -EINVAL if the requested preview window is + * Returns zero if successful, or -EINVAL if the requested preview window is * impossible and cannot reasonably be adjusted. */ int omap_vout_new_window(struct v4l2_rect *crop, @@ -155,7 +155,7 @@ EXPORT_SYMBOL_GPL(omap_vout_new_window); * window would fall outside the display boundaries, the cropping rectangle * will also be adjusted to maintain the rescaling ratios. If successful, crop * and win are updated. - * Returns zero if succesful, or -EINVAL if the requested cropping rectangle is + * Returns zero if successful, or -EINVAL if the requested cropping rectangle is * impossible and cannot reasonably be adjusted. */ int omap_vout_new_crop(struct v4l2_pix_format *pix, diff --git a/drivers/media/video/omap1_camera.c b/drivers/media/video/omap1_camera.c index eab31cbd68eb..5954b9306630 100644 --- a/drivers/media/video/omap1_camera.c +++ b/drivers/media/video/omap1_camera.c @@ -687,7 +687,7 @@ static void videobuf_done(struct omap1_cam_dev *pcdev, * In CONTIG mode, the current buffer parameters had already * been entered into the DMA programming register set while the * buffer was fetched with prepare_next_vb(), they may have also - * been transfered into the runtime set and already active if + * been transferred into the runtime set and already active if * the DMA still running. */ } else { @@ -835,7 +835,7 @@ static irqreturn_t cam_isr(int irq, void *data) /* * If exactly 2 sgbufs from the next sglist have * been programmed into the DMA engine (the - * frist one already transfered into the DMA + * first one already transferred into the DMA * runtime register set, the second one still * in the programming set), then we are in sync. */ diff --git a/drivers/media/video/omap3isp/isp.c b/drivers/media/video/omap3isp/isp.c index 1a9963bd6d40..503bd7922bd6 100644 --- a/drivers/media/video/omap3isp/isp.c +++ b/drivers/media/video/omap3isp/isp.c @@ -715,7 +715,7 @@ static int isp_pipeline_link_notify(struct media_pad *source, * Walk the entities chain starting at the pipeline output video node and start * all modules in the chain in the given mode. * - * Return 0 if successfull, or the return value of the failed video::s_stream + * Return 0 if successful, or the return value of the failed video::s_stream * operation otherwise. */ static int isp_pipeline_enable(struct isp_pipeline *pipe, @@ -883,7 +883,7 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe) * Set the pipeline to the given stream state. Pipelines can be started in * single-shot or continuous mode. * - * Return 0 if successfull, or the return value of the failed video::s_stream + * Return 0 if successful, or the return value of the failed video::s_stream * operation otherwise. */ int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe, @@ -1283,7 +1283,7 @@ static void __isp_subclk_update(struct isp_device *isp) clk |= ISPCTRL_RSZ_CLK_EN; /* NOTE: For CCDC & Preview submodules, we need to affect internal - * RAM aswell. + * RAM as well. */ if (isp->subclk_resources & OMAP3_ISP_SUBCLK_CCDC) clk |= ISPCTRL_CCDC_CLK_EN | ISPCTRL_CCDC_RAM_EN; @@ -1431,7 +1431,7 @@ static int isp_get_clocks(struct isp_device *isp) * Increment the reference count on the ISP. If the first reference is taken, * enable clocks and power-up all submodules. * - * Return a pointer to the ISP device structure, or NULL if an error occured. + * Return a pointer to the ISP device structure, or NULL if an error occurred. */ struct isp_device *omap3isp_get(struct isp_device *isp) { diff --git a/drivers/media/video/omap3isp/ispccdc.h b/drivers/media/video/omap3isp/ispccdc.h index d403af5d31d2..483a19cac1ad 100644 --- a/drivers/media/video/omap3isp/ispccdc.h +++ b/drivers/media/video/omap3isp/ispccdc.h @@ -150,7 +150,7 @@ struct ispccdc_lsc { * @input: Active input * @output: Active outputs * @video_out: Output video node - * @error: A hardware error occured during capture + * @error: A hardware error occurred during capture * @alaw: A-law compression enabled (1) or disabled (0) * @lpf: Low pass filter enabled (1) or disabled (0) * @obclamp: Optical-black clamp enabled (1) or disabled (0) @@ -163,7 +163,7 @@ struct ispccdc_lsc { * @shadow_update: Controls update in progress by userspace * @syncif: Interface synchronization configuration * @vpcfg: Video port configuration - * @underrun: A buffer underrun occured and a new buffer has been queued + * @underrun: A buffer underrun occurred and a new buffer has been queued * @state: Streaming state * @lock: Serializes shadow_update with interrupt handler * @wait: Wait queue used to stop the module diff --git a/drivers/media/video/omap3isp/ispccp2.c b/drivers/media/video/omap3isp/ispccp2.c index 0efef2e78d93..0e16cab8e089 100644 --- a/drivers/media/video/omap3isp/ispccp2.c +++ b/drivers/media/video/omap3isp/ispccp2.c @@ -772,7 +772,7 @@ static int ccp2_enum_frame_size(struct v4l2_subdev *sd, * @sd : pointer to v4l2 subdev structure * @fh : V4L2 subdev file handle * @fmt : pointer to v4l2 subdev format structure - * return -EINVAL or zero on sucess + * return -EINVAL or zero on success */ static int ccp2_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, struct v4l2_subdev_format *fmt) diff --git a/drivers/media/video/omap3isp/ispcsi2.c b/drivers/media/video/omap3isp/ispcsi2.c index fb503f3db3be..69161a682b3d 100644 --- a/drivers/media/video/omap3isp/ispcsi2.c +++ b/drivers/media/video/omap3isp/ispcsi2.c @@ -969,7 +969,7 @@ static int csi2_enum_frame_size(struct v4l2_subdev *sd, * @sd : pointer to v4l2 subdev structure * @fh : V4L2 subdev file handle * @fmt: pointer to v4l2 subdev format structure - * return -EINVAL or zero on sucess + * return -EINVAL or zero on success */ static int csi2_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, struct v4l2_subdev_format *fmt) diff --git a/drivers/media/video/omap3isp/isppreview.c b/drivers/media/video/omap3isp/isppreview.c index baf9374201dc..2b16988a501d 100644 --- a/drivers/media/video/omap3isp/isppreview.c +++ b/drivers/media/video/omap3isp/isppreview.c @@ -34,7 +34,7 @@ #include "ispreg.h" #include "isppreview.h" -/* Default values in Office Flourescent Light for RGBtoRGB Blending */ +/* Default values in Office Fluorescent Light for RGBtoRGB Blending */ static struct omap3isp_prev_rgbtorgb flr_rgb2rgb = { { /* RGB-RGB Matrix */ {0x01E2, 0x0F30, 0x0FEE}, @@ -44,7 +44,7 @@ static struct omap3isp_prev_rgbtorgb flr_rgb2rgb = { {0x0000, 0x0000, 0x0000} }; -/* Default values in Office Flourescent Light for RGB to YUV Conversion*/ +/* Default values in Office Fluorescent Light for RGB to YUV Conversion*/ static struct omap3isp_prev_csc flr_prev_csc = { { /* CSC Coef Matrix */ {66, 129, 25}, @@ -54,22 +54,22 @@ static struct omap3isp_prev_csc flr_prev_csc = { {0x0, 0x0, 0x0} }; -/* Default values in Office Flourescent Light for CFA Gradient*/ +/* Default values in Office Fluorescent Light for CFA Gradient*/ #define FLR_CFA_GRADTHRS_HORZ 0x28 #define FLR_CFA_GRADTHRS_VERT 0x28 -/* Default values in Office Flourescent Light for Chroma Suppression*/ +/* Default values in Office Fluorescent Light for Chroma Suppression*/ #define FLR_CSUP_GAIN 0x0D #define FLR_CSUP_THRES 0xEB -/* Default values in Office Flourescent Light for Noise Filter*/ +/* Default values in Office Fluorescent Light for Noise Filter*/ #define FLR_NF_STRGTH 0x03 /* Default values for White Balance */ #define FLR_WBAL_DGAIN 0x100 #define FLR_WBAL_COEF 0x20 -/* Default values in Office Flourescent Light for Black Adjustment*/ +/* Default values in Office Fluorescent Light for Black Adjustment*/ #define FLR_BLKADJ_BLUE 0x0 #define FLR_BLKADJ_GREEN 0x0 #define FLR_BLKADJ_RED 0x0 @@ -137,7 +137,7 @@ preview_enable_invalaw(struct isp_prev_device *prev, u8 enable) * @enable: 1 - Enable, 0 - Disable * * NOTE: PRV_WSDR_ADDR and PRV_WADD_OFFSET must be set also - * The proccess is applied for each captured frame. + * The process is applied for each captured frame. */ static void preview_enable_drkframe_capture(struct isp_prev_device *prev, u8 enable) @@ -157,7 +157,7 @@ preview_enable_drkframe_capture(struct isp_prev_device *prev, u8 enable) * @enable: 1 - Acquires memory bandwidth since the pixels in each frame is * subtracted with the pixels in the current frame. * - * The proccess is applied for each captured frame. + * The process is applied for each captured frame. */ static void preview_enable_drkframe(struct isp_prev_device *prev, u8 enable) @@ -1528,7 +1528,7 @@ static long preview_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) * preview_set_stream - Enable/Disable streaming on preview subdev * @sd : pointer to v4l2 subdev structure * @enable: 1 == Enable, 0 == Disable - * return -EINVAL or zero on sucess + * return -EINVAL or zero on success */ static int preview_set_stream(struct v4l2_subdev *sd, int enable) { @@ -1780,7 +1780,7 @@ static int preview_enum_frame_size(struct v4l2_subdev *sd, * @sd : pointer to v4l2 subdev structure * @fh : V4L2 subdev file handle * @fmt: pointer to v4l2 subdev format structure - * return -EINVAL or zero on sucess + * return -EINVAL or zero on success */ static int preview_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, struct v4l2_subdev_format *fmt) diff --git a/drivers/media/video/omap3isp/isppreview.h b/drivers/media/video/omap3isp/isppreview.h index f2d63ca4bd6f..fa943bd05c7f 100644 --- a/drivers/media/video/omap3isp/isppreview.h +++ b/drivers/media/video/omap3isp/isppreview.h @@ -163,7 +163,7 @@ struct isptables_update { * @output: Bitmask of the active output * @video_in: Input video entity * @video_out: Output video entity - * @error: A hardware error occured during capture + * @error: A hardware error occurred during capture * @params: Module configuration data * @shadow_update: If set, update the hardware configured in the next interrupt * @underrun: Whether the preview entity has queued buffers on the output diff --git a/drivers/media/video/omap3isp/ispqueue.h b/drivers/media/video/omap3isp/ispqueue.h index 251de3e1679d..92c5a12157d5 100644 --- a/drivers/media/video/omap3isp/ispqueue.h +++ b/drivers/media/video/omap3isp/ispqueue.h @@ -46,9 +46,9 @@ struct scatterlist; * device yet. * @ISP_BUF_STATE_ACTIVE: The buffer is in use for an active video transfer. * @ISP_BUF_STATE_ERROR: The device is done with the buffer and an error - * occured. For capture device the buffer likely contains corrupted data or + * occurred. For capture device the buffer likely contains corrupted data or * no data at all. - * @ISP_BUF_STATE_DONE: The device is done with the buffer and no error occured. + * @ISP_BUF_STATE_DONE: The device is done with the buffer and no error occurred. * For capture devices the buffer contains valid data. */ enum isp_video_buffer_state { diff --git a/drivers/media/video/omap3isp/ispresizer.c b/drivers/media/video/omap3isp/ispresizer.c index 75d39b115d42..653f88ba56db 100644 --- a/drivers/media/video/omap3isp/ispresizer.c +++ b/drivers/media/video/omap3isp/ispresizer.c @@ -751,7 +751,7 @@ static void resizer_print_status(struct isp_res_device *res) * ratio will thus result in a resizing factor slightly larger than the * requested value. * - * To accomodate that, and make sure the TRM equations are satisfied exactly, we + * To accommodate that, and make sure the TRM equations are satisfied exactly, we * compute the input crop rectangle as the last step. * * As if the situation wasn't complex enough, the maximum output width depends @@ -1386,7 +1386,7 @@ static int resizer_enum_frame_size(struct v4l2_subdev *sd, * @sd : pointer to v4l2 subdev structure * @fh : V4L2 subdev file handle * @fmt : pointer to v4l2 subdev format structure - * return -EINVAL or zero on sucess + * return -EINVAL or zero on success */ static int resizer_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, struct v4l2_subdev_format *fmt) diff --git a/drivers/media/video/omap3isp/ispvideo.c b/drivers/media/video/omap3isp/ispvideo.c index a0bb5db9cb8a..208a7ec739d7 100644 --- a/drivers/media/video/omap3isp/ispvideo.c +++ b/drivers/media/video/omap3isp/ispvideo.c @@ -494,12 +494,12 @@ static const struct isp_video_queue_operations isp_video_queue_ops = { /* * omap3isp_video_buffer_next - Complete the current buffer and return the next * @video: ISP video object - * @error: Whether an error occured during capture + * @error: Whether an error occurred during capture * * Remove the current video buffer from the DMA queue and fill its timestamp, * field count and state fields before waking up its completion handler. * - * The buffer state is set to VIDEOBUF_DONE if no error occured (@error is 0) + * The buffer state is set to VIDEOBUF_DONE if no error occurred (@error is 0) * or VIDEOBUF_ERROR otherwise (@error is non-zero). * * The DMA queue is expected to contain at least one buffer. @@ -578,7 +578,7 @@ struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video, /* * omap3isp_video_resume - Perform resume operation on the buffers * @video: ISP video object - * @continuous: Pipeline is in single shot mode if 0 or continous mode otherwise + * @continuous: Pipeline is in single shot mode if 0 or continuous mode otherwise * * This function is intended to be used on suspend/resume scenario. It * requests video queue layer to discard buffers marked as DONE if it's in diff --git a/drivers/media/video/ov6650.c b/drivers/media/video/ov6650.c index fe8e3ebd9ce4..456d9ad9ae5a 100644 --- a/drivers/media/video/ov6650.c +++ b/drivers/media/video/ov6650.c @@ -1038,7 +1038,7 @@ static int ov6650_reset(struct i2c_client *client) ret = ov6650_reg_rmw(client, REG_COMA, COMA_RESET, 0); if (ret) dev_err(&client->dev, - "An error occured while entering soft reset!\n"); + "An error occurred while entering soft reset!\n"); return ret; } diff --git a/drivers/media/video/ov9640.c b/drivers/media/video/ov9640.c index 53d88a2ab920..5173ac449dd8 100644 --- a/drivers/media/video/ov9640.c +++ b/drivers/media/video/ov9640.c @@ -273,7 +273,7 @@ static int ov9640_reset(struct i2c_client *client) ret = ov9640_reg_write(client, OV9640_COM7, OV9640_COM7_SCCB_RESET); if (ret) dev_err(&client->dev, - "An error occured while entering soft reset!\n"); + "An error occurred while entering soft reset!\n"); return ret; } diff --git a/drivers/media/video/pvrusb2/pvrusb2-eeprom.c b/drivers/media/video/pvrusb2/pvrusb2-eeprom.c index aeed1c2945fb..9515f3a68f8f 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-eeprom.c +++ b/drivers/media/video/pvrusb2/pvrusb2-eeprom.c @@ -32,7 +32,7 @@ Read and analyze data in the eeprom. Use tveeprom to figure out the packet structure, since this is another Hauppauge device and - internally it has a family resemblence to ivtv-type devices + internally it has a family resemblance to ivtv-type devices */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/drivers/media/video/pvrusb2/pvrusb2-hdw.h index 51d3009ab57f..d7753ae9ff46 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.h +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.h @@ -75,7 +75,7 @@ enum pvr2_v4l_type { * (but it might still on the bus). In this state there's nothing we can * do; it must be replugged in order to recover. * - * COLD - Device is in an unusuable state, needs microcontroller firmware. + * COLD - Device is in an unusable state, needs microcontroller firmware. * * WARM - We can communicate with the device and the proper * microcontroller firmware is running, but other device initialization is diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c index 02686771740d..c1ee09a043ba 100644 --- a/drivers/media/video/pxa_camera.c +++ b/drivers/media/video/pxa_camera.c @@ -714,7 +714,7 @@ static void pxa_camera_wakeup(struct pxa_camera_dev *pcdev, * * The DMA chaining is done with DMA running. This means a tiny temporal window * remains, where a buffer is queued on the chain, while the chain is already - * stopped. This means the tailed buffer would never be transfered by DMA. + * stopped. This means the tailed buffer would never be transferred by DMA. * This function restarts the capture for this corner case, where : * - DADR() == DADDR_STOP * - a videobuffer is queued on the pcdev->capture list diff --git a/drivers/media/video/s5p-fimc/fimc-reg.c b/drivers/media/video/s5p-fimc/fimc-reg.c index 4d929a394521..4893b2d91d84 100644 --- a/drivers/media/video/s5p-fimc/fimc-reg.c +++ b/drivers/media/video/s5p-fimc/fimc-reg.c @@ -356,7 +356,7 @@ void fimc_hw_en_capture(struct fimc_ctx *ctx) /* one shot mode */ cfg |= S5P_CIIMGCPT_CPT_FREN_ENABLE | S5P_CIIMGCPT_IMGCPTEN; } else { - /* Continous frame capture mode (freerun). */ + /* Continuous frame capture mode (freerun). */ cfg &= ~(S5P_CIIMGCPT_CPT_FREN_ENABLE | S5P_CIIMGCPT_CPT_FRMOD_CNT); cfg |= S5P_CIIMGCPT_IMGCPTEN; diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 61c6007c8ea6..50f1be05ebd3 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -7460,7 +7460,7 @@ int saa7134_board_init2(struct saa7134_dev *dev) dev->tuner_type = TUNER_PHILIPS_FM1216ME_MK3; break; default: - printk(KERN_ERR "%s Cant determine tuner type %x from EEPROM\n", dev->name, tuner_t); + printk(KERN_ERR "%s Can't determine tuner type %x from EEPROM\n", dev->name, tuner_t); } } else if ((data[1] != 0) && (data[1] != 0xff)) { /* new config structure */ @@ -7480,7 +7480,7 @@ int saa7134_board_init2(struct saa7134_dev *dev) printk(KERN_INFO "%s Board has DVB-T\n", dev->name); break; default: - printk(KERN_ERR "%s Cant determine tuner type %x from EEPROM\n", dev->name, tuner_t); + printk(KERN_ERR "%s Can't determine tuner type %x from EEPROM\n", dev->name, tuner_t); } } else { printk(KERN_ERR "%s unexpected config structure\n", dev->name); diff --git a/drivers/media/video/saa7164/saa7164-cmd.c b/drivers/media/video/saa7164/saa7164-cmd.c index 6a4c217ed3a7..62fac7f9d04e 100644 --- a/drivers/media/video/saa7164/saa7164-cmd.c +++ b/drivers/media/video/saa7164/saa7164-cmd.c @@ -257,7 +257,7 @@ out: } /* Wait for a signal event, without holding a mutex. Either return TIMEOUT if - * the event never occured, or SAA_OK if it was signaled during the wait. + * the event never occurred, or SAA_OK if it was signaled during the wait. */ int saa7164_cmd_wait(struct saa7164_dev *dev, u8 seqno) { diff --git a/drivers/media/video/saa7164/saa7164-fw.c b/drivers/media/video/saa7164/saa7164-fw.c index b369300cce06..a266bf0169e6 100644 --- a/drivers/media/video/saa7164/saa7164-fw.c +++ b/drivers/media/video/saa7164/saa7164-fw.c @@ -444,7 +444,7 @@ int saa7164_downloadfirmware(struct saa7164_dev *dev) printk(KERN_INFO " .Reserved = 0x%x\n", hdr->reserved); printk(KERN_INFO " .Version = 0x%x\n", hdr->version); - /* Retreive bootloader if reqd */ + /* Retrieve bootloader if reqd */ if ((hdr->firmwaresize == 0) && (hdr->bslsize == 0)) /* Second bootloader in the firmware file */ filesize = hdr->reserved * 16; diff --git a/drivers/media/video/saa7164/saa7164-types.h b/drivers/media/video/saa7164/saa7164-types.h index df1d2997fa6c..1d2140a3eb38 100644 --- a/drivers/media/video/saa7164/saa7164-types.h +++ b/drivers/media/video/saa7164/saa7164-types.h @@ -412,7 +412,7 @@ struct tmComResVBIFormatDescrHeader { u8 StartLine; /* NTSC Start = 10 */ u8 EndLine; /* NTSC = 21 */ u8 FieldRate; /* 60 for NTSC */ - u8 bNumLines; /* Unsed - scheduled for removal */ + u8 bNumLines; /* Unused - scheduled for removal */ } __attribute__((packed)); struct tmComResProbeCommit { diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c index ce56a1cdbf0a..0e07c493e6f0 100644 --- a/drivers/media/video/sn9c102/sn9c102_core.c +++ b/drivers/media/video/sn9c102/sn9c102_core.c @@ -1810,7 +1810,7 @@ static int sn9c102_open(struct file *filp) /* We will not release the "open_mutex" lock, so that only one process can be in the wait queue below. This way the process - will be sleeping while holding the lock, without loosing its + will be sleeping while holding the lock, without losing its priority after any wake_up(). */ err = wait_event_interruptible_exclusive(cam->wait_open, diff --git a/drivers/media/video/sn9c102/sn9c102_sensor.h b/drivers/media/video/sn9c102/sn9c102_sensor.h index 7f38549715b6..3679970dba2c 100644 --- a/drivers/media/video/sn9c102/sn9c102_sensor.h +++ b/drivers/media/video/sn9c102/sn9c102_sensor.h @@ -180,7 +180,7 @@ struct sn9c102_sensor { It should be used to initialize the sensor only, but may also configure part of the SN9C1XX chip if necessary. You don't need to setup picture settings like brightness, contrast, etc.. here, if - the corrisponding controls are implemented (see below), since + the corresponding controls are implemented (see below), since they are adjusted in the core driver by calling the set_ctrl() method after init(), where the arguments are the default values specified in the v4l2_queryctrl list of supported controls; diff --git a/drivers/media/video/tcm825x.c b/drivers/media/video/tcm825x.c index 54681a535822..b6ee1bd342dc 100644 --- a/drivers/media/video/tcm825x.c +++ b/drivers/media/video/tcm825x.c @@ -493,7 +493,7 @@ static int ioctl_g_ctrl(struct v4l2_int_device *s, int val, r; struct vcontrol *lvc; - /* exposure time is special, spread accross 2 registers */ + /* exposure time is special, spread across 2 registers */ if (vc->id == V4L2_CID_EXPOSURE) { int val_lower, val_upper; @@ -538,7 +538,7 @@ static int ioctl_s_ctrl(struct v4l2_int_device *s, struct vcontrol *lvc; int val = vc->value; - /* exposure time is special, spread accross 2 registers */ + /* exposure time is special, spread across 2 registers */ if (vc->id == V4L2_CID_EXPOSURE) { int val_lower, val_upper; val_lower = val & TCM825X_MASK(TCM825X_ESRSPD_L); diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c index a25e2b5e1944..c46a3bb95852 100644 --- a/drivers/media/video/tvaudio.c +++ b/drivers/media/video/tvaudio.c @@ -1058,11 +1058,11 @@ static int tda9874a_initialize(struct CHIPSTATE *chip) #define TDA9875_MVR 0x1b /* Main volume droite */ #define TDA9875_MBA 0x1d /* Main Basse */ #define TDA9875_MTR 0x1e /* Main treble */ -#define TDA9875_ACS 0x1f /* Auxilary channel select (FM) 0b0000000*/ -#define TDA9875_AVL 0x20 /* Auxilary volume gauche */ -#define TDA9875_AVR 0x21 /* Auxilary volume droite */ -#define TDA9875_ABA 0x22 /* Auxilary Basse */ -#define TDA9875_ATR 0x23 /* Auxilary treble */ +#define TDA9875_ACS 0x1f /* Auxiliary channel select (FM) 0b0000000*/ +#define TDA9875_AVL 0x20 /* Auxiliary volume gauche */ +#define TDA9875_AVR 0x21 /* Auxiliary volume droite */ +#define TDA9875_ABA 0x22 /* Auxiliary Basse */ +#define TDA9875_ATR 0x23 /* Auxiliary treble */ #define TDA9875_MSR 0x02 /* Monitor select register */ #define TDA9875_C1MSB 0x03 /* Carrier 1 (FM) frequency register MSB */ diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index 545c0294813d..fc766b9f24c5 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c @@ -394,11 +394,11 @@ int uvc_commit_video(struct uvc_streaming *stream, * * uvc_video_decode_end is called with header data at the end of a bulk or * isochronous payload. It performs any additional header data processing and - * returns 0 or a negative error code if an error occured. As header data have + * returns 0 or a negative error code if an error occurred. As header data have * already been processed by uvc_video_decode_start, this functions isn't * required to perform sanity checks a second time. * - * For isochronous transfers where a payload is always transfered in a single + * For isochronous transfers where a payload is always transferred in a single * URB, the three functions will be called in a row. * * To let the decoder process header data and update its internal state even @@ -658,7 +658,7 @@ static void uvc_video_decode_bulk(struct urb *urb, struct uvc_streaming *stream, buf); } while (ret == -EAGAIN); - /* If an error occured skip the rest of the payload. */ + /* If an error occurred skip the rest of the payload. */ if (ret < 0 || buf == NULL) { stream->bulk.skip_payload = 1; } else { @@ -821,7 +821,7 @@ static int uvc_alloc_urb_buffers(struct uvc_streaming *stream, return stream->urb_size / psize; /* Compute the number of packets. Bulk endpoints might transfer UVC - * payloads accross multiple URBs. + * payloads across multiple URBs. */ npackets = DIV_ROUND_UP(size, psize); if (npackets > UVC_MAX_PACKETS) diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index a01ed39e6c16..506edcc2ddeb 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c @@ -48,7 +48,7 @@ printk(KERN_CONT "%s: " fmt, vfd->name, ## arg);\ } while (0) -/* Zero out the end of the struct pointed to by p. Everthing after, but +/* Zero out the end of the struct pointed to by p. Everything after, but * not including, the specified field is cleared. */ #define CLEAR_AFTER_FIELD(p, field) \ memset((u8 *)(p) + offsetof(typeof(*(p)), field) + sizeof((p)->field), \ diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c index 75301d10a838..ca372eb911d0 100644 --- a/drivers/media/video/vpx3220.c +++ b/drivers/media/video/vpx3220.c @@ -354,7 +354,7 @@ static int vpx3220_s_std(struct v4l2_subdev *sd, v4l2_std_id std) /* Here we back up the input selection because it gets overwritten when we fill the registers with the - choosen video norm */ + chosen video norm */ temp_input = vpx3220_fp_read(sd, 0xf2); v4l2_dbg(1, debug, sd, "s_std %llx\n", (unsigned long long)std); diff --git a/drivers/media/video/zoran/videocodec.h b/drivers/media/video/zoran/videocodec.h index b654bfff8740..def55585ad23 100644 --- a/drivers/media/video/zoran/videocodec.h +++ b/drivers/media/video/zoran/videocodec.h @@ -57,7 +57,7 @@ therfor they may not be initialized. The other functions are just for convenience, as they are for sure used by - most/all of the codecs. The last ones may be ommited, too. + most/all of the codecs. The last ones may be omitted, too. See the structure declaration below for more information and which data has to be set up for the master and the slave. diff --git a/drivers/media/video/zoran/zoran.h b/drivers/media/video/zoran/zoran.h index 4bb368e6fd47..f3f640014928 100644 --- a/drivers/media/video/zoran/zoran.h +++ b/drivers/media/video/zoran/zoran.h @@ -259,7 +259,7 @@ struct card_info { struct vfe_polarity vfe_pol; u8 gpio_pol[ZR_GPIO_MAX]; - /* is the /GWS line conected? */ + /* is the /GWS line connected? */ u8 gws_not_connected; /* avs6eyes mux setting */ diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c index 7c3921de9589..2771d818406e 100644 --- a/drivers/media/video/zoran/zoran_driver.c +++ b/drivers/media/video/zoran/zoran_driver.c @@ -1254,7 +1254,7 @@ static int setup_overlay(struct zoran_fh *fh, int on) { struct zoran *zr = fh->zr; - /* If there is nothing to do, return immediatly */ + /* If there is nothing to do, return immediately */ if ((on && fh->overlay_active != ZORAN_FREE) || (!on && fh->overlay_active == ZORAN_FREE)) return 0; diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c index 57b42bfc7d23..4a1909a32b60 100644 --- a/drivers/memstick/core/mspro_block.c +++ b/drivers/memstick/core/mspro_block.c @@ -973,7 +973,7 @@ try_again: } /* Memory allocated for attributes by this function should be freed by - * mspro_block_data_clear, no matter if the initialization process succeded + * mspro_block_data_clear, no matter if the initialization process succeeded * or failed. */ static int mspro_block_read_attributes(struct memstick_dev *card) diff --git a/drivers/memstick/host/r592.c b/drivers/memstick/host/r592.c index 700d420a59ac..668f5c6a0399 100644 --- a/drivers/memstick/host/r592.c +++ b/drivers/memstick/host/r592.c @@ -796,7 +796,7 @@ static int r592_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (memstick_add_host(host)) goto error7; - message("driver succesfully loaded"); + message("driver successfully loaded"); return 0; error7: free_irq(dev->irq, dev); diff --git a/drivers/memstick/host/r592.h b/drivers/memstick/host/r592.h index eee264e6028f..c5726c1e8832 100644 --- a/drivers/memstick/host/r592.h +++ b/drivers/memstick/host/r592.h @@ -43,12 +43,12 @@ /* Error detection via CRC */ #define R592_STATUS_SEND_ERR (1 << 24) /* Send failed */ -#define R592_STATUS_RECV_ERR (1 << 25) /* Recieve failed */ +#define R592_STATUS_RECV_ERR (1 << 25) /* Receive failed */ /* Card state */ -#define R592_STATUS_RDY (1 << 28) /* RDY signal recieved */ +#define R592_STATUS_RDY (1 << 28) /* RDY signal received */ #define R592_STATUS_CED (1 << 29) /* INT: Command done (serial mode)*/ -#define R592_STATUS_SFIFO_INPUT (1 << 30) /* Small fifo recieved data*/ +#define R592_STATUS_SFIFO_INPUT (1 << 30) /* Small fifo received data*/ #define R592_SFIFO_SIZE 32 /* total size of small fifo is 32 bytes */ #define R592_SFIFO_PACKET 8 /* packet size of small fifo */ diff --git a/drivers/message/fusion/lsi/mpi_log_fc.h b/drivers/message/fusion/lsi/mpi_log_fc.h index face6e7acc72..03be8b217709 100644 --- a/drivers/message/fusion/lsi/mpi_log_fc.h +++ b/drivers/message/fusion/lsi/mpi_log_fc.h @@ -38,8 +38,8 @@ typedef enum _MpiIocLogInfoFc { MPI_IOCLOGINFO_FC_INIT_BASE = 0x20000000, MPI_IOCLOGINFO_FC_INIT_ERROR_OUT_OF_ORDER_FRAME = 0x20000001, /* received an out of order frame - unsupported */ - MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_START_OF_FRAME = 0x20000002, /* Bad Rx Frame, bad start of frame primative */ - MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_END_OF_FRAME = 0x20000003, /* Bad Rx Frame, bad end of frame primative */ + MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_START_OF_FRAME = 0x20000002, /* Bad Rx Frame, bad start of frame primitive */ + MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_END_OF_FRAME = 0x20000003, /* Bad Rx Frame, bad end of frame primitive */ MPI_IOCLOGINFO_FC_INIT_ERROR_OVER_RUN = 0x20000004, /* Bad Rx Frame, overrun */ MPI_IOCLOGINFO_FC_INIT_ERROR_RX_OTHER = 0x20000005, /* Other errors caught by IOC which require retries */ MPI_IOCLOGINFO_FC_INIT_ERROR_SUBPROC_DEAD = 0x20000006, /* Main processor could not initialize sub-processor */ diff --git a/drivers/message/fusion/lsi/mpi_log_sas.h b/drivers/message/fusion/lsi/mpi_log_sas.h index 8b04810df469..f62960b5d527 100644 --- a/drivers/message/fusion/lsi/mpi_log_sas.h +++ b/drivers/message/fusion/lsi/mpi_log_sas.h @@ -56,9 +56,9 @@ #define IOP_LOGINFO_CODE_FWUPLOAD_NO_FLASH_AVAILABLE (0x0003E000) /* Tried to upload from flash, but there is none */ #define IOP_LOGINFO_CODE_FWUPLOAD_UNKNOWN_IMAGE_TYPE (0x0003E001) /* ImageType field contents were invalid */ #define IOP_LOGINFO_CODE_FWUPLOAD_WRONG_IMAGE_SIZE (0x0003E002) /* ImageSize field in TCSGE was bad/offset in MfgPg 4 was wrong */ -#define IOP_LOGINFO_CODE_FWUPLOAD_ENTIRE_FLASH_UPLOAD_FAILED (0x0003E003) /* Error occured while attempting to upload the entire flash */ -#define IOP_LOGINFO_CODE_FWUPLOAD_REGION_UPLOAD_FAILED (0x0003E004) /* Error occured while attempting to upload single flash region */ -#define IOP_LOGINFO_CODE_FWUPLOAD_DMA_FAILURE (0x0003E005) /* Problem occured while DMAing FW to host memory */ +#define IOP_LOGINFO_CODE_FWUPLOAD_ENTIRE_FLASH_UPLOAD_FAILED (0x0003E003) /* Error occurred while attempting to upload the entire flash */ +#define IOP_LOGINFO_CODE_FWUPLOAD_REGION_UPLOAD_FAILED (0x0003E004) /* Error occurred while attempting to upload single flash region */ +#define IOP_LOGINFO_CODE_FWUPLOAD_DMA_FAILURE (0x0003E005) /* Problem occurred while DMAing FW to host memory */ #define IOP_LOGINFO_CODE_DIAG_MSG_ERROR (0x00040000) /* Error handling diag msg - or'd with diag status */ @@ -187,8 +187,8 @@ #define PL_LOGINFO_SUB_CODE_BREAK_ON_INCOMPLETE_BREAK_RCVD (0x00005000) #define PL_LOGINFO_CODE_ENCL_MGMT_SMP_FRAME_FAILURE (0x00200000) /* Can't get SMP Frame */ -#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_READ_ERROR (0x00200010) /* Error occured on SMP Read */ -#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_WRITE_ERROR (0x00200020) /* Error occured on SMP Write */ +#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_READ_ERROR (0x00200010) /* Error occurred on SMP Read */ +#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_WRITE_ERROR (0x00200020) /* Error occurred on SMP Write */ #define PL_LOGINFO_CODE_ENCL_MGMT_NOT_SUPPORTED_ON_ENCL (0x00200040) /* Encl Mgmt services not available for this WWID */ #define PL_LOGINFO_CODE_ENCL_MGMT_ADDR_MODE_NOT_SUPPORTED (0x00200050) /* Address Mode not suppored */ #define PL_LOGINFO_CODE_ENCL_MGMT_BAD_SLOT_NUM (0x00200060) /* Invalid Slot Number in SEP Msg */ @@ -207,8 +207,8 @@ #define PL_LOGINFO_DA_SEP_RECEIVED_NACK_FROM_SLAVE (0x00200103) /* SEP NACK'd, it is busy */ #define PL_LOGINFO_DA_SEP_DID_NOT_RECEIVE_ACK (0x00200104) /* SEP didn't rcv. ACK (Last Rcvd Bit = 1) */ #define PL_LOGINFO_DA_SEP_BAD_STATUS_HDR_CHKSUM (0x00200105) /* SEP stopped or sent bad chksum in Hdr */ -#define PL_LOGINFO_DA_SEP_STOP_ON_DATA (0x00200106) /* SEP stopped while transfering data */ -#define PL_LOGINFO_DA_SEP_STOP_ON_SENSE_DATA (0x00200107) /* SEP stopped while transfering sense data */ +#define PL_LOGINFO_DA_SEP_STOP_ON_DATA (0x00200106) /* SEP stopped while transferring data */ +#define PL_LOGINFO_DA_SEP_STOP_ON_SENSE_DATA (0x00200107) /* SEP stopped while transferring sense data */ #define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_1 (0x00200108) /* SEP returned unknown scsi status */ #define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_2 (0x00200109) /* SEP returned unknown scsi status */ #define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP (0x0020010A) /* SEP returned bad chksum after STOP */ diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index ec8080c98081..fa15e853d4e8 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -3435,7 +3435,7 @@ SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag) * If memory has already been allocated, the same (cached) value * is returned. * - * Return 0 if successfull, or non-zero for failure + * Return 0 if successful, or non-zero for failure **/ int mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size) @@ -6932,7 +6932,7 @@ EXPORT_SYMBOL(mpt_halt_firmware); * Message Unit Reset - instructs the IOC to reset the Reply Post and * Free FIFO's. All the Message Frames on Reply Free FIFO are discarded. * All posted buffers are freed, and event notification is turned off. - * IOC doesnt reply to any outstanding request. This will transfer IOC + * IOC doesn't reply to any outstanding request. This will transfer IOC * to READY state. **/ int @@ -7905,7 +7905,7 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info) "Owner", /* 15h */ "Open Transmit DMA Abort", /* 16h */ "IO Device Missing Delay Retry", /* 17h */ - "IO Cancelled Due to Recieve Error", /* 18h */ + "IO Cancelled Due to Receive Error", /* 18h */ NULL, /* 19h */ NULL, /* 1Ah */ NULL, /* 1Bh */ diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index 878bda0cce70..6e6e16aab9da 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -985,7 +985,7 @@ retry_wait: ReplyMsg = (pFWDownloadReply_t)iocp->ioctl_cmds.reply; iocstat = le16_to_cpu(ReplyMsg->IOCStatus) & MPI_IOCSTATUS_MASK; if (iocstat == MPI_IOCSTATUS_SUCCESS) { - printk(MYIOC_s_INFO_FMT "F/W update successfull!\n", iocp->name); + printk(MYIOC_s_INFO_FMT "F/W update successful!\n", iocp->name); return 0; } else if (iocstat == MPI_IOCSTATUS_INVALID_FUNCTION) { printk(MYIOC_s_WARN_FMT "Hmmm... F/W download not supported!?!\n", @@ -2407,7 +2407,7 @@ done_free_mem: } /* mf is null if command issued successfully - * otherwise, failure occured after mf acquired. + * otherwise, failure occurred after mf acquired. */ if (mf) mpt_free_msg_frame(ioc, mf); diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index f5a14afad2cd..66f94125de4e 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -307,7 +307,7 @@ mptsas_requeue_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event, spin_unlock_irqrestore(&ioc->fw_event_lock, flags); } -/* free memory assoicated to a sas firmware event */ +/* free memory associated to a sas firmware event */ static void mptsas_free_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event) { @@ -1094,7 +1094,7 @@ mptsas_block_io_starget(struct scsi_target *starget) /** * mptsas_target_reset_queue * - * Receive request for TARGET_RESET after recieving an firmware + * Receive request for TARGET_RESET after receiving an firmware * event NOT_RESPONDING_EVENT, then put command in link list * and queue if task_queue already in use. * @@ -1403,7 +1403,7 @@ mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure, /** * mptsas_add_end_device - report a new end device to sas transport layer * @ioc: Pointer to MPT_ADAPTER structure - * @phy_info: decribes attached device + * @phy_info: describes attached device * * return (0) success (1) failure * @@ -1481,7 +1481,7 @@ mptsas_add_end_device(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info) /** * mptsas_del_end_device - report a deleted end device to sas transport layer * @ioc: Pointer to MPT_ADAPTER structure - * @phy_info: decribes attached device + * @phy_info: describes attached device * **/ static void diff --git a/drivers/message/i2o/README b/drivers/message/i2o/README index 911fc3021e3b..f072a8eb3041 100644 --- a/drivers/message/i2o/README +++ b/drivers/message/i2o/README @@ -53,7 +53,7 @@ Symbios Logic (Now LSI) BoxHill Corporation Loan of initial FibreChannel disk array used for development work. -European Comission +European Commission Funding the work done by the University of Helsinki SysKonnect diff --git a/drivers/message/i2o/device.c b/drivers/message/i2o/device.c index 0ee4264f5db7..4547db99f7da 100644 --- a/drivers/message/i2o/device.c +++ b/drivers/message/i2o/device.c @@ -65,7 +65,7 @@ int i2o_device_claim(struct i2o_device *dev) rc = i2o_device_issue_claim(dev, I2O_CMD_UTIL_CLAIM, I2O_CLAIM_PRIMARY); if (!rc) - pr_debug("i2o: claim of device %d succeded\n", + pr_debug("i2o: claim of device %d succeeded\n", dev->lct_data.tid); else pr_debug("i2o: claim of device %d failed %d\n", @@ -110,7 +110,7 @@ int i2o_device_claim_release(struct i2o_device *dev) } if (!rc) - pr_debug("i2o: claim release of device %d succeded\n", + pr_debug("i2o: claim release of device %d succeeded\n", dev->lct_data.tid); else pr_debug("i2o: claim release of device %d failed %d\n", @@ -248,7 +248,7 @@ static int i2o_device_add(struct i2o_controller *c, i2o_lct_entry *entry) goto unreg_dev; } - /* create user entries refering to this device */ + /* create user entries referring to this device */ list_for_each_entry(tmp, &c->devices, list) if ((tmp->lct_data.user_tid == i2o_dev->lct_data.tid) && (tmp != i2o_dev)) { @@ -267,7 +267,7 @@ static int i2o_device_add(struct i2o_controller *c, i2o_lct_entry *entry) goto rmlink1; } - /* create parent entries refering to this device */ + /* create parent entries referring to this device */ list_for_each_entry(tmp, &c->devices, list) if ((tmp->lct_data.parent_tid == i2o_dev->lct_data.tid) && (tmp != i2o_dev)) { diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c index 47ec5bc0ed21..643ad52e3ca2 100644 --- a/drivers/message/i2o/i2o_block.c +++ b/drivers/message/i2o/i2o_block.c @@ -610,7 +610,7 @@ static int i2o_block_release(struct gendisk *disk, fmode_t mode) /* * This is to deail with the case of an application - * opening a device and then the device dissapears while + * opening a device and then the device disappears while * it's in use, and then the application tries to release * it. ex: Unmounting a deleted RAID volume at reboot. * If we send messages, it will just cause FAILs since @@ -717,7 +717,7 @@ static unsigned int i2o_block_check_events(struct gendisk *disk, /** * i2o_block_transfer - Transfer a request to/from the I2O controller - * @req: the request which should be transfered + * @req: the request which should be transferred * * This function converts the request into a I2O message. The necessary * DMA buffers are allocated and after everything is setup post the message diff --git a/drivers/message/i2o/i2o_block.h b/drivers/message/i2o/i2o_block.h index 67f921b4419b..cf8873cbca3f 100644 --- a/drivers/message/i2o/i2o_block.h +++ b/drivers/message/i2o/i2o_block.h @@ -73,7 +73,7 @@ struct i2o_block_device { struct i2o_device *i2o_dev; /* pointer to I2O device */ struct gendisk *gd; spinlock_t lock; /* queue lock */ - struct list_head open_queue; /* list of transfered, but unfinished + struct list_head open_queue; /* list of transferred, but unfinished requests */ unsigned int open_queue_depth; /* number of requests in the queue */ diff --git a/drivers/message/i2o/i2o_scsi.c b/drivers/message/i2o/i2o_scsi.c index 97bdf82ec905..f003957e8e1c 100644 --- a/drivers/message/i2o/i2o_scsi.c +++ b/drivers/message/i2o/i2o_scsi.c @@ -204,7 +204,7 @@ static int i2o_scsi_remove(struct device *dev) * i2o_scsi_probe - verify if dev is a I2O SCSI device and install it * @dev: device to verify if it is a I2O SCSI device * - * Retrieve channel, id and lun for I2O device. If everthing goes well + * Retrieve channel, id and lun for I2O device. If everything goes well * register the I2O device as SCSI device on the I2O SCSI controller. * * Returns 0 on success or negative error code on failure. diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index e2fea580585a..3ed3ff06be5d 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -201,7 +201,7 @@ config TWL4030_POWER as clock request handshaking. This driver uses board-specific data to initialize the resources - and load scripts controling which resources are switched off/on + and load scripts controlling which resources are switched off/on or reset when a sleep, wakeup or warm reset event occurs. config TWL4030_CODEC diff --git a/drivers/mfd/ab8500-gpadc.c b/drivers/mfd/ab8500-gpadc.c index bc93b2e8230c..6421ad1160de 100644 --- a/drivers/mfd/ab8500-gpadc.c +++ b/drivers/mfd/ab8500-gpadc.c @@ -314,7 +314,7 @@ int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input) /* wait for completion of conversion */ if (!wait_for_completion_timeout(&gpadc->ab8500_gpadc_complete, 2*HZ)) { dev_err(gpadc->dev, - "timeout: didnt recieve GPADC conversion interrupt\n"); + "timeout: didn't receive GPADC conversion interrupt\n"); ret = -EINVAL; goto out; } diff --git a/drivers/mfd/ezx-pcap.c b/drivers/mfd/ezx-pcap.c index f2f4029e21a0..43a76c41cfcc 100644 --- a/drivers/mfd/ezx-pcap.c +++ b/drivers/mfd/ezx-pcap.c @@ -185,7 +185,7 @@ static void pcap_isr_work(struct work_struct *work) ezx_pcap_read(pcap, PCAP_REG_MSR, &msr); ezx_pcap_read(pcap, PCAP_REG_ISR, &isr); - /* We cant service/ack irqs that are assigned to port 2 */ + /* We can't service/ack irqs that are assigned to port 2 */ if (!(pdata->config & PCAP_SECOND_PORT)) { ezx_pcap_read(pcap, PCAP_REG_INT_SEL, &int_sel); isr &= ~int_sel; @@ -457,7 +457,7 @@ static int __devinit ezx_pcap_probe(struct spi_device *spi) pcap->workqueue = create_singlethread_workqueue("pcapd"); if (!pcap->workqueue) { ret = -ENOMEM; - dev_err(&spi->dev, "cant create pcap thread\n"); + dev_err(&spi->dev, "can't create pcap thread\n"); goto free_pcap; } diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c index cb01209754e0..53450f433f10 100644 --- a/drivers/mfd/omap-usb-host.c +++ b/drivers/mfd/omap-usb-host.c @@ -332,7 +332,7 @@ static int __devinit usbhs_omap_probe(struct platform_device *pdev) int i; if (!pdata) { - dev_err(dev, "Missing platfrom data\n"); + dev_err(dev, "Missing platform data\n"); ret = -ENOMEM; goto end_probe; } diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c index c7687f6a78a0..57868416c760 100644 --- a/drivers/mfd/pcf50633-core.c +++ b/drivers/mfd/pcf50633-core.c @@ -51,7 +51,7 @@ static int __pcf50633_write(struct pcf50633 *pcf, u8 reg, int num, u8 *data) } -/* Read a block of upto 32 regs */ +/* Read a block of up to 32 regs */ int pcf50633_read_block(struct pcf50633 *pcf, u8 reg, int nr_regs, u8 *data) { @@ -65,7 +65,7 @@ int pcf50633_read_block(struct pcf50633 *pcf, u8 reg, } EXPORT_SYMBOL_GPL(pcf50633_read_block); -/* Write a block of upto 32 regs */ +/* Write a block of up to 32 regs */ int pcf50633_write_block(struct pcf50633 *pcf , u8 reg, int nr_regs, u8 *data) { diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c index fa937052fbab..dfbae34e1804 100644 --- a/drivers/mfd/twl6030-irq.c +++ b/drivers/mfd/twl6030-irq.c @@ -229,7 +229,7 @@ int twl6030_mmc_card_detect_config(void) twl6030_interrupt_unmask(TWL6030_MMCDETECT_INT_MASK, REG_INT_MSK_STS_B); /* - * Intially Configuring MMC_CTRL for receving interrupts & + * Initially Configuring MMC_CTRL for receiving interrupts & * Card status on TWL6030 for MMC1 */ ret = twl_i2c_read_u8(TWL6030_MODULE_ID0, ®_val, TWL6030_MMCCTRL); @@ -275,7 +275,7 @@ int twl6030_mmc_card_detect(struct device *dev, int slot) /* TWL6030 provide's Card detect support for * only MMC1 controller. */ - pr_err("Unkown MMC controller %d in %s\n", pdev->id, __func__); + pr_err("Unknown MMC controller %d in %s\n", pdev->id, __func__); return ret; } /* diff --git a/drivers/mfd/ucb1400_core.c b/drivers/mfd/ucb1400_core.c index d73f84ba0f08..daf69527ed83 100644 --- a/drivers/mfd/ucb1400_core.c +++ b/drivers/mfd/ucb1400_core.c @@ -8,7 +8,7 @@ * Copyright: MontaVista Software, Inc. * * Spliting done by: Marek Vasut - * If something doesnt work and it worked before spliting, e-mail me, + * If something doesn't work and it worked before spliting, e-mail me, * dont bother Nicolas please ;-) * * This program is free software; you can redistribute it and/or modify diff --git a/drivers/misc/bmp085.c b/drivers/misc/bmp085.c index ecd276ad6b19..5f898cb706a6 100644 --- a/drivers/misc/bmp085.c +++ b/drivers/misc/bmp085.c @@ -2,7 +2,7 @@ This driver supports the bmp085 digital barometric pressure and temperature sensor from Bosch Sensortec. The datasheet - is avaliable from their website: + is available from their website: http://www.bosch-sensortec.com/content/language1/downloads/BST-BMP085-DS000-05.pdf A pressure measurement is issued by reading from pressure0_input. @@ -429,7 +429,7 @@ static int __devinit bmp085_probe(struct i2c_client *client, if (err) goto exit_free; - dev_info(&data->client->dev, "Succesfully initialized bmp085!\n"); + dev_info(&data->client->dev, "Successfully initialized bmp085!\n"); goto exit; exit_free: diff --git a/drivers/misc/c2port/c2port-duramar2150.c b/drivers/misc/c2port/c2port-duramar2150.c index 338dcc121507..778fc3fdfb9b 100644 --- a/drivers/misc/c2port/c2port-duramar2150.c +++ b/drivers/misc/c2port/c2port-duramar2150.c @@ -41,7 +41,7 @@ static void duramar2150_c2port_access(struct c2port_device *dev, int status) outb(v | (C2D | C2CK), DIR_PORT); else /* When access is "off" is important that both lines are set - * as inputs or hi-impedence */ + * as inputs or hi-impedance */ outb(v & ~(C2D | C2CK), DIR_PORT); mutex_unlock(&update_lock); diff --git a/drivers/misc/ibmasm/remote.h b/drivers/misc/ibmasm/remote.h index 72acf5af7a2a..00dbf1d4373a 100644 --- a/drivers/misc/ibmasm/remote.h +++ b/drivers/misc/ibmasm/remote.h @@ -20,7 +20,7 @@ * * Author: Max Asböck * - * Orignally written by Pete Reynolds + * Originally written by Pete Reynolds */ #ifndef _IBMASM_REMOTE_H_ diff --git a/drivers/misc/iwmc3200top/main.c b/drivers/misc/iwmc3200top/main.c index 727af07f1fbd..b1f4563be9ae 100644 --- a/drivers/misc/iwmc3200top/main.c +++ b/drivers/misc/iwmc3200top/main.c @@ -268,7 +268,7 @@ static void iwmct_irq_read_worker(struct work_struct *ws) LOG_INFO(priv, IRQ, "ACK barker arrived " "- starting FW download\n"); } else { /* REBOOT barker */ - LOG_INFO(priv, IRQ, "Recieved reboot barker: %x\n", barker); + LOG_INFO(priv, IRQ, "Received reboot barker: %x\n", barker); priv->barker = barker; if (barker & BARKER_DNLOAD_SYNC_MSK) { diff --git a/drivers/misc/kgdbts.c b/drivers/misc/kgdbts.c index 27dc463097f3..74f16f167b8e 100644 --- a/drivers/misc/kgdbts.c +++ b/drivers/misc/kgdbts.c @@ -645,7 +645,7 @@ static int validate_simple_test(char *put_str) while (*chk_str != '\0' && *put_str != '\0') { /* If someone does a * to match the rest of the string, allow - * it, or stop if the recieved string is complete. + * it, or stop if the received string is complete. */ if (*put_str == '#' || *chk_str == '*') return 0; diff --git a/drivers/misc/sgi-gru/grukservices.c b/drivers/misc/sgi-gru/grukservices.c index 34749ee88dfa..9e9bddaa95ae 100644 --- a/drivers/misc/sgi-gru/grukservices.c +++ b/drivers/misc/sgi-gru/grukservices.c @@ -229,7 +229,7 @@ again: bid = blade_id < 0 ? uv_numa_blade_id() : blade_id; bs = gru_base[bid]; - /* Handle the case where migration occured while waiting for the sema */ + /* Handle the case where migration occurred while waiting for the sema */ down_read(&bs->bs_kgts_sema); if (blade_id < 0 && bid != uv_numa_blade_id()) { up_read(&bs->bs_kgts_sema); diff --git a/drivers/misc/sgi-gru/grutables.h b/drivers/misc/sgi-gru/grutables.h index 7a8b9068ea03..5c3ce2459675 100644 --- a/drivers/misc/sgi-gru/grutables.h +++ b/drivers/misc/sgi-gru/grutables.h @@ -379,7 +379,7 @@ struct gru_thread_state { required for contest */ char ts_cch_req_slice;/* CCH packet slice */ char ts_blade; /* If >= 0, migrate context if - ref from diferent blade */ + ref from different blade */ char ts_force_cch_reload; char ts_cbr_idx[GRU_CBR_AU];/* CBR numbers of each allocated CB */ diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c index 9ee4c788aa69..b4488c8f6b23 100644 --- a/drivers/misc/ti-st/st_kim.c +++ b/drivers/misc/ti-st/st_kim.c @@ -649,7 +649,7 @@ static int kim_probe(struct platform_device *pdev) /* multiple devices could exist */ st_kim_devices[pdev->id] = pdev; } else { - /* platform's sure about existance of 1 device */ + /* platform's sure about existence of 1 device */ st_kim_devices[0] = pdev; } diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c index f5cedeccad42..abc1a63bcc5e 100644 --- a/drivers/mmc/card/mmc_test.c +++ b/drivers/mmc/card/mmc_test.c @@ -292,7 +292,7 @@ static void mmc_test_free_mem(struct mmc_test_mem *mem) } /* - * Allocate a lot of memory, preferrably max_sz but at least min_sz. In case + * Allocate a lot of memory, preferably max_sz but at least min_sz. In case * there isn't much memory do not exceed 1/16th total lowmem pages. Also do * not exceed a maximum number of segments and try not to make segments much * bigger than maximum segment size. diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 14e95f39a7bf..772d0d0a541b 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -538,7 +538,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, /* * If enhanced_area_en is TRUE, host needs to enable ERASE_GRP_DEF - * bit. This bit will be lost everytime after a reset or power off. + * bit. This bit will be lost every time after a reset or power off. */ if (card->ext_csd.enhanced_area_en) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index 60842f878ded..f3b22bf89cc9 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c @@ -105,7 +105,7 @@ int mmc_go_idle(struct mmc_host *host) * that in case of hardware that won't pull up DAT3/nCS otherwise. * * SPI hosts ignore ios.chip_select; it's managed according to - * rules that must accomodate non-MMC slaves which this layer + * rules that must accommodate non-MMC slaves which this layer * won't even know about. */ if (!mmc_host_is_spi(host)) { diff --git a/drivers/mmc/core/sdio_irq.c b/drivers/mmc/core/sdio_irq.c index bb192f90e8e9..b3001617e67d 100644 --- a/drivers/mmc/core/sdio_irq.c +++ b/drivers/mmc/core/sdio_irq.c @@ -45,7 +45,7 @@ static int process_sdio_pending_irqs(struct mmc_card *card) struct sdio_func *func = card->sdio_func[i - 1]; if (!func) { printk(KERN_WARNING "%s: pending IRQ for " - "non-existant function\n", + "non-existent function\n", mmc_card_id(card)); ret = -EINVAL; } else if (func->irq_handler) { diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 80bc9a5c25cc..ea3888b65d5d 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -127,7 +127,7 @@ struct atmel_mci_dma { * EVENT_DATA_COMPLETE is set in @pending_events, all data-related * interrupts must be disabled and @data_status updated with a * snapshot of SR. Similarly, before EVENT_CMD_COMPLETE is set, the - * CMDRDY interupt must be disabled and @cmd_status updated with a + * CMDRDY interrupt must be disabled and @cmd_status updated with a * snapshot of SR, and before EVENT_XFER_COMPLETE can be set, the * bytes_xfered field of @data must be written. This is ensured by * using barriers. @@ -1082,7 +1082,7 @@ static void atmci_request_end(struct atmel_mci *host, struct mmc_request *mrq) /* * Update the MMC clock rate if necessary. This may be * necessary if set_ios() is called when a different slot is - * busy transfering data. + * busy transferring data. */ if (host->need_clock_update) { mci_writel(host, MR, host->mode_reg); diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index 2f7fc0c5146f..7c1e16aaf17f 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c @@ -99,7 +99,7 @@ #define r1b_timeout (HZ * 3) /* One of the critical speed parameters is the amount of data which may - * be transfered in one command. If this value is too low, the SD card + * be transferred in one command. If this value is too low, the SD card * controller has to do multiple partial block writes (argggh!). With * today (2008) SD cards there is little speed gain if we transfer more * than 64 KBytes at a time. So use this value until there is any indication diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 1ccd4b256cee..a04f87d7ee3d 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c @@ -874,7 +874,7 @@ static void finalize_request(struct s3cmci_host *host) if (!mrq->data) goto request_done; - /* Calulate the amout of bytes transfer if there was no error */ + /* Calculate the amout of bytes transfer if there was no error */ if (mrq->data->error == 0) { mrq->data->bytes_xfered = (mrq->data->blocks * mrq->data->blksz); @@ -882,7 +882,7 @@ static void finalize_request(struct s3cmci_host *host) mrq->data->bytes_xfered = 0; } - /* If we had an error while transfering data we flush the + /* If we had an error while transferring data we flush the * DMA channel and the fifo to clear out any garbage. */ if (mrq->data->error != 0) { if (s3cmci_host_usedma(host)) @@ -980,7 +980,7 @@ static int s3cmci_setup_data(struct s3cmci_host *host, struct mmc_data *data) if ((data->blksz & 3) != 0) { /* We cannot deal with unaligned blocks with more than - * one block being transfered. */ + * one block being transferred. */ if (data->blocks > 1) { pr_warning("%s: can't do non-word sized block transfers (blksz %d)\n", __func__, data->blksz); diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c index 6ae8d2f00ec7..62d37de6de76 100644 --- a/drivers/mmc/host/tmio_mmc_pio.c +++ b/drivers/mmc/host/tmio_mmc_pio.c @@ -355,7 +355,7 @@ static int tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command /* * This chip always returns (at least?) as much data as you ask for. * I'm unsure what happens if you ask for less than a block. This should be - * looked into to ensure that a funny length read doesnt hose the controller. + * looked into to ensure that a funny length read doesn't hose the controller. */ static void tmio_mmc_pio_irq(struct tmio_mmc_host *host) { diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c index 7fca0a386ba0..62e5a4d171e1 100644 --- a/drivers/mmc/host/wbsd.c +++ b/drivers/mmc/host/wbsd.c @@ -484,7 +484,7 @@ static void wbsd_fill_fifo(struct wbsd_host *host) /* * Check that we aren't being called after the - * entire buffer has been transfered. + * entire buffer has been transferred. */ if (host->num_sg == 0) return; @@ -828,7 +828,7 @@ static void wbsd_request(struct mmc_host *mmc, struct mmc_request *mrq) /* * If this is a data transfer the request * will be finished after the data has - * transfered. + * transferred. */ if (cmd->data && !cmd->error) { /* @@ -904,7 +904,7 @@ static void wbsd_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) setup &= ~WBSD_DAT3_H; /* - * We cannot resume card detection immediatly + * We cannot resume card detection immediately * because of capacitance and delays in the chip. */ mod_timer(&host->ignore_timer, jiffies + HZ / 100); diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig index 35c6a23b183b..b1e3c26edd6d 100644 --- a/drivers/mtd/chips/Kconfig +++ b/drivers/mtd/chips/Kconfig @@ -19,7 +19,7 @@ config MTD_JEDECPROBE help This option enables JEDEC-style probing of flash chips which are not compatible with the Common Flash Interface, but will use the common - CFI-targetted flash drivers for any chips which are identified which + CFI-targeted flash drivers for any chips which are identified which are in fact compatible in all but the probe method. This actually covers most AMD/Fujitsu-compatible chips and also non-CFI Intel chips. diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index 092aef11120c..09cb7c8d93b4 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -1247,12 +1247,12 @@ static int inval_cache_and_wait_for_operation( break; if (chip->erase_suspended && chip_state == FL_ERASING) { - /* Erase suspend occured while sleep: reset timeout */ + /* Erase suspend occurred while sleep: reset timeout */ timeo = reset_timeo; chip->erase_suspended = 0; } if (chip->write_suspended && chip_state == FL_WRITING) { - /* Write suspend occured while sleep: reset timeout */ + /* Write suspend occurred while sleep: reset timeout */ timeo = reset_timeo; chip->write_suspended = 0; } diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index f9a5331e9445..0b49266840b9 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c @@ -263,7 +263,7 @@ static void fixup_old_sst_eraseregion(struct mtd_info *mtd) struct cfi_private *cfi = map->fldrv_priv; /* - * These flashes report two seperate eraseblock regions based on the + * These flashes report two separate eraseblock regions based on the * sector_erase-size and block_erase-size, although they both operate on the * same memory. This is not allowed according to CFI, so we just pick the * sector_erase-size. @@ -611,8 +611,8 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd) * * Note that anything more complicated than checking if no bits are toggling * (including checking DQ5 for an error status) is tricky to get working - * correctly and is therefore not done (particulary with interleaved chips - * as each chip must be checked independantly of the others). + * correctly and is therefore not done (particularly with interleaved chips + * as each chip must be checked independently of the others). */ static int __xipram chip_ready(struct map_info *map, unsigned long addr) { @@ -635,8 +635,8 @@ static int __xipram chip_ready(struct map_info *map, unsigned long addr) * * Note that anything more complicated than checking if no bits are toggling * (including checking DQ5 for an error status) is tricky to get working - * correctly and is therefore not done (particulary with interleaved chips - * as each chip must be checked independantly of the others). + * correctly and is therefore not done (particularly with interleaved chips + * as each chip must be checked independently of the others). * */ static int __xipram chip_good(struct map_info *map, unsigned long addr, map_word expected) diff --git a/drivers/mtd/chips/cfi_util.c b/drivers/mtd/chips/cfi_util.c index 6ae3d111e1e7..8e464054a631 100644 --- a/drivers/mtd/chips/cfi_util.c +++ b/drivers/mtd/chips/cfi_util.c @@ -1,6 +1,6 @@ /* * Common Flash Interface support: - * Generic utility functions not dependant on command set + * Generic utility functions not dependent on command set * * Copyright (C) 2002 Red Hat * Copyright (C) 2003 STMicroelectronics Limited diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c index 4e1be51cc122..ea832ea0e4aa 100644 --- a/drivers/mtd/chips/jedec_probe.c +++ b/drivers/mtd/chips/jedec_probe.c @@ -2075,7 +2075,7 @@ static inline int jedec_match( uint32_t base, } /* - * Make sure the ID's dissappear when the device is taken out of + * Make sure the ID's disappear when the device is taken out of * ID mode. The only time this should fail when it should succeed * is when the ID's are written as data to the same * addresses. For this rare and unfortunate case the chip diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c index f29a6f9df6e7..97183c8c9e33 100644 --- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c @@ -295,7 +295,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size) dev->mtd.owner = THIS_MODULE; if (add_mtd_device(&dev->mtd)) { - /* Device didnt get added, so free the entry */ + /* Device didn't get added, so free the entry */ goto devinit_err; } list_add(&dev->list, &blkmtd_device_list); diff --git a/drivers/mtd/devices/doc2001plus.c b/drivers/mtd/devices/doc2001plus.c index 719b2915dc3a..8b36fa77a195 100644 --- a/drivers/mtd/devices/doc2001plus.c +++ b/drivers/mtd/devices/doc2001plus.c @@ -90,7 +90,7 @@ static inline int DoC_WaitReady(void __iomem * docptr) return ret; } -/* For some reason the Millennium Plus seems to occassionally put itself +/* For some reason the Millennium Plus seems to occasionally put itself * into reset mode. For me this happens randomly, with no pattern that I * can detect. M-systems suggest always check this on any block level * operation and setting to normal mode if in reset mode. diff --git a/drivers/mtd/devices/docecc.c b/drivers/mtd/devices/docecc.c index a99838bb2dc0..37ef29a73ee4 100644 --- a/drivers/mtd/devices/docecc.c +++ b/drivers/mtd/devices/docecc.c @@ -109,7 +109,7 @@ for(ci=(n)-1;ci >=0;ci--)\ of the integer "alpha_to[i]" with a(0) being the LSB and a(m-1) the MSB. Thus for example the polynomial representation of @^5 would be given by the binary representation of the integer "alpha_to[5]". - Similarily, index_of[] can be used as follows: + Similarly, index_of[] can be used as follows: As above, let @ represent the primitive element of GF(2^m) that is the root of the primitive polynomial p(x). In order to find the power of @ (alpha) that has the polynomial representation @@ -121,7 +121,7 @@ for(ci=(n)-1;ci >=0;ci--)\ NOTE: The element alpha_to[2^m-1] = 0 always signifying that the representation of "@^infinity" = 0 is (0,0,0,...,0). - Similarily, the element index_of[0] = A0 always signifying + Similarly, the element index_of[0] = A0 always signifying that the power of alpha which has the polynomial representation (0,0,...,0) is "infinity". diff --git a/drivers/mtd/devices/lart.c b/drivers/mtd/devices/lart.c index caf604167f03..4b829f97d56c 100644 --- a/drivers/mtd/devices/lart.c +++ b/drivers/mtd/devices/lart.c @@ -353,7 +353,7 @@ static inline int erase_block (__u32 offset) /* put the flash back into command mode */ write32 (DATA_TO_FLASH (READ_ARRAY),offset); - /* was the erase successfull? */ + /* was the erase successful? */ if ((status & STATUS_ERASE_ERR)) { printk (KERN_WARNING "%s: erase error at address 0x%.8x.\n",module_name,offset); @@ -508,7 +508,7 @@ static inline int write_dword (__u32 offset,__u32 x) /* put the flash back into command mode */ write32 (DATA_TO_FLASH (READ_ARRAY),offset); - /* was the write successfull? */ + /* was the write successful? */ if ((status & STATUS_PGM_ERR) || read32 (offset) != x) { printk (KERN_WARNING "%s: write error at address 0x%.8x.\n",module_name,offset); diff --git a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c index ef0aba0ce58f..41b8cdcc64cb 100644 --- a/drivers/mtd/devices/pmc551.c +++ b/drivers/mtd/devices/pmc551.c @@ -351,7 +351,7 @@ static int pmc551_write(struct mtd_info *mtd, loff_t to, size_t len, * Fixup routines for the V370PDC * PCI device ID 0x020011b0 * - * This function basicly kick starts the DRAM oboard the card and gets it + * This function basically kick starts the DRAM oboard the card and gets it * ready to be used. Before this is done the device reads VERY erratic, so * much that it can crash the Linux 2.2.x series kernels when a user cat's * /proc/pci .. though that is mainly a kernel bug in handling the PCI DEVSEL @@ -540,7 +540,7 @@ static u32 fixup_pmc551(struct pci_dev *dev) /* * Check to make certain the DEVSEL is set correctly, this device - * has a tendancy to assert DEVSEL and TRDY when a write is performed + * has a tendency to assert DEVSEL and TRDY when a write is performed * to the memory when memory is read-only */ if ((cmd & PCI_STATUS_DEVSEL_MASK) != 0x0) { diff --git a/drivers/mtd/lpddr/lpddr_cmds.c b/drivers/mtd/lpddr/lpddr_cmds.c index 04fdfcca93f7..12679925b420 100644 --- a/drivers/mtd/lpddr/lpddr_cmds.c +++ b/drivers/mtd/lpddr/lpddr_cmds.c @@ -3,7 +3,7 @@ * erase, lock/unlock support for LPDDR flash memories * (C) 2008 Korolev Alexey * (C) 2008 Vasiliy Leonenko - * Many thanks to Roman Borisov for intial enabling + * Many thanks to Roman Borisov for initial enabling * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -171,7 +171,7 @@ static int wait_for_ready(struct map_info *map, struct flchip *chip, mutex_lock(&chip->mutex); } if (chip->erase_suspended || chip->write_suspended) { - /* Suspend has occured while sleep: reset timeout */ + /* Suspend has occurred while sleep: reset timeout */ timeo = reset_timeo; chip->erase_suspended = chip->write_suspended = 0; } diff --git a/drivers/mtd/maps/ceiva.c b/drivers/mtd/maps/ceiva.c index e5f645b775ad..23f551dc8ca8 100644 --- a/drivers/mtd/maps/ceiva.c +++ b/drivers/mtd/maps/ceiva.c @@ -42,7 +42,7 @@ * * Please note: * 1. The flash size given should be the largest flash size that can - * be accomodated. + * be accommodated. * * 2. The bus width must defined in clps_setup_flash. * @@ -58,7 +58,7 @@ #define BOOT_PARTITION_SIZE_KiB (16) #define PARAMS_PARTITION_SIZE_KiB (8) #define KERNEL_PARTITION_SIZE_KiB (4*128) -/* Use both remaing portion of first flash, and all of second flash */ +/* Use both remaining portion of first flash, and all of second flash */ #define ROOT_PARTITION_SIZE_KiB (3*128) + (8*128) static struct mtd_partition ceiva_partitions[] = { diff --git a/drivers/mtd/maps/cfi_flagadm.c b/drivers/mtd/maps/cfi_flagadm.c index b4ed81611918..f71343cd77cc 100644 --- a/drivers/mtd/maps/cfi_flagadm.c +++ b/drivers/mtd/maps/cfi_flagadm.c @@ -33,7 +33,7 @@ /* We split the flash chip up into four parts. - * 1: bootloader firts 128k (0x00000000 - 0x0001FFFF) size 0x020000 + * 1: bootloader first 128k (0x00000000 - 0x0001FFFF) size 0x020000 * 2: kernel 640k (0x00020000 - 0x000BFFFF) size 0x0A0000 * 3: compressed 1536k root ramdisk (0x000C0000 - 0x0023FFFF) size 0x180000 * 4: writeable diskpartition (jffs)(0x00240000 - 0x003FFFFF) size 0x1C0000 diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c index 917022948399..6799e75d74e0 100644 --- a/drivers/mtd/maps/pcmciamtd.c +++ b/drivers/mtd/maps/pcmciamtd.c @@ -497,7 +497,7 @@ static int pcmciamtd_config(struct pcmcia_device *link) dev->pcmcia_map.set_vpp = pcmciamtd_set_vpp; /* Request a memory window for PCMCIA. Some architeures can map windows - * upto the maximum that PCMCIA can support (64MiB) - this is ideal and + * up to the maximum that PCMCIA can support (64MiB) - this is ideal and * we aim for a window the size of the whole card - otherwise we try * smaller windows until we succeed */ diff --git a/drivers/mtd/maps/pmcmsp-flash.c b/drivers/mtd/maps/pmcmsp-flash.c index acb13fa5001c..64aea6acd48e 100644 --- a/drivers/mtd/maps/pmcmsp-flash.c +++ b/drivers/mtd/maps/pmcmsp-flash.c @@ -3,7 +3,7 @@ * Config with both CFI and JEDEC device support. * * Basically physmap.c with the addition of partitions and - * an array of mapping info to accomodate more than one flash type per board. + * an array of mapping info to accommodate more than one flash type per board. * * Copyright 2005-2007 PMC-Sierra, Inc. * diff --git a/drivers/mtd/maps/sc520cdp.c b/drivers/mtd/maps/sc520cdp.c index 85c1e56309ec..4d8aaaf4bb76 100644 --- a/drivers/mtd/maps/sc520cdp.c +++ b/drivers/mtd/maps/sc520cdp.c @@ -197,7 +197,7 @@ static void sc520cdp_setup_par(void) } /* - ** Find the PARxx registers that are reponsible for activating + ** Find the PARxx registers that are responsible for activating ** ROMCS0, ROMCS1 and BOOTCS. Reprogram each of these with a ** new value from the table. */ diff --git a/drivers/mtd/maps/tqm8xxl.c b/drivers/mtd/maps/tqm8xxl.c index c08e140d40ed..0718dfb3ee64 100644 --- a/drivers/mtd/maps/tqm8xxl.c +++ b/drivers/mtd/maps/tqm8xxl.c @@ -63,7 +63,7 @@ static void __iomem *start_scan_addr; */ #ifdef CONFIG_MTD_PARTITIONS -/* Currently, TQM8xxL has upto 8MiB flash */ +/* Currently, TQM8xxL has up to 8MiB flash */ static unsigned long tqm8xxl_max_flash_size = 0x00800000; /* partition definition for first flash bank diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c index 1e74ad961040..3326615ad66b 100644 --- a/drivers/mtd/mtdblock.c +++ b/drivers/mtd/mtdblock.c @@ -129,7 +129,7 @@ static int write_cached_data (struct mtdblk_dev *mtdblk) return ret; /* - * Here we could argubly set the cache state to STATE_CLEAN. + * Here we could arguably set the cache state to STATE_CLEAN. * However this could lead to inconsistency since we will not * be notified if this content is altered on the flash by other * means. Let's declare it empty and leave buffering tasks to diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 145b3d0dc0db..4c36ef66a46b 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -234,7 +234,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t * the data. For our userspace tools it is important * to dump areas with ecc errors ! * For kernel internal usage it also might return -EUCLEAN - * to signal the caller that a bitflip has occured and has + * to signal the caller that a bitflip has occurred and has * been corrected by the ECC algorithm. * Userspace software which accesses NAND this way * must be aware of the fact that it deals with NAND diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index a92054e945e1..edec457d361d 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -239,7 +239,7 @@ config MTD_NAND_BCM_UMI help This enables the NAND flash controller on the BCM UMI block. - No board specfic support is done by this driver, each board + No board specific support is done by this driver, each board must advertise a platform_device for the driver to attach. config MTD_NAND_BCM_UMI_HWCS diff --git a/drivers/mtd/nand/ams-delta.c b/drivers/mtd/nand/ams-delta.c index a067d090cb31..bc65bf71e1a2 100644 --- a/drivers/mtd/nand/ams-delta.c +++ b/drivers/mtd/nand/ams-delta.c @@ -228,7 +228,7 @@ static int __devinit ams_delta_init(struct platform_device *pdev) AMS_DELTA_LATCH2_NAND_NCE | AMS_DELTA_LATCH2_NAND_NWP); - /* Scan to find existance of the device */ + /* Scan to find existence of the device */ if (nand_scan(ams_delta_mtd, 1)) { err = -ENXIO; goto out_mtd; diff --git a/drivers/mtd/nand/autcpu12.c b/drivers/mtd/nand/autcpu12.c index 7c95da1f612c..0911cf03db80 100644 --- a/drivers/mtd/nand/autcpu12.c +++ b/drivers/mtd/nand/autcpu12.c @@ -176,7 +176,7 @@ static int __init autcpu12_init(void) */ this->options = NAND_USE_FLASH_BBT; - /* Scan to find existance of the device */ + /* Scan to find existence of the device */ if (nand_scan(autcpu12_mtd, 1)) { err = -ENXIO; goto out_ior; diff --git a/drivers/mtd/nand/cs553x_nand.c b/drivers/mtd/nand/cs553x_nand.c index 9f1b451005ca..71c35a0b9826 100644 --- a/drivers/mtd/nand/cs553x_nand.c +++ b/drivers/mtd/nand/cs553x_nand.c @@ -241,7 +241,7 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr) /* Enable the following for a flash based bad block table */ this->options = NAND_USE_FLASH_BBT | NAND_NO_AUTOINCR; - /* Scan to find existance of the device */ + /* Scan to find existence of the device */ if (nand_scan(new_mtd, 1)) { err = -ENXIO; goto out_ior; diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c index 8c8d3c86c0e8..4633f094c510 100644 --- a/drivers/mtd/nand/denali.c +++ b/drivers/mtd/nand/denali.c @@ -724,7 +724,7 @@ static uint32_t wait_for_irq(struct denali_nand_info *denali, uint32_t irq_mask) } /* This helper function setups the registers for ECC and whether or not - * the spare area will be transfered. */ + * the spare area will be transferred. */ static void setup_ecc_for_xfer(struct denali_nand_info *denali, bool ecc_en, bool transfer_spare) { @@ -965,7 +965,7 @@ static bool handle_ecc(struct denali_nand_info *denali, uint8_t *buf, if (ECC_ERROR_CORRECTABLE(err_correction_info)) { /* If err_byte is larger than ECC_SECTOR_SIZE, - * means error happend in OOB, so we ignore + * means error happened in OOB, so we ignore * it. It's no need for us to correct it * err_device is represented the NAND error * bits are happened in if there are more @@ -1109,7 +1109,7 @@ static void denali_write_page(struct mtd_info *mtd, struct nand_chip *chip, } /* This is the callback that the NAND core calls to write a page without ECC. - * raw access is similiar to ECC page writes, so all the work is done in the + * raw access is similar to ECC page writes, so all the work is done in the * write_page() function above. */ static void denali_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip, diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c index b7f8de7b2780..96c0b34ba8db 100644 --- a/drivers/mtd/nand/diskonchip.c +++ b/drivers/mtd/nand/diskonchip.c @@ -137,7 +137,7 @@ static struct rs_control *rs_decoder; * * Fabrice Bellard figured this out in the old docecc code. I added * some comments, improved a minor bit and converted it to make use - * of the generic Reed-Solomon libary. tglx + * of the generic Reed-Solomon library. tglx */ static int doc_ecc_decode(struct rs_control *rs, uint8_t *data, uint8_t *ecc) { @@ -400,7 +400,7 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr) doc200x_hwcontrol(mtd, 0, NAND_CTRL_ALE | NAND_CTRL_CHANGE); doc200x_hwcontrol(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); - /* We cant' use dev_ready here, but at least we wait for the + /* We can't' use dev_ready here, but at least we wait for the * command to complete */ udelay(50); @@ -986,7 +986,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, dummy = ReadDOC(docptr, ECCConf); } - /* Error occured ? */ + /* Error occurred ? */ if (dummy & 0x80) { for (i = 0; i < 6; i++) { if (DoC_is_MillenniumPlus(doc)) @@ -1160,7 +1160,7 @@ static inline int __init nftl_partscan(struct mtd_info *mtd, struct mtd_partitio /* NOTE: The lines below modify internal variables of the NAND and MTD layers; variables with have already been configured by nand_scan. Unfortunately, we didn't know before this point what these values - should be. Thus, this code is somewhat dependant on the exact + should be. Thus, this code is somewhat dependent on the exact implementation of the NAND layer. */ if (mh->UnitSizeFactor != 0xff) { this->bbt_erase_shift += (0xff - mh->UnitSizeFactor); diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index 7a13d42cbabd..537e380b8dcb 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -59,7 +59,7 @@ struct fsl_elbc_mtd { unsigned int fmr; /* FCM Flash Mode Register value */ }; -/* Freescale eLBC FCM controller infomation */ +/* Freescale eLBC FCM controller information */ struct fsl_elbc_fcm_ctrl { struct nand_hw_control controller; diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c index 205b10b9f9b9..0d45ef3883e8 100644 --- a/drivers/mtd/nand/fsmc_nand.c +++ b/drivers/mtd/nand/fsmc_nand.c @@ -335,7 +335,7 @@ static void fsmc_enable_hwecc(struct mtd_info *mtd, int mode) /* * fsmc_read_hwecc_ecc4 - Hardware ECC calculator for ecc4 option supported by - * FSMC. ECC is 13 bytes for 512 bytes of data (supports error correction upto + * FSMC. ECC is 13 bytes for 512 bytes of data (supports error correction up to * max of 8-bits) */ static int fsmc_read_hwecc_ecc4(struct mtd_info *mtd, const uint8_t *data, @@ -381,7 +381,7 @@ static int fsmc_read_hwecc_ecc4(struct mtd_info *mtd, const uint8_t *data, /* * fsmc_read_hwecc_ecc1 - Hardware ECC calculator for ecc1 option supported by - * FSMC. ECC is 3 bytes for 512 bytes of data (supports error correction upto + * FSMC. ECC is 3 bytes for 512 bytes of data (supports error correction up to * max of 1-bit) */ static int fsmc_read_hwecc_ecc1(struct mtd_info *mtd, const uint8_t *data, @@ -408,10 +408,10 @@ static int fsmc_read_hwecc_ecc1(struct mtd_info *mtd, const uint8_t *data, * @buf: buffer to store read data * @page: page number to read * - * This routine is needed for fsmc verison 8 as reading from NAND chip has to be + * This routine is needed for fsmc version 8 as reading from NAND chip has to be * performed in a strict sequence as follows: * data(512 byte) -> ecc(13 byte) - * After this read, fsmc hardware generates and reports error data bits(upto a + * After this read, fsmc hardware generates and reports error data bits(up to a * max of 8 bits) */ static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, @@ -686,7 +686,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) } /* - * Scan to find existance of the device + * Scan to find existence of the device */ if (nand_scan_ident(&host->mtd, 1, NULL)) { ret = -ENXIO; diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 85cfc061d41c..c54a4cbac6bc 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -1582,7 +1582,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, } /** - * nand_read - [MTD Interface] MTD compability function for nand_do_read_ecc + * nand_read - [MTD Interface] MTD compatibility function for nand_do_read_ecc * @mtd: MTD device structure * @from: offset to read from * @len: number of bytes to read diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index a1e8b30078d9..af46428286fe 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -945,7 +945,7 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc rd2 = NULL; /* Per chip or per device ? */ chipsel = (td->options & NAND_BBT_PERCHIP) ? i : -1; - /* Mirrored table avilable ? */ + /* Mirrored table available ? */ if (md) { if (td->pages[i] == -1 && md->pages[i] == -1) { writeops = 0x03; diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index 213181be0d9a..893d95bfea48 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c @@ -162,7 +162,7 @@ MODULE_PARM_DESC(bitflips, "Maximum number of random bit flips per page (z MODULE_PARM_DESC(gravepages, "Pages that lose data [: maximum reads (defaults to 3)]" " separated by commas e.g. 1401:2 means page 1401" " can be read only twice before failing"); -MODULE_PARM_DESC(rptwear, "Number of erases inbetween reporting wear, if not zero"); +MODULE_PARM_DESC(rptwear, "Number of erases between reporting wear, if not zero"); MODULE_PARM_DESC(overridesize, "Specifies the NAND Flash size overriding the ID bytes. " "The size is specified in erase blocks and as the exponent of a power of two" " e.g. 5 means a size of 32 erase blocks"); diff --git a/drivers/mtd/nand/nomadik_nand.c b/drivers/mtd/nand/nomadik_nand.c index 8c0b69375224..a045a4a581b6 100644 --- a/drivers/mtd/nand/nomadik_nand.c +++ b/drivers/mtd/nand/nomadik_nand.c @@ -151,7 +151,7 @@ static int nomadik_nand_probe(struct platform_device *pdev) nand->options = pdata->options; /* - * Scan to find existance of the device + * Scan to find existence of the device */ if (nand_scan(&host->mtd, 1)) { ret = -ENXIO; diff --git a/drivers/mtd/nand/pasemi_nand.c b/drivers/mtd/nand/pasemi_nand.c index 59efa829ef24..20bfe5f15afd 100644 --- a/drivers/mtd/nand/pasemi_nand.c +++ b/drivers/mtd/nand/pasemi_nand.c @@ -157,7 +157,7 @@ static int __devinit pasemi_nand_probe(struct platform_device *ofdev) /* Enable the following for a flash based bad block table */ chip->options = NAND_USE_FLASH_BBT | NAND_NO_AUTOINCR; - /* Scan to find existance of the device */ + /* Scan to find existence of the device */ if (nand_scan(pasemi_nand_mtd, 1)) { err = -ENXIO; goto out_lpc; diff --git a/drivers/mtd/nand/plat_nand.c b/drivers/mtd/nand/plat_nand.c index 317aff428e42..caf5a736340a 100644 --- a/drivers/mtd/nand/plat_nand.c +++ b/drivers/mtd/nand/plat_nand.c @@ -95,7 +95,7 @@ static int __devinit plat_nand_probe(struct platform_device *pdev) goto out; } - /* Scan to find existance of the device */ + /* Scan to find existence of the device */ if (nand_scan(&data->mtd, pdata->chip.nr_chips)) { err = -ENXIO; goto out; diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index ab7f4c33ced6..ff0701276d65 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -184,7 +184,7 @@ struct pxa3xx_nand_info { static int use_dma = 1; module_param(use_dma, bool, 0444); -MODULE_PARM_DESC(use_dma, "enable DMA for data transfering to/from NAND HW"); +MODULE_PARM_DESC(use_dma, "enable DMA for data transferring to/from NAND HW"); /* * Default NAND flash controller configuration setup by the diff --git a/drivers/mtd/nand/r852.c b/drivers/mtd/nand/r852.c index 6322d1fb5d62..cae2e013c986 100644 --- a/drivers/mtd/nand/r852.c +++ b/drivers/mtd/nand/r852.c @@ -185,7 +185,7 @@ static void r852_do_dma(struct r852_device *dev, uint8_t *buf, int do_read) dbg_verbose("doing dma %s ", do_read ? "read" : "write"); - /* Set intial dma state: for reading first fill on board buffer, + /* Set initial dma state: for reading first fill on board buffer, from device, for writes first fill the buffer from memory*/ dev->dma_state = do_read ? DMA_INTERNAL : DMA_MEMORY; @@ -766,7 +766,7 @@ static irqreturn_t r852_irq(int irq, void *data) ret = IRQ_HANDLED; dev->card_detected = !!(card_status & R852_CARD_IRQ_INSERT); - /* we shouldn't recieve any interrupts if we wait for card + /* we shouldn't receive any interrupts if we wait for card to settle */ WARN_ON(dev->card_unstable); @@ -794,13 +794,13 @@ static irqreturn_t r852_irq(int irq, void *data) ret = IRQ_HANDLED; if (dma_status & R852_DMA_IRQ_ERROR) { - dbg("recieved dma error IRQ"); + dbg("received dma error IRQ"); r852_dma_done(dev, -EIO); complete(&dev->dma_done); goto out; } - /* recieved DMA interrupt out of nowhere? */ + /* received DMA interrupt out of nowhere? */ WARN_ON_ONCE(dev->dma_stage == 0); if (dev->dma_stage == 0) @@ -960,7 +960,7 @@ int r852_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) &dev->card_detect_work, 0); - printk(KERN_NOTICE DRV_NAME ": driver loaded succesfully\n"); + printk(KERN_NOTICE DRV_NAME ": driver loaded successfully\n"); return 0; error10: diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c index 546c2f0eb2e8..81bbb5ee148d 100644 --- a/drivers/mtd/nand/sh_flctl.c +++ b/drivers/mtd/nand/sh_flctl.c @@ -78,7 +78,7 @@ static void start_translation(struct sh_flctl *flctl) static void timeout_error(struct sh_flctl *flctl, const char *str) { - dev_err(&flctl->pdev->dev, "Timeout occured in %s\n", str); + dev_err(&flctl->pdev->dev, "Timeout occurred in %s\n", str); } static void wait_completion(struct sh_flctl *flctl) diff --git a/drivers/mtd/nand/sm_common.c b/drivers/mtd/nand/sm_common.c index 4a8f367c295c..57cc80cd01a3 100644 --- a/drivers/mtd/nand/sm_common.c +++ b/drivers/mtd/nand/sm_common.c @@ -121,7 +121,7 @@ int sm_register_device(struct mtd_info *mtd, int smartmedia) if (ret) return ret; - /* Bad block marker postion */ + /* Bad block marker position */ chip->badblockpos = 0x05; chip->badblockbits = 7; chip->block_markbad = sm_block_markbad; diff --git a/drivers/mtd/nand/tmio_nand.c b/drivers/mtd/nand/tmio_nand.c index 38fb16771f85..14c578707824 100644 --- a/drivers/mtd/nand/tmio_nand.c +++ b/drivers/mtd/nand/tmio_nand.c @@ -4,7 +4,7 @@ * Slightly murky pre-git history of the driver: * * Copyright (c) Ian Molton 2004, 2005, 2008 - * Original work, independant of sharps code. Included hardware ECC support. + * Original work, independent of sharps code. Included hardware ECC support. * Hard ECC did not work for writes in the early revisions. * Copyright (c) Dirk Opfer 2005. * Modifications developed from sharps code but diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c index f591f615d3f6..1fcb41adab07 100644 --- a/drivers/mtd/onenand/omap2.c +++ b/drivers/mtd/onenand/omap2.c @@ -608,7 +608,7 @@ static int omap2_onenand_enable(struct mtd_info *mtd) ret = regulator_enable(c->regulator); if (ret != 0) - dev_err(&c->pdev->dev, "cant enable regulator\n"); + dev_err(&c->pdev->dev, "can't enable regulator\n"); return ret; } @@ -620,7 +620,7 @@ static int omap2_onenand_disable(struct mtd_info *mtd) ret = regulator_disable(c->regulator); if (ret != 0) - dev_err(&c->pdev->dev, "cant disable regulator\n"); + dev_err(&c->pdev->dev, "can't disable regulator\n"); return ret; } diff --git a/drivers/mtd/onenand/onenand_sim.c b/drivers/mtd/onenand/onenand_sim.c index 8b246061d511..5ef3bd547772 100644 --- a/drivers/mtd/onenand/onenand_sim.c +++ b/drivers/mtd/onenand/onenand_sim.c @@ -321,7 +321,7 @@ static void onenand_data_handle(struct onenand_chip *this, int cmd, continue; if (memcmp(dest + off, ffchars, this->subpagesize) && onenand_check_overwrite(dest + off, src + off, this->subpagesize)) - printk(KERN_ERR "over-write happend at 0x%08x\n", offset); + printk(KERN_ERR "over-write happened at 0x%08x\n", offset); memcpy(dest + off, src + off, this->subpagesize); } /* Fall through */ @@ -335,7 +335,7 @@ static void onenand_data_handle(struct onenand_chip *this, int cmd, dest = ONENAND_CORE_SPARE(flash, this, offset); if (memcmp(dest, ffchars, mtd->oobsize) && onenand_check_overwrite(dest, src, mtd->oobsize)) - printk(KERN_ERR "OOB: over-write happend at 0x%08x\n", + printk(KERN_ERR "OOB: over-write happened at 0x%08x\n", offset); memcpy(dest, src, mtd->oobsize); break; diff --git a/drivers/mtd/sm_ftl.c b/drivers/mtd/sm_ftl.c index 2b0daae4018d..ed3d6cd2c6dc 100644 --- a/drivers/mtd/sm_ftl.c +++ b/drivers/mtd/sm_ftl.c @@ -540,7 +540,7 @@ static int sm_check_block(struct sm_ftl *ftl, int zone, int block) return -EIO; } - /* If the block is sliced (partialy erased usually) erase it */ + /* If the block is sliced (partially erased usually) erase it */ if (i == 2) { sm_erase_block(ftl, zone, block, 1); return 1; @@ -878,7 +878,7 @@ static int sm_init_zone(struct sm_ftl *ftl, int zone_num) return 0; } -/* Get and automaticly initialize an FTL mapping for one zone */ +/* Get and automatically initialize an FTL mapping for one zone */ struct ftl_zone *sm_get_zone(struct sm_ftl *ftl, int zone_num) { struct ftl_zone *zone; diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index 11eb8ef12485..d2d12ab7def4 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -968,7 +968,7 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, * contains garbage because of a power cut during erase * operation. So we just schedule this PEB for erasure. * - * Besides, in case of NOR flash, we deliberatly + * Besides, in case of NOR flash, we deliberately * corrupt both headers because NOR flash erasure is * slow and can start from the end. */ diff --git a/drivers/net/3c501.c b/drivers/net/3c501.c index 9e1c03eb97ae..5420f6de27df 100644 --- a/drivers/net/3c501.c +++ b/drivers/net/3c501.c @@ -399,7 +399,7 @@ static void el_timeout(struct net_device *dev) * as we may still be attempting to retrieve the last RX packet buffer. * * When a transmit times out we dump the card into control mode and just - * start again. It happens enough that it isnt worth logging. + * start again. It happens enough that it isn't worth logging. * * We avoid holding the spin locks when doing the packet load to the board. * The device is very slow, and its DMA mode is even slower. If we held the @@ -499,7 +499,7 @@ static netdev_tx_t el_start_xmit(struct sk_buff *skb, struct net_device *dev) * * Handle the ether interface interrupts. The 3c501 needs a lot more * hand holding than most cards. In particular we get a transmit interrupt - * with a collision error because the board firmware isnt capable of rewinding + * with a collision error because the board firmware isn't capable of rewinding * its own transmit buffer pointers. It can however count to 16 for us. * * On the receive side the card is also very dumb. It has no buffering to @@ -732,7 +732,7 @@ static void el_receive(struct net_device *dev) * el_reset: Reset a 3c501 card * @dev: The 3c501 card about to get zapped * - * Even resetting a 3c501 isnt simple. When you activate reset it loses all + * Even resetting a 3c501 isn't simple. When you activate reset it loses all * its configuration. You must hold the lock when doing this. The function * cannot take the lock itself as it is callable from the irq handler. */ diff --git a/drivers/net/3c523.c b/drivers/net/3c523.c index de579d043169..bc0d1a1c2e28 100644 --- a/drivers/net/3c523.c +++ b/drivers/net/3c523.c @@ -44,7 +44,7 @@ this for the 64K version would require a lot of heinous bank switching, which I'm sure not interested in doing. If you try to implement a bank switching version, you'll basically have to remember - what bank is enabled and do a switch everytime you access a memory + what bank is enabled and do a switch every time you access a memory location that's not current. You'll also have to remap pointers on the driver side, because it only knows about 16K of the memory. Anyone desperate or masochistic enough to try? diff --git a/drivers/net/3c527.c b/drivers/net/3c527.c index 8c094bae8bf3..d9d056d207f3 100644 --- a/drivers/net/3c527.c +++ b/drivers/net/3c527.c @@ -51,7 +51,7 @@ DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " Richard Procter tx_csm != ap->tx_ret_csm) { printk(KERN_WARNING "%s: Transmitter is stuck, %08x\n", @@ -2564,7 +2564,7 @@ restart: /* * A TX-descriptor producer (an IRQ) might have gotten - * inbetween, making the ring free again. Since xmit is + * between, making the ring free again. Since xmit is * serialized, this is the only situation we have to * re-test. */ diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c index 2ca880b4c0db..88495c48a81d 100644 --- a/drivers/net/amd8111e.c +++ b/drivers/net/amd8111e.c @@ -1398,7 +1398,7 @@ static void amd8111e_set_multicast_list(struct net_device *dev) mc_filter[1] = mc_filter[0] = 0; lp->options &= ~OPTION_MULTICAST_ENABLE; amd8111e_writeq(*(u64*)mc_filter,lp->mmio + LADRF); - /* disable promiscous mode */ + /* disable promiscuous mode */ writel(PROM, lp->mmio + CMD2); return; } diff --git a/drivers/net/at1700.c b/drivers/net/at1700.c index f4744fc89768..65a78f965dd2 100644 --- a/drivers/net/at1700.c +++ b/drivers/net/at1700.c @@ -133,7 +133,7 @@ struct net_local { /* Run-time register bank 2 definitions. */ #define DATAPORT 8 /* Word-wide DMA or programmed-I/O dataport. */ #define TX_START 10 -#define COL16CNTL 11 /* Controll Reg for 16 collisions */ +#define COL16CNTL 11 /* Control Reg for 16 collisions */ #define MODE13 13 #define RX_CTRL 14 /* Configuration registers only on the '865A/B chips. */ diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c index 1ff001a8270c..b0a71e2f28a9 100644 --- a/drivers/net/atl1e/atl1e_main.c +++ b/drivers/net/atl1e/atl1e_main.c @@ -2509,7 +2509,7 @@ static struct pci_driver atl1e_driver = { .id_table = atl1e_pci_tbl, .probe = atl1e_probe, .remove = __devexit_p(atl1e_remove), - /* Power Managment Hooks */ + /* Power Management Hooks */ #ifdef CONFIG_PM .suspend = atl1e_suspend, .resume = atl1e_resume, diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c index e637e9f28fd4..f46ee4546fdc 100644 --- a/drivers/net/atlx/atl2.c +++ b/drivers/net/atlx/atl2.c @@ -1701,7 +1701,7 @@ static struct pci_driver atl2_driver = { .id_table = atl2_pci_tbl, .probe = atl2_probe, .remove = __devexit_p(atl2_remove), - /* Power Managment Hooks */ + /* Power Management Hooks */ .suspend = atl2_suspend, #ifdef CONFIG_PM .resume = atl2_resume, diff --git a/drivers/net/bcm63xx_enet.c b/drivers/net/bcm63xx_enet.c index e94a966af418..c48104b08861 100644 --- a/drivers/net/bcm63xx_enet.c +++ b/drivers/net/bcm63xx_enet.c @@ -597,7 +597,7 @@ static int bcm_enet_set_mac_address(struct net_device *dev, void *p) } /* - * Change rx mode (promiscous/allmulti) and update multicast list + * Change rx mode (promiscuous/allmulti) and update multicast list */ static void bcm_enet_set_multicast_list(struct net_device *dev) { diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 5a4a87e7c5ea..1e2d825bb94a 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -1331,7 +1331,7 @@ err: /* * Uses MCC for this command as it may be called in BH context - * (mc == NULL) => multicast promiscous + * (mc == NULL) => multicast promiscuous */ int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id, struct net_device *netdev, struct be_dma_mem *mem) diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index a71163f1e34b..9a54c8b24ff9 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -708,7 +708,7 @@ static void be_set_multicast_list(struct net_device *netdev) goto done; } - /* BE was previously in promiscous mode; disable it */ + /* BE was previously in promiscuous mode; disable it */ if (adapter->promiscuous) { adapter->promiscuous = false; be_cmd_promiscuous_config(adapter, adapter->port_num, 0); diff --git a/drivers/net/bna/bna_hw.h b/drivers/net/bna/bna_hw.h index 806b224a4c63..6cb89692f5c1 100644 --- a/drivers/net/bna/bna_hw.h +++ b/drivers/net/bna/bna_hw.h @@ -897,7 +897,7 @@ static struct bna_ritseg_pool_cfg name[BFI_RIT_SEG_TOTAL_POOLS] = \ * Catapult RSS Table Base Offset Address * * Exists in RAD memory space. - * Each entry is 352 bits, but alligned on + * Each entry is 352 bits, but aligned on * 64 byte (512 bit) boundary. Accessed * 4 byte words, the whole entry can be * broken into 11 word accesses. diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index b7ff87b35fbb..e0fca701d2f3 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -1220,7 +1220,7 @@ struct bnx2x { struct bnx2x_dcbx_port_params dcbx_port_params; int dcb_version; - /* DCBX Negotation results */ + /* DCBX Negotiation results */ struct dcbx_features dcbx_local_feat; u32 dcbx_error; u32 pending_max; diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h index be503cc0a50b..dac1bf9cbbfa 100644 --- a/drivers/net/bnx2x/bnx2x_hsi.h +++ b/drivers/net/bnx2x/bnx2x_hsi.h @@ -3019,7 +3019,7 @@ struct tstorm_eth_mac_filter_config { /* - * common flag to indicate existance of TPA. + * common flag to indicate existence of TPA. */ struct tstorm_eth_tpa_exist { #if defined(__BIG_ENDIAN) diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index f2f367d4e74d..974ef2be36a5 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -2823,7 +2823,7 @@ static u16 bnx2x_wait_reset_complete(struct bnx2x *bp, struct link_params *params) { u16 cnt, ctrl; - /* Wait for soft reset to get cleared upto 1 sec */ + /* Wait for soft reset to get cleared up to 1 sec */ for (cnt = 0; cnt < 1000; cnt++) { bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, &ctrl); @@ -4141,7 +4141,7 @@ static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy, val = (1<<5); /* * Note that 2.5G works only when used with 1G - * advertisment + * advertisement */ } else val = (1<<5); @@ -4151,7 +4151,7 @@ static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy, PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) val |= (1<<7); - /* Note that 2.5G works only when used with 1G advertisment */ + /* Note that 2.5G works only when used with 1G advertisement */ if (phy->speed_cap_mask & (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G | PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)) @@ -5232,14 +5232,14 @@ static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy, bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 1); } else { - /* Force 1Gbps using autoneg with 1G advertisment */ + /* Force 1Gbps using autoneg with 1G advertisement */ /* Allow CL37 through CL73 */ DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n"); bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c); - /* Enable Full-Duplex advertisment on CL37 */ + /* Enable Full-Duplex advertisement on CL37 */ bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LP, 0x0020); /* Enable CL37 AN */ @@ -6269,7 +6269,7 @@ static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy, switch (actual_phy_selection) { case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT: - /* Do nothing. Essentialy this is like the priority copper */ + /* Do nothing. Essentially this is like the priority copper */ break; case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY: val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER; @@ -7765,7 +7765,7 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); msleep(10); - /* The PHY reset is controled by GPIO 1 + /* The PHY reset is controlled by GPIO 1 * Hold it as vars low */ /* clear link led */ diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 32e64cc85d2c..a97a4a1c344f 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -3702,7 +3702,7 @@ static void bnx2x_eq_int(struct bnx2x *bp) if ((hw_cons & EQ_DESC_MAX_PAGE) == EQ_DESC_MAX_PAGE) hw_cons++; - /* This function may never run in parralel with itself for a + /* This function may never run in parallel with itself for a * specific bp, thus there is no need in "paired" read memory * barrier here. */ @@ -5089,7 +5089,7 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) /* Step 1: set zeroes to all ilt page entries with valid bit on * Step 2: set the timers first/last ilt entry to point * to the entire range to prevent ILT range error for 3rd/4th - * vnic (this code assumes existance of the vnic) + * vnic (this code assumes existence of the vnic) * * both steps performed by call to bnx2x_ilt_client_init_op() * with dummy TM client @@ -8685,7 +8685,7 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) E1H_FUNC_MAX * sizeof(struct drv_func_mb); /* * get mf configuration: - * 1. existance of MF configuration + * 1. existence of MF configuration * 2. MAC address must be legal (check only upper bytes) * for Switch-Independent mode; * OVLAN must be legal for Switch-Dependent mode @@ -8727,7 +8727,7 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) default: /* Unknown configuration: reset mf_config */ bp->mf_config[vn] = 0; - DP(NETIF_MSG_PROBE, "Unkown MF mode 0x%x\n", + DP(NETIF_MSG_PROBE, "Unknown MF mode 0x%x\n", val); } } @@ -9777,7 +9777,7 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, #endif - /* Configure interupt mode: try to enable MSI-X/MSI if + /* Configure interrupt mode: try to enable MSI-X/MSI if * needed, set bp->num_queues appropriately. */ bnx2x_set_int_mode(bp); diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index 1c89f19a4425..1509a2318af9 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -175,9 +175,9 @@ the initial credit value; read returns the current value of the credit counter. Must be initialized to 1 at start-up. */ #define CCM_REG_CFC_INIT_CRD 0xd0204 -/* [RW 2] Auxillary counter flag Q number 1. */ +/* [RW 2] Auxiliary counter flag Q number 1. */ #define CCM_REG_CNT_AUX1_Q 0xd00c8 -/* [RW 2] Auxillary counter flag Q number 2. */ +/* [RW 2] Auxiliary counter flag Q number 2. */ #define CCM_REG_CNT_AUX2_Q 0xd00cc /* [RW 28] The CM header value for QM request (primary). */ #define CCM_REG_CQM_CCM_HDR_P 0xd008c @@ -457,13 +457,13 @@ #define CSDM_REG_AGG_INT_MODE_9 0xc21dc /* [RW 13] The start address in the internal RAM for the cfc_rsp lcid */ #define CSDM_REG_CFC_RSP_START_ADDR 0xc2008 -/* [RW 16] The maximum value of the competion counter #0 */ +/* [RW 16] The maximum value of the completion counter #0 */ #define CSDM_REG_CMP_COUNTER_MAX0 0xc201c -/* [RW 16] The maximum value of the competion counter #1 */ +/* [RW 16] The maximum value of the completion counter #1 */ #define CSDM_REG_CMP_COUNTER_MAX1 0xc2020 -/* [RW 16] The maximum value of the competion counter #2 */ +/* [RW 16] The maximum value of the completion counter #2 */ #define CSDM_REG_CMP_COUNTER_MAX2 0xc2024 -/* [RW 16] The maximum value of the competion counter #3 */ +/* [RW 16] The maximum value of the completion counter #3 */ #define CSDM_REG_CMP_COUNTER_MAX3 0xc2028 /* [RW 13] The start address in the internal RAM for the completion counters. */ @@ -851,7 +851,7 @@ #define IGU_REG_ATTN_MSG_ADDR_L 0x130120 /* [R 4] Debug: [3] - attention write done message is pending (0-no pending; * 1-pending). [2:0] = PFID. Pending means attention message was sent; but - * write done didnt receive. */ + * write done didn't receive. */ #define IGU_REG_ATTN_WRITE_DONE_PENDING 0x130030 #define IGU_REG_BLOCK_CONFIGURATION 0x130000 #define IGU_REG_COMMAND_REG_32LSB_DATA 0x130124 @@ -862,7 +862,7 @@ #define IGU_REG_CSTORM_TYPE_0_SB_CLEANUP 0x130200 /* [R 5] Debug: ctrl_fsm */ #define IGU_REG_CTRL_FSM 0x130064 -/* [R 1] data availble for error memory. If this bit is clear do not red +/* [R 1] data available for error memory. If this bit is clear do not red * from error_handling_memory. */ #define IGU_REG_ERROR_HANDLING_DATA_VALID 0x130130 /* [RW 11] Parity mask register #0 read/write */ @@ -3015,7 +3015,7 @@ block. Should be used for close the gates. */ #define PXP_REG_HST_DISCARD_DOORBELLS 0x1030a4 /* [R 1] debug only: '1' means this PSWHST is discarding doorbells. This bit - should update accoring to 'hst_discard_doorbells' register when the state + should update according to 'hst_discard_doorbells' register when the state machine is idle */ #define PXP_REG_HST_DISCARD_DOORBELLS_STATUS 0x1030a0 /* [RW 1] When 1; new internal writes arriving to the block are discarded. @@ -3023,7 +3023,7 @@ #define PXP_REG_HST_DISCARD_INTERNAL_WRITES 0x1030a8 /* [R 6] debug only: A bit mask for all PSWHST internal write clients. '1' means this PSWHST is discarding inputs from this client. Each bit should - update accoring to 'hst_discard_internal_writes' register when the state + update according to 'hst_discard_internal_writes' register when the state machine is idle. */ #define PXP_REG_HST_DISCARD_INTERNAL_WRITES_STATUS 0x10309c /* [WB 160] Used for initialization of the inbound interrupts memory */ @@ -3822,13 +3822,13 @@ #define TSDM_REG_AGG_INT_T_1 0x420bc /* [RW 13] The start address in the internal RAM for the cfc_rsp lcid */ #define TSDM_REG_CFC_RSP_START_ADDR 0x42008 -/* [RW 16] The maximum value of the competion counter #0 */ +/* [RW 16] The maximum value of the completion counter #0 */ #define TSDM_REG_CMP_COUNTER_MAX0 0x4201c -/* [RW 16] The maximum value of the competion counter #1 */ +/* [RW 16] The maximum value of the completion counter #1 */ #define TSDM_REG_CMP_COUNTER_MAX1 0x42020 -/* [RW 16] The maximum value of the competion counter #2 */ +/* [RW 16] The maximum value of the completion counter #2 */ #define TSDM_REG_CMP_COUNTER_MAX2 0x42024 -/* [RW 16] The maximum value of the competion counter #3 */ +/* [RW 16] The maximum value of the completion counter #3 */ #define TSDM_REG_CMP_COUNTER_MAX3 0x42028 /* [RW 13] The start address in the internal RAM for the completion counters. */ @@ -4284,13 +4284,13 @@ #define USDM_REG_AGG_INT_T_6 0xc40d0 /* [RW 13] The start address in the internal RAM for the cfc_rsp lcid */ #define USDM_REG_CFC_RSP_START_ADDR 0xc4008 -/* [RW 16] The maximum value of the competion counter #0 */ +/* [RW 16] The maximum value of the completion counter #0 */ #define USDM_REG_CMP_COUNTER_MAX0 0xc401c -/* [RW 16] The maximum value of the competion counter #1 */ +/* [RW 16] The maximum value of the completion counter #1 */ #define USDM_REG_CMP_COUNTER_MAX1 0xc4020 -/* [RW 16] The maximum value of the competion counter #2 */ +/* [RW 16] The maximum value of the completion counter #2 */ #define USDM_REG_CMP_COUNTER_MAX2 0xc4024 -/* [RW 16] The maximum value of the competion counter #3 */ +/* [RW 16] The maximum value of the completion counter #3 */ #define USDM_REG_CMP_COUNTER_MAX3 0xc4028 /* [RW 13] The start address in the internal RAM for the completion counters. */ @@ -4798,13 +4798,13 @@ #define XSDM_REG_AGG_INT_MODE_1 0x1661bc /* [RW 13] The start address in the internal RAM for the cfc_rsp lcid */ #define XSDM_REG_CFC_RSP_START_ADDR 0x166008 -/* [RW 16] The maximum value of the competion counter #0 */ +/* [RW 16] The maximum value of the completion counter #0 */ #define XSDM_REG_CMP_COUNTER_MAX0 0x16601c -/* [RW 16] The maximum value of the competion counter #1 */ +/* [RW 16] The maximum value of the completion counter #1 */ #define XSDM_REG_CMP_COUNTER_MAX1 0x166020 -/* [RW 16] The maximum value of the competion counter #2 */ +/* [RW 16] The maximum value of the completion counter #2 */ #define XSDM_REG_CMP_COUNTER_MAX2 0x166024 -/* [RW 16] The maximum value of the competion counter #3 */ +/* [RW 16] The maximum value of the completion counter #3 */ #define XSDM_REG_CMP_COUNTER_MAX3 0x166028 /* [RW 13] The start address in the internal RAM for the completion counters. */ diff --git a/drivers/net/bonding/bond_alb.h b/drivers/net/bonding/bond_alb.h index 118c28aa471e..b3bc7502868f 100644 --- a/drivers/net/bonding/bond_alb.h +++ b/drivers/net/bonding/bond_alb.h @@ -76,7 +76,7 @@ struct tlb_client_info { */ u32 tx_bytes; /* Each Client acumulates the BytesTx that * were tranmitted to it, and after each - * CallBack the LoadHistory is devided + * CallBack the LoadHistory is divided * by the balance interval */ u32 load_history; /* This field contains the amount of Bytes diff --git a/drivers/net/caif/caif_shmcore.c b/drivers/net/caif/caif_shmcore.c index 80511167f35b..731aa1193770 100644 --- a/drivers/net/caif/caif_shmcore.c +++ b/drivers/net/caif/caif_shmcore.c @@ -591,7 +591,7 @@ int caif_shmcore_probe(struct shmdev_layer *pshm_dev) (NR_TX_BUF * TX_BUF_SZ + NR_RX_BUF * RX_BUF_SZ)) { pr_warn("ERROR, Amount of available" - " Phys. SHM cannot accomodate current SHM " + " Phys. SHM cannot accommodate current SHM " "driver configuration, Bailing out ...\n"); free_netdev(pshm_dev->pshm_netdev); return -ENOMEM; diff --git a/drivers/net/caif/caif_spi.c b/drivers/net/caif/caif_spi.c index 20da1996d354..57e639373815 100644 --- a/drivers/net/caif/caif_spi.c +++ b/drivers/net/caif/caif_spi.c @@ -397,7 +397,7 @@ int cfspi_xmitlen(struct cfspi *cfspi) int pkts = 0; /* - * Decommit previously commited frames. + * Decommit previously committed frames. * skb_queue_splice_tail(&cfspi->chead,&cfspi->qhead) */ while (skb_peek(&cfspi->chead)) { diff --git a/drivers/net/caif/caif_spi_slave.c b/drivers/net/caif/caif_spi_slave.c index 1b9943a4edab..b009e03cda9e 100644 --- a/drivers/net/caif/caif_spi_slave.c +++ b/drivers/net/caif/caif_spi_slave.c @@ -98,7 +98,7 @@ void cfspi_xfer(struct work_struct *work) cfspi_dbg_state(cfspi, CFSPI_STATE_FETCH_PKT); - /* Copy commited SPI frames after the SPI indication. */ + /* Copy committed SPI frames after the SPI indication. */ ptr = (u8 *) cfspi->xfer.va_tx; ptr += SPI_IND_SZ; len = cfspi_xmitfrm(cfspi, ptr, cfspi->tx_cpck_len); @@ -158,7 +158,7 @@ void cfspi_xfer(struct work_struct *work) cfspi_dbg_state(cfspi, CFSPI_STATE_SIG_ACTIVE); - /* Signal that we are ready to recieve data. */ + /* Signal that we are ready to receive data. */ cfspi->dev->sig_xfer(true, cfspi->dev); cfspi_dbg_state(cfspi, CFSPI_STATE_WAIT_XFER_DONE); diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index 57d2ffbbb433..74efb5a2ad41 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c @@ -416,7 +416,7 @@ static netdev_tx_t at91_start_xmit(struct sk_buff *skb, struct net_device *dev) stats->tx_bytes += cf->can_dlc; - /* _NOTE_: substract AT91_MB_TX_FIRST offset from mb! */ + /* _NOTE_: subtract AT91_MB_TX_FIRST offset from mb! */ can_put_echo_skb(skb, dev, mb - AT91_MB_TX_FIRST); /* @@ -782,7 +782,7 @@ static void at91_irq_tx(struct net_device *dev, u32 reg_sr) reg_msr = at91_read(priv, AT91_MSR(mb)); if (likely(reg_msr & AT91_MSR_MRDY && ~reg_msr & AT91_MSR_MABT)) { - /* _NOTE_: substract AT91_MB_TX_FIRST offset from mb! */ + /* _NOTE_: subtract AT91_MB_TX_FIRST offset from mb! */ can_get_echo_skb(dev, mb - AT91_MB_TX_FIRST); dev->stats.tx_packets++; } diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index 31552959aed7..7e5cc0bd913d 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c @@ -813,7 +813,7 @@ static int c_can_handle_state_change(struct net_device *dev, struct sk_buff *skb; struct can_berr_counter bec; - /* propogate the error condition to the CAN stack */ + /* propagate the error condition to the CAN stack */ skb = alloc_can_err_skb(dev, &cf); if (unlikely(!skb)) return 0; @@ -887,7 +887,7 @@ static int c_can_handle_bus_err(struct net_device *dev, if (lec_type == LEC_UNUSED || lec_type == LEC_NO_ERROR) return 0; - /* propogate the error condition to the CAN stack */ + /* propagate the error condition to the CAN stack */ skb = alloc_can_err_skb(dev, &cf); if (unlikely(!skb)) return 0; diff --git a/drivers/net/can/janz-ican3.c b/drivers/net/can/janz-ican3.c index 102b16c6cc97..587fba48cdd9 100644 --- a/drivers/net/can/janz-ican3.c +++ b/drivers/net/can/janz-ican3.c @@ -274,7 +274,7 @@ static inline void ican3_set_page(struct ican3_dev *mod, unsigned int page) */ /* - * Recieve a message from the ICAN3 "old-style" firmware interface + * Receive a message from the ICAN3 "old-style" firmware interface * * LOCKING: must hold mod->lock * @@ -1050,7 +1050,7 @@ static void ican3_handle_inquiry(struct ican3_dev *mod, struct ican3_msg *msg) complete(&mod->termination_comp); break; default: - dev_err(mod->dev, "recieved an unknown inquiry response\n"); + dev_err(mod->dev, "received an unknown inquiry response\n"); break; } } @@ -1058,7 +1058,7 @@ static void ican3_handle_inquiry(struct ican3_dev *mod, struct ican3_msg *msg) static void ican3_handle_unknown_message(struct ican3_dev *mod, struct ican3_msg *msg) { - dev_warn(mod->dev, "recieved unknown message: spec 0x%.2x length %d\n", + dev_warn(mod->dev, "received unknown message: spec 0x%.2x length %d\n", msg->spec, le16_to_cpu(msg->len)); } @@ -1113,7 +1113,7 @@ static bool ican3_txok(struct ican3_dev *mod) } /* - * Recieve one CAN frame from the hardware + * Receive one CAN frame from the hardware * * CONTEXT: must be called from user context */ diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c index 74cd880c7e06..92feac68b66e 100644 --- a/drivers/net/can/mscan/mscan.c +++ b/drivers/net/can/mscan/mscan.c @@ -246,7 +246,7 @@ static netdev_tx_t mscan_start_xmit(struct sk_buff *skb, struct net_device *dev) out_be16(®s->tx.idr3_2, can_id); can_id >>= 16; - /* EFF_FLAGS are inbetween the IDs :( */ + /* EFF_FLAGS are between the IDs :( */ can_id = (can_id & 0x7) | ((can_id << 2) & 0xffe0) | MSCAN_EFF_FLAGS; } else { diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c index 0a8de01d52f7..a358ea9445a2 100644 --- a/drivers/net/can/sja1000/sja1000.c +++ b/drivers/net/can/sja1000/sja1000.c @@ -425,7 +425,7 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) cf->data[3] = ecc & ECC_SEG; break; } - /* Error occured during transmission? */ + /* Error occurred during transmission? */ if ((ecc & ECC_DIR) == 0) cf->data[2] |= CAN_ERR_PROT_TX; } diff --git a/drivers/net/can/softing/softing.h b/drivers/net/can/softing/softing.h index 7ec9f4db3d52..afd7d85b6915 100644 --- a/drivers/net/can/softing/softing.h +++ b/drivers/net/can/softing/softing.h @@ -22,7 +22,7 @@ struct softing_priv { struct softing *card; struct { int pending; - /* variables wich hold the circular buffer */ + /* variables which hold the circular buffer */ int echo_put; int echo_get; } tx; diff --git a/drivers/net/can/softing/softing_main.c b/drivers/net/can/softing/softing_main.c index aeea9f9ff6e8..7a70709d5608 100644 --- a/drivers/net/can/softing/softing_main.c +++ b/drivers/net/can/softing/softing_main.c @@ -218,7 +218,7 @@ static int softing_handle_1(struct softing *card) ptr = buf; cmd = *ptr++; if (cmd == 0xff) - /* not quite usefull, probably the card has got out */ + /* not quite useful, probably the card has got out */ return 0; netdev = card->net[0]; if (cmd & CMD_BUS2) diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c index 4d07f1ee7168..f7bbde9eb2cb 100644 --- a/drivers/net/can/ti_hecc.c +++ b/drivers/net/can/ti_hecc.c @@ -663,7 +663,7 @@ static int ti_hecc_error(struct net_device *ndev, int int_status, struct can_frame *cf; struct sk_buff *skb; - /* propogate the error condition to the can stack */ + /* propagate the error condition to the can stack */ skb = alloc_can_err_skb(ndev, &cf); if (!skb) { if (printk_ratelimit()) diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c index e75f1a876972..a72c7bfb4090 100644 --- a/drivers/net/can/usb/ems_usb.c +++ b/drivers/net/can/usb/ems_usb.c @@ -386,7 +386,7 @@ static void ems_usb_rx_err(struct ems_usb *dev, struct ems_cpc_msg *msg) break; } - /* Error occured during transmission? */ + /* Error occurred during transmission? */ if ((ecc & SJA1000_ECC_DIR) == 0) cf->data[2] |= CAN_ERR_PROT_TX; diff --git a/drivers/net/can/usb/esd_usb2.c b/drivers/net/can/usb/esd_usb2.c index dc53c831ea95..eb8b0e600282 100644 --- a/drivers/net/can/usb/esd_usb2.c +++ b/drivers/net/can/usb/esd_usb2.c @@ -284,7 +284,7 @@ static void esd_usb2_rx_event(struct esd_usb2_net_priv *priv, break; } - /* Error occured during transmission? */ + /* Error occurred during transmission? */ if (!(ecc & SJA1000_ECC_DIR)) cf->data[2] |= CAN_ERR_PROT_TX; diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index 3437613f0454..143a28c666af 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c @@ -51,7 +51,7 @@ * TX has 4 queues. currently these queues are used in a round-robin * fashion for load balancing. They can also be used for QoS. for that * to work, however, QoS information needs to be exposed down to the driver - * level so that subqueues get targetted to particular transmit rings. + * level so that subqueues get targeted to particular transmit rings. * alternatively, the queues can be configured via use of the all-purpose * ioctl. * @@ -5165,7 +5165,7 @@ err_out_free_res: pci_release_regions(pdev); err_write_cacheline: - /* Try to restore it in case the error occured after we + /* Try to restore it in case the error occurred after we * set it. */ pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, orig_cacheline_size); diff --git a/drivers/net/cassini.h b/drivers/net/cassini.h index faf4746a0f3e..b361424d5f57 100644 --- a/drivers/net/cassini.h +++ b/drivers/net/cassini.h @@ -772,7 +772,7 @@ #define RX_DEBUG_INTR_WRITE_PTR_MASK 0xC0000000 /* interrupt write pointer of the interrupt queue */ -/* flow control frames are emmitted using two PAUSE thresholds: +/* flow control frames are emitted using two PAUSE thresholds: * XOFF PAUSE uses pause time value pre-programmed in the Send PAUSE MAC reg * XON PAUSE uses a pause time of 0. granularity of threshold is 64bytes. * PAUSE thresholds defined in terms of FIFO occupancy and may be translated diff --git a/drivers/net/chelsio/mv88e1xxx.c b/drivers/net/chelsio/mv88e1xxx.c index 809047a99e96..71018a4fdf15 100644 --- a/drivers/net/chelsio/mv88e1xxx.c +++ b/drivers/net/chelsio/mv88e1xxx.c @@ -41,7 +41,7 @@ static void mdio_clear_bit(struct cphy *cphy, int reg, u32 bitval) * * PARAMS: cphy - Pointer to PHY instance data. * - * RETURN: 0 - Successfull reset. + * RETURN: 0 - Successful reset. * -1 - Timeout. */ static int mv88e1xxx_reset(struct cphy *cphy, int wait) diff --git a/drivers/net/chelsio/pm3393.c b/drivers/net/chelsio/pm3393.c index 7dbb16d36fff..40c7b93ababc 100644 --- a/drivers/net/chelsio/pm3393.c +++ b/drivers/net/chelsio/pm3393.c @@ -293,7 +293,7 @@ static int pm3393_enable_port(struct cmac *cmac, int which) pm3393_enable(cmac, which); /* - * XXX This should be done by the PHY and preferrably not at all. + * XXX This should be done by the PHY and preferably not at all. * The PHY doesn't give us link status indication on its own so have * the link management code query it instead. */ diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c index f778b15ad3fd..8754d4473042 100644 --- a/drivers/net/chelsio/sge.c +++ b/drivers/net/chelsio/sge.c @@ -1662,7 +1662,7 @@ irqreturn_t t1_interrupt(int irq, void *data) * The code figures out how many entries the sk_buff will require in the * cmdQ and updates the cmdQ data structure with the state once the enqueue * has complete. Then, it doesn't access the global structure anymore, but - * uses the corresponding fields on the stack. In conjuction with a spinlock + * uses the corresponding fields on the stack. In conjunction with a spinlock * around that code, we can make the function reentrant without holding the * lock when we actually enqueue (which might be expensive, especially on * architectures with IO MMUs). diff --git a/drivers/net/chelsio/vsc7326.c b/drivers/net/chelsio/vsc7326.c index 106a590f0d9a..b0cb388f5e12 100644 --- a/drivers/net/chelsio/vsc7326.c +++ b/drivers/net/chelsio/vsc7326.c @@ -566,7 +566,7 @@ static int mac_disable(struct cmac *mac, int which) for (i = 0; i <= 0x3a; ++i) vsc_write(mac->adapter, CRA(4, port, i), 0); - /* Clear sofware counters */ + /* Clear software counters */ memset(&mac->stats, 0, sizeof(struct cmac_statistics)); return 0; diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c index 80c2feeefec5..9d267d3a6892 100644 --- a/drivers/net/cris/eth_v10.c +++ b/drivers/net/cris/eth_v10.c @@ -1383,7 +1383,7 @@ e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) spin_lock(&np->lock); /* Preempt protection */ switch (cmd) { /* The ioctls below should be considered obsolete but are */ - /* still present for compatability with old scripts/apps */ + /* still present for compatibility with old scripts/apps */ case SET_ETH_SPEED_10: /* 10 Mbps */ e100_set_speed(dev, 10); break; diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index f9f6645b2e61..bfa2d56af1ee 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c @@ -199,7 +199,7 @@ static inline void refill_rspq(struct adapter *adapter, * need_skb_unmap - does the platform need unmapping of sk_buffs? * * Returns true if the platform needs sk_buff unmapping. The compiler - * optimizes away unecessary code if this returns true. + * optimizes away unnecessary code if this returns true. */ static inline int need_skb_unmap(void) { diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c index d55db6b38e7b..c688421da9c7 100644 --- a/drivers/net/cxgb3/t3_hw.c +++ b/drivers/net/cxgb3/t3_hw.c @@ -1386,11 +1386,11 @@ struct intr_info { * @reg: the interrupt status register to process * @mask: a mask to apply to the interrupt status * @acts: table of interrupt actions - * @stats: statistics counters tracking interrupt occurences + * @stats: statistics counters tracking interrupt occurrences * * A table driven interrupt handler that applies a set of masks to an * interrupt status word and performs the corresponding actions if the - * interrupts described by the mask have occured. The actions include + * interrupts described by the mask have occurred. The actions include * optionally printing a warning or alert message, and optionally * incrementing a stat counter. The table is terminated by an entry * specifying mask 0. Returns the number of fatal interrupt conditions. @@ -2783,7 +2783,7 @@ static void init_mtus(unsigned short mtus[]) { /* * See draft-mathis-plpmtud-00.txt for the values. The min is 88 so - * it can accomodate max size TCP/IP headers when SACK and timestamps + * it can accommodate max size TCP/IP headers when SACK and timestamps * are enabled and still have at least 8 bytes of payload. */ mtus[0] = 88; diff --git a/drivers/net/cxgb4/t4_hw.c b/drivers/net/cxgb4/t4_hw.c index b9fd8a6f2cc4..d1ec111aebd8 100644 --- a/drivers/net/cxgb4/t4_hw.c +++ b/drivers/net/cxgb4/t4_hw.c @@ -883,7 +883,7 @@ struct intr_info { * * A table driven interrupt handler that applies a set of masks to an * interrupt status word and performs the corresponding actions if the - * interrupts described by the mask have occured. The actions include + * interrupts described by the mask have occurred. The actions include * optionally emitting a warning or alert message. The table is terminated * by an entry specifying mask 0. Returns the number of fatal interrupt * conditions. diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c index 6aad64df4dcb..4661cbbd9bd9 100644 --- a/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/cxgb4vf/cxgb4vf_main.c @@ -2738,7 +2738,7 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev, cfg_queues(adapter); /* - * Print a short notice on the existance and configuration of the new + * Print a short notice on the existence and configuration of the new * VF network device ... */ for_each_port(adapter, pidx) { diff --git a/drivers/net/cxgb4vf/sge.c b/drivers/net/cxgb4vf/sge.c index e0b3d1bc2fdf..bb65121f581c 100644 --- a/drivers/net/cxgb4vf/sge.c +++ b/drivers/net/cxgb4vf/sge.c @@ -224,8 +224,8 @@ static inline bool is_buf_mapped(const struct rx_sw_desc *sdesc) /** * need_skb_unmap - does the platform need unmapping of sk_buffs? * - * Returns true if the platfrom needs sk_buff unmapping. The compiler - * optimizes away unecessary code if this returns true. + * Returns true if the platform needs sk_buff unmapping. The compiler + * optimizes away unnecessary code if this returns true. */ static inline int need_skb_unmap(void) { @@ -267,7 +267,7 @@ static inline unsigned int fl_cap(const struct sge_fl *fl) * * Tests specified Free List to see whether the number of buffers * available to the hardware has falled below our "starvation" - * threshhold. + * threshold. */ static inline bool fl_starving(const struct sge_fl *fl) { @@ -1149,7 +1149,7 @@ int t4vf_eth_xmit(struct sk_buff *skb, struct net_device *dev) if (unlikely(credits < ETHTXQ_STOP_THRES)) { /* * After we're done injecting the Work Request for this - * packet, we'll be below our "stop threshhold" so stop the TX + * packet, we'll be below our "stop threshold" so stop the TX * Queue now and schedule a request for an SGE Egress Queue * Update message. The queue will get started later on when * the firmware processes this Work Request and sends us an diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index baca6bfcb089..807b6bb200eb 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c @@ -94,14 +94,14 @@ MODULE_VERSION(EMAC_MODULE_VERSION); static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1"; /* Configuration items */ -#define EMAC_DEF_PASS_CRC (0) /* Do not pass CRC upto frames */ +#define EMAC_DEF_PASS_CRC (0) /* Do not pass CRC up to frames */ #define EMAC_DEF_QOS_EN (0) /* EMAC proprietary QoS disabled */ #define EMAC_DEF_NO_BUFF_CHAIN (0) /* No buffer chain */ #define EMAC_DEF_MACCTRL_FRAME_EN (0) /* Discard Maccontrol frames */ #define EMAC_DEF_SHORT_FRAME_EN (0) /* Discard short frames */ #define EMAC_DEF_ERROR_FRAME_EN (0) /* Discard error frames */ -#define EMAC_DEF_PROM_EN (0) /* Promiscous disabled */ -#define EMAC_DEF_PROM_CH (0) /* Promiscous channel is 0 */ +#define EMAC_DEF_PROM_EN (0) /* Promiscuous disabled */ +#define EMAC_DEF_PROM_CH (0) /* Promiscuous channel is 0 */ #define EMAC_DEF_BCAST_EN (1) /* Broadcast enabled */ #define EMAC_DEF_BCAST_CH (0) /* Broadcast channel is 0 */ #define EMAC_DEF_MCAST_EN (1) /* Multicast enabled */ @@ -1013,7 +1013,7 @@ static void emac_rx_handler(void *token, int len, int status) return; } - /* recycle on recieve error */ + /* recycle on receive error */ if (status < 0) { ndev->stats.rx_errors++; goto recycle; diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index f4d0922ec65b..dd70738eb2f4 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c @@ -160,7 +160,7 @@ static int e1000_get_settings(struct net_device *netdev, &adapter->link_duplex); ecmd->speed = adapter->link_speed; - /* unfortunatly FULL_DUPLEX != DUPLEX_FULL + /* unfortunately FULL_DUPLEX != DUPLEX_FULL * and HALF_DUPLEX != DUPLEX_HALF */ if (adapter->link_duplex == FULL_DUPLEX) diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h index c70b23d52284..5c9a8403668b 100644 --- a/drivers/net/e1000/e1000_hw.h +++ b/drivers/net/e1000/e1000_hw.h @@ -1026,7 +1026,7 @@ extern void __iomem *ce4100_gbe_mdio_base_virt; #define E1000_KUMCTRLSTA 0x00034 /* MAC-PHY interface - RW */ #define E1000_MDPHYA 0x0003C /* PHY address - RW */ -#define E1000_MANC2H 0x05860 /* Managment Control To Host - RW */ +#define E1000_MANC2H 0x05860 /* Management Control To Host - RW */ #define E1000_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW */ #define E1000_GCR 0x05B00 /* PCI-Ex Control */ diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index bfab14092d2c..477e066a1cf0 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -205,7 +205,7 @@ static struct pci_driver e1000_driver = { .probe = e1000_probe, .remove = __devexit_p(e1000_remove), #ifdef CONFIG_PM - /* Power Managment Hooks */ + /* Power Management Hooks */ .suspend = e1000_suspend, .resume = e1000_resume, #endif diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index a39d4a4d871c..506a0a0043b3 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -4886,7 +4886,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, if (skb->protocol == htons(ETH_P_IP)) tx_flags |= E1000_TX_FLAGS_IPV4; - /* if count is 0 then mapping error has occured */ + /* if count is 0 then mapping error has occurred */ count = e1000_tx_map(adapter, skb, first, max_per_txd, nr_frags, mss); if (count) { e1000_tx_queue(adapter, tx_flags, count); diff --git a/drivers/net/enc28j60_hw.h b/drivers/net/enc28j60_hw.h index 1a0b20969f80..25b41de49f0e 100644 --- a/drivers/net/enc28j60_hw.h +++ b/drivers/net/enc28j60_hw.h @@ -303,7 +303,7 @@ /* maximum ethernet frame length */ #define MAX_FRAMELEN 1518 -/* Prefered half duplex: LEDA: Link status LEDB: Rx/Tx activity */ +/* Preferred half duplex: LEDA: Link status LEDB: Rx/Tx activity */ #define ENC28J60_LAMPS_MODE 0x3476 #endif diff --git a/drivers/net/eth16i.c b/drivers/net/eth16i.c index fb717be511f6..12d28e9d0cb7 100644 --- a/drivers/net/eth16i.c +++ b/drivers/net/eth16i.c @@ -13,7 +13,7 @@ This driver supports following cards : - ICL EtherTeam 16i - ICL EtherTeam 32 EISA - (Uses true 32 bit transfers rather than 16i compability mode) + (Uses true 32 bit transfers rather than 16i compatibility mode) Example Module usage: insmod eth16i.o io=0x2a0 mediatype=bnc diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c index db0290f05bdf..a83dd312c3ac 100644 --- a/drivers/net/ethoc.c +++ b/drivers/net/ethoc.c @@ -542,7 +542,7 @@ static irqreturn_t ethoc_interrupt(int irq, void *dev_id) /* Figure out what triggered the interrupt... * The tricky bit here is that the interrupt source bits get - * set in INT_SOURCE for an event irregardless of whether that + * set in INT_SOURCE for an event regardless of whether that * event is masked or not. Thus, in order to figure out what * triggered the interrupt, we need to remove the sources * for all events that are currently masked. This behaviour diff --git a/drivers/net/fec.h b/drivers/net/fec.h index ace318df4c8d..8b2c6d797e6d 100644 --- a/drivers/net/fec.h +++ b/drivers/net/fec.h @@ -97,11 +97,11 @@ struct bufdesc { * The following definitions courtesy of commproc.h, which where * Copyright (c) 1997 Dan Malek (dmalek@jlc.net). */ -#define BD_SC_EMPTY ((ushort)0x8000) /* Recieve is empty */ +#define BD_SC_EMPTY ((ushort)0x8000) /* Receive is empty */ #define BD_SC_READY ((ushort)0x8000) /* Transmit is ready */ #define BD_SC_WRAP ((ushort)0x2000) /* Last buffer descriptor */ #define BD_SC_INTRPT ((ushort)0x1000) /* Interrupt on change */ -#define BD_SC_CM ((ushort)0x0200) /* Continous mode */ +#define BD_SC_CM ((ushort)0x0200) /* Continuous mode */ #define BD_SC_ID ((ushort)0x0100) /* Rec'd too many idles */ #define BD_SC_P ((ushort)0x0100) /* xmt preamble */ #define BD_SC_BR ((ushort)0x0020) /* Break received */ diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 7b92897ca66b..d5ab4dad5051 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -440,7 +440,7 @@ union ring_type { #define NV_RX3_VLAN_TAG_PRESENT (1<<16) #define NV_RX3_VLAN_TAG_MASK (0x0000FFFF) -/* Miscelaneous hardware related defines: */ +/* Miscellaneous hardware related defines: */ #define NV_PCI_REGSZ_VER1 0x270 #define NV_PCI_REGSZ_VER2 0x2d4 #define NV_PCI_REGSZ_VER3 0x604 @@ -1488,7 +1488,7 @@ static int phy_init(struct net_device *dev) } } - /* some phys clear out pause advertisment on reset, set it back */ + /* some phys clear out pause advertisement on reset, set it back */ mii_rw(dev, np->phyaddr, MII_ADVERTISE, reg); /* restart auto negotiation, power down phy */ @@ -2535,7 +2535,7 @@ static void nv_tx_timeout(struct net_device *dev) else nv_tx_done_optimized(dev, np->tx_ring_size); - /* save current HW postion */ + /* save current HW position */ if (np->tx_change_owner) put_tx.ex = np->tx_change_owner->first_tx_desc; else @@ -4053,7 +4053,7 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) } else if (ecmd->autoneg == AUTONEG_DISABLE) { /* Note: autonegotiation disable, speed 1000 intentionally - * forbidden - noone should need that. */ + * forbidden - no one should need that. */ if (ecmd->speed != SPEED_10 && ecmd->speed != SPEED_100) return -EINVAL; @@ -4103,7 +4103,7 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) adv |= ADVERTISE_100HALF; if (ecmd->advertising & ADVERTISED_100baseT_Full) adv |= ADVERTISE_100FULL; - if (np->pause_flags & NV_PAUSEFRAME_RX_REQ) /* for rx we set both advertisments but disable tx pause */ + if (np->pause_flags & NV_PAUSEFRAME_RX_REQ) /* for rx we set both advertisements but disable tx pause */ adv |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; if (np->pause_flags & NV_PAUSEFRAME_TX_REQ) adv |= ADVERTISE_PAUSE_ASYM; @@ -4148,7 +4148,7 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) if (ecmd->speed == SPEED_100 && ecmd->duplex == DUPLEX_FULL) adv |= ADVERTISE_100FULL; np->pause_flags &= ~(NV_PAUSEFRAME_AUTONEG|NV_PAUSEFRAME_RX_ENABLE|NV_PAUSEFRAME_TX_ENABLE); - if (np->pause_flags & NV_PAUSEFRAME_RX_REQ) {/* for rx we set both advertisments but disable tx pause */ + if (np->pause_flags & NV_PAUSEFRAME_RX_REQ) {/* for rx we set both advertisements but disable tx pause */ adv |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; np->pause_flags |= NV_PAUSEFRAME_RX_ENABLE; } @@ -4449,7 +4449,7 @@ static int nv_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam* adv = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ); adv &= ~(ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM); - if (np->pause_flags & NV_PAUSEFRAME_RX_REQ) /* for rx we set both advertisments but disable tx pause */ + if (np->pause_flags & NV_PAUSEFRAME_RX_REQ) /* for rx we set both advertisements but disable tx pause */ adv |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; if (np->pause_flags & NV_PAUSEFRAME_TX_REQ) adv |= ADVERTISE_PAUSE_ASYM; diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h index ec5d595ce2e2..b2fe7edefad9 100644 --- a/drivers/net/gianfar.h +++ b/drivers/net/gianfar.h @@ -1043,7 +1043,7 @@ enum gfar_errata { }; /* Struct stolen almost completely (and shamelessly) from the FCC enet source - * (Ok, that's not so true anymore, but there is a family resemblence) + * (Ok, that's not so true anymore, but there is a family resemblance) * The GFAR buffer descriptors track the ring buffers. The rx_bd_base * and tx_bd_base always point to the currently available buffer. * The dirty_tx tracks the current buffer that is being sent by the diff --git a/drivers/net/hamradio/Makefile b/drivers/net/hamradio/Makefile index 9def86704a91..104096070026 100644 --- a/drivers/net/hamradio/Makefile +++ b/drivers/net/hamradio/Makefile @@ -3,7 +3,7 @@ # # # 19971130 Moved the amateur radio related network drivers from -# drivers/net/ to drivers/hamradio for easier maintainance. +# drivers/net/ to drivers/hamradio for easier maintenance. # Joerg Reuter DL1BKE # # 20000806 Rewritten to use lists instead of if-statements. diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c index 7d9ced0738c5..96a98d2ff151 100644 --- a/drivers/net/hamradio/yam.c +++ b/drivers/net/hamradio/yam.c @@ -30,7 +30,7 @@ * 0.1 F1OAT 07.06.98 Add timer polling routine for channel arbitration * 0.2 F6FBB 08.06.98 Added delay after FPGA programming * 0.3 F6FBB 29.07.98 Delayed PTT implementation for dupmode=2 - * 0.4 F6FBB 30.07.98 Added TxTail, Slottime and Persistance + * 0.4 F6FBB 30.07.98 Added TxTail, Slottime and Persistence * 0.5 F6FBB 01.08.98 Shared IRQs, /proc/net and network statistics * 0.6 F6FBB 25.08.98 Added 1200Bds format * 0.7 F6FBB 12.09.98 Added to the kernel configuration diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c index 8e2c4601b5f5..8e10d2f6a5ad 100644 --- a/drivers/net/hp100.c +++ b/drivers/net/hp100.c @@ -180,8 +180,8 @@ struct hp100_private { u_int *page_vaddr_algn; /* Aligned virtual address of allocated page */ u_long whatever_offset; /* Offset to bus/phys/dma address */ - int rxrcommit; /* # Rx PDLs commited to adapter */ - int txrcommit; /* # Tx PDLs commited to adapter */ + int rxrcommit; /* # Rx PDLs committed to adapter */ + int txrcommit; /* # Tx PDLs committed to adapter */ }; /* @@ -716,7 +716,7 @@ static int __devinit hp100_probe1(struct net_device *dev, int ioaddr, * implemented/tested only with the lassen chip anyway... */ if (lp->mode == 1) { /* busmaster */ dma_addr_t page_baddr; - /* Get physically continous memory for TX & RX PDLs */ + /* Get physically continuous memory for TX & RX PDLs */ /* Conversion to new PCI API : * Pages are always aligned and zeroed, no need to it ourself. * Doc says should be OK for EISA bus as well - Jean II */ @@ -1596,7 +1596,7 @@ drop: /* clean_txring checks if packets have been sent by the card by reading * the TX_PDL register from the performance page and comparing it to the - * number of commited packets. It then frees the skb's of the packets that + * number of committed packets. It then frees the skb's of the packets that * obviously have been sent to the network. * * Needs the PERFORMANCE page selected. @@ -1617,7 +1617,7 @@ static void hp100_clean_txring(struct net_device *dev) #ifdef HP100_DEBUG if (donecount > MAX_TX_PDL) - printk("hp100: %s: Warning: More PDLs transmitted than commited to card???\n", dev->name); + printk("hp100: %s: Warning: More PDLs transmitted than committed to card???\n", dev->name); #endif for (; 0 != donecount; donecount--) { @@ -1765,7 +1765,7 @@ drop: * Receive Function (Non-Busmaster mode) * Called when an "Receive Packet" interrupt occurs, i.e. the receive * packet counter is non-zero. - * For non-busmaster, this function does the whole work of transfering + * For non-busmaster, this function does the whole work of transferring * the packet to the host memory and then up to higher layers via skb * and netif_rx. */ @@ -1892,7 +1892,7 @@ static void hp100_rx_bm(struct net_device *dev) /* RX_PKT_CNT states how many PDLs are currently formatted and available to * the cards BM engine */ if ((hp100_inw(RX_PKT_CNT) & 0x00ff) >= lp->rxrcommit) { - printk("hp100: %s: More packets received than commited? RX_PKT_CNT=0x%x, commit=0x%x\n", + printk("hp100: %s: More packets received than committed? RX_PKT_CNT=0x%x, commit=0x%x\n", dev->name, hp100_inw(RX_PKT_CNT) & 0x00ff, lp->rxrcommit); return; @@ -2256,7 +2256,7 @@ static irqreturn_t hp100_interrupt(int irq, void *dev_id) if (lp->mode != 1) /* non busmaster */ hp100_rx(dev); else if (!(val & HP100_RX_PDL_FILL_COMPL)) { - /* Shouldnt happen - maybe we missed a RX_PDL_FILL Interrupt? */ + /* Shouldn't happen - maybe we missed a RX_PDL_FILL Interrupt? */ hp100_rx_bm(dev); } } diff --git a/drivers/net/hp100.h b/drivers/net/hp100.h index e6ca128a5564..b60e96fe38b4 100644 --- a/drivers/net/hp100.h +++ b/drivers/net/hp100.h @@ -109,7 +109,7 @@ #define HP100_REG_MAC_CFG_2 0x0d /* RW: (8) Misc MAC functions */ #define HP100_REG_MAC_CFG_3 0x0e /* RW: (8) Misc MAC functions */ #define HP100_REG_MAC_CFG_4 0x0f /* R: (8) Misc MAC states */ -#define HP100_REG_DROPPED 0x10 /* R: (16),11:0 Pkts cant fit in mem */ +#define HP100_REG_DROPPED 0x10 /* R: (16),11:0 Pkts can't fit in mem */ #define HP100_REG_CRC 0x12 /* R: (8) Pkts with CRC */ #define HP100_REG_ABORT 0x13 /* R: (8) Aborted Tx pkts */ #define HP100_REG_TRAIN_REQUEST 0x14 /* RW: (16) Endnode MAC register. */ diff --git a/drivers/net/ibm_newemac/tah.c b/drivers/net/ibm_newemac/tah.c index 8ead6a96abaa..5f51bf7c9dc5 100644 --- a/drivers/net/ibm_newemac/tah.c +++ b/drivers/net/ibm_newemac/tah.c @@ -60,7 +60,7 @@ void tah_reset(struct platform_device *ofdev) printk(KERN_ERR "%s: reset timeout\n", ofdev->dev.of_node->full_name); - /* 10KB TAH TX FIFO accomodates the max MTU of 9000 */ + /* 10KB TAH TX FIFO accommodates the max MTU of 9000 */ out_be32(&p->mr, TAH_MR_CVR | TAH_MR_ST_768 | TAH_MR_TFS_10KB | TAH_MR_DTFP | TAH_MR_DIG); diff --git a/drivers/net/ibmlana.c b/drivers/net/ibmlana.c index 94d9969ec0bb..8ff68ae6b520 100644 --- a/drivers/net/ibmlana.c +++ b/drivers/net/ibmlana.c @@ -53,7 +53,7 @@ History: still work with 2.0.x.... Jan 28th, 2000 in Linux 2.2.13, the version.h file mysteriously didn't get - included. Added a workaround for this. Futhermore, it now + included. Added a workaround for this. Furthermore, it now not only compiles as a modules ;-) Jan 30th, 2000 newer kernels automatically probe more than one board, so the @@ -481,7 +481,7 @@ static void InitBoard(struct net_device *dev) if ((dev->flags & IFF_ALLMULTI) || netdev_mc_count(dev) > camcnt) rcrval |= RCREG_AMC; - /* promiscous mode ? */ + /* promiscuous mode ? */ if (dev->flags & IFF_PROMISC) rcrval |= RCREG_PRO; diff --git a/drivers/net/ibmlana.h b/drivers/net/ibmlana.h index aa3ddbdee4bb..accd5efc9c8a 100644 --- a/drivers/net/ibmlana.h +++ b/drivers/net/ibmlana.h @@ -90,7 +90,7 @@ typedef struct { #define RCREG_ERR 0x8000 /* accept damaged and collided pkts */ #define RCREG_RNT 0x4000 /* accept packets that are < 64 */ #define RCREG_BRD 0x2000 /* accept broadcasts */ -#define RCREG_PRO 0x1000 /* promiscous mode */ +#define RCREG_PRO 0x1000 /* promiscuous mode */ #define RCREG_AMC 0x0800 /* accept all multicasts */ #define RCREG_LB_NONE 0x0000 /* no loopback */ #define RCREG_LB_MAC 0x0200 /* MAC loopback */ diff --git a/drivers/net/igb/e1000_mac.c b/drivers/net/igb/e1000_mac.c index 90c5e01e9235..ce8255fc3c52 100644 --- a/drivers/net/igb/e1000_mac.c +++ b/drivers/net/igb/e1000_mac.c @@ -181,7 +181,7 @@ s32 igb_vfta_set(struct e1000_hw *hw, u32 vid, bool add) * address and must override the actual permanent MAC address. If an * alternate MAC address is fopund it is saved in the hw struct and * prgrammed into RAR0 and the cuntion returns success, otherwise the - * fucntion returns an error. + * function returns an error. **/ s32 igb_check_alt_mac_addr(struct e1000_hw *hw) { @@ -982,7 +982,7 @@ out: } /** - * igb_get_speed_and_duplex_copper - Retreive current speed/duplex + * igb_get_speed_and_duplex_copper - Retrieve current speed/duplex * @hw: pointer to the HW structure * @speed: stores the current speed * @duplex: stores the current duplex diff --git a/drivers/net/igb/e1000_phy.c b/drivers/net/igb/e1000_phy.c index 6694bf3e5ad9..d639706eb3f6 100644 --- a/drivers/net/igb/e1000_phy.c +++ b/drivers/net/igb/e1000_phy.c @@ -1421,7 +1421,7 @@ out: } /** - * igb_check_downshift - Checks whether a downshift in speed occured + * igb_check_downshift - Checks whether a downshift in speed occurred * @hw: pointer to the HW structure * * Success returns 0, Failure returns 1 diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 3d850af0cdda..0dfd1b93829e 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -200,7 +200,7 @@ static struct pci_driver igb_driver = { .probe = igb_probe, .remove = __devexit_p(igb_remove), #ifdef CONFIG_PM - /* Power Managment Hooks */ + /* Power Management Hooks */ .suspend = igb_suspend, .resume = igb_resume, #endif @@ -2292,7 +2292,7 @@ static void igb_init_hw_timer(struct igb_adapter *adapter) /** * Scale the NIC clock cycle by a large factor so that * relatively small clock corrections can be added or - * substracted at each clock tick. The drawbacks of a large + * subtracted at each clock tick. The drawbacks of a large * factor are a) that the clock register overflows more quickly * (not such a big deal) and b) that the increment per tick has * to fit into 24 bits. As a result we need to use a shift of @@ -3409,7 +3409,7 @@ static void igb_set_rx_mode(struct net_device *netdev) } else { /* * Write addresses to the MTA, if the attempt fails - * then we should just turn on promiscous mode so + * then we should just turn on promiscuous mode so * that we can at least receive multicast traffic */ count = igb_write_mc_addr_list(netdev); @@ -3423,7 +3423,7 @@ static void igb_set_rx_mode(struct net_device *netdev) /* * Write addresses to available RAR registers, if there is not * sufficient space to store all the addresses then enable - * unicast promiscous mode + * unicast promiscuous mode */ count = igb_write_uc_addr_list(netdev); if (count < 0) { @@ -4317,7 +4317,7 @@ netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *skb, /* * count reflects descriptors mapped, if 0 or less then mapping error - * has occured and we need to rewind the descriptor queue + * has occurred and we need to rewind the descriptor queue */ count = igb_tx_map_adv(tx_ring, skb, first); if (!count) { @@ -5352,8 +5352,8 @@ static void igb_msg_task(struct igb_adapter *adapter) * The unicast table address is a register array of 32-bit registers. * The table is meant to be used in a way similar to how the MTA is used * however due to certain limitations in the hardware it is necessary to - * set all the hash bits to 1 and use the VMOLR ROPE bit as a promiscous - * enable bit to allow vlan tag stripping when promiscous mode is enabled + * set all the hash bits to 1 and use the VMOLR ROPE bit as a promiscuous + * enable bit to allow vlan tag stripping when promiscuous mode is enabled **/ static void igb_set_uta(struct igb_adapter *adapter) { diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c index 6ccc32fd7338..1d04ca6fdaea 100644 --- a/drivers/net/igbvf/netdev.c +++ b/drivers/net/igbvf/netdev.c @@ -2227,7 +2227,7 @@ static netdev_tx_t igbvf_xmit_frame_ring_adv(struct sk_buff *skb, /* * count reflects descriptors mapped, if 0 then mapping error - * has occured and we need to rewind the descriptor queue + * has occurred and we need to rewind the descriptor queue */ count = igbvf_tx_map_adv(adapter, tx_ring, skb, first); diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c index a5b0f0e194bb..58cd3202b48c 100644 --- a/drivers/net/ipg.c +++ b/drivers/net/ipg.c @@ -486,14 +486,14 @@ static int ipg_config_autoneg(struct net_device *dev) phyctrl = ipg_r8(PHY_CTRL); mac_ctrl_val = ipg_r32(MAC_CTRL); - /* Set flags for use in resolving auto-negotation, assuming + /* Set flags for use in resolving auto-negotiation, assuming * non-1000Mbps, half duplex, no flow control. */ fullduplex = 0; txflowcontrol = 0; rxflowcontrol = 0; - /* To accomodate a problem in 10Mbps operation, + /* To accommodate a problem in 10Mbps operation, * set a global flag if PHY running in 10Mbps mode. */ sp->tenmbpsmode = 0; @@ -846,7 +846,7 @@ static void init_tfdlist(struct net_device *dev) } /* - * Free all transmit buffers which have already been transfered + * Free all transmit buffers which have already been transferred * via DMA to the IPG. */ static void ipg_nic_txfree(struct net_device *dev) @@ -920,7 +920,7 @@ static void ipg_tx_timeout(struct net_device *dev) /* * For TxComplete interrupts, free all transmit - * buffers which have already been transfered via DMA + * buffers which have already been transferred via DMA * to the IPG. */ static void ipg_nic_txcleanup(struct net_device *dev) @@ -1141,13 +1141,13 @@ static int ipg_nic_rx_check_error(struct net_device *dev) /* Increment detailed receive error statistics. */ if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFIFOOVERRUN) { - IPG_DEBUG_MSG("RX FIFO overrun occured.\n"); + IPG_DEBUG_MSG("RX FIFO overrun occurred.\n"); sp->stats.rx_fifo_errors++; } if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXRUNTFRAME) { - IPG_DEBUG_MSG("RX runt occured.\n"); + IPG_DEBUG_MSG("RX runt occurred.\n"); sp->stats.rx_length_errors++; } @@ -1156,7 +1156,7 @@ static int ipg_nic_rx_check_error(struct net_device *dev) */ if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXALIGNMENTERROR) { - IPG_DEBUG_MSG("RX alignment error occured.\n"); + IPG_DEBUG_MSG("RX alignment error occurred.\n"); sp->stats.rx_frame_errors++; } @@ -1421,12 +1421,12 @@ static int ipg_nic_rx(struct net_device *dev) /* Increment detailed receive error statistics. */ if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFIFOOVERRUN) { - IPG_DEBUG_MSG("RX FIFO overrun occured.\n"); + IPG_DEBUG_MSG("RX FIFO overrun occurred.\n"); sp->stats.rx_fifo_errors++; } if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXRUNTFRAME) { - IPG_DEBUG_MSG("RX runt occured.\n"); + IPG_DEBUG_MSG("RX runt occurred.\n"); sp->stats.rx_length_errors++; } @@ -1436,7 +1436,7 @@ static int ipg_nic_rx(struct net_device *dev) */ if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXALIGNMENTERROR) { - IPG_DEBUG_MSG("RX alignment error occured.\n"); + IPG_DEBUG_MSG("RX alignment error occurred.\n"); sp->stats.rx_frame_errors++; } @@ -1460,7 +1460,7 @@ static int ipg_nic_rx(struct net_device *dev) } } else { - /* Adjust the new buffer length to accomodate the size + /* Adjust the new buffer length to accommodate the size * of the received frame. */ skb_put(skb, framelen); @@ -1488,7 +1488,7 @@ static int ipg_nic_rx(struct net_device *dev) } /* - * If there are more RFDs to proces and the allocated amount of RFD + * If there are more RFDs to process and the allocated amount of RFD * processing time has expired, assert Interrupt Requested to make * sure we come back to process the remaining RFDs. */ @@ -1886,7 +1886,7 @@ static netdev_tx_t ipg_nic_hard_start_xmit(struct sk_buff *skb, /* Request TxComplete interrupts at an interval defined * by the constant IPG_FRAMESBETWEENTXCOMPLETES. * Request TxComplete interrupt for every frame - * if in 10Mbps mode to accomodate problem with 10Mbps + * if in 10Mbps mode to accommodate problem with 10Mbps * processing. */ if (sp->tenmbpsmode) @@ -2098,7 +2098,7 @@ static int ipg_nic_change_mtu(struct net_device *dev, int new_mtu) struct ipg_nic_private *sp = netdev_priv(dev); int err; - /* Function to accomodate changes to Maximum Transfer Unit + /* Function to accommodate changes to Maximum Transfer Unit * (or MTU) of IPG NIC. Cannot use default function since * the default will not allow for MTU > 1500 bytes. */ diff --git a/drivers/net/irda/ali-ircc.c b/drivers/net/irda/ali-ircc.c index 92631eb6f6a3..872183f29ec4 100644 --- a/drivers/net/irda/ali-ircc.c +++ b/drivers/net/irda/ali-ircc.c @@ -76,7 +76,7 @@ static int ali_ircc_probe_53(ali_chip_t *chip, chipio_t *info); static int ali_ircc_init_43(ali_chip_t *chip, chipio_t *info); static int ali_ircc_init_53(ali_chip_t *chip, chipio_t *info); -/* These are the currently known ALi sourth-bridge chipsets, the only one difference +/* These are the currently known ALi south-bridge chipsets, the only one difference * is that M1543C doesn't support HP HDSL-3600 */ static ali_chip_t chips[] = @@ -1108,7 +1108,7 @@ static void ali_ircc_sir_change_speed(struct ali_ircc_cb *priv, __u32 speed) outb(lcr, iobase+UART_LCR); /* Set 8N1 */ outb(fcr, iobase+UART_FCR); /* Enable FIFO's */ - /* without this, the conection will be broken after come back from FIR speed, + /* without this, the connection will be broken after come back from FIR speed, but with this, the SIR connection is harder to established */ outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase+UART_MCR); diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c index f81d944fc360..174cafad2c1a 100644 --- a/drivers/net/irda/donauboe.c +++ b/drivers/net/irda/donauboe.c @@ -56,7 +56,7 @@ /* do_probe module parameter Enable this code */ /* Probe code is very useful for understanding how the hardware works */ /* Use it with various combinations of TT_LEN, RX_LEN */ -/* Strongly recomended, disable if the probe fails on your machine */ +/* Strongly recommended, disable if the probe fails on your machine */ /* and send me the output of dmesg */ #define USE_PROBE 1 #undef USE_PROBE diff --git a/drivers/net/irda/donauboe.h b/drivers/net/irda/donauboe.h index 77fcf4459161..d92d54e839b9 100644 --- a/drivers/net/irda/donauboe.h +++ b/drivers/net/irda/donauboe.h @@ -51,7 +51,7 @@ /* The documentation for this chip is allegedly released */ /* However I have not seen it, not have I managed to contact */ -/* anyone who has. HOWEVER the chip bears a striking resemblence */ +/* anyone who has. HOWEVER the chip bears a striking resemblance */ /* to the IrDA controller in the Toshiba RISC TMPR3922 chip */ /* the documentation for this is freely available at */ /* http://www.madingley.org/james/resources/toshoboe/TMPR3922.pdf */ diff --git a/drivers/net/irda/girbil-sir.c b/drivers/net/irda/girbil-sir.c index a31b8fa8aaa9..96cdecff349d 100644 --- a/drivers/net/irda/girbil-sir.c +++ b/drivers/net/irda/girbil-sir.c @@ -38,7 +38,7 @@ static int girbil_change_speed(struct sir_dev *dev, unsigned speed); /* Control register 1 */ #define GIRBIL_TXEN 0x01 /* Enable transmitter */ #define GIRBIL_RXEN 0x02 /* Enable receiver */ -#define GIRBIL_ECAN 0x04 /* Cancel self emmited data */ +#define GIRBIL_ECAN 0x04 /* Cancel self emitted data */ #define GIRBIL_ECHO 0x08 /* Echo control characters */ /* LED Current Register (0x2) */ diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index e4ea61944c22..d9267cb98a23 100644 --- a/drivers/net/irda/irda-usb.c +++ b/drivers/net/irda/irda-usb.c @@ -370,7 +370,7 @@ static void speed_bulk_callback(struct urb *urb) /* urb is now available */ //urb->status = 0; -> tested above - /* New speed and xbof is now commited in hardware */ + /* New speed and xbof is now committed in hardware */ self->new_speed = -1; self->new_xbofs = -1; @@ -602,7 +602,7 @@ static void write_bulk_callback(struct urb *urb) IRDA_DEBUG(1, "%s(), Changing speed now...\n", __func__); irda_usb_change_speed_xbofs(self); } else { - /* New speed and xbof is now commited in hardware */ + /* New speed and xbof is now committed in hardware */ self->new_speed = -1; self->new_xbofs = -1; /* Done, waiting for next packet */ diff --git a/drivers/net/irda/mcs7780.c b/drivers/net/irda/mcs7780.c index cc821de2c966..be52bfed66a9 100644 --- a/drivers/net/irda/mcs7780.c +++ b/drivers/net/irda/mcs7780.c @@ -588,7 +588,7 @@ static int mcs_speed_change(struct mcs_cb *mcs) mcs_get_reg(mcs, MCS_MODE_REG, &rval); - /* MINRXPW values recomended by MosChip */ + /* MINRXPW values recommended by MosChip */ if (mcs->new_speed <= 115200) { rval &= ~MCS_FIR; @@ -799,7 +799,7 @@ static void mcs_receive_irq(struct urb *urb) ret = usb_submit_urb(urb, GFP_ATOMIC); } -/* Transmit callback funtion. */ +/* Transmit callback function. */ static void mcs_send_irq(struct urb *urb) { struct mcs_cb *mcs = urb->context; @@ -811,7 +811,7 @@ static void mcs_send_irq(struct urb *urb) netif_wake_queue(ndev); } -/* Transmit callback funtion. */ +/* Transmit callback function. */ static netdev_tx_t mcs_hard_xmit(struct sk_buff *skb, struct net_device *ndev) { diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c index 559fe854d76d..7a963d4e6d06 100644 --- a/drivers/net/irda/nsc-ircc.c +++ b/drivers/net/irda/nsc-ircc.c @@ -716,7 +716,7 @@ static int nsc_ircc_probe_338(nsc_chip_t *chip, chipio_t *info) int reg, com = 0; int pnp; - /* Read funtion enable register (FER) */ + /* Read function enable register (FER) */ outb(CFG_338_FER, cfg_base); reg = inb(cfg_base+1); diff --git a/drivers/net/irda/nsc-ircc.h b/drivers/net/irda/nsc-ircc.h index 7ba7738759b9..32fa58211fad 100644 --- a/drivers/net/irda/nsc-ircc.h +++ b/drivers/net/irda/nsc-ircc.h @@ -135,7 +135,7 @@ #define LSR_TXRDY 0x20 /* Transmitter ready */ #define LSR_TXEMP 0x40 /* Transmitter empty */ -#define ASCR 0x07 /* Auxillary Status and Control Register */ +#define ASCR 0x07 /* Auxiliary Status and Control Register */ #define ASCR_RXF_TOUT 0x01 /* Rx FIFO timeout */ #define ASCR_FEND_INF 0x02 /* Frame end bytes in rx FIFO */ #define ASCR_S_EOT 0x04 /* Set end of transmission */ diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c index c192c31e4c5c..001ed0a255f6 100644 --- a/drivers/net/irda/pxaficp_ir.c +++ b/drivers/net/irda/pxaficp_ir.c @@ -40,7 +40,7 @@ #define ICCR0_AME (1 << 7) /* Address match enable */ #define ICCR0_TIE (1 << 6) /* Transmit FIFO interrupt enable */ -#define ICCR0_RIE (1 << 5) /* Recieve FIFO interrupt enable */ +#define ICCR0_RIE (1 << 5) /* Receive FIFO interrupt enable */ #define ICCR0_RXE (1 << 4) /* Receive enable */ #define ICCR0_TXE (1 << 3) /* Transmit enable */ #define ICCR0_TUS (1 << 2) /* Transmit FIFO underrun select */ @@ -483,7 +483,7 @@ static irqreturn_t pxa_irda_fir_irq(int irq, void *dev_id) } if (icsr0 & ICSR0_EIF) { - /* An error in FIFO occured, or there is a end of frame */ + /* An error in FIFO occurred, or there is a end of frame */ pxa_irda_fir_irq_eif(si, dev, icsr0); } diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c index 1c1677cfea29..8800e1fe4129 100644 --- a/drivers/net/irda/smsc-ircc2.c +++ b/drivers/net/irda/smsc-ircc2.c @@ -1582,7 +1582,7 @@ static irqreturn_t smsc_ircc_interrupt_sir(struct net_device *dev) int iobase; int iir, lsr; - /* Already locked comming here in smsc_ircc_interrupt() */ + /* Already locked coming here in smsc_ircc_interrupt() */ /*spin_lock(&self->lock);*/ iobase = self->io.sir_base; diff --git a/drivers/net/irda/via-ircc.c b/drivers/net/irda/via-ircc.c index 67c0ad42d818..fc896854e282 100644 --- a/drivers/net/irda/via-ircc.c +++ b/drivers/net/irda/via-ircc.c @@ -29,7 +29,7 @@ F02 Oct/28/02: Add SB device ID for 3147 and 3177. 2004-02-16: - Removed unneeded 'legacy' pci stuff. -- Make sure SIR mode is set (hw_init()) before calling mode-dependant stuff. +- Make sure SIR mode is set (hw_init()) before calling mode-dependent stuff. - On speed change from core, don't send SIR frame with new speed. Use current speed and change speeds later. - Make module-param dongle_id actually work. @@ -385,7 +385,7 @@ static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id) self->io.dongle_id = dongle_id; /* The only value we must override it the baudrate */ - /* Maximum speeds and capabilities are dongle-dependant. */ + /* Maximum speeds and capabilities are dongle-dependent. */ switch( self->io.dongle_id ){ case 0x0d: self->qos.baud_rate.bits = diff --git a/drivers/net/irda/vlsi_ir.h b/drivers/net/irda/vlsi_ir.h index d66fab854bf1..a076eb125349 100644 --- a/drivers/net/irda/vlsi_ir.h +++ b/drivers/net/irda/vlsi_ir.h @@ -209,7 +209,7 @@ enum vlsi_pio_irintr { IRINTR_ACTEN = 0x80, /* activity interrupt enable */ IRINTR_ACTIVITY = 0x40, /* activity monitor (traffic detected) */ IRINTR_RPKTEN = 0x20, /* receive packet interrupt enable*/ - IRINTR_RPKTINT = 0x10, /* rx-packet transfered from fifo to memory finished */ + IRINTR_RPKTINT = 0x10, /* rx-packet transferred from fifo to memory finished */ IRINTR_TPKTEN = 0x08, /* transmit packet interrupt enable */ IRINTR_TPKTINT = 0x04, /* last bit of tx-packet+crc shifted to ir-pulser */ IRINTR_OE_EN = 0x02, /* UART rx fifo overrun error interrupt enable */ @@ -739,7 +739,7 @@ typedef struct vlsi_irda_dev { /* the remapped error flags we use for returning from frame * post-processing in vlsi_process_tx/rx() after it was completed * by the hardware. These functions either return the >=0 number - * of transfered bytes in case of success or the negative (-) + * of transferred bytes in case of success or the negative (-) * of the or'ed error flags. */ diff --git a/drivers/net/ixgbe/ixgbe_dcb.c b/drivers/net/ixgbe/ixgbe_dcb.c index 41c529fac0ab..686a17aadef3 100644 --- a/drivers/net/ixgbe/ixgbe_dcb.c +++ b/drivers/net/ixgbe/ixgbe_dcb.c @@ -36,7 +36,7 @@ /** * ixgbe_ieee_credits - This calculates the ieee traffic class * credits from the configured bandwidth percentages. Credits - * are the smallest unit programable into the underlying + * are the smallest unit programmable into the underlying * hardware. The IEEE 802.1Qaz specification do not use bandwidth * groups so this is much simplified from the CEE case. */ diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index fec4c724c37a..327c8614198c 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c @@ -360,7 +360,7 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) return DCB_NO_HW_CHG; /* - * Only take down the adapter if an app change occured. FCoE + * Only take down the adapter if an app change occurred. FCoE * may shuffle tx rings in this case and this can not be done * without a reset currently. */ @@ -599,7 +599,7 @@ static u8 ixgbe_dcbnl_setapp(struct net_device *netdev, break; /* The FCoE application priority may be changed multiple - * times in quick sucession with switches that build up + * times in quick succession with switches that build up * TLVs. To avoid creating uneeded device resets this * checks the actual HW configuration and clears * BIT_APP_UPCHG if a HW configuration change is not diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index f17e4a7ee731..6f8adc7f5d7c 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -644,7 +644,7 @@ void ixgbe_unmap_and_free_tx_resource(struct ixgbe_ring *tx_ring, * @adapter: driver private struct * @index: reg idx of queue to query (0-127) * - * Helper function to determine the traffic index for a paticular + * Helper function to determine the traffic index for a particular * register index. * * Returns : a tc index for use in range 0-7, or 0-3 @@ -3556,7 +3556,7 @@ void ixgbe_set_rx_mode(struct net_device *netdev) } else { /* * Write addresses to the MTA, if the attempt fails - * then we should just turn on promiscous mode so + * then we should just turn on promiscuous mode so * that we can at least receive multicast traffic */ hw->mac.ops.update_mc_addr_list(hw, netdev); @@ -3567,7 +3567,7 @@ void ixgbe_set_rx_mode(struct net_device *netdev) /* * Write addresses to available RAR registers, if there is not * sufficient space to store all the addresses then enable - * unicast promiscous mode + * unicast promiscuous mode */ count = ixgbe_write_uc_addr_list(netdev); if (count < 0) { @@ -4443,7 +4443,7 @@ static inline bool ixgbe_set_sriov_queues(struct ixgbe_adapter *adapter) } /* - * ixgbe_set_num_queues: Allocate queues for device, feature dependant + * ixgbe_set_num_queues: Allocate queues for device, feature dependent * @adapter: board private structure to initialize * * This is the top level queue allocation routine. The order here is very diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c index f72f705f6183..df5b8aa4795d 100644 --- a/drivers/net/ixgbe/ixgbe_phy.c +++ b/drivers/net/ixgbe/ixgbe_phy.c @@ -1694,7 +1694,7 @@ static void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw) } /** - * ixgbe_tn_check_overtemp - Checks if an overtemp occured. + * ixgbe_tn_check_overtemp - Checks if an overtemp occurred. * @hw: pointer to hardware structure * * Checks if the LASI temp alarm status was triggered due to overtemp diff --git a/drivers/net/ixgbe/ixgbe_x540.c b/drivers/net/ixgbe/ixgbe_x540.c index f47e93fe32be..d9323c08f5c7 100644 --- a/drivers/net/ixgbe/ixgbe_x540.c +++ b/drivers/net/ixgbe/ixgbe_x540.c @@ -573,7 +573,7 @@ static s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask) * @hw: pointer to hardware structure * @mask: Mask to specify which semaphore to release * - * Releases the SWFW semaphore throught the SW_FW_SYNC register + * Releases the SWFW semaphore through the SW_FW_SYNC register * for the specified function (CSR, PHY0, PHY1, EVM, Flash) **/ static void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask) diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index 054ab05b7c6a..05fa7c85deed 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c @@ -1925,7 +1925,7 @@ static void ixgbevf_acquire_msix_vectors(struct ixgbevf_adapter *adapter, } /* - * ixgbevf_set_num_queues: Allocate queues for device, feature dependant + * ixgbevf_set_num_queues: Allocate queues for device, feature dependent * @adapter: board private structure to initialize * * This is the top level queue allocation routine. The order here is very diff --git a/drivers/net/ks8842.c b/drivers/net/ks8842.c index efd44afeae83..f0d8346d0fa5 100644 --- a/drivers/net/ks8842.c +++ b/drivers/net/ks8842.c @@ -321,7 +321,7 @@ static void ks8842_reset_hw(struct ks8842_adapter *adapter) /* RX 2 kb high watermark */ ks8842_write16(adapter, 0, 0x1000, REG_QRFCR); - /* aggresive back off in half duplex */ + /* aggressive back off in half duplex */ ks8842_enable_bits(adapter, 32, 1 << 8, REG_SGCR1); /* enable no excessive collison drop */ diff --git a/drivers/net/ks8851.c b/drivers/net/ks8851.c index 0fa4a9887ba2..bcd9ba68c9f2 100644 --- a/drivers/net/ks8851.c +++ b/drivers/net/ks8851.c @@ -141,7 +141,7 @@ static int msg_enable; * * All these calls issue SPI transactions to access the chip's registers. They * all require that the necessary lock is held to prevent accesses when the - * chip is busy transfering packet data (RX/TX FIFO accesses). + * chip is busy transferring packet data (RX/TX FIFO accesses). */ /** @@ -483,7 +483,7 @@ static void ks8851_rx_pkts(struct ks8851_net *ks) * * This form of operation would require us to hold the SPI bus' * chipselect low during the entie transaction to avoid any - * reset to the data stream comming from the chip. + * reset to the data stream coming from the chip. */ for (; rxfc != 0; rxfc--) { @@ -634,7 +634,7 @@ static void ks8851_irq_work(struct work_struct *work) /** * calc_txlen - calculate size of message to send packet - * @len: Lenght of data + * @len: Length of data * * Returns the size of the TXFIFO message needed to send * this packet. @@ -1472,7 +1472,7 @@ static int ks8851_phy_reg(int reg) * @reg: The register to read. * * This call reads data from the PHY register specified in @reg. Since the - * device does not support all the MII registers, the non-existant values + * device does not support all the MII registers, the non-existent values * are always returned as zero. * * We return zero for unsupported registers as the MII code does not check diff --git a/drivers/net/ks8851_mll.c b/drivers/net/ks8851_mll.c index 2e2c69b24062..61631cace913 100644 --- a/drivers/net/ks8851_mll.c +++ b/drivers/net/ks8851_mll.c @@ -470,7 +470,7 @@ static int msg_enable; * * All these calls issue transactions to access the chip's registers. They * all require that the necessary lock is held to prevent accesses when the - * chip is busy transfering packet data (RX/TX FIFO accesses). + * chip is busy transferring packet data (RX/TX FIFO accesses). */ /** @@ -1364,7 +1364,7 @@ static int ks_phy_reg(int reg) * @reg: The register to read. * * This call reads data from the PHY register specified in @reg. Since the - * device does not support all the MII registers, the non-existant values + * device does not support all the MII registers, the non-existent values * are always returned as zero. * * We return zero for unsupported registers as the MII code does not check diff --git a/drivers/net/lib8390.c b/drivers/net/lib8390.c index da74db4a03d4..17b75e5f1b0a 100644 --- a/drivers/net/lib8390.c +++ b/drivers/net/lib8390.c @@ -35,7 +35,7 @@ Alexey Kuznetsov : use the 8390's six bit hash multicast filter. Paul Gortmaker : tweak ANK's above multicast changes a bit. Paul Gortmaker : update packet statistics for v2.1.x - Alan Cox : support arbitary stupid port mappings on the + Alan Cox : support arbitrary stupid port mappings on the 68K Macintosh. Support >16bit I/O spaces Paul Gortmaker : add kmod support for auto-loading of the 8390 module by all drivers that require it. @@ -121,7 +121,7 @@ static void __NS8390_init(struct net_device *dev, int startp); /* * SMP and the 8390 setup. * - * The 8390 isnt exactly designed to be multithreaded on RX/TX. There is + * The 8390 isn't exactly designed to be multithreaded on RX/TX. There is * a page register that controls bank and packet buffer access. We guard * this with ei_local->page_lock. Nobody should assume or set the page other * than zero when the lock is not held. Lock holders must restore page 0 diff --git a/drivers/net/lp486e.c b/drivers/net/lp486e.c index 3698824744cb..385a95311cd2 100644 --- a/drivers/net/lp486e.c +++ b/drivers/net/lp486e.c @@ -27,7 +27,7 @@ Credits: Thanks to Murphy Software BV for letting me write this in their time. - Well, actually, I get payed doing this... + Well, actually, I get paid doing this... (Also: see http://www.murphy.nl for murphy, and my homepage ~ard for more information on the Professional Workstation) diff --git a/drivers/net/meth.h b/drivers/net/meth.h index a78dc1ca8c29..5b145c6bad60 100644 --- a/drivers/net/meth.h +++ b/drivers/net/meth.h @@ -144,7 +144,7 @@ typedef struct rx_packet { /* Bits 22 through 28 are used to determine IPGR2 */ #define METH_REV_SHIFT 29 /* Bits 29 through 31 are used to determine the revision */ - /* 000: Inital revision */ + /* 000: Initial revision */ /* 001: First revision, Improved TX concatenation */ @@ -193,7 +193,7 @@ typedef struct rx_packet { /* 1: A TX message had the INT request bit set, the packet has been sent. */ #define METH_INT_TX_LINK_FAIL BIT(2) /* 0: No interrupt pending, 1: PHY has reported a link failure */ #define METH_INT_MEM_ERROR BIT(3) /* 0: No interrupt pending */ - /* 1: A memory error occurred durring DMA, DMA stopped, Fatal */ + /* 1: A memory error occurred during DMA, DMA stopped, Fatal */ #define METH_INT_TX_ABORT BIT(4) /* 0: No interrupt pending, 1: The TX aborted operation, DMA stopped, FATAL */ #define METH_INT_RX_THRESHOLD BIT(5) /* 0: No interrupt pending, 1: Selected receive threshold condition Valid */ #define METH_INT_RX_UNDERFLOW BIT(6) /* 0: No interrupt pending, 1: FIFO was empty, packet could not be queued */ diff --git a/drivers/net/mlx4/en_main.c b/drivers/net/mlx4/en_main.c index 9317b61a75b8..9276b1b25586 100644 --- a/drivers/net/mlx4/en_main.c +++ b/drivers/net/mlx4/en_main.c @@ -236,7 +236,7 @@ static void *mlx4_en_add(struct mlx4_dev *dev) goto err_mr; } - /* Configure wich ports to start according to module parameters */ + /* Configure which ports to start according to module parameters */ mdev->port_cnt = 0; mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_ETH) mdev->port_cnt++; diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c index 4f158baa0246..77063f91c564 100644 --- a/drivers/net/mlx4/en_netdev.c +++ b/drivers/net/mlx4/en_netdev.c @@ -247,7 +247,7 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) priv->port); if (err) en_err(priv, "Failed enabling " - "promiscous mode\n"); + "promiscuous mode\n"); /* Disable port multicast filter (unconditionally) */ err = mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0, @@ -276,7 +276,7 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) } /* - * Not in promiscous mode + * Not in promiscuous mode */ if (priv->flags & MLX4_EN_FLAG_PROMISC) { @@ -292,14 +292,14 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) err = mlx4_unicast_promisc_remove(mdev->dev, priv->base_qpn, priv->port); if (err) - en_err(priv, "Failed disabling promiscous mode\n"); + en_err(priv, "Failed disabling promiscuous mode\n"); /* Disable Multicast promisc */ if (priv->flags & MLX4_EN_FLAG_MC_PROMISC) { err = mlx4_multicast_promisc_remove(mdev->dev, priv->base_qpn, priv->port); if (err) - en_err(priv, "Failed disabling multicast promiscous mode\n"); + en_err(priv, "Failed disabling multicast promiscuous mode\n"); priv->flags &= ~MLX4_EN_FLAG_MC_PROMISC; } @@ -331,7 +331,7 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) err = mlx4_multicast_promisc_remove(mdev->dev, priv->base_qpn, priv->port); if (err) - en_err(priv, "Failed disabling multicast promiscous mode\n"); + en_err(priv, "Failed disabling multicast promiscuous mode\n"); priv->flags &= ~MLX4_EN_FLAG_MC_PROMISC; } diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c index 05998ee297c9..cfd50bc49169 100644 --- a/drivers/net/mlx4/en_rx.c +++ b/drivers/net/mlx4/en_rx.c @@ -706,7 +706,7 @@ int mlx4_en_poll_rx_cq(struct napi_struct *napi, int budget) } -/* Calculate the last offset position that accomodates a full fragment +/* Calculate the last offset position that accommodates a full fragment * (assuming fagment size = stride-align) */ static int mlx4_en_last_alloc_offset(struct mlx4_en_priv *priv, u16 stride, u16 align) { diff --git a/drivers/net/mlx4/en_selftest.c b/drivers/net/mlx4/en_selftest.c index 9c91a92da705..191a8dcd8a93 100644 --- a/drivers/net/mlx4/en_selftest.c +++ b/drivers/net/mlx4/en_selftest.c @@ -149,7 +149,7 @@ void mlx4_en_ex_selftest(struct net_device *dev, u32 *flags, u64 *buf) netif_carrier_off(dev); retry_tx: - /* Wait untill all tx queues are empty. + /* Wait until all tx queues are empty. * there should not be any additional incoming traffic * since we turned the carrier off */ msleep(200); diff --git a/drivers/net/mlx4/en_tx.c b/drivers/net/mlx4/en_tx.c index 01feb8fd42ad..b229acf1855f 100644 --- a/drivers/net/mlx4/en_tx.c +++ b/drivers/net/mlx4/en_tx.c @@ -636,7 +636,7 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) if (unlikely(!real_size)) goto tx_drop; - /* Allign descriptor to TXBB size */ + /* Align descriptor to TXBB size */ desc_size = ALIGN(real_size, TXBB_SIZE); nr_txbb = desc_size / TXBB_SIZE; if (unlikely(nr_txbb > MAX_DESC_TXBBS)) { diff --git a/drivers/net/mlx4/mcg.c b/drivers/net/mlx4/mcg.c index e71372aa9cc4..279521aed826 100644 --- a/drivers/net/mlx4/mcg.c +++ b/drivers/net/mlx4/mcg.c @@ -222,7 +222,7 @@ static int existing_steering_entry(struct mlx4_dev *dev, u8 vep_num, u8 port, /* the given qpn is listed as a promisc qpn * we need to add it as a duplicate to this entry - * for future refernce */ + * for future references */ list_for_each_entry(dqp, &entry->duplicates, list) { if (qpn == dqp->qpn) return 0; /* qp is already duplicated */ diff --git a/drivers/net/mlx4/port.c b/drivers/net/mlx4/port.c index eca7d8596f87..8856659fb43c 100644 --- a/drivers/net/mlx4/port.c +++ b/drivers/net/mlx4/port.c @@ -172,7 +172,7 @@ int mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac, int *qpn, u8 wrap) } if (mac == (MLX4_MAC_MASK & be64_to_cpu(table->entries[i]))) { - /* MAC already registered, increase refernce count */ + /* MAC already registered, increase references count */ ++table->refs[i]; goto out; } @@ -360,7 +360,7 @@ int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index) if (table->refs[i] && (vlan == (MLX4_VLAN_MASK & be32_to_cpu(table->entries[i])))) { - /* Vlan already registered, increase refernce count */ + /* Vlan already registered, increase references count */ *index = i; ++table->refs[i]; goto out; diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 673dc600c891..1446de59ae53 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -3702,7 +3702,7 @@ abort: /* * This function determines the number of slices supported. - * The number slices is the minumum of the number of CPUS, + * The number slices is the minimum of the number of CPUS, * the number of MSI-X irqs supported, the number of slices * supported by the firmware */ diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c index a761076b69c3..53aeea4b536e 100644 --- a/drivers/net/myri_sbus.c +++ b/drivers/net/myri_sbus.c @@ -1009,7 +1009,7 @@ static int __devinit myri_sbus_probe(struct platform_device *op) /* Map in the MyriCOM register/localram set. */ if (mp->eeprom.cpuvers < CPUVERS_4_0) { - /* XXX Makes no sense, if control reg is non-existant this + /* XXX Makes no sense, if control reg is non-existent this * XXX driver cannot function at all... maybe pre-4.0 is * XXX only a valid version for PCI cards? Ask feldy... */ diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c index 2fd39630b1e5..aa2813e06d00 100644 --- a/drivers/net/natsemi.c +++ b/drivers/net/natsemi.c @@ -203,7 +203,7 @@ skbuff at an offset of "+2", 16-byte aligning the IP header. IIId. Synchronization Most operations are synchronized on the np->lock irq spinlock, except the -recieve and transmit paths which are synchronised using a combination of +receive and transmit paths which are synchronised using a combination of hardware descriptor ownership, disabling interrupts and NAPI poll scheduling. IVb. References @@ -726,7 +726,7 @@ static void move_int_phy(struct net_device *dev, int addr) * There are two addresses we must avoid: * - the address on the external phy that is used for transmission. * - the address that we want to access. User space can access phys - * on the mii bus with SIOCGMIIREG/SIOCSMIIREG, independant from the + * on the mii bus with SIOCGMIIREG/SIOCSMIIREG, independent from the * phy that is used for transmission. */ @@ -1982,7 +1982,7 @@ static void init_ring(struct net_device *dev) np->rx_head_desc = &np->rx_ring[0]; - /* Please be carefull before changing this loop - at least gcc-2.95.1 + /* Please be careful before changing this loop - at least gcc-2.95.1 * miscompiles it otherwise. */ /* Initialize all Rx descriptors. */ diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h index d8bd73d7e296..dc1967c1f312 100644 --- a/drivers/net/netxen/netxen_nic_hdr.h +++ b/drivers/net/netxen/netxen_nic_hdr.h @@ -780,7 +780,7 @@ enum { /* * capabilities register, can be used to selectively enable/disable features - * for backward compability + * for backward compatibility */ #define CRB_NIC_CAPABILITIES_HOST NETXEN_NIC_REG(0x1a8) #define CRB_NIC_MSI_MODE_HOST NETXEN_NIC_REG(0x270) diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c index a41b2cf4d917..6667e0667a88 100644 --- a/drivers/net/ns83820.c +++ b/drivers/net/ns83820.c @@ -512,7 +512,7 @@ static void ns83820_vlan_rx_register(struct net_device *ndev, struct vlan_group /* Packet Receiver * * The hardware supports linked lists of receive descriptors for - * which ownership is transfered back and forth by means of an + * which ownership is transferred back and forth by means of an * ownership bit. While the hardware does support the use of a * ring for receive descriptors, we only make use of a chain in * an attempt to reduce bus traffic under heavy load scenarios. @@ -1147,7 +1147,7 @@ again: #ifdef NS83820_VLAN_ACCEL_SUPPORT if(vlan_tx_tag_present(skb)) { /* fetch the vlan tag info out of the - * ancilliary data if the vlan code + * ancillary data if the vlan code * is using hw vlan acceleration */ short tag = vlan_tx_tag_get(skb); diff --git a/drivers/net/pch_gbe/pch_gbe.h b/drivers/net/pch_gbe/pch_gbe.h index e1e33c80fb25..bf126e76fabf 100644 --- a/drivers/net/pch_gbe/pch_gbe.h +++ b/drivers/net/pch_gbe/pch_gbe.h @@ -351,7 +351,7 @@ struct pch_gbe_functions { }; /** - * struct pch_gbe_mac_info - MAC infomation + * struct pch_gbe_mac_info - MAC information * @addr[6]: Store the MAC address * @fc: Mode of flow control * @fc_autoneg: Auto negotiation enable for flow control setting @@ -375,7 +375,7 @@ struct pch_gbe_mac_info { }; /** - * struct pch_gbe_phy_info - PHY infomation + * struct pch_gbe_phy_info - PHY information * @addr: PHY address * @id: PHY's identifier * @revision: PHY's revision @@ -393,7 +393,7 @@ struct pch_gbe_phy_info { /*! * @ingroup Gigabit Ether driver Layer * @struct pch_gbe_bus_info - * @brief Bus infomation + * @brief Bus information */ struct pch_gbe_bus_info { u8 type; @@ -404,7 +404,7 @@ struct pch_gbe_bus_info { /*! * @ingroup Gigabit Ether driver Layer * @struct pch_gbe_hw - * @brief Hardware infomation + * @brief Hardware information */ struct pch_gbe_hw { void *back; @@ -462,7 +462,7 @@ struct pch_gbe_tx_desc { /** - * struct pch_gbe_buffer - Buffer infomation + * struct pch_gbe_buffer - Buffer information * @skb: pointer to a socket buffer * @dma: DMA address * @time_stamp: time stamp @@ -477,7 +477,7 @@ struct pch_gbe_buffer { }; /** - * struct pch_gbe_tx_ring - tx ring infomation + * struct pch_gbe_tx_ring - tx ring information * @tx_lock: spinlock structs * @desc: pointer to the descriptor ring memory * @dma: physical address of the descriptor ring @@ -499,7 +499,7 @@ struct pch_gbe_tx_ring { }; /** - * struct pch_gbe_rx_ring - rx ring infomation + * struct pch_gbe_rx_ring - rx ring information * @desc: pointer to the descriptor ring memory * @dma: physical address of the descriptor ring * @size: length of descriptor ring in bytes diff --git a/drivers/net/pch_gbe/pch_gbe_ethtool.c b/drivers/net/pch_gbe/pch_gbe_ethtool.c index c8c873b31a89..d2174a40d708 100644 --- a/drivers/net/pch_gbe/pch_gbe_ethtool.c +++ b/drivers/net/pch_gbe/pch_gbe_ethtool.c @@ -21,7 +21,7 @@ #include "pch_gbe_api.h" /** - * pch_gbe_stats - Stats item infomation + * pch_gbe_stats - Stats item information */ struct pch_gbe_stats { char string[ETH_GSTRING_LEN]; diff --git a/drivers/net/pch_gbe/pch_gbe_main.c b/drivers/net/pch_gbe/pch_gbe_main.c index 50986840c99c..2ef2f9cdefa6 100644 --- a/drivers/net/pch_gbe/pch_gbe_main.c +++ b/drivers/net/pch_gbe/pch_gbe_main.c @@ -1011,7 +1011,7 @@ static void pch_gbe_tx_queue(struct pch_gbe_adapter *adapter, tmp_skb->len = skb->len; memcpy(&tmp_skb->data[ETH_HLEN + 2], &skb->data[ETH_HLEN], (skb->len - ETH_HLEN)); - /*-- Set Buffer infomation --*/ + /*-- Set Buffer information --*/ buffer_info->length = tmp_skb->len; buffer_info->dma = dma_map_single(&adapter->pdev->dev, tmp_skb->data, buffer_info->length, @@ -1540,7 +1540,7 @@ int pch_gbe_setup_tx_resources(struct pch_gbe_adapter *adapter, size = (int)sizeof(struct pch_gbe_buffer) * tx_ring->count; tx_ring->buffer_info = vzalloc(size); if (!tx_ring->buffer_info) { - pr_err("Unable to allocate memory for the buffer infomation\n"); + pr_err("Unable to allocate memory for the buffer information\n"); return -ENOMEM; } diff --git a/drivers/net/pci-skeleton.c b/drivers/net/pci-skeleton.c index 1766dc4f07e1..c0f23376a462 100644 --- a/drivers/net/pci-skeleton.c +++ b/drivers/net/pci-skeleton.c @@ -214,7 +214,7 @@ static struct { { "SMC1211TX EZCard 10/100 (RealTek RTL8139)" }, /* { MPX5030, "Accton MPX5030 (RealTek RTL8139)" },*/ { "Delta Electronics 8139 10/100BaseTX" }, - { "Addtron Technolgy 8139 10/100BaseTX" }, + { "Addtron Technology 8139 10/100BaseTX" }, }; diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c index 321b12f82645..81ac330f931d 100644 --- a/drivers/net/pcmcia/3c574_cs.c +++ b/drivers/net/pcmcia/3c574_cs.c @@ -950,7 +950,7 @@ static struct net_device_stats *el3_get_stats(struct net_device *dev) } /* Update statistics. - Suprisingly this need not be run single-threaded, but it effectively is. + Surprisingly this need not be run single-threaded, but it effectively is. The counters clear when read, so the adds must merely be atomic. */ static void update_stats(struct net_device *dev) diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index d3cb77205863..3077d72e8222 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c @@ -780,7 +780,7 @@ module_exit(exit_axnet_cs); Alexey Kuznetsov : use the 8390's six bit hash multicast filter. Paul Gortmaker : tweak ANK's above multicast changes a bit. Paul Gortmaker : update packet statistics for v2.1.x - Alan Cox : support arbitary stupid port mappings on the + Alan Cox : support arbitrary stupid port mappings on the 68K Macintosh. Support >16bit I/O spaces Paul Gortmaker : add kmod support for auto-loading of the 8390 module by all drivers that require it. @@ -842,7 +842,7 @@ static void do_set_multicast_list(struct net_device *dev); /* * SMP and the 8390 setup. * - * The 8390 isnt exactly designed to be multithreaded on RX/TX. There is + * The 8390 isn't exactly designed to be multithreaded on RX/TX. There is * a page register that controls bank and packet buffer access. We guard * this with ei_local->page_lock. Nobody should assume or set the page other * than zero when the lock is not held. Lock holders must restore page 0 diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index 8a9ff5318923..108591756440 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c @@ -1264,7 +1264,7 @@ static netdev_tx_t smc_start_xmit(struct sk_buff *skb, /*====================================================================== - Handle a Tx anomolous event. Entered while in Window 2. + Handle a Tx anomalous event. Entered while in Window 2. ======================================================================*/ diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index aee3bb0358bf..768037602dff 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c @@ -1651,7 +1651,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev) /* * On selected chips turn on the BCR18:NOUFLO bit. This stops transmit * starting until the packet is loaded. Strike one for reliability, lose - * one for latency - although on PCI this isnt a big loss. Older chips + * one for latency - although on PCI this isn't a big loss. Older chips * have FIFO's smaller than a packet, so you can't do this. * Turn on BCR18:BurstRdEn and BCR18:BurstWrEn. */ diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 993c52c82aeb..ff6129319b89 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -534,7 +534,7 @@ EXPORT_SYMBOL(phy_detach); /* Generic PHY support and helper functions */ /** - * genphy_config_advert - sanitize and advertise auto-negotation parameters + * genphy_config_advert - sanitize and advertise auto-negotiation parameters * @phydev: target phy_device struct * * Description: Writes MII_ADVERTISE with the appropriate values, @@ -683,7 +683,7 @@ int genphy_config_aneg(struct phy_device *phydev) return result; if (result == 0) { - /* Advertisment hasn't changed, but maybe aneg was never on to + /* Advertisement hasn't changed, but maybe aneg was never on to * begin with? Or maybe phy was isolated? */ int ctl = phy_read(phydev, MII_BMCR); diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 9f6d670748d1..4609bc0e2f56 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -1448,7 +1448,7 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb) /* *check if we are on the last channel or - *we exceded the lenght of the data to + *we exceded the length of the data to *fragment */ if ((nfree <= 0) || (flen > len)) diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c index 4e6b72f57de8..2573f525f11c 100644 --- a/drivers/net/ppp_synctty.c +++ b/drivers/net/ppp_synctty.c @@ -178,7 +178,7 @@ ppp_print_buffer (const char *name, const __u8 *buf, int count) * way to fix this is to use a rwlock in the tty struct, but for now * we use a single global rwlock for all ttys in ppp line discipline. * - * FIXME: Fixed in tty_io nowdays. + * FIXME: Fixed in tty_io nowadays. */ static DEFINE_RWLOCK(disc_data_lock); diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index 78c0e3c9b2b5..693aaef4e3ce 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c @@ -115,7 +115,7 @@ struct pppoe_net { * 2) Session stage (MAC and SID are known) * * Ethernet frames have a special tag for this but - * we use simplier approach based on session id + * we use simpler approach based on session id */ static inline bool stage_session(__be16 sid) { diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c index 5ecfa4b1e758..ffdf7349ef7a 100644 --- a/drivers/net/ps3_gelic_net.c +++ b/drivers/net/ps3_gelic_net.c @@ -632,7 +632,7 @@ static inline void gelic_card_enable_rxdmac(struct gelic_card *card) * @card: card structure * * gelic_card_disable_rxdmac terminates processing on the DMA controller by - * turing off DMA and issueing a force end + * turing off DMA and issuing a force end */ static inline void gelic_card_disable_rxdmac(struct gelic_card *card) { @@ -650,7 +650,7 @@ static inline void gelic_card_disable_rxdmac(struct gelic_card *card) * @card: card structure * * gelic_card_disable_txdmac terminates processing on the DMA controller by - * turing off DMA and issueing a force end + * turing off DMA and issuing a force end */ static inline void gelic_card_disable_txdmac(struct gelic_card *card) { diff --git a/drivers/net/ps3_gelic_net.h b/drivers/net/ps3_gelic_net.h index 32521ae5e824..fadadf9097a3 100644 --- a/drivers/net/ps3_gelic_net.h +++ b/drivers/net/ps3_gelic_net.h @@ -117,7 +117,7 @@ enum gelic_descr_rx_error { GELIC_DESCR_RXDATAERR = 0x00020000, /* IP packet format error */ GELIC_DESCR_RXCALERR = 0x00010000, /* cariier extension length * error */ - GELIC_DESCR_RXCREXERR = 0x00008000, /* carrier extention error */ + GELIC_DESCR_RXCREXERR = 0x00008000, /* carrier extension error */ GELIC_DESCR_RXMLTCST = 0x00004000, /* multicast address frame */ /* bit 13..0 reserved */ }; diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c index 4a624a29393f..b5ae29d20f2e 100644 --- a/drivers/net/ps3_gelic_wireless.c +++ b/drivers/net/ps3_gelic_wireless.c @@ -814,7 +814,7 @@ static int gelic_wl_set_auth(struct net_device *netdev, * you will not decide suitable cipher from * its beacon. * You should have knowledge about the AP's - * cipher infomation in other method prior to + * cipher information in other method prior to * the association. */ if (!precise_ie()) diff --git a/drivers/net/pxa168_eth.c b/drivers/net/pxa168_eth.c index 1b63c8aef121..89f7540d90f9 100644 --- a/drivers/net/pxa168_eth.c +++ b/drivers/net/pxa168_eth.c @@ -462,7 +462,7 @@ static u32 hash_function(unsigned char *mac_addr_orig) * pep - ETHERNET . * mac_addr - MAC address. * skip - if 1, skip this address.Used in case of deleting an entry which is a - * part of chain in the hash table.We cant just delete the entry since + * part of chain in the hash table.We can't just delete the entry since * that will break the chain.We need to defragment the tables time to * time. * rd - 0 Discard packet upon match. diff --git a/drivers/net/qla3xxx.h b/drivers/net/qla3xxx.h index 3362a661248c..73e234366a82 100644 --- a/drivers/net/qla3xxx.h +++ b/drivers/net/qla3xxx.h @@ -770,7 +770,7 @@ enum { FM93C56A_WDS = 0x0, FM93C56A_ERASE = 0x3, FM93C56A_ERASE_ALL = 0x0, -/* Command Extentions */ +/* Command Extensions */ FM93C56A_WEN_EXT = 0x3, FM93C56A_WRITE_ALL_EXT = 0x1, FM93C56A_WDS_EXT = 0x0, diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 49bfa5813068..5bb311945436 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -660,7 +660,7 @@ static void ql_disable_interrupts(struct ql_adapter *qdev) /* If we're running with multiple MSI-X vectors then we enable on the fly. * Otherwise, we may have multiple outstanding workers and don't want to * enable until the last one finishes. In this case, the irq_cnt gets - * incremented everytime we queue a worker and decremented everytime + * incremented every time we queue a worker and decremented every time * a worker finishes. Once it hits zero we enable the interrupt. */ u32 ql_enable_completion_interrupt(struct ql_adapter *qdev, u32 intr) @@ -3299,7 +3299,7 @@ msi: * will service it. An example would be if there are * 2 vectors (so 2 RSS rings) and 8 TX completion rings. * This would mean that vector 0 would service RSS ring 0 - * and TX competion rings 0,1,2 and 3. Vector 1 would + * and TX completion rings 0,1,2 and 3. Vector 1 would * service RSS ring 1 and TX completion rings 4,5,6 and 7. */ static void ql_set_tx_vect(struct ql_adapter *qdev) @@ -4152,7 +4152,7 @@ static int ql_change_rx_buffers(struct ql_adapter *qdev) int i, status; u32 lbq_buf_len; - /* Wait for an oustanding reset to complete. */ + /* Wait for an outstanding reset to complete. */ if (!test_bit(QL_ADAPTER_UP, &qdev->flags)) { int i = 3; while (i-- && !test_bit(QL_ADAPTER_UP, &qdev->flags)) { @@ -4281,7 +4281,7 @@ static void qlge_set_multicast_list(struct net_device *ndev) if (ql_set_routing_reg (qdev, RT_IDX_PROMISCUOUS_SLOT, RT_IDX_VALID, 1)) { netif_err(qdev, hw, qdev->ndev, - "Failed to set promiscous mode.\n"); + "Failed to set promiscuous mode.\n"); } else { set_bit(QL_PROMISCUOUS, &qdev->flags); } @@ -4291,7 +4291,7 @@ static void qlge_set_multicast_list(struct net_device *ndev) if (ql_set_routing_reg (qdev, RT_IDX_PROMISCUOUS_SLOT, RT_IDX_VALID, 0)) { netif_err(qdev, hw, qdev->ndev, - "Failed to clear promiscous mode.\n"); + "Failed to clear promiscuous mode.\n"); } else { clear_bit(QL_PROMISCUOUS, &qdev->flags); } diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index e3ebd90ae651..200a363c3bf5 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c @@ -535,7 +535,7 @@ static int r6040_rx(struct net_device *dev, int limit) /* RX dribble */ if (err & DSC_RX_ERR_DRI) dev->stats.rx_frame_errors++; - /* Buffer lenght exceeded */ + /* Buffer length exceeded */ if (err & DSC_RX_ERR_BUF) dev->stats.rx_length_errors++; /* Packet too long */ diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 356e74d20b80..337bdcd5abc9 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -2353,7 +2353,7 @@ static int start_nic(struct s2io_nic *nic) if (s2io_link_fault_indication(nic) == MAC_RMAC_ERR_TIMER) { /* - * Dont see link state interrupts initally on some switches, + * Dont see link state interrupts initially on some switches, * so directly scheduling the link state task here. */ schedule_work(&nic->set_link_task); @@ -3563,7 +3563,7 @@ static void s2io_reset(struct s2io_nic *sp) } /* - * Clear spurious ECC interrupts that would have occured on + * Clear spurious ECC interrupts that would have occurred on * XFRAME II cards after reset. */ if (sp->device_type == XFRAME_II_DEVICE) { @@ -4065,7 +4065,7 @@ static int s2io_close(struct net_device *dev) * Description : * This function is the Tx entry point of the driver. S2IO NIC supports * certain protocol assist features on Tx side, namely CSO, S/G, LSO. - * NOTE: when device cant queue the pkt,just the trans_start variable will + * NOTE: when device can't queue the pkt,just the trans_start variable will * not be upadted. * Return value: * 0 on success & 1 on failure. diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index 7d160306b651..2d144979f6f8 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h @@ -376,7 +376,7 @@ static const u16 fifo_selector[MAX_TX_FIFOS] = {0, 1, 3, 3, 7, 7, 7, 7}; /* Maintains Per FIFO related information. */ struct tx_fifo_config { #define MAX_AVAILABLE_TXDS 8192 - u32 fifo_len; /* specifies len of FIFO upto 8192, ie no of TxDLs */ + u32 fifo_len; /* specifies len of FIFO up to 8192, ie no of TxDLs */ /* Priority definition */ #define TX_FIFO_PRI_0 0 /*Highest */ #define TX_FIFO_PRI_1 1 diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 734fcfb52e85..d96b23769bd1 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -692,7 +692,7 @@ static int falcon_gmii_wait(struct efx_nic *efx) efx_oword_t md_stat; int count; - /* wait upto 50ms - taken max from datasheet */ + /* wait up to 50ms - taken max from datasheet */ for (count = 0; count < 5000; count++) { efx_reado(efx, &md_stat, FR_AB_MD_STAT); if (EFX_OWORD_FIELD(md_stat, FRF_AB_MD_BSY) == 0) { @@ -1221,7 +1221,7 @@ static int falcon_reset_sram(struct efx_nic *efx) return 0; } - } while (++count < 20); /* wait upto 0.4 sec */ + } while (++count < 20); /* wait up to 0.4 sec */ netif_err(efx, hw, efx->net_dev, "timed out waiting for SRAM reset\n"); return -ETIMEDOUT; diff --git a/drivers/net/sfc/mcdi.c b/drivers/net/sfc/mcdi.c index 5e118f0d2479..d98479030ef2 100644 --- a/drivers/net/sfc/mcdi.c +++ b/drivers/net/sfc/mcdi.c @@ -453,7 +453,7 @@ static void efx_mcdi_ev_death(struct efx_nic *efx, int rc) * * There's a race here with efx_mcdi_rpc(), because we might receive * a REBOOT event *before* the request has been copied out. In polled - * mode (during startup) this is irrelevent, because efx_mcdi_complete() + * mode (during startup) this is irrelevant, because efx_mcdi_complete() * is ignored. In event mode, this condition is just an edge-case of * receiving a REBOOT event after posting the MCDI request. Did the mc * reboot before or after the copyout? The best we can do always is diff --git a/drivers/net/sfc/mcdi_pcol.h b/drivers/net/sfc/mcdi_pcol.h index b86a15f221ad..41fe06fa0600 100644 --- a/drivers/net/sfc/mcdi_pcol.h +++ b/drivers/net/sfc/mcdi_pcol.h @@ -103,7 +103,7 @@ * * If Code==CMDDONE, then the fields are further interpreted as: * - * - LEVEL==INFO Command succeded + * - LEVEL==INFO Command succeeded * - LEVEL==ERR Command failed * * 0 8 16 24 32 @@ -572,7 +572,7 @@ (4*(_numwords)) /* MC_CMD_SET_RAND_SEED: - * Set the 16byte seed for the MC psuedo-random generator + * Set the 16byte seed for the MC pseudo-random generator */ #define MC_CMD_SET_RAND_SEED 0x1a #define MC_CMD_SET_RAND_SEED_IN_LEN 16 @@ -1162,7 +1162,7 @@ #define MC_CMD_MAC_STATS_CMD_CLEAR_WIDTH 1 #define MC_CMD_MAC_STATS_CMD_PERIODIC_CHANGE_LBN 2 #define MC_CMD_MAC_STATS_CMD_PERIODIC_CHANGE_WIDTH 1 -/* Remaining PERIOD* fields only relevent when PERIODIC_CHANGE is set */ +/* Remaining PERIOD* fields only relevant when PERIODIC_CHANGE is set */ #define MC_CMD_MAC_STATS_CMD_PERIODIC_ENABLE_LBN 3 #define MC_CMD_MAC_STATS_CMD_PERIODIC_ENABLE_WIDTH 1 #define MC_CMD_MAC_STATS_CMD_PERIODIC_CLEAR_LBN 4 diff --git a/drivers/net/sfc/mcdi_phy.c b/drivers/net/sfc/mcdi_phy.c index ec3f740f5465..7e3c65b0c99f 100644 --- a/drivers/net/sfc/mcdi_phy.c +++ b/drivers/net/sfc/mcdi_phy.c @@ -449,7 +449,7 @@ void efx_mcdi_phy_check_fcntl(struct efx_nic *efx, u32 lpa) struct efx_mcdi_phy_data *phy_cfg = efx->phy_data; u32 rmtadv; - /* The link partner capabilities are only relevent if the + /* The link partner capabilities are only relevant if the * link supports flow control autonegotiation */ if (~phy_cfg->supported_cap & (1 << MC_CMD_PHY_CAP_AN_LBN)) return; diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 215d5c51bfa0..9ffa9a6b55a0 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -670,7 +670,7 @@ struct efx_filter_state; * @irq_zero_count: Number of legacy IRQs seen with queue flags == 0 * @fatal_irq_level: IRQ level (bit number) used for serious errors * @mtd_list: List of MTDs attached to the NIC - * @nic_data: Hardware dependant state + * @nic_data: Hardware dependent state * @mac_lock: MAC access lock. Protects @port_enabled, @phy_mode, * @port_inhibited, efx_monitor() and efx_reconfigure_port() * @port_enabled: Port enabled indicator. diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c index 3a0cc63428ee..dd03bf619988 100644 --- a/drivers/net/sgiseeq.c +++ b/drivers/net/sgiseeq.c @@ -33,7 +33,7 @@ static char *sgiseeqstr = "SGI Seeq8003"; * with that in mind, I've decided to make this driver look completely like a * stupid Lance from a driver architecture perspective. Only difference is that * here our "ring buffer" looks and acts like a real Lance one does but is - * layed out like how the HPC DMA and the Seeq want it to. You'd be surprised + * laid out like how the HPC DMA and the Seeq want it to. You'd be surprised * how a stupid idea like this can pay off in performance, not to mention * making this driver 2,000 times easier to write. ;-) */ @@ -77,7 +77,7 @@ struct sgiseeq_tx_desc { }; /* - * Warning: This structure is layed out in a certain way because HPC dma + * Warning: This structure is laid out in a certain way because HPC dma * descriptors must be 8-byte aligned. So don't touch this without * some care. */ diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index e9e7a530552c..8a72a979ee71 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -1875,7 +1875,7 @@ static int sh_eth_drv_probe(struct platform_device *pdev) if (ret) goto out_unregister; - /* print device infomation */ + /* print device information */ pr_info("Base address at 0x%x, %pM, IRQ %d.\n", (u32)ndev->base_addr, ndev->dev_addr, ndev->irq); diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c index 3406ed870917..b436e007eea0 100644 --- a/drivers/net/sis190.c +++ b/drivers/net/sis190.c @@ -93,7 +93,7 @@ enum sis190_registers { IntrStatus = 0x20, IntrMask = 0x24, IntrControl = 0x28, - IntrTimer = 0x2c, // unused (Interupt Timer) + IntrTimer = 0x2c, // unused (Interrupt Timer) PMControl = 0x30, // unused (Power Mgmt Control/Status) rsv2 = 0x34, // reserved ROMControl = 0x38, @@ -234,7 +234,7 @@ enum _DescStatusBit { RxSizeMask = 0x0000ffff /* * The asic could apparently do vlan, TSO, jumbo (sis191 only) and - * provide two (unused with Linux) Tx queues. No publically + * provide two (unused with Linux) Tx queues. No publicly * available documentation alas. */ }; diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c index 84d4167eee9a..cb317cd069ff 100644 --- a/drivers/net/sis900.c +++ b/drivers/net/sis900.c @@ -1180,7 +1180,7 @@ sis900_init_rx_ring(struct net_device *net_dev) * * 630E equalizer workaround rule(Cyrus Huang 08/15) * PHY register 14h(Test) - * Bit 14: 0 -- Automatically dectect (default) + * Bit 14: 0 -- Automatically detect (default) * 1 -- Manually set Equalizer filter * Bit 13: 0 -- (Default) * 1 -- Speed up convergence of equalizer setting @@ -1192,7 +1192,7 @@ sis900_init_rx_ring(struct net_device *net_dev) * Then set equalizer value, and set Bit 14 to 1, Bit 9 to 0 * Link Off:Set Bit 13 to 1, Bit 14 to 0 * Calculate Equalizer value: - * When Link is ON and Bit 14 is 0, SIS900PHY will auto-dectect proper equalizer value. + * When Link is ON and Bit 14 is 0, SIS900PHY will auto-detect proper equalizer value. * When the equalizer is stable, this value is not a fixed value. It will be within * a small range(eg. 7~9). Then we get a minimum and a maximum value(eg. min=7, max=9) * 0 <= max <= 4 --> set equalizer to max @@ -1723,7 +1723,7 @@ static int sis900_rx(struct net_device *net_dev) rx_size = data_size - CRC_SIZE; #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) - /* ``TOOLONG'' flag means jumbo packet recived. */ + /* ``TOOLONG'' flag means jumbo packet received. */ if ((rx_status & TOOLONG) && data_size <= MAX_FRAME_SIZE) rx_status &= (~ ((unsigned int)TOOLONG)); #endif diff --git a/drivers/net/skfp/ess.c b/drivers/net/skfp/ess.c index 8639a0884f5c..2fc5987b41dc 100644 --- a/drivers/net/skfp/ess.c +++ b/drivers/net/skfp/ess.c @@ -241,7 +241,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, != SMT_RDF_SUCCESS) || (sm->smt_tid != smc->ess.alloc_trans_id)) { - DB_ESS("ESS: Allocation Responce not accepted\n",0,0) ; + DB_ESS("ESS: Allocation Response not accepted\n",0,0) ; return fs; } @@ -393,7 +393,7 @@ static int process_bw_alloc(struct s_smc *smc, long int payload, long int overhe * | T-NEG | * - - * - * T-NEG is discribed by the equation: + * T-NEG is described by the equation: * * (-) fddiMACT-NEG * T-NEG = ------------------- @@ -479,7 +479,7 @@ static void ess_send_response(struct s_smc *smc, struct smt_header *sm, void *p ; /* - * get and initialize the responce frame + * get and initialize the response frame */ if (sba_cmd == CHANGE_ALLOCATION) { if (!(mb=smt_build_frame(smc,SMT_RAF,SMT_REPLY, @@ -578,7 +578,7 @@ static void ess_send_alc_req(struct s_smc *smc) } /* - * get and initialize the responce frame + * get and initialize the response frame */ if (!(mb=smt_build_frame(smc,SMT_RAF,SMT_REQUEST, sizeof(struct smt_sba_alc_req)))) diff --git a/drivers/net/skfp/fplustm.c b/drivers/net/skfp/fplustm.c index ca4e7bb6a5a8..a20ed1a98099 100644 --- a/drivers/net/skfp/fplustm.c +++ b/drivers/net/skfp/fplustm.c @@ -340,7 +340,7 @@ static void mac_counter_init(struct s_smc *smc) outpw(FM_A(FM_LCNTR),0) ; outpw(FM_A(FM_ECNTR),0) ; /* - * clear internal error counter stucture + * clear internal error counter structure */ ec = (u_long *)&smc->hw.fp.err_stats ; for (i = (sizeof(struct err_st)/sizeof(long)) ; i ; i--) @@ -1262,8 +1262,8 @@ Function DOWNCALL/INTERN (SMT, fplustm.c) Para mode = 1 RX_ENABLE_ALLMULTI enable all multicasts 2 RX_DISABLE_ALLMULTI disable "enable all multicasts" - 3 RX_ENABLE_PROMISC enable promiscous - 4 RX_DISABLE_PROMISC disable promiscous + 3 RX_ENABLE_PROMISC enable promiscuous + 4 RX_DISABLE_PROMISC disable promiscuous 5 RX_ENABLE_NSA enable reception of NSA frames 6 RX_DISABLE_NSA disable reception of NSA frames diff --git a/drivers/net/skfp/h/cmtdef.h b/drivers/net/skfp/h/cmtdef.h index f2f771d8be76..5a6c6122ccb0 100644 --- a/drivers/net/skfp/h/cmtdef.h +++ b/drivers/net/skfp/h/cmtdef.h @@ -19,7 +19,7 @@ /* * implementation specific constants - * MODIIFY THE FOLLWOING THREE DEFINES + * MODIIFY THE FOLLOWING THREE DEFINES */ #define AMDPLC /* if Amd PLC chip used */ #ifdef CONC @@ -456,7 +456,7 @@ struct s_plc { u_long soft_err ; /* error counter */ u_long parity_err ; /* error counter */ u_long ebuf_err ; /* error counter */ - u_long ebuf_cont ; /* continous error counter */ + u_long ebuf_cont ; /* continuous error counter */ u_long phyinv ; /* error counter */ u_long vsym_ctr ; /* error counter */ u_long mini_ctr ; /* error counter */ diff --git a/drivers/net/skfp/h/fplustm.h b/drivers/net/skfp/h/fplustm.h index 6d738e1e2393..d43191ed938b 100644 --- a/drivers/net/skfp/h/fplustm.h +++ b/drivers/net/skfp/h/fplustm.h @@ -237,8 +237,8 @@ struct s_smt_fp { */ #define RX_ENABLE_ALLMULTI 1 /* enable all multicasts */ #define RX_DISABLE_ALLMULTI 2 /* disable "enable all multicasts" */ -#define RX_ENABLE_PROMISC 3 /* enable promiscous */ -#define RX_DISABLE_PROMISC 4 /* disable promiscous */ +#define RX_ENABLE_PROMISC 3 /* enable promiscuous */ +#define RX_DISABLE_PROMISC 4 /* disable promiscuous */ #define RX_ENABLE_NSA 5 /* enable reception of NSA frames */ #define RX_DISABLE_NSA 6 /* disable reception of NSA frames */ diff --git a/drivers/net/skfp/h/smc.h b/drivers/net/skfp/h/smc.h index 026a83b9f743..c774a95902f5 100644 --- a/drivers/net/skfp/h/smc.h +++ b/drivers/net/skfp/h/smc.h @@ -388,7 +388,7 @@ struct smt_config { u_long rmt_t_poll ; /* RMT : claim/beacon poller */ u_long rmt_dup_mac_behavior ; /* Flag for the beavior of SMT if * a Duplicate MAC Address was detected. - * FALSE: SMT will leave finaly the ring + * FALSE: SMT will leave finally the ring * TRUE: SMT will reinstert into the ring */ u_long mac_d_max ; /* MAC : D_Max timer value */ diff --git a/drivers/net/skfp/h/smt.h b/drivers/net/skfp/h/smt.h index 2976757a36fb..2030f9cbb24b 100644 --- a/drivers/net/skfp/h/smt.h +++ b/drivers/net/skfp/h/smt.h @@ -793,7 +793,7 @@ struct smt_rdf { } ; /* - * SBA Request Allocation Responce Frame + * SBA Request Allocation Response Frame */ struct smt_sba_alc_res { struct smt_header smt ; /* generic header */ diff --git a/drivers/net/skfp/h/supern_2.h b/drivers/net/skfp/h/supern_2.h index 5ba0b8306753..0b73690280f6 100644 --- a/drivers/net/skfp/h/supern_2.h +++ b/drivers/net/skfp/h/supern_2.h @@ -14,7 +14,7 @@ /* defines for AMD Supernet II chip set - the chips are refered to as + the chips are referred to as FPLUS Formac Plus PLC Physical Layer @@ -386,7 +386,7 @@ struct tx_queue { #define FM_MDISRCV (4<<8) /* disable receive function */ #define FM_MRES0 (5<<8) /* reserve */ #define FM_MLIMPROM (6<<8) /* limited-promiscuous mode */ -#define FM_MPROMISCOUS (7<<8) /* address detection : promiscous */ +#define FM_MPROMISCOUS (7<<8) /* address detection : promiscuous */ #define FM_SELSA 0x0800 /* select-short-address bit */ diff --git a/drivers/net/skfp/hwmtm.c b/drivers/net/skfp/hwmtm.c index af5a755e269d..e26398b5a7dc 100644 --- a/drivers/net/skfp/hwmtm.c +++ b/drivers/net/skfp/hwmtm.c @@ -691,7 +691,7 @@ static u_long repair_rxd_ring(struct s_smc *smc, struct s_smt_rx_queue *queue) * interrupt service routine, handles the interrupt requests * generated by the FDDI adapter. * - * NOTE: The operating system dependent module must garantee that the + * NOTE: The operating system dependent module must guarantee that the * interrupts of the adapter are disabled when it calls fddi_isr. * * About the USE_BREAK_ISR mechanismn: diff --git a/drivers/net/skfp/pcmplc.c b/drivers/net/skfp/pcmplc.c index 112d35b1bf0e..88d02d0a42c4 100644 --- a/drivers/net/skfp/pcmplc.c +++ b/drivers/net/skfp/pcmplc.c @@ -1680,7 +1680,7 @@ void plc_irq(struct s_smc *smc, int np, unsigned int cmd) * Prevent counter from being wrapped after * hanging years in that interrupt. */ - plc->ebuf_cont++ ; /* Ebuf continous error */ + plc->ebuf_cont++ ; /* Ebuf continuous error */ } #ifdef SUPERNET_3 @@ -1717,8 +1717,8 @@ void plc_irq(struct s_smc *smc, int np, unsigned int cmd) } #endif /* SUPERNET_3 */ } else { - /* Reset the continous error variable */ - plc->ebuf_cont = 0 ; /* reset Ebuf continous error */ + /* Reset the continuous error variable */ + plc->ebuf_cont = 0 ; /* reset Ebuf continuous error */ } if (cmd & PL_PHYINV) { /* physical layer invalid signal */ plc->phyinv++ ; diff --git a/drivers/net/skfp/smt.c b/drivers/net/skfp/smt.c index 1e1bd0c201c8..08d94329c12f 100644 --- a/drivers/net/skfp/smt.c +++ b/drivers/net/skfp/smt.c @@ -219,7 +219,7 @@ void smt_emulate_token_ct(struct s_smc *smc, int mac_index) /* * Only when ring is up we will have a token count. The - * flag is unfortunatly a single instance value. This + * flag is unfortunately a single instance value. This * doesn't matter now, because we currently have only * one MAC instance. */ diff --git a/drivers/net/skge.h b/drivers/net/skge.h index 507addcaffa3..51c0214ac25c 100644 --- a/drivers/net/skge.h +++ b/drivers/net/skge.h @@ -1038,7 +1038,7 @@ enum { PHY_ST_PRE_SUP = 1<<6, /* Bit 6: Preamble Suppression */ PHY_ST_AN_OVER = 1<<5, /* Bit 5: Auto-Negotiation Over */ - PHY_ST_REM_FLT = 1<<4, /* Bit 4: Remote Fault Condition Occured */ + PHY_ST_REM_FLT = 1<<4, /* Bit 4: Remote Fault Condition Occurred */ PHY_ST_AN_CAP = 1<<3, /* Bit 3: Auto-Negotiation Capability */ PHY_ST_LSYNC = 1<<2, /* Bit 2: Link Synchronized */ PHY_ST_JAB_DET = 1<<1, /* Bit 1: Jabber Detected */ @@ -1721,8 +1721,8 @@ enum { GM_GPSR_LINK_UP = 1<<12, /* Bit 12: Link Up Status */ GM_GPSR_PAUSE = 1<<11, /* Bit 11: Pause State */ GM_GPSR_TX_ACTIVE = 1<<10, /* Bit 10: Tx in Progress */ - GM_GPSR_EXC_COL = 1<<9, /* Bit 9: Excessive Collisions Occured */ - GM_GPSR_LAT_COL = 1<<8, /* Bit 8: Late Collisions Occured */ + GM_GPSR_EXC_COL = 1<<9, /* Bit 9: Excessive Collisions Occurred */ + GM_GPSR_LAT_COL = 1<<8, /* Bit 8: Late Collisions Occurred */ GM_GPSR_PHY_ST_CH = 1<<5, /* Bit 5: PHY Status Change */ GM_GPSR_GIG_SPEED = 1<<4, /* Bit 4: Gigabit Speed (1 = 1000 Mbps) */ @@ -2227,7 +2227,7 @@ enum { XM_ST_BC = 1<<7, /* Bit 7: Broadcast packet */ XM_ST_MC = 1<<6, /* Bit 6: Multicast packet */ XM_ST_UC = 1<<5, /* Bit 5: Unicast packet */ - XM_ST_TX_UR = 1<<4, /* Bit 4: FIFO Underrun occured */ + XM_ST_TX_UR = 1<<4, /* Bit 4: FIFO Underrun occurred */ XM_ST_CS_ERR = 1<<3, /* Bit 3: Carrier Sense Error */ XM_ST_LAT_COL = 1<<2, /* Bit 2: Late Collision Error */ XM_ST_MUL_COL = 1<<1, /* Bit 1: Multiple Collisions */ diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 2a91868788f7..ff8d262dc276 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -932,7 +932,7 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR); sky2_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON); - /* On chips without ram buffer, pause is controled by MAC level */ + /* On chips without ram buffer, pause is controlled by MAC level */ if (!(hw->flags & SKY2_HW_RAM_BUFFER)) { /* Pause threshold is scaled by 8 in bytes */ if (hw->chip_id == CHIP_ID_YUKON_FE_P && @@ -3255,7 +3255,7 @@ static void sky2_reset(struct sky2_hw *hw) /* Take device down (offline). * Equivalent to doing dev_stop() but this does not - * inform upper layers of the transistion. + * inform upper layers of the transition. */ static void sky2_detach(struct net_device *dev) { diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index 6861b0e8db9a..0c6d10c5f053 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h @@ -1194,7 +1194,7 @@ enum { PHY_ST_PRE_SUP = 1<<6, /* Bit 6: Preamble Suppression */ PHY_ST_AN_OVER = 1<<5, /* Bit 5: Auto-Negotiation Over */ - PHY_ST_REM_FLT = 1<<4, /* Bit 4: Remote Fault Condition Occured */ + PHY_ST_REM_FLT = 1<<4, /* Bit 4: Remote Fault Condition Occurred */ PHY_ST_AN_CAP = 1<<3, /* Bit 3: Auto-Negotiation Capability */ PHY_ST_LSYNC = 1<<2, /* Bit 2: Link Synchronized */ PHY_ST_JAB_DET = 1<<1, /* Bit 1: Jabber Detected */ @@ -1725,8 +1725,8 @@ enum { GM_GPSR_LINK_UP = 1<<12, /* Bit 12: Link Up Status */ GM_GPSR_PAUSE = 1<<11, /* Bit 11: Pause State */ GM_GPSR_TX_ACTIVE = 1<<10, /* Bit 10: Tx in Progress */ - GM_GPSR_EXC_COL = 1<<9, /* Bit 9: Excessive Collisions Occured */ - GM_GPSR_LAT_COL = 1<<8, /* Bit 8: Late Collisions Occured */ + GM_GPSR_EXC_COL = 1<<9, /* Bit 9: Excessive Collisions Occurred */ + GM_GPSR_LAT_COL = 1<<8, /* Bit 8: Late Collisions Occurred */ GM_GPSR_PHY_ST_CH = 1<<5, /* Bit 5: PHY Status Change */ GM_GPSR_GIG_SPEED = 1<<4, /* Bit 4: Gigabit Speed (1 = 1000 Mbps) */ diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index 68d48ab6eacf..5f53fbbf67be 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h @@ -921,7 +921,7 @@ static const char * chip_ids[ 16 ] = { * Hack Alert: Some setups just can't write 8 or 16 bits reliably when not * aligned to a 32 bit boundary. I tell you that does exist! * Fortunately the affected register accesses can be easily worked around - * since we can write zeroes to the preceeding 16 bits without adverse + * since we can write zeroes to the preceding 16 bits without adverse * effects and use a 32-bit access. * * Enforce it on any 32-bit capable setup for now. diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index 1566259c1f27..c498b720b532 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c @@ -1669,7 +1669,7 @@ static int smsc911x_eeprom_send_cmd(struct smsc911x_data *pdata, u32 op) } if (e2cmd & E2P_CMD_EPC_TIMEOUT_) { - SMSC_TRACE(DRV, "Error occured during eeprom operation"); + SMSC_TRACE(DRV, "Error occurred during eeprom operation"); return -EINVAL; } diff --git a/drivers/net/smsc9420.c b/drivers/net/smsc9420.c index b09ee1c319e8..4c92ad8be765 100644 --- a/drivers/net/smsc9420.c +++ b/drivers/net/smsc9420.c @@ -364,7 +364,7 @@ static int smsc9420_eeprom_send_cmd(struct smsc9420_pdata *pd, u32 op) } if (e2cmd & E2P_CMD_EPC_TIMEOUT_) { - smsc_info(HW, "Error occured during eeprom operation"); + smsc_info(HW, "Error occurred during eeprom operation"); return -EINVAL; } diff --git a/drivers/net/stmmac/norm_desc.c b/drivers/net/stmmac/norm_desc.c index cd0cc76f7a1c..029c2a2cf524 100644 --- a/drivers/net/stmmac/norm_desc.c +++ b/drivers/net/stmmac/norm_desc.c @@ -67,7 +67,7 @@ static int ndesc_get_tx_len(struct dma_desc *p) /* This function verifies if each incoming frame has some errors * and, if required, updates the multicast statistics. - * In case of success, it returns csum_none becasue the device + * In case of success, it returns csum_none because the device * is not able to compute the csum in HW. */ static int ndesc_get_rx_status(void *data, struct stmmac_extra_stats *x, struct dma_desc *p) diff --git a/drivers/net/sunbmac.h b/drivers/net/sunbmac.h index 8db88945b889..4943e975a731 100644 --- a/drivers/net/sunbmac.h +++ b/drivers/net/sunbmac.h @@ -185,7 +185,7 @@ #define BIGMAC_RXCFG_ENABLE 0x00000001 /* Enable the receiver */ #define BIGMAC_RXCFG_FIFO 0x0000000e /* Default rx fthresh... */ #define BIGMAC_RXCFG_PSTRIP 0x00000020 /* Pad byte strip enable */ -#define BIGMAC_RXCFG_PMISC 0x00000040 /* Enable promiscous mode */ +#define BIGMAC_RXCFG_PMISC 0x00000040 /* Enable promiscuous mode */ #define BIGMAC_RXCFG_DERR 0x00000080 /* Disable error checking */ #define BIGMAC_RXCFG_DCRCS 0x00000100 /* Disable CRC stripping */ #define BIGMAC_RXCFG_ME 0x00000200 /* Receive packets addressed to me */ diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index c1a344829b54..d3be735c4719 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c @@ -1150,7 +1150,7 @@ static void gem_pcs_reinit_adv(struct gem *gp) val &= ~(PCS_CFG_ENABLE | PCS_CFG_TO); writel(val, gp->regs + PCS_CFG); - /* Advertise all capabilities except assymetric + /* Advertise all capabilities except asymmetric * pause. */ val = readl(gp->regs + PCS_MIIADV); diff --git a/drivers/net/sunhme.h b/drivers/net/sunhme.h index 756b5bf3aa89..64f278360d89 100644 --- a/drivers/net/sunhme.h +++ b/drivers/net/sunhme.h @@ -223,7 +223,7 @@ /* BigMac receive config register. */ #define BIGMAC_RXCFG_ENABLE 0x00000001 /* Enable the receiver */ #define BIGMAC_RXCFG_PSTRIP 0x00000020 /* Pad byte strip enable */ -#define BIGMAC_RXCFG_PMISC 0x00000040 /* Enable promiscous mode */ +#define BIGMAC_RXCFG_PMISC 0x00000040 /* Enable promiscuous mode */ #define BIGMAC_RXCFG_DERR 0x00000080 /* Disable error checking */ #define BIGMAC_RXCFG_DCRCS 0x00000100 /* Disable CRC stripping */ #define BIGMAC_RXCFG_REJME 0x00000200 /* Reject packets addressed to me */ diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c index b6eec8cea209..7ca51cebcddd 100644 --- a/drivers/net/tc35815.c +++ b/drivers/net/tc35815.c @@ -119,13 +119,13 @@ struct tc35815_regs { /* * Bit assignments */ -/* DMA_Ctl bit asign ------------------------------------------------------- */ +/* DMA_Ctl bit assign ------------------------------------------------------- */ #define DMA_RxAlign 0x00c00000 /* 1:Reception Alignment */ #define DMA_RxAlign_1 0x00400000 #define DMA_RxAlign_2 0x00800000 #define DMA_RxAlign_3 0x00c00000 #define DMA_M66EnStat 0x00080000 /* 1:66MHz Enable State */ -#define DMA_IntMask 0x00040000 /* 1:Interupt mask */ +#define DMA_IntMask 0x00040000 /* 1:Interrupt mask */ #define DMA_SWIntReq 0x00020000 /* 1:Software Interrupt request */ #define DMA_TxWakeUp 0x00010000 /* 1:Transmit Wake Up */ #define DMA_RxBigE 0x00008000 /* 1:Receive Big Endian */ @@ -134,11 +134,11 @@ struct tc35815_regs { #define DMA_PowrMgmnt 0x00001000 /* 1:Power Management */ #define DMA_DmBurst_Mask 0x000001fc /* DMA Burst size */ -/* RxFragSize bit asign ---------------------------------------------------- */ +/* RxFragSize bit assign ---------------------------------------------------- */ #define RxFrag_EnPack 0x00008000 /* 1:Enable Packing */ #define RxFrag_MinFragMask 0x00000ffc /* Minimum Fragment */ -/* MAC_Ctl bit asign ------------------------------------------------------- */ +/* MAC_Ctl bit assign ------------------------------------------------------- */ #define MAC_Link10 0x00008000 /* 1:Link Status 10Mbits */ #define MAC_EnMissRoll 0x00002000 /* 1:Enable Missed Roll */ #define MAC_MissRoll 0x00000400 /* 1:Missed Roll */ @@ -152,7 +152,7 @@ struct tc35815_regs { #define MAC_HaltImm 0x00000002 /* 1:Halt Immediate */ #define MAC_HaltReq 0x00000001 /* 1:Halt request */ -/* PROM_Ctl bit asign ------------------------------------------------------ */ +/* PROM_Ctl bit assign ------------------------------------------------------ */ #define PROM_Busy 0x00008000 /* 1:Busy (Start Operation) */ #define PROM_Read 0x00004000 /*10:Read operation */ #define PROM_Write 0x00002000 /*01:Write operation */ @@ -162,7 +162,7 @@ struct tc35815_regs { #define PROM_Addr_Ena 0x00000030 /*11xxxx:PROM Write enable */ /*00xxxx: disable */ -/* CAM_Ctl bit asign ------------------------------------------------------- */ +/* CAM_Ctl bit assign ------------------------------------------------------- */ #define CAM_CompEn 0x00000010 /* 1:CAM Compare Enable */ #define CAM_NegCAM 0x00000008 /* 1:Reject packets CAM recognizes,*/ /* accept other */ @@ -170,7 +170,7 @@ struct tc35815_regs { #define CAM_GroupAcc 0x00000002 /* 1:Multicast assept */ #define CAM_StationAcc 0x00000001 /* 1:unicast accept */ -/* CAM_Ena bit asign ------------------------------------------------------- */ +/* CAM_Ena bit assign ------------------------------------------------------- */ #define CAM_ENTRY_MAX 21 /* CAM Data entry max count */ #define CAM_Ena_Mask ((1<ifr_data, sizeof(data)); if (error) { - pr_err("cant copy from user\n"); + pr_err("can't copy from user\n"); RET(-EFAULT); } DBG("%d 0x%x 0x%x\n", data[0], data[1], data[2]); @@ -999,7 +999,7 @@ static inline void bdx_rxdb_free_elem(struct rxdb *db, int n) * * RxD fifo is smaller than RxF fifo by design. Upon high load, RxD will be * filled and packets will be dropped by nic without getting into host or - * cousing interrupt. Anyway, in that condition, host has no chance to proccess + * cousing interrupt. Anyway, in that condition, host has no chance to process * all packets, but dropping in nic is cheaper, since it takes 0 cpu cycles */ @@ -1200,8 +1200,8 @@ static void bdx_recycle_skb(struct bdx_priv *priv, struct rxd_desc *rxdd) RET(); } -/* bdx_rx_receive - recieves full packets from RXD fifo and pass them to OS - * NOTE: a special treatment is given to non-continous descriptors +/* bdx_rx_receive - receives full packets from RXD fifo and pass them to OS + * NOTE: a special treatment is given to non-continuous descriptors * that start near the end, wraps around and continue at the beginning. a second * part is copied right after the first, and then descriptor is interpreted as * normal. fifo has an extra space to allow such operations @@ -1584,9 +1584,9 @@ err_mem: } /* - * bdx_tx_space - calculates avalable space in TX fifo + * bdx_tx_space - calculates available space in TX fifo * @priv - NIC private structure - * Returns avaliable space in TX fifo in bytes + * Returns available space in TX fifo in bytes */ static inline int bdx_tx_space(struct bdx_priv *priv) { diff --git a/drivers/net/tehuti.h b/drivers/net/tehuti.h index b6ba8601e2b5..c5642fefc9e7 100644 --- a/drivers/net/tehuti.h +++ b/drivers/net/tehuti.h @@ -502,7 +502,7 @@ struct txd_desc { #define GMAC_RX_FILTER_ACRC 0x0010 /* accept crc error */ #define GMAC_RX_FILTER_AM 0x0008 /* accept multicast */ #define GMAC_RX_FILTER_AB 0x0004 /* accept broadcast */ -#define GMAC_RX_FILTER_PRM 0x0001 /* [0:1] promiscous mode */ +#define GMAC_RX_FILTER_PRM 0x0001 /* [0:1] promiscuous mode */ #define MAX_FRAME_AB_VAL 0x3fff /* 13:0 */ diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 73c942d85f07..b8c5f35577e4 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -9712,7 +9712,7 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, eeprom->len += b_count; } - /* read bytes upto the last 4 byte boundary */ + /* read bytes up to the last 4 byte boundary */ pd = &data[eeprom->len]; for (i = 0; i < (len - (len & 3)); i += 4) { ret = tg3_nvram_read_be32(tp, offset + i, &val); diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 73884b69b749..5e96706ad108 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2130,7 +2130,7 @@ #define MII_TG3_DSP_EXP96 0x0f96 #define MII_TG3_DSP_EXP97 0x0f97 -#define MII_TG3_AUX_CTRL 0x18 /* auxilliary control register */ +#define MII_TG3_AUX_CTRL 0x18 /* auxiliary control register */ #define MII_TG3_AUXCTL_PCTL_100TX_LPWR 0x0010 #define MII_TG3_AUXCTL_PCTL_SPR_ISOLATE 0x0020 @@ -2146,7 +2146,7 @@ #define MII_TG3_AUXCTL_ACTL_TX_6DB 0x0400 #define MII_TG3_AUXCTL_SHDWSEL_AUXCTL 0x0000 -#define MII_TG3_AUX_STAT 0x19 /* auxilliary status register */ +#define MII_TG3_AUX_STAT 0x19 /* auxiliary status register */ #define MII_TG3_AUX_STAT_LPASS 0x0004 #define MII_TG3_AUX_STAT_SPDMASK 0x0700 #define MII_TG3_AUX_STAT_10HALF 0x0100 diff --git a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c index 10800f16a231..8a3b191b195b 100644 --- a/drivers/net/tokenring/3c359.c +++ b/drivers/net/tokenring/3c359.c @@ -208,7 +208,7 @@ static void print_rx_state(struct net_device *dev) * passing/getting the next value from the nic. As with all requests * on this nic it has to be done in two stages, a) tell the nic which * memory address you want to access and b) pass/get the value from the nic. - * With the EEProm, you have to wait before and inbetween access a) and b). + * With the EEProm, you have to wait before and between access a) and b). * As this is only read at initialization time and the wait period is very * small we shouldn't have to worry about scheduling issues. */ diff --git a/drivers/net/tokenring/madgemc.c b/drivers/net/tokenring/madgemc.c index 785ad1a2157b..2bedc0ace812 100644 --- a/drivers/net/tokenring/madgemc.c +++ b/drivers/net/tokenring/madgemc.c @@ -73,7 +73,7 @@ static void madgemc_setint(struct net_device *dev, int val); static irqreturn_t madgemc_interrupt(int irq, void *dev_id); /* - * These work around paging, however they don't guarentee you're on the + * These work around paging, however they don't guarantee you're on the * right page. */ #define SIFREADB(reg) (inb(dev->base_addr + ((reg<0x8)?reg:reg-0x8))) @@ -387,7 +387,7 @@ getout: * both with their own disadvantages... * * 1) Read in the SIFSTS register from the TMS controller. This - * is guarenteed to be accurate, however, there's a fairly + * is guaranteed to be accurate, however, there's a fairly * large performance penalty for doing so: the Madge chips * must request the register from the Eagle, the Eagle must * read them from its internal bus, and then take the route @@ -454,7 +454,7 @@ static irqreturn_t madgemc_interrupt(int irq, void *dev_id) } /* - * Set the card to the prefered ring speed. + * Set the card to the preferred ring speed. * * Unlike newer cards, the MC16/32 have their speed selection * circuit connected to the Madge ASICs and not to the TMS380 diff --git a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c index 63db5a6762ae..d9044aba7afa 100644 --- a/drivers/net/tokenring/smctr.c +++ b/drivers/net/tokenring/smctr.c @@ -393,7 +393,7 @@ static int smctr_alloc_shared_memory(struct net_device *dev) tp->rx_bdb_end[NON_MAC_QUEUE] = (BDBlock *)smctr_malloc(dev, 0); /* Allocate MAC transmit buffers. - * MAC Tx Buffers doen't have to be on an ODD Boundry. + * MAC Tx Buffers doen't have to be on an ODD Boundary. */ tp->tx_buff_head[MAC_QUEUE] = (__u16 *)smctr_malloc(dev, tp->tx_buff_size[MAC_QUEUE]); @@ -415,7 +415,7 @@ static int smctr_alloc_shared_memory(struct net_device *dev) /* Allocate Non-MAC transmit buffers. * ?? For maximum Netware performance, put Tx Buffers on - * ODD Boundry and then restore malloc to Even Boundrys. + * ODD Boundary and then restore malloc to Even Boundrys. */ smctr_malloc(dev, 1L); tp->tx_buff_head[NON_MAC_QUEUE] @@ -1311,7 +1311,7 @@ static unsigned int smctr_get_num_rx_bdbs(struct net_device *dev) mem_used += sizeof(BDBlock) * tp->num_rx_bdbs[MAC_QUEUE]; /* Allocate MAC transmit buffers. - * MAC transmit buffers don't have to be on an ODD Boundry. + * MAC transmit buffers don't have to be on an ODD Boundary. */ mem_used += tp->tx_buff_size[MAC_QUEUE]; @@ -1325,7 +1325,7 @@ static unsigned int smctr_get_num_rx_bdbs(struct net_device *dev) /* Allocate Non-MAC transmit buffers. * For maximum Netware performance, put Tx Buffers on - * ODD Boundry,and then restore malloc to Even Boundrys. + * ODD Boundary,and then restore malloc to Even Boundrys. */ mem_used += 1L; mem_used += tp->tx_buff_size[NON_MAC_QUEUE]; @@ -3069,8 +3069,8 @@ static int smctr_load_node_addr(struct net_device *dev) * disabled.!? * * NOTE 2: If the monitor_state is MS_BEACON_TEST_STATE and the receive_mask - * has any multi-cast or promiscous bits set, the receive_mask needs to - * be changed to clear the multi-cast or promiscous mode bits, the lobe_test + * has any multi-cast or promiscuous bits set, the receive_mask needs to + * be changed to clear the multi-cast or promiscuous mode bits, the lobe_test * run, and then the receive mask set back to its original value if the test * is successful. */ diff --git a/drivers/net/tokenring/tms380tr.h b/drivers/net/tokenring/tms380tr.h index 60b30ee38dcb..e5a617c586c2 100644 --- a/drivers/net/tokenring/tms380tr.h +++ b/drivers/net/tokenring/tms380tr.h @@ -442,7 +442,7 @@ typedef struct { #define PASS_FIRST_BUF_ONLY 0x0100 /* Passes only first internal buffer * of each received frame; FrameSize * of RPLs must contain internal - * BUFFER_SIZE bits for promiscous mode. + * BUFFER_SIZE bits for promiscuous mode. */ #define ENABLE_FULL_DUPLEX_SELECTION 0x2000 /* Enable the use of full-duplex diff --git a/drivers/net/tsi108_eth.h b/drivers/net/tsi108_eth.h index 5a77ae6c5f36..5fee7d78dc6d 100644 --- a/drivers/net/tsi108_eth.h +++ b/drivers/net/tsi108_eth.h @@ -305,9 +305,9 @@ #define TSI108_TX_CRC (1 << 5) /* Generate CRC for this packet */ #define TSI108_TX_INT (1 << 14) /* Generate an IRQ after frag. processed */ #define TSI108_TX_RETRY (0xf << 16) /* 4 bit field indicating num. of retries */ -#define TSI108_TX_COL (1 << 20) /* Set if a collision occured */ -#define TSI108_TX_LCOL (1 << 24) /* Set if a late collision occured */ -#define TSI108_TX_UNDER (1 << 25) /* Set if a FIFO underrun occured */ +#define TSI108_TX_COL (1 << 20) /* Set if a collision occurred */ +#define TSI108_TX_LCOL (1 << 24) /* Set if a late collision occurred */ +#define TSI108_TX_UNDER (1 << 25) /* Set if a FIFO underrun occurred */ #define TSI108_TX_RLIM (1 << 26) /* Set if the retry limit was reached */ #define TSI108_TX_OK (1 << 30) /* Set if the frame TX was successful */ #define TSI108_TX_OWN (1 << 31) /* Set if the device owns the descriptor */ @@ -332,7 +332,7 @@ typedef struct { #define TSI108_RX_RUNT (1 << 4)/* Packet is less than minimum size */ #define TSI108_RX_HASH (1 << 7)/* Hash table match */ #define TSI108_RX_BAD (1 << 8) /* Bad frame */ -#define TSI108_RX_OVER (1 << 9) /* FIFO overrun occured */ +#define TSI108_RX_OVER (1 << 9) /* FIFO overrun occurred */ #define TSI108_RX_TRUNC (1 << 11) /* Packet truncated due to excess length */ #define TSI108_RX_CRC (1 << 12) /* Packet had a CRC error */ #define TSI108_RX_INT (1 << 13) /* Generate an IRQ after frag. processed */ diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c index 4dbd493b996b..efaa1d69b720 100644 --- a/drivers/net/tulip/de4x5.c +++ b/drivers/net/tulip/de4x5.c @@ -79,7 +79,7 @@ every usable DECchip board, I pinched Donald's 'next_module' field to link my modules together. - Upto 15 EISA cards can be supported under this driver, limited primarily + Up to 15 EISA cards can be supported under this driver, limited primarily by the available IRQ lines. I have checked different configurations of multiple depca, EtherWORKS 3 cards and de4x5 cards and have not found a problem yet (provided you have at least depca.c v0.38) ... @@ -517,7 +517,7 @@ struct mii_phy { u_int mci; /* 21142 MII Connector Interrupt info */ }; -#define DE4X5_MAX_PHY 8 /* Allow upto 8 attached PHY devices per board */ +#define DE4X5_MAX_PHY 8 /* Allow up to 8 attached PHY devices per board */ struct sia_phy { u_char mc; /* Media Code */ @@ -1436,7 +1436,7 @@ de4x5_sw_reset(struct net_device *dev) /* Poll for setup frame completion (adapter interrupts are disabled now) */ - for (j=0, i=0;(i<500) && (j==0);i++) { /* Upto 500ms delay */ + for (j=0, i=0;(i<500) && (j==0);i++) { /* Up to 500ms delay */ mdelay(1); if ((s32)le32_to_cpu(lp->tx_ring[lp->tx_new].status) >= 0) j=1; } diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c index 7064e035757a..fb07f48910ae 100644 --- a/drivers/net/tulip/dmfe.c +++ b/drivers/net/tulip/dmfe.c @@ -1224,7 +1224,7 @@ static void dmfe_timer(unsigned long data) /* If chip reports that link is failed it could be because external - PHY link status pin is not conected correctly to chip + PHY link status pin is not connected correctly to chip To be sure ask PHY too. */ diff --git a/drivers/net/tulip/eeprom.c b/drivers/net/tulip/eeprom.c index 3031ed9c4a1a..296486bf0956 100644 --- a/drivers/net/tulip/eeprom.c +++ b/drivers/net/tulip/eeprom.c @@ -115,7 +115,7 @@ static void __devinit tulip_build_fake_mediatable(struct tulip_private *tp) 0x02, /* phy reset sequence length */ 0x01, 0x00, /* phy reset sequence */ 0x00, 0x78, /* media capabilities */ - 0x00, 0xe0, /* nway advertisment */ + 0x00, 0xe0, /* nway advertisement */ 0x00, 0x05, /* fdx bit map */ 0x00, 0x06 /* ttm bit map */ }; diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index 7fa5ec2de942..82653cb07857 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c @@ -846,7 +846,7 @@ typhoon_start_tx(struct sk_buff *skb, struct net_device *dev) if(typhoon_num_free_tx(txRing) < (numDesc + 2)) { netif_stop_queue(dev); - /* A Tx complete IRQ could have gotten inbetween, making + /* A Tx complete IRQ could have gotten between, making * the ring free again. Only need to recheck here, since * Tx is serialized. */ diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h index 055b87ab4f07..d12fcad145e9 100644 --- a/drivers/net/ucc_geth.h +++ b/drivers/net/ucc_geth.h @@ -80,7 +80,7 @@ struct ucc_geth { frames) received that were between 128 (Including FCS length==4) and 255 octets */ u32 txok; /* Total number of octets residing in frames - that where involved in successfull + that where involved in successful transmission */ u16 txcf; /* Total number of PAUSE control frames transmitted by this MAC */ @@ -759,7 +759,7 @@ struct ucc_geth_hardware_statistics { frames) received that were between 128 (Including FCS length==4) and 255 octets */ u32 txok; /* Total number of octets residing in frames - that where involved in successfull + that where involved in successful transmission */ u16 txcf; /* Total number of PAUSE control frames transmitted by this MAC */ diff --git a/drivers/net/usb/cdc_eem.c b/drivers/net/usb/cdc_eem.c index 5f3b97668e63..555284761313 100644 --- a/drivers/net/usb/cdc_eem.c +++ b/drivers/net/usb/cdc_eem.c @@ -190,7 +190,7 @@ static int eem_rx_fixup(struct usbnet *dev, struct sk_buff *skb) /* * EEM packet header format: - * b0..14: EEM type dependant (Data or Command) + * b0..14: EEM type dependent (Data or Command) * b15: bmType */ header = get_unaligned_le16(skb->data); diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c index 7dc84971f26f..ad0298f9b5f9 100644 --- a/drivers/net/usb/kaweth.c +++ b/drivers/net/usb/kaweth.c @@ -1221,7 +1221,7 @@ static void kaweth_disconnect(struct usb_interface *intf) usb_set_intfdata(intf, NULL); if (!kaweth) { - dev_warn(&intf->dev, "unregistering non-existant device\n"); + dev_warn(&intf->dev, "unregistering non-existent device\n"); return; } netdev = kaweth->net; diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c index 5e7f069eab53..eb5d75df5d5d 100644 --- a/drivers/net/via-rhine.c +++ b/drivers/net/via-rhine.c @@ -1861,7 +1861,7 @@ static void rhine_restart_tx(struct net_device *dev) { u32 intr_status; /* - * If new errors occured, we need to sort them out before doing Tx. + * If new errors occurred, we need to sort them out before doing Tx. * In that case the ISR will be back here RSN anyway. */ intr_status = get_intr_status(dev); @@ -1887,7 +1887,7 @@ static void rhine_restart_tx(struct net_device *dev) { /* This should never happen */ if (debug > 1) printk(KERN_WARNING "%s: rhine_restart_tx() " - "Another error occured %8.8x.\n", + "Another error occurred %8.8x.\n", dev->name, intr_status); } diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index 0d6fec6b7d93..4fe051753842 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -292,7 +292,7 @@ VELOCITY_PARAM(DMA_length, "DMA length"); /* IP_byte_align[] is used for IP header DWORD byte aligned 0: indicate the IP header won't be DWORD byte aligned.(Default) . 1: indicate the IP header will be DWORD byte aligned. - In some enviroment, the IP header should be DWORD byte aligned, + In some environment, the IP header should be DWORD byte aligned, or the packet will be droped when we receive it. (eg: IPVS) */ VELOCITY_PARAM(IP_byte_align, "Enable IP header dword aligned"); @@ -1994,7 +1994,7 @@ static inline void velocity_rx_csum(struct rx_desc *rd, struct sk_buff *skb) * @dev: network device * * Replace the current skb that is scheduled for Rx processing by a - * shorter, immediatly allocated skb, if the received packet is small + * shorter, immediately allocated skb, if the received packet is small * enough. This function returns a negative value if the received * packet is too big or if memory is exhausted. */ diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index cc14b4a75048..0d47c3a05307 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -892,7 +892,7 @@ vmxnet3_prepare_tso(struct sk_buff *skb, * Transmits a pkt thru a given tq * Returns: * NETDEV_TX_OK: descriptors are setup successfully - * NETDEV_TX_OK: error occured, the pkt is dropped + * NETDEV_TX_OK: error occurred, the pkt is dropped * NETDEV_TX_BUSY: tx ring is full, queue is stopped * * Side-effects: @@ -2685,7 +2685,7 @@ vmxnet3_read_mac_addr(struct vmxnet3_adapter *adapter, u8 *mac) * Enable MSIx vectors. * Returns : * 0 on successful enabling of required vectors, - * VMXNET3_LINUX_MIN_MSIX_VECT when only minumum number of vectors required + * VMXNET3_LINUX_MIN_MSIX_VECT when only minimum number of vectors required * could be enabled. * number of vectors which can be enabled otherwise (this number is smaller * than VMXNET3_LINUX_MIN_MSIX_VECT) diff --git a/drivers/net/vxge/vxge-config.c b/drivers/net/vxge/vxge-config.c index e74e4b42592d..401bebf59502 100644 --- a/drivers/net/vxge/vxge-config.c +++ b/drivers/net/vxge/vxge-config.c @@ -187,7 +187,7 @@ vxge_hw_vpath_fw_api(struct __vxge_hw_virtualpath *vpath, u32 action, VXGE_HW_DEF_DEVICE_POLL_MILLIS); /* The __vxge_hw_device_register_poll can udelay for a significant - * amount of time, blocking other proccess from the CPU. If it delays + * amount of time, blocking other process from the CPU. If it delays * for ~5secs, a NMI error can occur. A way around this is to give up * the processor via msleep, but this is not allowed is under lock. * So, only allow it to sleep for ~4secs if open. Otherwise, delay for diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index 395423aeec00..aff68c1118d4 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -2282,7 +2282,7 @@ vxge_alarm_msix_handle(int irq, void *dev_id) VXGE_HW_VPATH_MSIX_ACTIVE) + VXGE_ALARM_MSIX_ID; for (i = 0; i < vdev->no_of_vpath; i++) { - /* Reduce the chance of loosing alarm interrupts by masking + /* Reduce the chance of losing alarm interrupts by masking * the vector. A pending bit will be set if an alarm is * generated and on unmask the interrupt will be fired. */ @@ -2788,7 +2788,7 @@ static int vxge_open(struct net_device *dev) } /* Enable vpath to sniff all unicast/multicast traffic that not - * addressed to them. We allow promiscous mode for PF only + * addressed to them. We allow promiscuous mode for PF only */ val64 = 0; @@ -2890,7 +2890,7 @@ out0: return ret; } -/* Loop throught the mac address list and delete all the entries */ +/* Loop through the mac address list and delete all the entries */ static void vxge_free_mac_add_list(struct vxge_vpath *vpath) { @@ -2957,7 +2957,7 @@ static int do_vxge_close(struct net_device *dev, int do_io) val64); } - /* Remove the function 0 from promiscous mode */ + /* Remove the function 0 from promiscuous mode */ vxge_hw_mgmt_reg_write(vdev->devh, vxge_hw_mgmt_reg_type_mrpcim, 0, diff --git a/drivers/net/vxge/vxge-traffic.c b/drivers/net/vxge/vxge-traffic.c index 8674f331311c..2638b8d97b8f 100644 --- a/drivers/net/vxge/vxge-traffic.c +++ b/drivers/net/vxge/vxge-traffic.c @@ -1111,7 +1111,7 @@ void vxge_hw_channel_dtr_free(struct __vxge_hw_channel *channel, void *dtrh) * vxge_hw_channel_dtr_count * @channel: Channel handle. Obtained via vxge_hw_channel_open(). * - * Retreive number of DTRs available. This function can not be called + * Retrieve number of DTRs available. This function can not be called * from data path. ring_initial_replenishi() is the only user. */ int vxge_hw_channel_dtr_count(struct __vxge_hw_channel *channel) @@ -2060,7 +2060,7 @@ enum vxge_hw_status vxge_hw_vpath_promisc_enable( vpath = vp->vpath; - /* Enable promiscous mode for function 0 only */ + /* Enable promiscuous mode for function 0 only */ if (!(vpath->hldev->access_rights & VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM)) return VXGE_HW_OK; diff --git a/drivers/net/vxge/vxge-traffic.h b/drivers/net/vxge/vxge-traffic.h index 9d9dfda4c7ab..6c2fc0b72af5 100644 --- a/drivers/net/vxge/vxge-traffic.h +++ b/drivers/net/vxge/vxge-traffic.h @@ -681,7 +681,7 @@ struct vxge_hw_xmac_aggr_stats { * @rx_red_discard: Count of received frames that are discarded because of RED * (Random Early Discard). * @rx_xgmii_ctrl_err_cnt: Maintains a count of unexpected or misplaced control - * characters occuring between times of normal data transmission + * characters occurring between times of normal data transmission * (i.e. not included in RX_XGMII_DATA_ERR_CNT). This counter is * incremented when either - * 1) The Reconciliation Sublayer (RS) is expecting one control diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c index 10bafd59f9c3..6fb6f8e667d0 100644 --- a/drivers/net/wan/cosa.c +++ b/drivers/net/wan/cosa.c @@ -329,7 +329,7 @@ static int startmicrocode(struct cosa_data *cosa, int address); static int readmem(struct cosa_data *cosa, char __user *data, int addr, int len); static int cosa_reset_and_read_id(struct cosa_data *cosa, char *id); -/* Auxilliary functions */ +/* Auxiliary functions */ static int get_wait_data(struct cosa_data *cosa); static int put_wait_data(struct cosa_data *cosa, int data); static int puthexnumber(struct cosa_data *cosa, int number); diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c index 4578e5b4b411..acb9ea830628 100644 --- a/drivers/net/wan/dscc4.c +++ b/drivers/net/wan/dscc4.c @@ -56,7 +56,7 @@ * IV. Notes * The current error (XDU, RFO) recovery code is untested. * So far, RDO takes his RX channel down and the right sequence to enable it - * again is still a mistery. If RDO happens, plan a reboot. More details + * again is still a mystery. If RDO happens, plan a reboot. More details * in the code (NB: as this happens, TX still works). * Don't mess the cables during operation, especially on DTE ports. I don't * suggest it for DCE either but at least one can get some messages instead @@ -1065,7 +1065,7 @@ static int dscc4_open(struct net_device *dev) /* * Due to various bugs, there is no way to reliably reset a - * specific port (manufacturer's dependant special PCI #RST wiring + * specific port (manufacturer's dependent special PCI #RST wiring * apart: it affects all ports). Thus the device goes in the best * silent mode possible at dscc4_close() time and simply claims to * be up if it's opened again. It still isn't possible to change @@ -1230,9 +1230,9 @@ static inline int dscc4_check_clock_ability(int port) * scaling. Of course some rounding may take place. * - no high speed mode (40Mb/s). May be trivial to do but I don't have an * appropriate external clocking device for testing. - * - no time-slot/clock mode 5: shameless lazyness. + * - no time-slot/clock mode 5: shameless laziness. * - * The clock signals wiring can be (is ?) manufacturer dependant. Good luck. + * The clock signals wiring can be (is ?) manufacturer dependent. Good luck. * * BIG FAT WARNING: if the device isn't provided enough clocking signal, it * won't pass the init sequence. For example, straight back-to-back DTE without diff --git a/drivers/net/wan/hostess_sv11.c b/drivers/net/wan/hostess_sv11.c index 48edc5f4dac8..e817583e6ec5 100644 --- a/drivers/net/wan/hostess_sv11.c +++ b/drivers/net/wan/hostess_sv11.c @@ -15,7 +15,7 @@ * The hardware does the bus handling to avoid the need for delays between * touching control registers. * - * Port B isnt wired (why - beats me) + * Port B isn't wired (why - beats me) * * Generic HDLC port Copyright (C) 2008 Krzysztof Halasa */ diff --git a/drivers/net/wan/ixp4xx_hss.c b/drivers/net/wan/ixp4xx_hss.c index 6c571e198835..f1e1643dc3eb 100644 --- a/drivers/net/wan/ixp4xx_hss.c +++ b/drivers/net/wan/ixp4xx_hss.c @@ -178,7 +178,7 @@ * * The resulting average clock frequency (assuming 33.333 MHz oscillator) is: * freq = 66.666 MHz / (A + (B + 1) / (C + 1)) - * minumum freq = 66.666 MHz / (A + 1) + * minimum freq = 66.666 MHz / (A + 1) * maximum freq = 66.666 MHz / A * * Example: A = 2, B = 2, C = 7, CLOCK_CR register = 2 << 22 | 2 << 12 | 7 @@ -230,7 +230,7 @@ #define PKT_PIPE_MODE_WRITE 0x57 /* HDLC packet status values - desc->status */ -#define ERR_SHUTDOWN 1 /* stop or shutdown occurrance */ +#define ERR_SHUTDOWN 1 /* stop or shutdown occurrence */ #define ERR_HDLC_ALIGN 2 /* HDLC alignment error */ #define ERR_HDLC_FCS 3 /* HDLC Frame Check Sum error */ #define ERR_RXFREE_Q_EMPTY 4 /* RX-free queue became empty while receiving diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c index 70feb84df670..b7f2358d23be 100644 --- a/drivers/net/wan/lmc/lmc_main.c +++ b/drivers/net/wan/lmc/lmc_main.c @@ -24,7 +24,7 @@ * * Linux driver notes: * Linux uses the device struct lmc_private to pass private information - * arround. + * around. * * The initialization portion of this driver (the lmc_reset() and the * lmc_dec_reset() functions, as well as the led controls and the diff --git a/drivers/net/wan/lmc/lmc_var.h b/drivers/net/wan/lmc/lmc_var.h index 65d01978e784..01ad45218d19 100644 --- a/drivers/net/wan/lmc/lmc_var.h +++ b/drivers/net/wan/lmc/lmc_var.h @@ -180,7 +180,7 @@ struct lmc___ctl { /* - * Carefull, look at the data sheet, there's more to this + * Careful, look at the data sheet, there's more to this * structure than meets the eye. It should probably be: * * struct tulip_desc_t { @@ -380,7 +380,7 @@ struct lmc___softc { /* CSR6 settings */ #define OPERATION_MODE 0x00000200 /* Full Duplex */ #define PROMISC_MODE 0x00000040 /* Promiscuous Mode */ -#define RECIEVE_ALL 0x40000000 /* Recieve All */ +#define RECIEVE_ALL 0x40000000 /* Receive All */ #define PASS_BAD_FRAMES 0x00000008 /* Pass Bad Frames */ /* Dec control registers CSR6 as well */ @@ -398,7 +398,7 @@ struct lmc___softc { #define TULIP_CMD_RECEIVEALL 0x40000000L /* (RW) Receivel all frames? */ #define TULIP_CMD_MUSTBEONE 0x02000000L /* (RW) Must Be One (21140) */ #define TULIP_CMD_TXTHRSHLDCTL 0x00400000L /* (RW) Transmit Threshold Mode (21140) */ -#define TULIP_CMD_STOREFWD 0x00200000L /* (RW) Store and Foward (21140) */ +#define TULIP_CMD_STOREFWD 0x00200000L /* (RW) Store and Forward (21140) */ #define TULIP_CMD_NOHEARTBEAT 0x00080000L /* (RW) No Heartbeat (21140) */ #define TULIP_CMD_PORTSELECT 0x00040000L /* (RW) Post Select (100Mb) (21140) */ #define TULIP_CMD_FULLDUPLEX 0x00000200L /* (RW) Full Duplex Mode */ diff --git a/drivers/net/wan/z85230.c b/drivers/net/wan/z85230.c index 93956861ea21..0806232e0f8f 100644 --- a/drivers/net/wan/z85230.c +++ b/drivers/net/wan/z85230.c @@ -542,7 +542,7 @@ static void z8530_dma_tx(struct z8530_channel *chan) z8530_tx(chan); return; } - /* This shouldnt occur in DMA mode */ + /* This shouldn't occur in DMA mode */ printk(KERN_ERR "DMA tx - bogus event!\n"); z8530_tx(chan); } @@ -1219,7 +1219,7 @@ static const char *z8530_type_name[]={ * @io: the port value in question * * Describe a Z8530 in a standard format. We must pass the I/O as - * the port offset isnt predictable. The main reason for this function + * the port offset isn't predictable. The main reason for this function * is to try and get a common format of report. */ @@ -1588,7 +1588,7 @@ static void z8530_rx_done(struct z8530_channel *c) unsigned long flags; /* - * Complete this DMA. Neccessary to find the length + * Complete this DMA. Necessary to find the length */ flags=claim_dma_lock(); @@ -1657,7 +1657,7 @@ static void z8530_rx_done(struct z8530_channel *c) * fifo length for this. Thus we want to flip to the new * buffer and then mess around copying and allocating * things. For the current case it doesn't matter but - * if you build a system where the sync irq isnt blocked + * if you build a system where the sync irq isn't blocked * by the kernel IRQ disable then you need only block the * sync IRQ for the RT_LOCK area. * diff --git a/drivers/net/wimax/i2400m/control.c b/drivers/net/wimax/i2400m/control.c index 12b84ed0e38a..727d728649b7 100644 --- a/drivers/net/wimax/i2400m/control.c +++ b/drivers/net/wimax/i2400m/control.c @@ -378,7 +378,7 @@ void i2400m_report_tlv_system_state(struct i2400m *i2400m, * the device's state as sometimes we need to do a link-renew (the BS * wants us to renew a DHCP lease, for example). * - * In fact, doc says that everytime we get a link-up, we should do a + * In fact, doc says that every time we get a link-up, we should do a * DHCP negotiation... */ static @@ -675,7 +675,7 @@ void i2400m_msg_to_dev_cancel_wait(struct i2400m *i2400m, int code) * - the ack message wasn't formatted correctly * * The returned skb has been allocated with wimax_msg_to_user_alloc(), - * it contains the reponse in a netlink attribute and is ready to be + * it contains the response in a netlink attribute and is ready to be * passed up to user space with wimax_msg_to_user_send(). To access * the payload and its length, use wimax_msg_{data,len}() on the skb. * diff --git a/drivers/net/wimax/i2400m/driver.c b/drivers/net/wimax/i2400m/driver.c index 65bc334ed57b..47cae7150bc1 100644 --- a/drivers/net/wimax/i2400m/driver.c +++ b/drivers/net/wimax/i2400m/driver.c @@ -654,7 +654,7 @@ void __i2400m_dev_reset_handle(struct work_struct *ws) if (result == -EUCLEAN) { /* * We come here because the reset during operational mode - * wasn't successully done and need to proceed to a bus + * wasn't successfully done and need to proceed to a bus * reset. For the dev_reset_handle() to be able to handle * the reset event later properly, we restore boot_mode back * to the state before previous reset. ie: just like we are @@ -755,7 +755,7 @@ EXPORT_SYMBOL_GPL(i2400m_error_recovery); * Alloc the command and ack buffers for boot mode * * Get the buffers needed to deal with boot mode messages. These - * buffers need to be allocated before the sdio recieve irq is setup. + * buffers need to be allocated before the sdio receive irq is setup. */ static int i2400m_bm_buf_alloc(struct i2400m *i2400m) diff --git a/drivers/net/wimax/i2400m/fw.c b/drivers/net/wimax/i2400m/fw.c index 8b55a5b14152..85dadd5bf4be 100644 --- a/drivers/net/wimax/i2400m/fw.c +++ b/drivers/net/wimax/i2400m/fw.c @@ -54,7 +54,7 @@ * endpoint and read from it in the notification endpoint. In SDIO we * talk to it via the write address and read from the read address. * - * Upon entrance to boot mode, the device sends (preceeded with a few + * Upon entrance to boot mode, the device sends (preceded with a few * zero length packets (ZLPs) on the notification endpoint in USB) a * reboot barker (4 le32 words with the same value). We ack it by * sending the same barker to the device. The device acks with a @@ -1589,7 +1589,7 @@ int i2400m_dev_bootstrap(struct i2400m *i2400m, enum i2400m_bri flags) i2400m->fw_name = fw_name; ret = i2400m_fw_bootstrap(i2400m, fw, flags); release_firmware(fw); - if (ret >= 0) /* firmware loaded succesfully */ + if (ret >= 0) /* firmware loaded successfully */ break; i2400m->fw_name = NULL; } diff --git a/drivers/net/wimax/i2400m/i2400m-usb.h b/drivers/net/wimax/i2400m/i2400m-usb.h index eb80243e22df..6650fde99e1d 100644 --- a/drivers/net/wimax/i2400m/i2400m-usb.h +++ b/drivers/net/wimax/i2400m/i2400m-usb.h @@ -105,14 +105,14 @@ static inline void edc_init(struct edc *edc) * * @edc: pointer to error density counter. * @max_err: maximum number of errors we can accept over the timeframe - * @timeframe: lenght of the timeframe (in jiffies). + * @timeframe: length of the timeframe (in jiffies). * * Returns: !0 1 if maximum acceptable errors per timeframe has been * exceeded. 0 otherwise. * * This is way to determine if the number of acceptable errors per time * period has been exceeded. It is not accurate as there are cases in which - * this scheme will not work, for example if there are periodic occurences + * this scheme will not work, for example if there are periodic occurrences * of errors that straddle updates to the start time. This scheme is * sufficient for our usage. * @@ -204,7 +204,7 @@ enum { * usb_autopm_get/put_interface() barriers when executing * commands. See doc in i2400mu_suspend() for more information. * - * @rx_size_auto_shrink: if true, the rx_size is shrinked + * @rx_size_auto_shrink: if true, the rx_size is shrunk * automatically based on the average size of the received * transactions. This allows the receive code to allocate smaller * chunks of memory and thus reduce pressure on the memory diff --git a/drivers/net/wimax/i2400m/i2400m.h b/drivers/net/wimax/i2400m/i2400m.h index 030cbfd31704..5eacc653a94d 100644 --- a/drivers/net/wimax/i2400m/i2400m.h +++ b/drivers/net/wimax/i2400m/i2400m.h @@ -526,7 +526,7 @@ struct i2400m_barker_db; * * @barker: barker type that the device uses; this is initialized by * i2400m_is_boot_barker() the first time it is called. Then it - * won't change during the life cycle of the device and everytime + * won't change during the life cycle of the device and every time * a boot barker is received, it is just verified for it being the * same. * @@ -928,7 +928,7 @@ extern void i2400m_report_tlv_rf_switches_status( struct i2400m *, const struct i2400m_tlv_rf_switches_status *); /* - * Helpers for firmware backwards compability + * Helpers for firmware backwards compatibility * * As we aim to support at least the firmware version that was * released with the previous kernel/driver release, some code will be diff --git a/drivers/net/wimax/i2400m/netdev.c b/drivers/net/wimax/i2400m/netdev.c index 94742e1eafe0..2edd8fe1c1f3 100644 --- a/drivers/net/wimax/i2400m/netdev.c +++ b/drivers/net/wimax/i2400m/netdev.c @@ -166,7 +166,7 @@ void i2400m_wake_tx_work(struct work_struct *ws) d_fnstart(3, dev, "(ws %p i2400m %p skb %p)\n", ws, i2400m, skb); result = -EINVAL; if (skb == NULL) { - dev_err(dev, "WAKE&TX: skb dissapeared!\n"); + dev_err(dev, "WAKE&TX: skb disappeared!\n"); goto out_put; } /* If we have, somehow, lost the connection after this was diff --git a/drivers/net/wimax/i2400m/op-rfkill.c b/drivers/net/wimax/i2400m/op-rfkill.c index 9e02b90b0080..b0dba35a8ad2 100644 --- a/drivers/net/wimax/i2400m/op-rfkill.c +++ b/drivers/net/wimax/i2400m/op-rfkill.c @@ -27,7 +27,7 @@ * - report changes in the HW RF Kill switch [with * wimax_rfkill_{sw,hw}_report(), which happens when we detect those * indications coming through hardware reports]. We also do it on - * initialization to let the stack know the intial HW state. + * initialization to let the stack know the initial HW state. * * - implement indications from the stack to change the SW RF Kill * switch (coming from sysfs, the wimax stack or user space). @@ -73,7 +73,7 @@ int i2400m_radio_is(struct i2400m *i2400m, enum wimax_rf_state state) * Generic Netlink will call this function when a message is sent from * userspace to change the software RF-Kill switch status. * - * This function will set the device's sofware RF-Kill switch state to + * This function will set the device's software RF-Kill switch state to * match what is requested. * * NOTE: the i2400m has a strict state machine; we can only set the diff --git a/drivers/net/wimax/i2400m/rx.c b/drivers/net/wimax/i2400m/rx.c index 844133b44af0..2f94a872101f 100644 --- a/drivers/net/wimax/i2400m/rx.c +++ b/drivers/net/wimax/i2400m/rx.c @@ -349,7 +349,7 @@ error_no_waiter: * * For reports: We can't clone the original skb where the data is * because we need to send this up via netlink; netlink has to add - * headers and we can't overwrite what's preceeding the payload...as + * headers and we can't overwrite what's preceding the payload...as * it is another message. So we just dup them. */ static @@ -425,7 +425,7 @@ error_check: * * As in i2400m_rx_ctl(), we can't clone the original skb where the * data is because we need to send this up via netlink; netlink has to - * add headers and we can't overwrite what's preceeding the + * add headers and we can't overwrite what's preceding the * payload...as it is another message. So we just dup them. */ static diff --git a/drivers/net/wimax/i2400m/tx.c b/drivers/net/wimax/i2400m/tx.c index 3f819efc06b5..4b30ed11d785 100644 --- a/drivers/net/wimax/i2400m/tx.c +++ b/drivers/net/wimax/i2400m/tx.c @@ -149,7 +149,7 @@ * (with a moved message header to make sure it is size-aligned to * 16), TAIL room that was unusable (and thus is marked with a message * header that says 'skip this') and at the head of the buffer, an - * imcomplete message with a couple of payloads. + * incomplete message with a couple of payloads. * * N ___________________________________________________ * | | @@ -819,7 +819,7 @@ EXPORT_SYMBOL_GPL(i2400m_tx); * the FIF that is ready for transmission. * * It sets the state in @i2400m to indicate the bus-specific driver is - * transfering that message (i2400m->tx_msg_size). + * transferring that message (i2400m->tx_msg_size). * * Once the transfer is completed, call i2400m_tx_msg_sent(). * diff --git a/drivers/net/wimax/i2400m/usb-fw.c b/drivers/net/wimax/i2400m/usb-fw.c index b58ec56b86f8..1fda46c55eb3 100644 --- a/drivers/net/wimax/i2400m/usb-fw.c +++ b/drivers/net/wimax/i2400m/usb-fw.c @@ -169,7 +169,7 @@ retry: * * Command can be a raw command, which requires no preparation (and * which might not even be following the command format). Checks that - * the right amount of data was transfered. + * the right amount of data was transferred. * * To satisfy USB requirements (no onstack, vmalloc or in data segment * buffers), we copy the command to i2400m->bm_cmd_buf and send it from diff --git a/drivers/net/wimax/i2400m/usb-rx.c b/drivers/net/wimax/i2400m/usb-rx.c index a26483a812a5..e3257681e360 100644 --- a/drivers/net/wimax/i2400m/usb-rx.c +++ b/drivers/net/wimax/i2400m/usb-rx.c @@ -58,7 +58,7 @@ * a zillion reads; by serializing, we are throttling. * * - RX data processing can get heavy enough so that it is not - * appropiate for doing it in the USB callback; thus we run it in a + * appropriate for doing it in the USB callback; thus we run it in a * process context. * * We provide a read buffer of an arbitrary size (short of a page); if diff --git a/drivers/net/wimax/i2400m/usb-tx.c b/drivers/net/wimax/i2400m/usb-tx.c index c65b9979f87e..ac357acfb3e9 100644 --- a/drivers/net/wimax/i2400m/usb-tx.c +++ b/drivers/net/wimax/i2400m/usb-tx.c @@ -168,7 +168,7 @@ retry: /* * Get the next TX message in the TX FIFO and send it to the device * - * Note we exit the loop if i2400mu_tx() fails; that funtion only + * Note we exit the loop if i2400mu_tx() fails; that function only * fails on hard error (failing to tx a buffer not being one of them, * see its doc). * diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 57a79b0475f6..4e5c7a11f04a 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -1884,7 +1884,7 @@ static int airo_open(struct net_device *dev) { /* Make sure the card is configured. * Wireless Extensions may postpone config changes until the card * is open (to pipeline changes and speed-up card setup). If - * those changes are not yet commited, do it now - Jean II */ + * those changes are not yet committed, do it now - Jean II */ if (test_bit(FLAG_COMMIT, &ai->flags)) { disable_MAC(ai, 1); writeConfigRid(ai, 1); @@ -1992,7 +1992,7 @@ static int mpi_send_packet (struct net_device *dev) /* * Magic, the cards firmware needs a length count (2 bytes) in the host buffer * right after TXFID_HDR.The TXFID_HDR contains the status short so payloadlen - * is immediatly after it. ------------------------------------------------ + * is immediately after it. ------------------------------------------------ * |TXFIDHDR+STATUS|PAYLOADLEN|802.3HDR|PACKETDATA| * ------------------------------------------------ */ @@ -2006,7 +2006,7 @@ static int mpi_send_packet (struct net_device *dev) sizeof(wifictlhdr8023) + 2 ; /* - * Firmware automaticly puts 802 header on so + * Firmware automatically puts 802 header on so * we don't need to account for it in the length */ if (test_bit(FLAG_MIC_CAPABLE, &ai->flags) && ai->micstats.enabled && @@ -2531,7 +2531,7 @@ static int mpi_init_descriptors (struct airo_info *ai) /* * We are setting up three things here: * 1) Map AUX memory for descriptors: Rid, TxFid, or RxFid. - * 2) Map PCI memory for issueing commands. + * 2) Map PCI memory for issuing commands. * 3) Allocate memory (shared) to send and receive ethernet frames. */ static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci) @@ -3947,7 +3947,7 @@ static u16 issuecommand(struct airo_info *ai, Cmd *pCmd, Resp *pRsp) { if ( max_tries == -1 ) { airo_print_err(ai->dev->name, - "Max tries exceeded when issueing command"); + "Max tries exceeded when issuing command"); if (IN4500(ai, COMMAND) & COMMAND_BUSY) OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY); return ERROR; @@ -4173,7 +4173,7 @@ done: } /* Note, that we are using BAP1 which is also used by transmit, so - * make sure this isnt called when a transmit is happening */ + * make sure this isn't called when a transmit is happening */ static int PC4500_writerid(struct airo_info *ai, u16 rid, const void *pBuf, int len, int lock) { @@ -4776,7 +4776,7 @@ static int proc_stats_rid_open( struct inode *inode, if (!statsLabels[i]) continue; if (j+strlen(statsLabels[i])+16>4096) { airo_print_warn(apriv->dev->name, - "Potentially disasterous buffer overflow averted!"); + "Potentially disastrous buffer overflow averted!"); break; } j+=sprintf(data->rbuffer+j, "%s: %u\n", statsLabels[i], diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c index b761fec0d721..ccc2edaaeda0 100644 --- a/drivers/net/wireless/ath/ar9170/main.c +++ b/drivers/net/wireless/ath/ar9170/main.c @@ -974,7 +974,7 @@ void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb) if (ar->rx_failover_missing <= 0) { /* * nested ar9170_rx call! - * termination is guranteed, even when the + * termination is guaranteed, even when the * combined frame also have a element with * a bad tag. */ diff --git a/drivers/net/wireless/ath/ar9170/phy.c b/drivers/net/wireless/ath/ar9170/phy.c index 0dbfcf79ac96..aa8d06ba1ee4 100644 --- a/drivers/net/wireless/ath/ar9170/phy.c +++ b/drivers/net/wireless/ath/ar9170/phy.c @@ -424,7 +424,7 @@ static u32 ar9170_get_default_phy_reg_val(u32 reg, bool is_2ghz, bool is_40mhz) /* * initialize some phy regs from eeprom values in modal_header[] - * acc. to band and bandwith + * acc. to band and bandwidth */ static int ar9170_init_phy_from_eeprom(struct ar9170 *ar, bool is_2ghz, bool is_40mhz) diff --git a/drivers/net/wireless/ath/ath5k/ani.h b/drivers/net/wireless/ath/ath5k/ani.h index d0a664039c87..034015397093 100644 --- a/drivers/net/wireless/ath/ath5k/ani.h +++ b/drivers/net/wireless/ath/ath5k/ani.h @@ -27,7 +27,7 @@ #define ATH5K_ANI_RSSI_THR_HIGH 40 #define ATH5K_ANI_RSSI_THR_LOW 7 -/* maximum availabe levels */ +/* maximum available levels */ #define ATH5K_ANI_MAX_FIRSTEP_LVL 2 #define ATH5K_ANI_MAX_NOISE_IMM_LVL 1 diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 4d7f21ee111c..349a5963931b 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1953,7 +1953,7 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf) #define FUDGE AR5K_TUNE_SW_BEACON_RESP + 3 /* We use FUDGE to make sure the next TBTT is ahead of the current TU. - * Since we later substract AR5K_TUNE_SW_BEACON_RESP (10) in the timer + * Since we later subtract AR5K_TUNE_SW_BEACON_RESP (10) in the timer * configuration we need to make sure it is bigger than that. */ if (bc_tsf == -1) { @@ -1971,7 +1971,7 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf) intval |= AR5K_BEACON_RESET_TSF; } else if (bc_tsf > hw_tsf) { /* - * beacon received, SW merge happend but HW TSF not yet updated. + * beacon received, SW merge happened but HW TSF not yet updated. * not possible to reconfigure timers yet, but next time we * receive a beacon with the same BSSID, the hardware will * automatically update the TSF and then we need to reconfigure @@ -2651,7 +2651,7 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan, synchronize_irq(sc->irq); stop_tasklets(sc); - /* Save ani mode and disable ANI durring + /* Save ani mode and disable ANI during * reset. If we don't we might get false * PHY error interrupts. */ ani_mode = ah->ah_sc->ani_state.ani_mode; diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c index 16b44ff7dd3e..a8fcc94269f7 100644 --- a/drivers/net/wireless/ath/ath5k/desc.c +++ b/drivers/net/wireless/ath/ath5k/desc.c @@ -51,7 +51,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, /* * Validate input * - Zero retries don't make sense. - * - A zero rate will put the HW into a mode where it continously sends + * - A zero rate will put the HW into a mode where it continuously sends * noise on the channel, so it is important to avoid this. */ if (unlikely(tx_tries0 == 0)) { @@ -190,7 +190,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, /* * Validate input * - Zero retries don't make sense. - * - A zero rate will put the HW into a mode where it continously sends + * - A zero rate will put the HW into a mode where it continuously sends * noise on the channel, so it is important to avoid this. */ if (unlikely(tx_tries0 == 0)) { @@ -300,7 +300,7 @@ ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, /* * Rates can be 0 as long as the retry count is 0 too. * A zero rate and nonzero retry count will put the HW into a mode where - * it continously sends noise on the channel, so it is important to + * it continuously sends noise on the channel, so it is important to * avoid this. */ if (unlikely((tx_rate1 == 0 && tx_tries1 != 0) || @@ -342,7 +342,7 @@ ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, \***********************/ /* - * Proccess the tx status descriptor on 5210/5211 + * Process the tx status descriptor on 5210/5211 */ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah, struct ath5k_desc *desc, struct ath5k_tx_status *ts) @@ -394,7 +394,7 @@ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah, } /* - * Proccess a tx status descriptor on 5212 + * Process a tx status descriptor on 5212 */ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, struct ath5k_desc *desc, struct ath5k_tx_status *ts) @@ -519,7 +519,7 @@ int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, } /* - * Proccess the rx status descriptor on 5210/5211 + * Process the rx status descriptor on 5210/5211 */ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah, struct ath5k_desc *desc, struct ath5k_rx_status *rs) @@ -602,7 +602,7 @@ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah, } /* - * Proccess the rx status descriptor on 5212 + * Process the rx status descriptor on 5212 */ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, struct ath5k_desc *desc, diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index b6561f785c6e..efb672cb31e4 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c @@ -1080,7 +1080,7 @@ ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode) * * To recreate the curves we read here the points and interpolate * later. Note that in most cases only 2 (higher and lower) curves are - * used (like RF5112) but vendors have the oportunity to include all + * used (like RF5112) but vendors have the opportunity to include all * 4 curves on eeprom. The final curve (higher power) has an extra * point for better accuracy like RF5112. */ @@ -1302,7 +1302,7 @@ ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode) /* * Pd gain 0 is not the last pd gain * so it only has 2 pd points. - * Continue wih pd gain 1. + * Continue with pd gain 1. */ pcinfo->pwr_i[1] = (val >> 10) & 0x1f; diff --git a/drivers/net/wireless/ath/ath5k/pci.c b/drivers/net/wireless/ath/ath5k/pci.c index 66598a0d1df0..3c44689a700b 100644 --- a/drivers/net/wireless/ath/ath5k/pci.c +++ b/drivers/net/wireless/ath/ath5k/pci.c @@ -57,7 +57,7 @@ static void ath5k_pci_read_cachesize(struct ath_common *common, int *csz) *csz = (int)u8tmp; /* - * This check was put in to avoid "unplesant" consequences if + * This check was put in to avoid "unpleasant" consequences if * the bootrom has not fully initialized all PCI devices. * Sometimes the cache line size register is not set */ diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index a702817daf72..d9b3f828455a 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c @@ -472,7 +472,7 @@ void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter) } /* - * The AR5210 uses promiscous mode to detect radar activity + * The AR5210 uses promiscuous mode to detect radar activity */ if (ah->ah_version == AR5K_AR5210 && (filter & AR5K_RX_FILTER_RADARERR)) { @@ -706,8 +706,8 @@ ath5k_check_timer_win(int a, int b, int window, int intval) * The need for this function arises from the fact that we have 4 separate * HW timer registers (TIMER0 - TIMER3), which are closely related to the * next beacon target time (NBTT), and that the HW updates these timers - * seperately based on the current TSF value. The hardware increments each - * timer by the beacon interval, when the local TSF coverted to TU is equal + * separately based on the current TSF value. The hardware increments each + * timer by the beacon interval, when the local TSF converted to TU is equal * to the value stored in the timer. * * The reception of a beacon with the same BSSID can update the local HW TSF diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 62ce2f4e8605..55441913344d 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -335,11 +335,11 @@ static void ath5k_hw_wait_for_synth(struct ath5k_hw *ah, * http://madwifi-project.org/ticket/1659 * with various measurements and diagrams * - * TODO: Deal with power drops due to probes by setting an apropriate + * TODO: Deal with power drops due to probes by setting an appropriate * tx power on the probe packets ! Make this part of the calibration process. */ -/* Initialize ah_gain durring attach */ +/* Initialize ah_gain during attach */ int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah) { /* Initialize the gain optimization values */ @@ -1049,7 +1049,7 @@ static int ath5k_hw_rfregs_init(struct ath5k_hw *ah, \**************************/ /* - * Convertion needed for RF5110 + * Conversion needed for RF5110 */ static u32 ath5k_hw_rf5110_chan2athchan(struct ieee80211_channel *channel) { @@ -1088,7 +1088,7 @@ static int ath5k_hw_rf5110_channel(struct ath5k_hw *ah, } /* - * Convertion needed for 5111 + * Conversion needed for 5111 */ static int ath5k_hw_rf5111_chan2athchan(unsigned int ieee, struct ath5k_athchan_2ghz *athchan) @@ -2201,7 +2201,7 @@ ath5k_create_power_curve(s16 pmin, s16 pmax, /* * Get the surrounding per-channel power calibration piers * for a given frequency so that we can interpolate between - * them and come up with an apropriate dataset for our current + * them and come up with an appropriate dataset for our current * channel. */ static void @@ -2618,7 +2618,7 @@ ath5k_write_pcdac_table(struct ath5k_hw *ah) /* * Set the gain boundaries and create final Power to PDADC table * - * We can have up to 4 pd curves, we need to do a simmilar process + * We can have up to 4 pd curves, we need to do a similar process * as we do for RF5112. This time we don't have an edge_flag but we * set the gain boundaries on a separate register. */ @@ -2826,13 +2826,13 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah, u32 target = channel->center_freq; int pdg, i; - /* Get surounding freq piers for this channel */ + /* Get surrounding freq piers for this channel */ ath5k_get_chan_pcal_surrounding_piers(ah, channel, &pcinfo_L, &pcinfo_R); /* Loop over pd gain curves on - * surounding freq piers by index */ + * surrounding freq piers by index */ for (pdg = 0; pdg < ee->ee_pd_gains[ee_mode]; pdg++) { /* Fill curves in reverse order @@ -2923,7 +2923,7 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah, } /* Interpolate between curves - * of surounding freq piers to + * of surrounding freq piers to * get the final curve for this * pd gain. Re-use tmpL for interpolation * output */ @@ -2947,7 +2947,7 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah, /* Fill min and max power levels for this * channel by interpolating the values on - * surounding channels to complete the dataset */ + * surrounding channels to complete the dataset */ ah->ah_txpower.txp_min_pwr = ath5k_get_interpolated_value(target, (s16) pcinfo_L->freq, (s16) pcinfo_R->freq, @@ -3179,7 +3179,7 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, /* FIXME: TPC scale reduction */ - /* Get surounding channels for per-rate power table + /* Get surrounding channels for per-rate power table * calibration */ ath5k_get_rate_pcal_data(ah, channel, &rate_info); diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h index e1c9abd8c879..d12b827033c1 100644 --- a/drivers/net/wireless/ath/ath5k/reg.h +++ b/drivers/net/wireless/ath/ath5k/reg.h @@ -132,8 +132,8 @@ * As i can see in ar5k_ar5210_tx_start Reyk uses some of the values of BCR * for this register, so i guess TQ1V,TQ1FV and BDMAE have the same meaning * here and SNP/SNAP means "snapshot" (so this register gets synced with BCR). - * So SNAPPEDBCRVALID sould also stand for "snapped BCR -values- valid", so i - * renamed it to SNAPSHOTSVALID to make more sense. I realy have no idea what + * So SNAPPEDBCRVALID should also stand for "snapped BCR -values- valid", so i + * renamed it to SNAPSHOTSVALID to make more sense. I really have no idea what * else can it be. I also renamed SNPBCMD to SNPADHOC to match BCR. */ #define AR5K_BSR 0x002c /* Register Address */ @@ -283,7 +283,7 @@ */ #define AR5K_ISR 0x001c /* Register Address [5210] */ #define AR5K_PISR 0x0080 /* Register Address [5211+] */ -#define AR5K_ISR_RXOK 0x00000001 /* Frame successfuly recieved */ +#define AR5K_ISR_RXOK 0x00000001 /* Frame successfuly received */ #define AR5K_ISR_RXDESC 0x00000002 /* RX descriptor request */ #define AR5K_ISR_RXERR 0x00000004 /* Receive error */ #define AR5K_ISR_RXNOFRM 0x00000008 /* No frame received (receive timeout) */ @@ -372,12 +372,12 @@ /* * Interrupt Mask Registers * - * As whith ISRs 5210 has one IMR (AR5K_IMR) and 5211/5212 has one primary + * As with ISRs 5210 has one IMR (AR5K_IMR) and 5211/5212 has one primary * (AR5K_PIMR) and 4 secondary IMRs (AR5K_SIMRx). Note that ISR/IMR flags match. */ #define AR5K_IMR 0x0020 /* Register Address [5210] */ #define AR5K_PIMR 0x00a0 /* Register Address [5211+] */ -#define AR5K_IMR_RXOK 0x00000001 /* Frame successfuly recieved*/ +#define AR5K_IMR_RXOK 0x00000001 /* Frame successfuly received*/ #define AR5K_IMR_RXDESC 0x00000002 /* RX descriptor request*/ #define AR5K_IMR_RXERR 0x00000004 /* Receive error*/ #define AR5K_IMR_RXNOFRM 0x00000008 /* No frame received (receive timeout)*/ @@ -895,7 +895,7 @@ #define AR5K_PCICFG_SL_INTEN 0x00000800 /* Enable interrupts when asleep */ #define AR5K_PCICFG_LED_BCTL 0x00001000 /* Led blink (?) [5210] */ #define AR5K_PCICFG_RETRY_FIX 0x00001000 /* Enable pci core retry fix */ -#define AR5K_PCICFG_SL_INPEN 0x00002000 /* Sleep even whith pending interrupts*/ +#define AR5K_PCICFG_SL_INPEN 0x00002000 /* Sleep even with pending interrupts*/ #define AR5K_PCICFG_SPWR_DN 0x00010000 /* Mask for power status */ #define AR5K_PCICFG_LEDMODE 0x000e0000 /* Ledmode [5211+] */ #define AR5K_PCICFG_LEDMODE_PROP 0x00000000 /* Blink on standard traffic [5211+] */ diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index ffcf44a4058b..106c0b06cf55 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -142,7 +142,7 @@ static void ar5008_hw_force_bias(struct ath_hw *ah, u16 synth_freq) /** * ar5008_hw_set_channel - tune to a channel on the external AR2133/AR5133 radios - * @ah: atheros hardware stucture + * @ah: atheros hardware structure * @chan: * * For the external AR2133/AR5133 radios, takes the MHz channel value and set diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 4a9271802991..6eadf975ae48 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -3240,7 +3240,7 @@ static int ar9300_compress_decision(struct ath_hw *ah, eep = ar9003_eeprom_struct_find_by_id(reference); if (eep == NULL) { ath_dbg(common, ATH_DBG_EEPROM, - "cant find reference eeprom struct %d\n", + "can't find reference eeprom struct %d\n", reference); return -1; } diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index c41ab8c30161..62e139a30a74 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c @@ -360,7 +360,7 @@ ret: * HTC Messages are handled directly here and the obtained SKB * is freed. * - * Sevice messages (Data, WMI) passed to the corresponding + * Service messages (Data, WMI) passed to the corresponding * endpoint RX handlers, which have to free the SKB. */ void ath9k_htc_rx_msg(struct htc_target *htc_handle, diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index e83128c50f7b..9c65459be100 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c @@ -44,7 +44,7 @@ static void ath_pci_read_cachesize(struct ath_common *common, int *csz) *csz = (int)u8tmp; /* - * This check was put in to avoid "unplesant" consequences if + * This check was put in to avoid "unpleasant" consequences if * the bootrom has not fully initialized all PCI devices. * Sometimes the cache line size register is not set */ diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index a3241cd089b1..4c0d36a6980f 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -792,7 +792,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, tx_info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; } else { - /* Set the choosen rate. No RTS for first series entry. */ + /* Set the chosen rate. No RTS for first series entry. */ ath_rc_rate_set_series(rate_table, &rates[i++], txrc, try_per_rate, rix, 0); } diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 26734e53b37f..88fa7fdffd05 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -628,8 +628,8 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, (u32)ATH_AMPDU_LIMIT_MAX); /* - * h/w can accept aggregates upto 16 bit lengths (65535). - * The IE, however can hold upto 65536, which shows up here + * h/w can accept aggregates up to 16 bit lengths (65535). + * The IE, however can hold up to 65536, which shows up here * as zero. Ignore 65536 since we are constrained by hw. */ if (tid->an->maxampdu) diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h index c6a5fae634a0..c01c43d8e61b 100644 --- a/drivers/net/wireless/ath/carl9170/carl9170.h +++ b/drivers/net/wireless/ath/carl9170/carl9170.h @@ -161,7 +161,7 @@ struct carl9170_sta_tid { * Naturally: The higher the limit, the faster the device CAN send. * However, even a slight over-commitment at the wrong time and the * hardware is doomed to send all already-queued frames at suboptimal - * rates. This in turn leads to an enourmous amount of unsuccessful + * rates. This in turn leads to an enormous amount of unsuccessful * retries => Latency goes up, whereas the throughput goes down. CRASH! */ #define CARL9170_NUM_TX_LIMIT_HARD ((AR9170_TXQ_DEPTH * 3) / 2) diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c index b6b0de600506..b6ae0e179c8d 100644 --- a/drivers/net/wireless/ath/carl9170/phy.c +++ b/drivers/net/wireless/ath/carl9170/phy.c @@ -427,7 +427,7 @@ static u32 carl9170_def_val(u32 reg, bool is_2ghz, bool is_40mhz) /* * initialize some phy regs from eeprom values in modal_header[] - * acc. to band and bandwith + * acc. to band and bandwidth */ static int carl9170_init_phy_from_eeprom(struct ar9170 *ar, bool is_2ghz, bool is_40mhz) diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c index 84866a4b8350..ec21ea9fd8d5 100644 --- a/drivers/net/wireless/ath/carl9170/rx.c +++ b/drivers/net/wireless/ath/carl9170/rx.c @@ -849,7 +849,7 @@ static void carl9170_rx_stream(struct ar9170 *ar, void *buf, unsigned int len) /* * nested carl9170_rx_stream call! * - * termination is guranteed, even when the + * termination is guaranteed, even when the * combined frame also have an element with * a bad tag. */ diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c index f82c400be288..2fb53d067512 100644 --- a/drivers/net/wireless/ath/carl9170/usb.c +++ b/drivers/net/wireless/ath/carl9170/usb.c @@ -430,7 +430,7 @@ static void carl9170_usb_rx_complete(struct urb *urb) * The system is too slow to cope with * the enormous workload. We have simply * run out of active rx urbs and this - * unfortunatly leads to an unpredictable + * unfortunately leads to an unpredictable * device. */ diff --git a/drivers/net/wireless/ath/hw.c b/drivers/net/wireless/ath/hw.c index 183c28281385..cc11d66f15bc 100644 --- a/drivers/net/wireless/ath/hw.c +++ b/drivers/net/wireless/ath/hw.c @@ -86,7 +86,7 @@ * IFRAME-01: 0110 * * An easy eye-inspeciton of this already should tell you that this frame - * will not pass our check. This is beacuse the bssid_mask tells the + * will not pass our check. This is because the bssid_mask tells the * hardware to only look at the second least significant bit and the * common bit amongst the MAC and BSSIDs is 0, this frame has the 2nd LSB * as 1, which does not match 0. diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index f828f294ba89..0e1b8793c864 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c @@ -268,7 +268,7 @@ ath_reg_apply_active_scan_flags(struct wiphy *wiphy, } /* - * If a country IE has been recieved check its rule for this + * If a country IE has been received check its rule for this * channel first before enabling active scan. The passive scan * would have been enforced by the initial processing of our * custom regulatory domain. @@ -476,7 +476,7 @@ ath_regd_init_wiphy(struct ath_regulatory *reg, wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; } else { /* - * This gets applied in the case of the absense of CRDA, + * This gets applied in the case of the absence of CRDA, * it's our own custom world regulatory domain, similar to * cfg80211's but we enable passive scanning. */ diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index 46e382ed46aa..39a11e8af4fa 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c @@ -439,7 +439,7 @@ static u8 mac_reader[] = { }; struct atmel_private { - void *card; /* Bus dependent stucture varies for PCcard */ + void *card; /* Bus dependent structure varies for PCcard */ int (*present_callback)(void *); /* And callback which uses it */ char firmware_id[32]; AtmelFWType firmware_type; @@ -3895,7 +3895,7 @@ static int reset_atmel_card(struct net_device *dev) This routine is also responsible for initialising some hardware-specific fields in the atmel_private structure, - including a copy of the firmware's hostinfo stucture + including a copy of the firmware's hostinfo structure which is the route into the rest of the firmware datastructures. */ struct atmel_private *priv = netdev_priv(dev); diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c index c96e19da2949..05263516c113 100644 --- a/drivers/net/wireless/atmel_cs.c +++ b/drivers/net/wireless/atmel_cs.c @@ -99,7 +99,7 @@ static void atmel_detach(struct pcmcia_device *link) } /* Call-back function to interrogate PCMCIA-specific information - about the current existance of the card */ + about the current existence of the card */ static int card_present(void *arg) { struct pcmcia_device *link = (struct pcmcia_device *)arg; diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index bd4cb75b6ca3..229f4388f790 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -648,7 +648,7 @@ struct b43_request_fw_context { char errors[B43_NR_FWTYPES][128]; /* Temporary buffer for storing the firmware name. */ char fwname[64]; - /* A fatal error occured while requesting. Firmware reqest + /* A fatal error occurred while requesting. Firmware reqest * can not continue, as any other reqest will also fail. */ int fatal_failure; }; diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 57eb5b649730..d59b0168c14a 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -4010,7 +4010,7 @@ static int b43_wireless_core_start(struct b43_wldev *dev) b43_mac_enable(dev); b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask); - /* Start maintainance work */ + /* Start maintenance work */ b43_periodic_tasks_setup(dev); b43_leds_init(dev); diff --git a/drivers/net/wireless/b43/phy_g.h b/drivers/net/wireless/b43/phy_g.h index 8569fdd4c6be..5413c906a3e7 100644 --- a/drivers/net/wireless/b43/phy_g.h +++ b/drivers/net/wireless/b43/phy_g.h @@ -164,7 +164,7 @@ struct b43_phy_g { /* Current Interference Mitigation mode */ int interfmode; /* Stack of saved values from the Interference Mitigation code. - * Each value in the stack is layed out as follows: + * Each value in the stack is laid out as follows: * bit 0-11: offset * bit 12-15: register ID * bit 16-32: value diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h index 001e841f118c..e789a89f1047 100644 --- a/drivers/net/wireless/b43/phy_n.h +++ b/drivers/net/wireless/b43/phy_n.h @@ -703,7 +703,7 @@ #define B43_NPHY_CHAN_ESTHANG B43_PHY_N(0x21D) /* Channel estimate hang */ #define B43_NPHY_FINERX2_CGC B43_PHY_N(0x221) /* Fine RX 2 clock gate control */ #define B43_NPHY_FINERX2_CGC_DECGC 0x0008 /* Decode gated clocks */ -#define B43_NPHY_TXPCTL_INIT B43_PHY_N(0x222) /* TX power controll init */ +#define B43_NPHY_TXPCTL_INIT B43_PHY_N(0x222) /* TX power control init */ #define B43_NPHY_TXPCTL_INIT_PIDXI1 0x00FF /* Power index init 1 */ #define B43_NPHY_TXPCTL_INIT_PIDXI1_SHIFT 0 #define B43_NPHY_PAPD_EN0 B43_PHY_N(0x297) /* PAPD Enable0 TBD */ diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h index c81b2f53b0c5..23583be1ee0b 100644 --- a/drivers/net/wireless/b43legacy/b43legacy.h +++ b/drivers/net/wireless/b43legacy/b43legacy.h @@ -488,7 +488,7 @@ struct b43legacy_phy { /* Current Interference Mitigation mode */ int interfmode; /* Stack of saved values from the Interference Mitigation code. - * Each value in the stack is layed out as follows: + * Each value in the stack is laid out as follows: * bit 0-11: offset * bit 12-15: register ID * bit 16-32: value diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c index 18d63f57777d..3d05dc15c6b8 100644 --- a/drivers/net/wireless/hostap/hostap_ap.c +++ b/drivers/net/wireless/hostap/hostap_ap.c @@ -2359,7 +2359,7 @@ int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[], } -/* Translate our list of Access Points & Stations to a card independant +/* Translate our list of Access Points & Stations to a card independent * format that the Wireless Tools will understand - Jean II */ int prism2_ap_translate_scan(struct net_device *dev, struct iw_request_info *info, char *buffer) diff --git a/drivers/net/wireless/hostap/hostap_ap.h b/drivers/net/wireless/hostap/hostap_ap.h index 655ceeba9612..334e2d0b8e11 100644 --- a/drivers/net/wireless/hostap/hostap_ap.h +++ b/drivers/net/wireless/hostap/hostap_ap.h @@ -114,7 +114,7 @@ struct sta_info { * has passed since last received frame from the station, a nullfunc data * frame is sent to the station. If this frame is not acknowledged and no other * frames have been received, the station will be disassociated after - * AP_DISASSOC_DELAY. Similarily, a the station will be deauthenticated after + * AP_DISASSOC_DELAY. Similarly, a the station will be deauthenticated after * AP_DEAUTH_DELAY. AP_TIMEOUT_RESOLUTION is the resolution that is used with * max inactivity timer. */ #define AP_MAX_INACTIVITY_SEC (5 * 60) diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c index 6038633ef361..12de46407c71 100644 --- a/drivers/net/wireless/hostap/hostap_ioctl.c +++ b/drivers/net/wireless/hostap/hostap_ioctl.c @@ -1945,7 +1945,7 @@ static char * __prism2_translate_scan(local_info_t *local, } -/* Translate scan data returned from the card to a card independant +/* Translate scan data returned from the card to a card independent * format that the Wireless Tools will understand - Jean II */ static inline int prism2_translate_scan(local_info_t *local, struct iw_request_info *info, @@ -2043,7 +2043,7 @@ static inline int prism2_ioctl_giwscan_sta(struct net_device *dev, * until results are ready for various reasons. * First, managing wait queues is complex and racy * (there may be multiple simultaneous callers). - * Second, we grab some rtnetlink lock before comming + * Second, we grab some rtnetlink lock before coming * here (in dev_ioctl()). * Third, the caller can wait on the Wireless Event * - Jean II */ diff --git a/drivers/net/wireless/hostap/hostap_wlan.h b/drivers/net/wireless/hostap/hostap_wlan.h index 1c66b3c1030d..88dc6a52bdf1 100644 --- a/drivers/net/wireless/hostap/hostap_wlan.h +++ b/drivers/net/wireless/hostap/hostap_wlan.h @@ -853,7 +853,7 @@ struct local_info { struct work_struct comms_qual_update; /* RSSI to dBm adjustment (for RX descriptor fields) */ - int rssi_to_dBm; /* substract from RSSI to get approximate dBm value */ + int rssi_to_dBm; /* subtract from RSSI to get approximate dBm value */ /* BSS list / protected by local->lock */ struct list_head bss_list; diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index 4b97f918daff..44307753587d 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c @@ -63,7 +63,7 @@ When data is sent to the firmware, the first TBD is used to indicate to the firmware if a Command or Data is being sent. If it is Command, all of the command information is contained within the physical address referred to by the TBD. If it is Data, the first TBD indicates the type of data packet, number -of fragments, etc. The next TBD then referrs to the actual packet location. +of fragments, etc. The next TBD then refers to the actual packet location. The Tx flow cycle is as follows: diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index 160881f234cc..42c3fe37af64 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c @@ -1181,7 +1181,7 @@ static void ipw_led_shutdown(struct ipw_priv *priv) /* * The following adds a new attribute to the sysfs representation * of this device driver (i.e. a new file in /sys/bus/pci/drivers/ipw/) - * used for controling the debug level. + * used for controlling the debug level. * * See the level definitions in ipw for details. */ @@ -3763,7 +3763,7 @@ static int ipw_queue_tx_init(struct ipw_priv *priv, q->txb = kmalloc(sizeof(q->txb[0]) * count, GFP_KERNEL); if (!q->txb) { - IPW_ERROR("vmalloc for auxilary BD structures failed\n"); + IPW_ERROR("vmalloc for auxiliary BD structures failed\n"); return -ENOMEM; } @@ -5581,7 +5581,7 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, return 0; } - /* Verify privacy compatability */ + /* Verify privacy compatibility */ if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) != ((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) { IPW_DEBUG_MERGE("Network '%s (%pM)' excluded " @@ -5808,7 +5808,7 @@ static int ipw_best_network(struct ipw_priv *priv, return 0; } - /* Verify privacy compatability */ + /* Verify privacy compatibility */ if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) != ((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) { IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded " @@ -8184,7 +8184,7 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv, static int is_network_packet(struct ipw_priv *priv, struct libipw_hdr_4addr *header) { - /* Filter incoming packets to determine if they are targetted toward + /* Filter incoming packets to determine if they are targeted toward * this network, discarding packets coming from ourselves */ switch (priv->ieee->iw_mode) { case IW_MODE_ADHOC: /* Header: Dest. | Source | BSSID */ @@ -8340,9 +8340,9 @@ static void ipw_handle_mgmt_packet(struct ipw_priv *priv, } /* - * Main entry function for recieving a packet with 80211 headers. This + * Main entry function for receiving a packet with 80211 headers. This * should be called when ever the FW has notified us that there is a new - * skb in the recieve queue. + * skb in the receive queue. */ static void ipw_rx(struct ipw_priv *priv) { @@ -8683,7 +8683,7 @@ static int ipw_sw_reset(struct ipw_priv *priv, int option) * functions defined in ipw_main to provide the HW interaction. * * The exception to this is the use of the ipw_get_ordinal() - * function used to poll the hardware vs. making unecessary calls. + * function used to poll the hardware vs. making unnecessary calls. * */ @@ -10419,7 +10419,7 @@ static void ipw_handle_promiscuous_tx(struct ipw_priv *priv, memset(&dummystats, 0, sizeof(dummystats)); - /* Filtering of fragment chains is done agains the first fragment */ + /* Filtering of fragment chains is done against the first fragment */ hdr = (void *)txb->fragments[0]->data; if (libipw_is_management(le16_to_cpu(hdr->frame_control))) { if (filter & IPW_PROM_NO_MGMT) diff --git a/drivers/net/wireless/ipw2x00/libipw_rx.c b/drivers/net/wireless/ipw2x00/libipw_rx.c index 0de1b1893220..e5ad76cd77da 100644 --- a/drivers/net/wireless/ipw2x00/libipw_rx.c +++ b/drivers/net/wireless/ipw2x00/libipw_rx.c @@ -925,7 +925,7 @@ drop_free: static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 }; /* -* Make ther structure we read from the beacon packet has +* Make the structure we read from the beacon packet to have * the right values */ static int libipw_verify_qos_info(struct libipw_qos_information_element diff --git a/drivers/net/wireless/iwlegacy/iwl-core.c b/drivers/net/wireless/iwlegacy/iwl-core.c index d418b647be80..1c3a8cb186bf 100644 --- a/drivers/net/wireless/iwlegacy/iwl-core.c +++ b/drivers/net/wireless/iwlegacy/iwl-core.c @@ -1030,7 +1030,7 @@ int iwl_legacy_apm_init(struct iwl_priv *priv) /* * Enable HAP INTA (interrupt from management bus) to * wake device's PCI Express link L1a -> L0s - * NOTE: This is no-op for 3945 (non-existant bit) + * NOTE: This is no-op for 3945 (non-existent bit) */ iwl_legacy_set_bit(priv, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A); diff --git a/drivers/net/wireless/iwlegacy/iwl-fh.h b/drivers/net/wireless/iwlegacy/iwl-fh.h index 4e20c7e5c883..6e6091816e36 100644 --- a/drivers/net/wireless/iwlegacy/iwl-fh.h +++ b/drivers/net/wireless/iwlegacy/iwl-fh.h @@ -436,7 +436,7 @@ * @finished_rb_num [0:11] - Indicates the index of the current RB * in which the last frame was written to * @finished_fr_num [0:11] - Indicates the index of the RX Frame - * which was transfered + * which was transferred */ struct iwl_rb_status { __le16 closed_rb_num; diff --git a/drivers/net/wireless/iwlegacy/iwl-scan.c b/drivers/net/wireless/iwlegacy/iwl-scan.c index 60f597f796ca..353234a02c6d 100644 --- a/drivers/net/wireless/iwlegacy/iwl-scan.c +++ b/drivers/net/wireless/iwlegacy/iwl-scan.c @@ -143,7 +143,7 @@ static void iwl_legacy_do_scan_abort(struct iwl_priv *priv) IWL_DEBUG_SCAN(priv, "Send scan abort failed %d\n", ret); iwl_legacy_force_scan_end(priv); } else - IWL_DEBUG_SCAN(priv, "Sucessfully send scan abort\n"); + IWL_DEBUG_SCAN(priv, "Successfully send scan abort\n"); } /** diff --git a/drivers/net/wireless/iwlegacy/iwl-sta.c b/drivers/net/wireless/iwlegacy/iwl-sta.c index 47c9da3834ea..66f0fb2bbe00 100644 --- a/drivers/net/wireless/iwlegacy/iwl-sta.c +++ b/drivers/net/wireless/iwlegacy/iwl-sta.c @@ -110,7 +110,7 @@ static int iwl_legacy_process_add_sta_resp(struct iwl_priv *priv, /* * XXX: The MAC address in the command buffer is often changed from * the original sent to the device. That is, the MAC address - * written to the command buffer often is not the same MAC adress + * written to the command buffer often is not the same MAC address * read from the command buffer when the command returns. This * issue has not yet been resolved and this debugging is left to * observe the problem. diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c index b5cb3be0eb4b..ed0148d714de 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c @@ -69,7 +69,7 @@ int iwl_alloc_isr_ict(struct iwl_priv *priv) if (!priv->_agn.ict_tbl_vir) return -ENOMEM; - /* align table to PAGE_SIZE boundry */ + /* align table to PAGE_SIZE boundary */ priv->_agn.aligned_ict_tbl_dma = ALIGN(priv->_agn.ict_tbl_dma, PAGE_SIZE); IWL_DEBUG_ISR(priv, "ict dma addr %Lx dma aligned %Lx diff %d\n", diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 6c30fa652e27..bafbe57c9602 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1040,7 +1040,7 @@ int iwl_apm_init(struct iwl_priv *priv) /* * Enable HAP INTA (interrupt from management bus) to * wake device's PCI Express link L1a -> L0s - * NOTE: This is no-op for 3945 (non-existant bit) + * NOTE: This is no-op for 3945 (non-existent bit) */ iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A); diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h index 55b8370bc6d4..474009a244d4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/iwlwifi/iwl-fh.h @@ -436,7 +436,7 @@ * @finished_rb_num [0:11] - Indicates the index of the current RB * in which the last frame was written to * @finished_fr_num [0:11] - Indicates the index of the RX Frame - * which was transfered + * which was transferred */ struct iwl_rb_status { __le16 closed_rb_num; diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 3a4d9e6b0421..914c77e44588 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -143,7 +143,7 @@ static void iwl_do_scan_abort(struct iwl_priv *priv) IWL_DEBUG_SCAN(priv, "Send scan abort failed %d\n", ret); iwl_force_scan_end(priv); } else - IWL_DEBUG_SCAN(priv, "Sucessfully send scan abort\n"); + IWL_DEBUG_SCAN(priv, "Successfully send scan abort\n"); } /** diff --git a/drivers/net/wireless/iwmc3200wifi/hal.c b/drivers/net/wireless/iwmc3200wifi/hal.c index 907ac890997c..1cabcb39643f 100644 --- a/drivers/net/wireless/iwmc3200wifi/hal.c +++ b/drivers/net/wireless/iwmc3200wifi/hal.c @@ -57,7 +57,7 @@ * This is due to the fact the host talks exclusively * to the UMAC and so there needs to be a special UMAC * command for talking to the LMAC. - * This is how a wifi command is layed out: + * This is how a wifi command is laid out: * ------------------------ * | iwm_udma_out_wifi_hdr | * ------------------------ @@ -72,7 +72,7 @@ * Those commands are handled by the device's bootrom, * and are typically sent when the UMAC and the LMAC * are not yet available. - * * This is how a non-wifi command is layed out: + * * This is how a non-wifi command is laid out: * --------------------------- * | iwm_udma_out_nonwifi_hdr | * --------------------------- diff --git a/drivers/net/wireless/iwmc3200wifi/tx.c b/drivers/net/wireless/iwmc3200wifi/tx.c index 3216621fc55a..be98074c0608 100644 --- a/drivers/net/wireless/iwmc3200wifi/tx.c +++ b/drivers/net/wireless/iwmc3200wifi/tx.c @@ -197,7 +197,7 @@ int iwm_tx_credit_alloc(struct iwm_priv *iwm, int id, int nb) spin_lock(&iwm->tx_credit.lock); if (!iwm_tx_credit_ok(iwm, id, nb)) { - IWM_DBG_TX(iwm, DBG, "No credit avaliable for pool[%d]\n", id); + IWM_DBG_TX(iwm, DBG, "No credit available for pool[%d]\n", id); ret = -ENOSPC; goto out; } diff --git a/drivers/net/wireless/libertas/README b/drivers/net/wireless/libertas/README index 60fd1afe89ac..1453eec82a99 100644 --- a/drivers/net/wireless/libertas/README +++ b/drivers/net/wireless/libertas/README @@ -70,7 +70,7 @@ rdrf These commands are used to read the MAC, BBP and RF registers from the card. These commands take one parameter that specifies the offset location that is to be read. This parameter must be specified in - hexadecimal (its possible to preceed preceding the number with a "0x"). + hexadecimal (its possible to precede preceding the number with a "0x"). Path: /sys/kernel/debug/libertas_wireless/ethX/registers/ @@ -84,7 +84,7 @@ wrrf These commands are used to write the MAC, BBP and RF registers in the card. These commands take two parameters that specify the offset location and the value that is to be written. This parameters must - be specified in hexadecimal (its possible to preceed the number + be specified in hexadecimal (its possible to precede the number with a "0x"). Usage: diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 30ef0351bfc4..5caa2ac14d61 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c @@ -1350,7 +1350,7 @@ static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev, * we remove all keys like in the WPA/WPA2 setup, * we just don't set RSN. * - * Therefore: fall-throught + * Therefore: fall-through */ case WLAN_CIPHER_SUITE_TKIP: case WLAN_CIPHER_SUITE_CCMP: diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c index fc8121190d38..8712cb213f2f 100644 --- a/drivers/net/wireless/libertas/if_cs.c +++ b/drivers/net/wireless/libertas/if_cs.c @@ -913,7 +913,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev) goto out3; } - /* Clear any interrupt cause that happend while sending + /* Clear any interrupt cause that happened while sending * firmware/initializing card */ if_cs_write16(card, IF_CS_CARD_INT_CAUSE, IF_CS_BIT_MASK); if_cs_enable_ints(card); diff --git a/drivers/net/wireless/libertas/if_spi.h b/drivers/net/wireless/libertas/if_spi.h index 8b1417d3b71b..d2ac1dcd7e2e 100644 --- a/drivers/net/wireless/libertas/if_spi.h +++ b/drivers/net/wireless/libertas/if_spi.h @@ -66,7 +66,7 @@ #define IF_SPI_HOST_INT_CTRL_REG 0x40 /* Host interrupt controller reg */ #define IF_SPI_CARD_INT_CAUSE_REG 0x44 /* Card interrupt cause reg */ -#define IF_SPI_CARD_INT_STATUS_REG 0x48 /* Card interupt status reg */ +#define IF_SPI_CARD_INT_STATUS_REG 0x48 /* Card interrupt status reg */ #define IF_SPI_CARD_INT_EVENT_MASK_REG 0x4C /* Card interrupt event mask */ #define IF_SPI_CARD_INT_STATUS_MASK_REG 0x50 /* Card interrupt status mask */ diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 56f439d58013..f4f4257a9d67 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -62,7 +62,7 @@ MODULE_PARM_DESC(fake_hw_scan, "Install fake (no-op) hw-scan handler"); * an intersection to occur but each device will still use their * respective regulatory requested domains. Subsequent radios will * use the resulting intersection. - * @HWSIM_REGTEST_WORLD_ROAM: Used for testing the world roaming. We acomplish + * @HWSIM_REGTEST_WORLD_ROAM: Used for testing the world roaming. We accomplish * this by using a custom beacon-capable regulatory domain for the first * radio. All other device world roam. * @HWSIM_REGTEST_CUSTOM_WORLD: Used for testing the custom world regulatory diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c index b4772c1c6135..3c7877a7c31c 100644 --- a/drivers/net/wireless/orinoco/hw.c +++ b/drivers/net/wireless/orinoco/hw.c @@ -1031,7 +1031,7 @@ int __orinoco_hw_set_tkip_key(struct orinoco_private *priv, int key_idx, else buf.tsc[4] = 0x10; - /* Wait upto 100ms for tx queue to empty */ + /* Wait up to 100ms for tx queue to empty */ for (k = 100; k > 0; k--) { udelay(1000); ret = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_TXQUEUEEMPTY, diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c index 356e6bb443a6..a946991989c6 100644 --- a/drivers/net/wireless/p54/main.c +++ b/drivers/net/wireless/p54/main.c @@ -465,7 +465,7 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd, if (slot < 0) { /* - * The device supports the choosen algorithm, but the + * The device supports the chosen algorithm, but the * firmware does not provide enough key slots to store * all of them. * But encryption offload for outgoing frames is always diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c index 7ecc0bda57b3..6d9204fef90b 100644 --- a/drivers/net/wireless/p54/p54spi.c +++ b/drivers/net/wireless/p54/p54spi.c @@ -287,7 +287,7 @@ static void p54spi_power_on(struct p54s_priv *priv) enable_irq(gpio_to_irq(p54spi_gpio_irq)); /* - * need to wait a while before device can be accessed, the lenght + * need to wait a while before device can be accessed, the length * is just a guess */ msleep(10); diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c index d44f8e20cce0..266d45bf86f5 100644 --- a/drivers/net/wireless/prism54/islpci_eth.c +++ b/drivers/net/wireless/prism54/islpci_eth.c @@ -113,7 +113,7 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev) * be aligned on a 4-byte boundary. If WDS is enabled add another 6 bytes * and add WDS address information */ if (likely(((long) skb->data & 0x03) | init_wds)) { - /* get the number of bytes to add and re-allign */ + /* get the number of bytes to add and re-align */ offset = (4 - (long) skb->data) & 0x03; offset += init_wds ? 6 : 0; @@ -342,7 +342,7 @@ islpci_eth_receive(islpci_private *priv) priv->pci_map_rx_address[index], MAX_FRAGMENT_SIZE_RX + 2, PCI_DMA_FROMDEVICE); - /* update the skb structure and allign the buffer */ + /* update the skb structure and align the buffer */ skb_put(skb, size); if (offset) { /* shift the buffer allocation offset bytes to get the right frame */ diff --git a/drivers/net/wireless/rayctl.h b/drivers/net/wireless/rayctl.h index 49d9b267bc0f..d7646f299bd3 100644 --- a/drivers/net/wireless/rayctl.h +++ b/drivers/net/wireless/rayctl.h @@ -578,7 +578,7 @@ struct tx_msg { UCHAR var[1]; }; -/****** ECF Receive Control Stucture (RCS) Area at Shared RAM offset 0x0800 */ +/****** ECF Receive Control Structure (RCS) Area at Shared RAM offset 0x0800 */ /* Structures for command specific parameters (rcs.var) */ struct rx_packet_cmd { UCHAR rx_data_ptr[2]; diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index 70b9abbdeb9e..8fbc5fa965e0 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -616,7 +616,7 @@ * READ_CONTROL: 0 write BBP, 1 read BBP * BUSY: ASIC is busy executing BBP commands * BBP_PAR_DUR: 0 4 MAC clocks, 1 8 MAC clocks - * BBP_RW_MODE: 0 serial, 1 paralell + * BBP_RW_MODE: 0 serial, 1 parallel */ #define BBP_CSR_CFG 0x101c #define BBP_CSR_CFG_VALUE FIELD32(0x000000ff) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 2ee6cebb9b25..dbf74d07d947 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1518,7 +1518,7 @@ static void rt2800_config_channel_rf2xxx(struct rt2x00_dev *rt2x00dev, if (rf->channel > 14) { /* * When TX power is below 0, we should increase it by 7 to - * make it a positive value (Minumum value is -7). + * make it a positive value (Minimum value is -7). * However this means that values between 0 and 7 have * double meaning, and we should set a 7DBm boost flag. */ diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index a3940d7300a4..7f10239f56a8 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -484,13 +484,13 @@ struct rt2x00intf_conf { enum nl80211_iftype type; /* - * TSF sync value, this is dependant on the operation type. + * TSF sync value, this is dependent on the operation type. */ enum tsf_sync sync; /* - * The MAC and BSSID addressess are simple array of bytes, - * these arrays are little endian, so when sending the addressess + * The MAC and BSSID addresses are simple array of bytes, + * these arrays are little endian, so when sending the addresses * to the drivers, copy the it into a endian-signed variable. * * Note that all devices (except rt2500usb) have 32 bits @@ -1131,7 +1131,7 @@ void rt2x00queue_stop_queue(struct data_queue *queue); * @drop: True to drop all pending frames. * * This function will flush the queue. After this call - * the queue is guarenteed to be empty. + * the queue is guaranteed to be empty. */ void rt2x00queue_flush_queue(struct data_queue *queue, bool drop); diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index e7f67d5eda52..9416e36de29e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c @@ -60,7 +60,7 @@ void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev, * Note that when NULL is passed as address we will send * 00:00:00:00:00 to the device to clear the address. * This will prevent the device being confused when it wants - * to ACK frames or consideres itself associated. + * to ACK frames or considers itself associated. */ memset(conf.mac, 0, sizeof(conf.mac)); if (mac) diff --git a/drivers/net/wireless/rt2x00/rt2x00crypto.c b/drivers/net/wireless/rt2x00/rt2x00crypto.c index 5e9074bf2b8e..3f5688fbf3f7 100644 --- a/drivers/net/wireless/rt2x00/rt2x00crypto.c +++ b/drivers/net/wireless/rt2x00/rt2x00crypto.c @@ -237,7 +237,7 @@ void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, } /* - * NOTE: Always count the payload as transfered, + * NOTE: Always count the payload as transferred, * even when alignment was set to zero. This is required * for determining the correct offset for the ICV data. */ diff --git a/drivers/net/wireless/rt2x00/rt2x00dump.h b/drivers/net/wireless/rt2x00/rt2x00dump.h index 5d6e0b83151f..063ebcce97f8 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dump.h +++ b/drivers/net/wireless/rt2x00/rt2x00dump.h @@ -51,7 +51,7 @@ * [rt2x00dump header][hardware descriptor][ieee802.11 frame] * * rt2x00dump header: The description of the dumped frame, as well as - * additional information usefull for debugging. See &rt2x00dump_hdr. + * additional information useful for debugging. See &rt2x00dump_hdr. * hardware descriptor: Descriptor that was used to receive or transmit * the frame. * ieee802.11 frame: The actual frame that was received or transmitted. diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c index c975b0a12e95..29abfdeb0b65 100644 --- a/drivers/net/wireless/rt2x00/rt2x00link.c +++ b/drivers/net/wireless/rt2x00/rt2x00link.c @@ -283,7 +283,7 @@ void rt2x00link_start_tuner(struct rt2x00_dev *rt2x00dev) /** * While scanning, link tuning is disabled. By default * the most sensitive settings will be used to make sure - * that all beacons and probe responses will be recieved + * that all beacons and probe responses will be received * during the scan. */ if (test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags)) diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 4b3c70eeef1f..4358051bfe1a 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -546,7 +546,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, } /* - * When DMA allocation is required we should guarentee to the + * When DMA allocation is required we should guarantee to the * driver that the DMA is aligned to a 4-byte boundary. * However some drivers require L2 padding to pad the payload * rather then the header. This could be a requirement for @@ -689,7 +689,7 @@ void rt2x00queue_for_each_entry(struct data_queue *queue, spin_unlock_irqrestore(&queue->index_lock, irqflags); /* - * Start from the TX done pointer, this guarentees that we will + * Start from the TX done pointer, this guarantees that we will * send out all frames in the correct order. */ if (index_start < index_end) { @@ -883,7 +883,7 @@ void rt2x00queue_flush_queue(struct data_queue *queue, bool drop) } /* - * Check if driver supports flushing, we can only guarentee + * Check if driver supports flushing, we can only guarantee * full support for flushing if the driver is able * to cancel all pending frames (drop = true). */ diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 0c8b0c699679..217861f8d95f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -344,8 +344,8 @@ struct txentry_desc { * only be touched after the device has signaled it is done with it. * @ENTRY_DATA_PENDING: This entry contains a valid frame and is waiting * for the signal to start sending. - * @ENTRY_DATA_IO_FAILED: Hardware indicated that an IO error occured - * while transfering the data to the hardware. No TX status report will + * @ENTRY_DATA_IO_FAILED: Hardware indicated that an IO error occurred + * while transferring the data to the hardware. No TX status report will * be expected from the hardware. * @ENTRY_DATA_STATUS_PENDING: The entry has been send to the device and * returned. It is now waiting for the status reporting before the @@ -365,7 +365,7 @@ enum queue_entry_flags { * @flags: Entry flags, see &enum queue_entry_flags. * @queue: The data queue (&struct data_queue) to which this entry belongs. * @skb: The buffer which is currently being transmitted (for TX queue), - * or used to directly recieve data in (for RX queue). + * or used to directly receive data in (for RX queue). * @entry_idx: The entry index number. * @priv_data: Private data belonging to this queue entry. The pointer * points to data specific to a particular driver and queue type. @@ -388,7 +388,7 @@ struct queue_entry { * @Q_INDEX: Index pointer to the current entry in the queue, if this entry is * owned by the hardware then the queue is considered to be full. * @Q_INDEX_DMA_DONE: Index pointer for the next entry which will have been - * transfered to the hardware. + * transferred to the hardware. * @Q_INDEX_DONE: Index pointer to the next entry which will be completed by * the hardware and for which we need to run the txdone handler. If this * entry is not owned by the hardware the queue is considered to be empty. @@ -627,7 +627,7 @@ static inline int rt2x00queue_threshold(struct data_queue *queue) } /** - * rt2x00queue_status_timeout - Check if a timeout occured for STATUS reports + * rt2x00queue_status_timeout - Check if a timeout occurred for STATUS reports * @queue: Queue to check. */ static inline int rt2x00queue_status_timeout(struct data_queue *queue) @@ -637,7 +637,7 @@ static inline int rt2x00queue_status_timeout(struct data_queue *queue) } /** - * rt2x00queue_timeout - Check if a timeout occured for DMA transfers + * rt2x00queue_timeout - Check if a timeout occurred for DMA transfers * @queue: Queue to check. */ static inline int rt2x00queue_dma_timeout(struct data_queue *queue) diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index fbe735f5b352..36f388f97d65 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -173,7 +173,7 @@ static void rt2x00usb_work_txdone_entry(struct queue_entry *entry) /* * If the transfer to hardware succeeded, it does not mean the * frame was send out correctly. It only means the frame - * was succesfully pushed to the hardware, we have no + * was successfully pushed to the hardware, we have no * way to determine the transmission status right now. * (Only indirectly by looking at the failed TX counters * in the register). diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h index 6aaf51fc7ad8..e11c759ac9ed 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.h +++ b/drivers/net/wireless/rt2x00/rt2x00usb.h @@ -400,7 +400,7 @@ void rt2x00usb_flush_queue(struct data_queue *queue); * @rt2x00dev: Pointer to &struct rt2x00_dev * * Check the health of the USB communication and determine - * if timeouts have occured. If this is the case, this function + * if timeouts have occurred. If this is the case, this function * will reset all communication to restore functionality again. */ void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev); diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index bb0c781f4a1b..0d7d93e1d398 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c @@ -520,7 +520,7 @@ void rtl_get_tcb_desc(struct ieee80211_hw *hw, *because hw will nerver use hw_rate *when tcb_desc->use_driver_rate = false *so we never set highest N rate here, - *and N rate will all be controled by FW + *and N rate will all be controlled by FW *when tcb_desc->use_driver_rate = false */ if (rtlmac->ht_enable) { diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 9cd7703c2a30..5938f6ee21e4 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -395,7 +395,7 @@ static void rtl_pci_init_aspm(struct ieee80211_hw *hw) * 0 - Disable ASPM, * 1 - Enable ASPM without Clock Req, * 2 - Enable ASPM with Clock Req, - * 3 - Alwyas Enable ASPM with Clock Req, + * 3 - Always Enable ASPM with Clock Req, * 4 - Always Enable ASPM without Clock Req. * set defult to RTL8192CE:3 RTL8192E:2 * */ diff --git a/drivers/net/wireless/rtlwifi/regd.c b/drivers/net/wireless/rtlwifi/regd.c index 3336ca999dfd..d26f957981ad 100644 --- a/drivers/net/wireless/rtlwifi/regd.c +++ b/drivers/net/wireless/rtlwifi/regd.c @@ -179,7 +179,7 @@ static void _rtl_reg_apply_active_scan_flags(struct wiphy *wiphy, } /* - *If a country IE has been recieved check its rule for this + *If a country IE has been received check its rule for this *channel first before enabling active scan. The passive scan *would have been enforced by the initial processing of our *custom regulatory domain. diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index 01226f8e70f9..07db95ff9bc5 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -1555,7 +1555,7 @@ struct rtl_priv { /*************************************** - Bluetooth Co-existance Related + Bluetooth Co-existence Related ****************************************/ enum bt_ant_num { diff --git a/drivers/net/wireless/wl1251/cmd.c b/drivers/net/wireless/wl1251/cmd.c index 0ade4bd617c0..81f164bc4888 100644 --- a/drivers/net/wireless/wl1251/cmd.c +++ b/drivers/net/wireless/wl1251/cmd.c @@ -104,7 +104,7 @@ int wl1251_cmd_test(struct wl1251 *wl, void *buf, size_t buf_len, u8 answer) * @wl: wl struct * @id: acx id * @buf: buffer for the response, including all headers, must work with dma - * @len: lenght of buf + * @len: length of buf */ int wl1251_cmd_interrogate(struct wl1251 *wl, u16 id, void *buf, size_t len) { diff --git a/drivers/net/wireless/wl1251/rx.c b/drivers/net/wireless/wl1251/rx.c index c1b3b3f03da2..6af35265c900 100644 --- a/drivers/net/wireless/wl1251/rx.c +++ b/drivers/net/wireless/wl1251/rx.c @@ -179,7 +179,7 @@ static void wl1251_rx_body(struct wl1251 *wl, rx_buffer = skb_put(skb, length); wl1251_mem_read(wl, rx_packet_ring_addr, rx_buffer, length); - /* The actual lenght doesn't include the target's alignment */ + /* The actual length doesn't include the target's alignment */ skb->len = desc->length - PLCP_HEADER_LENGTH; fc = (u16 *)skb->data; diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index f0aa7ab97bf7..96324336f936 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c @@ -359,7 +359,7 @@ int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer) * @wl: wl struct * @id: acx id * @buf: buffer for the response, including all headers, must work with dma - * @len: lenght of buf + * @len: length of buf */ int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len) { diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h index 856a8a2fff4f..8a8323896eec 100644 --- a/drivers/net/wireless/wl12xx/conf.h +++ b/drivers/net/wireless/wl12xx/conf.h @@ -497,7 +497,7 @@ struct conf_rx_settings { #define CONF_TX_RATE_RETRY_LIMIT 10 /* - * Rates supported for data packets when operating as AP. Note the absense + * Rates supported for data packets when operating as AP. Note the absence * of the 22Mbps rate. There is a FW limitation on 12 rates so we must drop * one. The rate dropped is not mandatory under any operating mode. */ @@ -572,7 +572,7 @@ enum conf_tx_ac { CONF_TX_AC_BK = 1, /* background */ CONF_TX_AC_VI = 2, /* video */ CONF_TX_AC_VO = 3, /* voice */ - CONF_TX_AC_CTS2SELF = 4, /* fictious AC, follows AC_VO */ + CONF_TX_AC_CTS2SELF = 4, /* fictitious AC, follows AC_VO */ CONF_TX_AC_ANY_TID = 0x1f }; @@ -1169,7 +1169,7 @@ struct conf_memory_settings { /* * Minimum required free tx memory blocks in order to assure optimum - * performence + * performance * * Range: 0-120 */ @@ -1177,7 +1177,7 @@ struct conf_memory_settings { /* * Minimum required free rx memory blocks in order to assure optimum - * performence + * performance * * Range: 0-120 */ diff --git a/drivers/net/wireless/wl12xx/io.h b/drivers/net/wireless/wl12xx/io.h index c1aac8292089..00c771ea70bf 100644 --- a/drivers/net/wireless/wl12xx/io.h +++ b/drivers/net/wireless/wl12xx/io.h @@ -94,7 +94,7 @@ static inline int wl1271_translate_addr(struct wl1271 *wl, int addr) * translated region. * * The translated regions occur next to each other in physical device - * memory, so just add the sizes of the preceeding address regions to + * memory, so just add the sizes of the preceding address regions to * get the offset to the new region. * * Currently, only the two first regions are addressed, and the diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c index 3e5befe4d03b..fc08f36fe1f5 100644 --- a/drivers/net/wireless/wl3501_cs.c +++ b/drivers/net/wireless/wl3501_cs.c @@ -290,7 +290,7 @@ static void wl3501_get_from_wla(struct wl3501_card *this, u16 src, void *dest, * \ \- IEEE 802.11 -/ \-------------- len --------------/ * \-struct wl3501_80211_tx_hdr--/ \-------- Ethernet Frame -------/ * - * Return = Postion in Card + * Return = Position in Card */ static u16 wl3501_get_tx_buffer(struct wl3501_card *this, u16 len) { @@ -1932,7 +1932,7 @@ static int wl3501_config(struct pcmcia_device *link) this->base_addr = dev->base_addr; if (!wl3501_get_flash_mac_addr(this)) { - printk(KERN_WARNING "%s: Cant read MAC addr in flash ROM?\n", + printk(KERN_WARNING "%s: Can't read MAC addr in flash ROM?\n", dev->name); unregister_netdev(dev); goto failed; diff --git a/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c b/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c index 0597d862fbd2..e36117486c91 100644 --- a/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c +++ b/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c @@ -169,7 +169,7 @@ static int rf2959_init_hw(struct zd_rf *rf) { CR85, 0x00 }, { CR86, 0x10 }, { CR87, 0x2A }, { CR88, 0x10 }, { CR89, 0x24 }, { CR90, 0x18 }, /* { CR91, 0x18 }, */ - /* should solve continous CTS frame problems */ + /* should solve continuous CTS frame problems */ { CR91, 0x00 }, { CR92, 0x0a }, { CR93, 0x00 }, { CR94, 0x01 }, { CR95, 0x00 }, { CR96, 0x40 }, { CR97, 0x37 }, diff --git a/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c b/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c index 9e74eb1b67d5..ba0a0ccb1fa0 100644 --- a/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c +++ b/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c @@ -353,7 +353,7 @@ static int uw2453_init_hw(struct zd_rf *rf) }; static const u32 rv[] = { - UW2453_REGWRITE(4, 0x2b), /* configure reciever gain */ + UW2453_REGWRITE(4, 0x2b), /* configure receiver gain */ UW2453_REGWRITE(5, 0x19e4f), /* configure transmitter gain */ UW2453_REGWRITE(6, 0xf81ad), /* enable RX/TX filter tuning */ UW2453_REGWRITE(7, 0x3fffe), /* disable TX gain in test mode */ diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c index 2642af4ee491..372572c0adc6 100644 --- a/drivers/net/xilinx_emaclite.c +++ b/drivers/net/xilinx_emaclite.c @@ -786,7 +786,7 @@ static int xemaclite_mdio_read(struct mii_bus *bus, int phy_id, int reg) * @reg: register number to write to * @val: value to write to the register number specified by reg * - * This fucntion waits till the device is ready to accept a new MDIO + * This function waits till the device is ready to accept a new MDIO * request and then writes the val to the MDIO Write Data register. */ static int xemaclite_mdio_write(struct mii_bus *bus, int phy_id, int reg, diff --git a/drivers/net/znet.c b/drivers/net/znet.c index ae07b3dfbcc1..ec2800ff8d42 100644 --- a/drivers/net/znet.c +++ b/drivers/net/znet.c @@ -652,7 +652,7 @@ static irqreturn_t znet_interrupt(int irq, void *dev_id) dev->stats.tx_errors++; /* Transceiver may be stuck if cable - * was removed while emiting a + * was removed while emitting a * packet. Flip it off, then on to * reset it. This is very empirical, * but it seems to work. */ diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index c9db49c10f45..8b63a691a9ed 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -676,7 +676,7 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, early_init_dt_check_for_initrd(node); - /* Retreive command line */ + /* Retrieve command line */ p = of_get_flat_dt_prop(node, "bootargs", &l); if (p != NULL && l > 0) strlcpy(cmd_line, p, min((int)l, COMMAND_LINE_SIZE)); diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index dcd7857784f2..d35e300b0ad1 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c @@ -136,7 +136,7 @@ EXPORT_SYMBOL(of_phy_find_device); * @hndlr: Link state callback for the network device * @iface: PHY data interface type * - * Returns a pointer to the phy_device if successfull. NULL otherwise + * Returns a pointer to the phy_device if successful. NULL otherwise */ struct phy_device *of_phy_connect(struct net_device *dev, struct device_node *phy_np, diff --git a/drivers/parisc/pdc_stable.c b/drivers/parisc/pdc_stable.c index 1062b8ffe244..246a92f677e4 100644 --- a/drivers/parisc/pdc_stable.c +++ b/drivers/parisc/pdc_stable.c @@ -141,7 +141,7 @@ struct pdcspath_attribute paths_attr_##_name = { \ * @entry: A pointer to an allocated pdcspath_entry. * * The general idea is that you don't read from the Stable Storage every time - * you access the files provided by the facilites. We store a copy of the + * you access the files provided by the facilities. We store a copy of the * content of the stable storage WRT various paths in these structs. We read * these structs when reading the files, and we will write to these structs when * writing to the files, and only then write them back to the Stable Storage. @@ -213,7 +213,7 @@ pdcspath_store(struct pdcspath_entry *entry) /* addr, devpath and count must be word aligned */ if (pdc_stable_write(entry->addr, devpath, sizeof(*devpath)) != PDC_OK) { - printk(KERN_ERR "%s: an error occured when writing to PDC.\n" + printk(KERN_ERR "%s: an error occurred when writing to PDC.\n" "It is likely that the Stable Storage data has been corrupted.\n" "Please check it carefully upon next reboot.\n", __func__); WARN_ON(1); diff --git a/drivers/parport/Kconfig b/drivers/parport/Kconfig index 855f389eea40..d92185a5523b 100644 --- a/drivers/parport/Kconfig +++ b/drivers/parport/Kconfig @@ -142,7 +142,7 @@ config PARPORT_AX88796 the AX88796 network controller chip. This code is also available as a module (say M), called parport_ax88796. - The driver is not dependant on the AX88796 network driver, and + The driver is not dependent on the AX88796 network driver, and should not interfere with the networking functions of the chip. config PARPORT_1284 diff --git a/drivers/parport/ieee1284.c b/drivers/parport/ieee1284.c index 8901ecf6e037..f9fd4b33a546 100644 --- a/drivers/parport/ieee1284.c +++ b/drivers/parport/ieee1284.c @@ -355,7 +355,7 @@ int parport_negotiate (struct parport *port, int mode) return 0; } - /* Go to compability forward idle mode */ + /* Go to compatibility forward idle mode */ if (port->ieee1284.mode != IEEE1284_MODE_COMPAT) parport_ieee1284_terminate (port); diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c index 8d62fb76cd41..a3755ffc03d4 100644 --- a/drivers/parport/parport_pc.c +++ b/drivers/parport/parport_pc.c @@ -1488,7 +1488,7 @@ static void __devinit winbond_check(int io, int key) outb(key, io); outb(key, io); /* Write Magic Sequence to EFER, extended - funtion enable register */ + function enable register */ outb(0x20, io); /* Write EFIR, extended function index register */ devid = inb(io + 1); /* Read EFDR, extended function data register */ outb(0x21, io); @@ -1527,7 +1527,7 @@ static void __devinit winbond_check2(int io, int key) x_oldid = inb(io + 2); outb(key, io); /* Write Magic Byte to EFER, extended - funtion enable register */ + function enable register */ outb(0x20, io + 2); /* Write EFIR, extended function index register */ devid = inb(io + 2); /* Read EFDR, extended function data register */ outb(0x21, io + 1); @@ -1569,7 +1569,7 @@ static void __devinit smsc_check(int io, int key) outb(key, io); outb(key, io); /* Write Magic Sequence to EFER, extended - funtion enable register */ + function enable register */ outb(0x0d, io); /* Write EFIR, extended function index register */ oldid = inb(io + 1); /* Read EFDR, extended function data register */ outb(0x0e, io); diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c index 3bc72d18b121..8f3faf343f75 100644 --- a/drivers/pci/hotplug/acpi_pcihp.c +++ b/drivers/pci/hotplug/acpi_pcihp.c @@ -351,7 +351,7 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags) * To handle different BIOS behavior, we look for _OSC on a root * bridge preferentially (according to PCI fw spec). Later for * OSHP within the scope of the hotplug controller and its parents, - * upto the host bridge under which this controller exists. + * up to the host bridge under which this controller exists. */ handle = acpi_find_root_bridge_handle(pdev); if (handle) { diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index e610cfe4f07b..2f67e9bc2f96 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -585,7 +585,7 @@ static void remove_bridge(acpi_handle handle) /* * On root bridges with hotplug slots directly underneath (ie, - * no p2p bridge inbetween), we call cleanup_bridge(). + * no p2p bridge between), we call cleanup_bridge(). * * The else clause cleans up root bridges that either had no * hotplug slots at all, or had a p2p bridge underneath. diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index ef7411c660b9..758adb5f47fd 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -290,7 +290,7 @@ static int is_php_dn(struct device_node *dn, const int **indexes, * @dn: device node of slot * * This subroutine will register a hotplugable slot with the - * PCI hotplug infrastructure. This routine is typicaly called + * PCI hotplug infrastructure. This routine is typically called * during boot time, if the hotplug slots are present at boot time, * or is called later, by the dlpar add code, if the slot is * being dynamically added during runtime. diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 7da3bef60d87..505c1c7075f0 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -2265,7 +2265,7 @@ int __init init_dmars(void) /* * TBD: * we could share the same root & context tables - * amoung all IOMMU's. Need to Split it later. + * among all IOMMU's. Need to Split it later. */ ret = iommu_alloc_root_entry(iommu); if (ret) { diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c index a22557b20283..3607faf28a4d 100644 --- a/drivers/pci/intr_remapping.c +++ b/drivers/pci/intr_remapping.c @@ -289,7 +289,7 @@ int free_irte(int irq) * source validation type */ #define SVT_NO_VERIFY 0x0 /* no verification is required */ -#define SVT_VERIFY_SID_SQ 0x1 /* verify using SID and SQ fiels */ +#define SVT_VERIFY_SID_SQ 0x1 /* verify using SID and SQ fields */ #define SVT_VERIFY_BUS 0x2 /* verify bus of request-id */ /* diff --git a/drivers/pci/iova.c b/drivers/pci/iova.c index 7914951ef29a..9606e599a475 100644 --- a/drivers/pci/iova.c +++ b/drivers/pci/iova.c @@ -391,7 +391,7 @@ reserve_iova(struct iova_domain *iovad, break; } - /* We are here either becasue this is the first reserver node + /* We are here either because this is the first reserver node * or need to insert remaining non overlap addr range */ iova = __insert_new_range(iovad, pfn_lo, pfn_hi); diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index a8a277a2e0d0..f8deb3e380a2 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -645,7 +645,7 @@ pci_adjust_legacy_attr(struct pci_bus *b, enum pci_mmap_state mmap_type) * a per-bus basis. This routine creates the files and ties them into * their associated read, write and mmap files from pci-sysfs.c * - * On error unwind, but don't propogate the error to the caller + * On error unwind, but don't propagate the error to the caller * as it is ok to set up the PCI bus without these files. */ void pci_create_legacy_files(struct pci_bus *b) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index bd80f6378463..5129ed6d8fa7 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -263,7 +263,7 @@ static void quirk_vialatency(struct pci_dev *dev) * This happens to include the IDE controllers.... * * VIA only apply this fix when an SB Live! is present but under - * both Linux and Windows this isnt enough, and we have seen + * both Linux and Windows this isn't enough, and we have seen * corruption without SB Live! but with things like 3 UDMA IDE * controllers. So we ignore that bit of the VIA recommendation.. */ @@ -2680,7 +2680,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_HINT, 0x0020, quirk_hotplug_bridge); * This is a quirk for the Ricoh MMC controller found as a part of * some mulifunction chips. - * This is very similiar and based on the ricoh_mmc driver written by + * This is very similar and based on the ricoh_mmc driver written by * Philip Langdale. Thank you for these magic sequences. * * These chips implement the four main memory card controllers (SD, MMC, MS, xD) diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c index fc7906eaf228..3e447d0387b7 100644 --- a/drivers/pcmcia/i82092.c +++ b/drivers/pcmcia/i82092.c @@ -54,7 +54,7 @@ static struct pccard_operations i82092aa_operations = { .set_mem_map = i82092aa_set_mem_map, }; -/* The card can do upto 4 sockets, allocate a structure for each of them */ +/* The card can do up to 4 sockets, allocate a structure for each of them */ struct socket_info { int number; diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index 42fbf1a75576..fe77e8223841 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c @@ -173,7 +173,7 @@ static int pcmcia_access_config(struct pcmcia_device *p_dev, c = p_dev->function_config; if (!(c->state & CONFIG_LOCKED)) { - dev_dbg(&p_dev->dev, "Configuration isnt't locked\n"); + dev_dbg(&p_dev->dev, "Configuration isn't't locked\n"); mutex_unlock(&s->ops_mutex); return -EACCES; } diff --git a/drivers/pcmcia/pxa2xx_lubbock.c b/drivers/pcmcia/pxa2xx_lubbock.c index 25afe637c657..c21888eebb58 100644 --- a/drivers/pcmcia/pxa2xx_lubbock.c +++ b/drivers/pcmcia/pxa2xx_lubbock.c @@ -187,7 +187,7 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, * We need to hack around the const qualifier as * well to keep this ugly workaround localized and * not force it to the rest of the code. Barf bags - * avaliable in the seat pocket in front of you! + * available in the seat pocket in front of you! */ ((socket_state_t *)state)->Vcc = 50; ((socket_state_t *)state)->Vpp = 50; diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h index 9ffa97d0b16c..a71789486cdf 100644 --- a/drivers/pcmcia/ti113x.h +++ b/drivers/pcmcia/ti113x.h @@ -691,7 +691,7 @@ static int ti12xx_2nd_slot_empty(struct yenta_socket *socket) /* * those are either single or dual slot CB with additional functions * like 1394, smartcard reader, etc. check the TIEALL flag for them - * the TIEALL flag binds the IRQ of all functions toghether. + * the TIEALL flag binds the IRQ of all functions together. * we catch the single slot variants later. */ sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL); diff --git a/drivers/platform/x86/intel_mid_thermal.c b/drivers/platform/x86/intel_mid_thermal.c index 6c12db503161..c2f4bd8013b5 100644 --- a/drivers/platform/x86/intel_mid_thermal.c +++ b/drivers/platform/x86/intel_mid_thermal.c @@ -202,7 +202,7 @@ static int mid_read_temp(struct thermal_zone_device *tzd, unsigned long *temp) if (ret) return ret; - /* Shift bits to accomodate the lower two data bits */ + /* Shift bits to accommodate the lower two data bits */ adc_val = (data << 2); addr++; diff --git a/drivers/pnp/card.c b/drivers/pnp/card.c index 4a651f69e17c..bc00693d0c79 100644 --- a/drivers/pnp/card.c +++ b/drivers/pnp/card.c @@ -320,7 +320,7 @@ void pnp_remove_card_device(struct pnp_dev *dev) * pnp_request_card_device - Searches for a PnP device under the specified card * @clink: pointer to the card link, cannot be NULL * @id: pointer to a PnP ID structure that explains the rules for finding the device - * @from: Starting place to search from. If NULL it will start from the begining. + * @from: Starting place to search from. If NULL it will start from the beginning. */ struct pnp_dev *pnp_request_card_device(struct pnp_card_link *clink, const char *id, struct pnp_dev *from) @@ -369,7 +369,7 @@ err_out: /** * pnp_release_card_device - call this when the driver no longer needs the device - * @dev: pointer to the PnP device stucture + * @dev: pointer to the PnP device structure */ void pnp_release_card_device(struct pnp_dev *dev) { diff --git a/drivers/pnp/pnpbios/bioscalls.c b/drivers/pnp/pnpbios/bioscalls.c index 8591f6ab1b35..b859d16cf78c 100644 --- a/drivers/pnp/pnpbios/bioscalls.c +++ b/drivers/pnp/pnpbios/bioscalls.c @@ -219,7 +219,7 @@ void pnpbios_print_status(const char *module, u16 status) module); break; case PNP_HARDWARE_ERROR: - printk(KERN_ERR "PnPBIOS: %s: a hardware failure has occured\n", + printk(KERN_ERR "PnPBIOS: %s: a hardware failure has occurred\n", module); break; default: diff --git a/drivers/pps/Kconfig b/drivers/pps/Kconfig index f0d3376b58ba..258ca596e1bc 100644 --- a/drivers/pps/Kconfig +++ b/drivers/pps/Kconfig @@ -35,7 +35,7 @@ config NTP_PPS depends on PPS && !NO_HZ help This option adds support for direct in-kernel time - syncronization using an external PPS signal. + synchronization using an external PPS signal. It doesn't work on tickless systems at the moment. diff --git a/drivers/ps3/ps3-lpm.c b/drivers/ps3/ps3-lpm.c index 8000985d0e8c..643697f71390 100644 --- a/drivers/ps3/ps3-lpm.c +++ b/drivers/ps3/ps3-lpm.c @@ -919,7 +919,7 @@ EXPORT_SYMBOL_GPL(ps3_disable_pm); * @offset: Offset in bytes from the start of the trace buffer. * @buf: Copy destination. * @count: Maximum count of bytes to copy. - * @bytes_copied: Pointer to a variable that will recieve the number of + * @bytes_copied: Pointer to a variable that will receive the number of * bytes copied to @buf. * * On error @buf will contain any successfully copied trace buffer data @@ -974,7 +974,7 @@ EXPORT_SYMBOL_GPL(ps3_lpm_copy_tb); * @offset: Offset in bytes from the start of the trace buffer. * @buf: A __user copy destination. * @count: Maximum count of bytes to copy. - * @bytes_copied: Pointer to a variable that will recieve the number of + * @bytes_copied: Pointer to a variable that will receive the number of * bytes copied to @buf. * * On error @buf will contain any successfully copied trace buffer data @@ -1074,7 +1074,7 @@ EXPORT_SYMBOL_GPL(ps3_disable_pm_interrupts); /** * ps3_lpm_open - Open the logical performance monitor device. - * @tb_type: Specifies the type of trace buffer lv1 sould use for this lpm + * @tb_type: Specifies the type of trace buffer lv1 should use for this lpm * instance, specified by one of enum ps3_lpm_tb_type. * @tb_cache: Optional user supplied buffer to use as the trace buffer cache. * If NULL, the driver will allocate and manage an internal buffer. diff --git a/drivers/ps3/ps3-sys-manager.c b/drivers/ps3/ps3-sys-manager.c index d37c445f0eda..1b98367110c4 100644 --- a/drivers/ps3/ps3-sys-manager.c +++ b/drivers/ps3/ps3-sys-manager.c @@ -80,7 +80,7 @@ static void __maybe_unused _dump_sm_header( * * Currently all messages received from the system manager are either * (16 bytes header + 8 bytes payload = 24 bytes) or (16 bytes header - * + 16 bytes payload = 32 bytes). This knowlege is used to simplify + * + 16 bytes payload = 32 bytes). This knowledge is used to simplify * the logic. */ diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c index 3a59d5f018d3..ee893581d4b7 100644 --- a/drivers/rapidio/rio-scan.c +++ b/drivers/rapidio/rio-scan.c @@ -295,7 +295,7 @@ static int __devinit rio_add_device(struct rio_dev *rdev) } /** - * rio_enable_rx_tx_port - enable input reciever and output transmitter of + * rio_enable_rx_tx_port - enable input receiver and output transmitter of * given port * @port: Master port associated with the RIO network * @local: local=1 select local port otherwise a far device is reached diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 3ffc6979d164..0fae51c4845a 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1313,7 +1313,7 @@ static int _regulator_enable(struct regulator_dev *rdev) return -EINVAL; /* Query before enabling in case configuration - * dependant. */ + * dependent. */ ret = _regulator_get_enable_time(rdev); if (ret >= 0) { delay = ret; diff --git a/drivers/regulator/max8952.c b/drivers/regulator/max8952.c index a8f4ecfb0843..daff7fd0e95c 100644 --- a/drivers/regulator/max8952.c +++ b/drivers/regulator/max8952.c @@ -262,7 +262,7 @@ static int __devinit max8952_pmic_probe(struct i2c_client *client, if (err) { dev_warn(max8952->dev, "VID0/1 gpio invalid: " - "DVS not avilable.\n"); + "DVS not available.\n"); max8952->vid0 = 0; max8952->vid1 = 0; /* Mark invalid */ diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 8ec6b069a7f5..23719f0acbf6 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -454,7 +454,7 @@ EXPORT_SYMBOL_GPL(rtc_update_irq_enable); * @rtc: pointer to the rtc device * * This function is called when an AIE, UIE or PIE mode interrupt - * has occured (or been emulated). + * has occurred (or been emulated). * * Triggers the registered irq_task function callback. */ diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c index 518a76ec71ca..e39b77a4609a 100644 --- a/drivers/rtc/rtc-at91rm9200.c +++ b/drivers/rtc/rtc-at91rm9200.c @@ -60,7 +60,7 @@ static void at91_rtc_decodetime(unsigned int timereg, unsigned int calreg, /* * The Calendar Alarm register does not have a field for * the year - so these will return an invalid value. When an - * alarm is set, at91_alarm_year wille store the current year. + * alarm is set, at91_alarm_year will store the current year. */ tm->tm_year = bcd2bin(date & AT91_RTC_CENT) * 100; /* century */ tm->tm_year += bcd2bin((date & AT91_RTC_YEAR) >> 8); /* year */ diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c index ca9cff85ab8a..a0fc4cf42abf 100644 --- a/drivers/rtc/rtc-bfin.c +++ b/drivers/rtc/rtc-bfin.c @@ -20,9 +20,9 @@ * write would be discarded and things quickly fall apart. * * To keep this delay from significantly degrading performance (we, in theory, - * would have to sleep for up to 1 second everytime we wanted to write a + * would have to sleep for up to 1 second every time we wanted to write a * register), we only check the write pending status before we start to issue - * a new write. We bank on the idea that it doesnt matter when the sync + * a new write. We bank on the idea that it doesn't matter when the sync * happens so long as we don't attempt another write before it does. The only * time userspace would take this penalty is when they try and do multiple * operations right after another ... but in this case, they need to take the diff --git a/drivers/rtc/rtc-lpc32xx.c b/drivers/rtc/rtc-lpc32xx.c index ec8701ce99f9..ae16250c762f 100644 --- a/drivers/rtc/rtc-lpc32xx.c +++ b/drivers/rtc/rtc-lpc32xx.c @@ -240,7 +240,7 @@ static int __devinit lpc32xx_rtc_probe(struct platform_device *pdev) spin_lock_init(&rtc->lock); /* - * The RTC is on a seperate power domain and can keep it's state + * The RTC is on a separate power domain and can keep it's state * across a chip power cycle. If the RTC has never been previously * setup, then set it up now for the first time. */ diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c index 9aae49139a0a..b00aad2620d4 100644 --- a/drivers/rtc/rtc-x1205.c +++ b/drivers/rtc/rtc-x1205.c @@ -573,7 +573,7 @@ static int x1205_probe(struct i2c_client *client, i2c_set_clientdata(client, rtc); - /* Check for power failures and eventualy enable the osc */ + /* Check for power failures and eventually enable the osc */ if ((err = x1205_get_status(client, &sr)) == 0) { if (sr & X1205_SR_RTCF) { dev_err(&client->dev, diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c index 1654a24817be..87a0cf160fe5 100644 --- a/drivers/s390/block/dasd_3990_erp.c +++ b/drivers/s390/block/dasd_3990_erp.c @@ -2207,7 +2207,7 @@ dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense) * DASD_3990_ERP_CONTROL_CHECK * * DESCRIPTION - * Does a generic inspection if a control check occured and sets up + * Does a generic inspection if a control check occurred and sets up * the related error recovery procedure * * PARAMETER @@ -2250,7 +2250,7 @@ dasd_3990_erp_inspect(struct dasd_ccw_req *erp) struct dasd_ccw_req *erp_new = NULL; char *sense; - /* if this problem occured on an alias retry on base */ + /* if this problem occurred on an alias retry on base */ erp_new = dasd_3990_erp_inspect_alias(erp); if (erp_new) return erp_new; @@ -2282,7 +2282,7 @@ dasd_3990_erp_inspect(struct dasd_ccw_req *erp) * DASD_3990_ERP_ADD_ERP * * DESCRIPTION - * This funtion adds an additional request block (ERP) to the head of + * This function adds an additional request block (ERP) to the head of * the given cqr (or erp). * For a command mode cqr the erp is initialized as an default erp * (retry TIC). diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c index cb6a67bc89ff..42e1bf35f689 100644 --- a/drivers/s390/block/dasd_devmap.c +++ b/drivers/s390/block/dasd_devmap.c @@ -302,7 +302,7 @@ dasd_parse_keyword( char *parsestring ) { /* * Try to interprete the first element on the comma separated parse string * as a device number or a range of devices. If the interpretation is - * successfull, create the matching dasd_devmap entries and return a pointer + * successful, create the matching dasd_devmap entries and return a pointer * to the residual string. * If interpretation fails or in case of an error, return an error code. */ diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 459f2cbe80fc..db8005d9f2fd 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c @@ -2858,7 +2858,7 @@ static struct dasd_ccw_req *dasd_raw_build_cp(struct dasd_device *startdev, /* * struct PFX_eckd_data has up to 2 byte as extended parameter * this is needed for write full track and has to be mentioned - * seperately + * separately * add 8 instead of 2 to keep 8 byte boundary */ pfx_datasize = sizeof(struct PFX_eckd_data) + 8; diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c index 4c023761946f..e21a5c39ef20 100644 --- a/drivers/s390/char/raw3270.c +++ b/drivers/s390/char/raw3270.c @@ -604,7 +604,7 @@ __raw3270_size_device(struct raw3270 *rp) /* * To determine the size of the 3270 device we need to do: * 1) send a 'read partition' data stream to the device - * 2) wait for the attn interrupt that preceeds the query reply + * 2) wait for the attn interrupt that precedes the query reply * 3) do a read modified to get the query reply * To make things worse we have to cope with intervention * required (3270 device switched to 'stand-by') and command diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c index e090a307fdee..87cd0ab242de 100644 --- a/drivers/s390/char/tape_char.c +++ b/drivers/s390/char/tape_char.c @@ -139,7 +139,7 @@ tapechar_read(struct file *filp, char __user *data, size_t count, loff_t *ppos) /* * If the tape isn't terminated yet, do it now. And since we then * are at the end of the tape there wouldn't be anything to read - * anyways. So we return immediatly. + * anyways. So we return immediately. */ if(device->required_tapemarks) { return tape_std_terminate_write(device); diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index d33554df2b06..2db1482b406e 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c @@ -328,7 +328,7 @@ tty3270_write_callback(struct raw3270_request *rq, void *data) tp = (struct tty3270 *) rq->view; if (rq->rc != 0) { - /* Write wasn't successfull. Refresh all. */ + /* Write wasn't successful. Refresh all. */ tp->update_flags = TTY_UPDATE_ALL; tty3270_set_timer(tp, 1); } diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index a845695ac314..6084103672b5 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c @@ -318,7 +318,7 @@ ccw_device_sense_id_done(struct ccw_device *cdev, int err) /** * ccw_device_notify() - inform the device's driver about an event - * @cdev: device for which an event occured + * @cdev: device for which an event occurred * @event: event that occurred * * Returns: @@ -688,7 +688,7 @@ ccw_device_online_verify(struct ccw_device *cdev, enum dev_event dev_event) (scsw_stctl(&cdev->private->irb.scsw) & SCSW_STCTL_STATUS_PEND)) { /* * No final status yet or final status not yet delivered - * to the device driver. Can't do path verfication now, + * to the device driver. Can't do path verification now, * delay until final status was delivered. */ cdev->private->flags.doverify = 1; diff --git a/drivers/s390/crypto/zcrypt_api.h b/drivers/s390/crypto/zcrypt_api.h index 88ebd114735b..9688f3985b07 100644 --- a/drivers/s390/crypto/zcrypt_api.h +++ b/drivers/s390/crypto/zcrypt_api.h @@ -76,7 +76,7 @@ struct ica_z90_status { /** * Large random numbers are pulled in 4096 byte chunks from the crypto cards - * and stored in a page. Be carefull when increasing this buffer due to size + * and stored in a page. Be careful when increasing this buffer due to size * limitations for AP requests. */ #define ZCRYPT_RNG_BUFFER_SIZE 4096 diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c index 9feb62febb3d..da8aa75bb20b 100644 --- a/drivers/s390/net/claw.c +++ b/drivers/s390/net/claw.c @@ -779,7 +779,7 @@ claw_irq_handler(struct ccw_device *cdev, case CLAW_START_WRITE: if (p_ch->irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) { dev_info(&cdev->dev, - "%s: Unit Check Occured in " + "%s: Unit Check Occurred in " "write channel\n", dev->name); clear_bit(0, (void *)&p_ch->IO_active); if (p_ch->irb->ecw[0] & 0x80) { diff --git a/drivers/s390/net/ctcm_fsms.c b/drivers/s390/net/ctcm_fsms.c index 8c921fc3511a..2d602207541b 100644 --- a/drivers/s390/net/ctcm_fsms.c +++ b/drivers/s390/net/ctcm_fsms.c @@ -184,7 +184,7 @@ static void ctcmpc_chx_resend(fsm_instance *, int, void *); static void ctcmpc_chx_send_sweep(fsm_instance *fsm, int event, void *arg); /** - * Check return code of a preceeding ccw_device call, halt_IO etc... + * Check return code of a preceding ccw_device call, halt_IO etc... * * ch : The channel, the error belongs to. * Returns the error code (!= 0) to inspect. diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index 7fbc4adbb6d5..49d1cfc3217e 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c @@ -1123,7 +1123,7 @@ list_modified: list_for_each_entry_safe(ipm, tmp, &card->ipm_list, list){ switch (ipm->ipm_state) { case LCS_IPM_STATE_SET_REQUIRED: - /* del from ipm_list so noone else can tamper with + /* del from ipm_list so no one else can tamper with * this entry */ list_del_init(&ipm->list); spin_unlock_irqrestore(&card->ipm_lock, flags); diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 10a3a3b4dd3e..85cc53117ea6 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -1107,7 +1107,7 @@ static int qeth_setup_card(struct qeth_card *card) INIT_LIST_HEAD(card->ip_tbd_list); INIT_LIST_HEAD(&card->cmd_waiter_list); init_waitqueue_head(&card->wait_q); - /* intial options */ + /* initial options */ qeth_set_intial_options(card); /* IP address takeover */ INIT_LIST_HEAD(&card->ipato.entries); diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index a0e05ef65924..8512b5c0ef82 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -1083,7 +1083,7 @@ static void zfcp_fsf_send_els_handler(struct zfcp_fsf_req *req) } break; case FSF_SBAL_MISMATCH: - /* should never occure, avoided in zfcp_fsf_send_els */ + /* should never occur, avoided in zfcp_fsf_send_els */ /* fall through */ default: req->status |= ZFCP_STATUS_FSFREQ_ERROR; diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index 8da5ed644c2b..98e97d90835b 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c @@ -391,7 +391,7 @@ int zfcp_qdio_open(struct zfcp_qdio *qdio) if (do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT, 0, 0, QDIO_MAX_BUFFERS_PER_Q)) goto failed_qdio; - /* set index of first avalable SBALS / number of available SBALS */ + /* set index of first available SBALS / number of available SBALS */ qdio->req_q_idx = 0; atomic_set(&qdio->req_q_free, QDIO_MAX_BUFFERS_PER_Q); atomic_set_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &qdio->adapter->status); diff --git a/drivers/sbus/char/jsflash.c b/drivers/sbus/char/jsflash.c index e8566224fe4b..6b4678a7900a 100644 --- a/drivers/sbus/char/jsflash.c +++ b/drivers/sbus/char/jsflash.c @@ -13,7 +13,7 @@ * TODO: Erase/program both banks of a 8MB SIMM. * * It is anticipated that programming an OS Flash will be a routine - * procedure. In the same time it is exeedingly dangerous because + * procedure. In the same time it is exceedingly dangerous because * a user can program its OBP flash with OS image and effectively * kill the machine. * diff --git a/drivers/sbus/char/max1617.h b/drivers/sbus/char/max1617.h index 0bb09c286cb4..cd30819a0a30 100644 --- a/drivers/sbus/char/max1617.h +++ b/drivers/sbus/char/max1617.h @@ -6,7 +6,7 @@ #define MAX1617_CPU_TEMP 0x01 /* Processor die temp in C */ #define MAX1617_STATUS 0x02 /* Chip status bits */ -/* Read-only versions of changable registers. */ +/* Read-only versions of changeable registers. */ #define MAX1617_RD_CFG_BYTE 0x03 /* Config register */ #define MAX1617_RD_CVRATE_BYTE 0x04 /* Temp conversion rate */ #define MAX1617_RD_AMB_HIGHLIM 0x05 /* Ambient high limit */ diff --git a/drivers/scsi/3w-9xxx.h b/drivers/scsi/3w-9xxx.h index 3343824855d0..040f7214e5b7 100644 --- a/drivers/scsi/3w-9xxx.h +++ b/drivers/scsi/3w-9xxx.h @@ -61,7 +61,7 @@ static twa_message_type twa_aen_table[] = { {0x0000, "AEN queue empty"}, {0x0001, "Controller reset occurred"}, {0x0002, "Degraded unit detected"}, - {0x0003, "Controller error occured"}, + {0x0003, "Controller error occurred"}, {0x0004, "Background rebuild failed"}, {0x0005, "Background rebuild done"}, {0x0006, "Incomplete unit detected"}, diff --git a/drivers/scsi/3w-xxxx.h b/drivers/scsi/3w-xxxx.h index 8b9f9d17e7fe..49dcf03c631a 100644 --- a/drivers/scsi/3w-xxxx.h +++ b/drivers/scsi/3w-xxxx.h @@ -8,7 +8,7 @@ Copyright (C) 1999-2010 3ware Inc. - Kernel compatiblity By: Andre Hedrick + Kernel compatibility By: Andre Hedrick Non-Copyright (C) 2000 Andre Hedrick This program is free software; you can redistribute it and/or modify diff --git a/drivers/scsi/53c700.scr b/drivers/scsi/53c700.scr index a064a092c604..ec822e3b7a27 100644 --- a/drivers/scsi/53c700.scr +++ b/drivers/scsi/53c700.scr @@ -31,7 +31,7 @@ ABSOLUTE StatusAddress = 0 ; Addr to receive status return ABSOLUTE ReceiveMsgAddress = 0 ; Addr to receive msg ; ; This is the magic component for handling scatter-gather. Each of the -; SG components is preceeded by a script fragment which moves the +; SG components is preceded by a script fragment which moves the ; necessary amount of data and jumps to the next SG segment. The final ; SG segment jumps back to . However, this address is the first SG script ; segment. diff --git a/drivers/scsi/53c700_d.h_shipped b/drivers/scsi/53c700_d.h_shipped index 0b42a51257f2..aa623da333c8 100644 --- a/drivers/scsi/53c700_d.h_shipped +++ b/drivers/scsi/53c700_d.h_shipped @@ -34,7 +34,7 @@ ABSOLUTE StatusAddress = 0 ; Addr to receive status return ABSOLUTE ReceiveMsgAddress = 0 ; Addr to receive msg ; ; This is the magic component for handling scatter-gather. Each of the -; SG components is preceeded by a script fragment which moves the +; SG components is preceded by a script fragment which moves the ; necessary amount of data and jumps to the next SG segment. The final ; SG segment jumps back to . However, this address is the first SG script ; segment. diff --git a/drivers/scsi/FlashPoint.c b/drivers/scsi/FlashPoint.c index e40cdfb7541f..dcd716d68600 100644 --- a/drivers/scsi/FlashPoint.c +++ b/drivers/scsi/FlashPoint.c @@ -2509,7 +2509,7 @@ static void FPT_ssel(unsigned long port, unsigned char p_card) WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT)); - /* Setup our STATE so we know what happend when + /* Setup our STATE so we know what happened when the wheels fall off. */ currSCCB->Sccb_scsistat = SELECT_ST; @@ -2900,7 +2900,7 @@ static void FPT_SendMsg(unsigned long port, unsigned char message) * * Function: FPT_sdecm * - * Description: Determine the proper responce to the message from the + * Description: Determine the proper response to the message from the * target device. * *---------------------------------------------------------------------*/ diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c index e7cd2fcbe036..165e4dd865d9 100644 --- a/drivers/scsi/NCR5380.c +++ b/drivers/scsi/NCR5380.c @@ -1198,12 +1198,12 @@ static irqreturn_t NCR5380_intr(int dummy, void *dev_id) */ if ((NCR5380_read(MODE_REG) & MR_DMA) && ((basr & BASR_END_DMA_TRANSFER) || !(basr & BASR_PHASE_MATCH))) { - int transfered; + int transferred; if (!hostdata->connected) panic("scsi%d : received end of DMA interrupt with no connected cmd\n", instance->hostno); - transfered = (hostdata->dmalen - NCR5380_dma_residual(instance)); + transferred = (hostdata->dmalen - NCR5380_dma_residual(instance)); hostdata->connected->SCp.this_residual -= transferred; hostdata->connected->SCp.ptr += transferred; hostdata->dmalen = 0; @@ -1563,7 +1563,7 @@ failed: * bytes to transfer, **data - pointer to data pointer. * * Returns : -1 when different phase is entered without transferring - * maximum number of bytes, 0 if all bytes or transfered or exit + * maximum number of bytes, 0 if all bytes or transferred or exit * is in same phase. * * Also, *phase, *count, *data are modified in place. @@ -1800,7 +1800,7 @@ static int do_abort(struct Scsi_Host *host) { * bytes to transfer, **data - pointer to data pointer. * * Returns : -1 when different phase is entered without transferring - * maximum number of bytes, 0 if all bytes or transfered or exit + * maximum number of bytes, 0 if all bytes or transferred or exit * is in same phase. * * Also, *phase, *count, *data are modified in place. diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 118ce83a737c..061995741444 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -747,8 +747,8 @@ char * get_container_type(unsigned tindex) * Arguments: [1] pointer to void [1] int * * Purpose: Sets SCSI inquiry data strings for vendor, product - * and revision level. Allows strings to be set in platform dependant - * files instead of in OS dependant driver source. + * and revision level. Allows strings to be set in platform dependent + * files instead of in OS dependent driver source. */ static void setinqstr(struct aac_dev *dev, void *data, int tindex) diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 29ab00016b78..ffb587817efc 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -1259,7 +1259,7 @@ struct aac_dev #define CACHE_UNSTABLE 2 /* - * Lets the client know at which level the data was commited on + * Lets the client know at which level the data was committed on * a write request */ diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index dd7ad3ba2dad..e7d0d47b9185 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -421,7 +421,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, if (!(hw_fib->header.XferState & cpu_to_le32(HostOwned))) return -EBUSY; /* - * There are 5 cases with the wait and reponse requested flags. + * There are 5 cases with the wait and response requested flags. * The only invalid cases are if the caller requests to wait and * does not request a response and if the caller does not want a * response and the Fib is not allocated from pool. If a response diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 081c6de92bc5..bfd618a69499 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -4544,7 +4544,7 @@ AscMemWordCopyPtrToLram(PortAddr iop_base, ushort s_addr, * Copy 4 bytes to LRAM. * * The source data is assumed to be in little-endian order in memory - * and is maintained in little-endian order when writen to LRAM. + * and is maintained in little-endian order when written to LRAM. */ static void AscMemDWordCopyPtrToLram(PortAddr iop_base, diff --git a/drivers/scsi/aha1740.c b/drivers/scsi/aha1740.c index d058f1ab82b5..1c10b796c1a2 100644 --- a/drivers/scsi/aha1740.c +++ b/drivers/scsi/aha1740.c @@ -461,7 +461,7 @@ static int aha1740_queuecommand_lck(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *) /* The Adaptec Spec says the card is so fast that the loops will only be executed once in the code below. Even if this was true with the fastest processors when the spec was - written, it doesn't seem to be true with todays fast + written, it doesn't seem to be true with today's fast processors. We print a warning if the code is executed more often than LOOPCNT_WARN. If this happens, it should be investigated. If the count reaches LOOPCNT_MAX, we assume diff --git a/drivers/scsi/aic7xxx/aic79xx.h b/drivers/scsi/aic7xxx/aic79xx.h index 95ee50385188..9b059422aacb 100644 --- a/drivers/scsi/aic7xxx/aic79xx.h +++ b/drivers/scsi/aic7xxx/aic79xx.h @@ -473,7 +473,7 @@ struct hardware_scb { * o A residual has occurred if SG_FULL_RESID is set in sgptr, * or residual_sgptr does not have SG_LIST_NULL set. * - * o We are transfering the last segment if residual_datacnt has + * o We are transferring the last segment if residual_datacnt has * the SG_LAST_SEG flag set. * * Host: @@ -516,7 +516,7 @@ struct hardware_scb { */ /* - * Definition of a scatter/gather element as transfered to the controller. + * Definition of a scatter/gather element as transferred to the controller. * The aic7xxx chips only support a 24bit length. We use the top byte of * the length to store additional address bits and a flag to indicate * that a given segment terminates the transfer. This gives us an diff --git a/drivers/scsi/aic7xxx/aic79xx.reg b/drivers/scsi/aic7xxx/aic79xx.reg index 0666c22ab55b..7e12c31ccfda 100644 --- a/drivers/scsi/aic7xxx/aic79xx.reg +++ b/drivers/scsi/aic7xxx/aic79xx.reg @@ -305,7 +305,7 @@ register HS_MAILBOX { } /* - * Sequencer Interupt Status + * Sequencer Interrupt Status */ register SEQINTSTAT { address 0x00C @@ -685,7 +685,7 @@ register DCHRXMSG0 { } /* - * CMC Recieve Message 0 + * CMC Receive Message 0 */ register CMCRXMSG0 { address 0x090 @@ -696,7 +696,7 @@ register CMCRXMSG0 { } /* - * Overlay Recieve Message 0 + * Overlay Receive Message 0 */ register OVLYRXMSG0 { address 0x090 @@ -732,7 +732,7 @@ register DCHRXMSG1 { } /* - * CMC Recieve Message 1 + * CMC Receive Message 1 */ register CMCRXMSG1 { address 0x091 @@ -742,7 +742,7 @@ register CMCRXMSG1 { } /* - * Overlay Recieve Message 1 + * Overlay Receive Message 1 */ register OVLYRXMSG1 { address 0x091 @@ -777,7 +777,7 @@ register DCHRXMSG2 { } /* - * CMC Recieve Message 2 + * CMC Receive Message 2 */ register CMCRXMSG2 { address 0x092 @@ -787,7 +787,7 @@ register CMCRXMSG2 { } /* - * Overlay Recieve Message 2 + * Overlay Receive Message 2 */ register OVLYRXMSG2 { address 0x092 @@ -816,7 +816,7 @@ register DCHRXMSG3 { } /* - * CMC Recieve Message 3 + * CMC Receive Message 3 */ register CMCRXMSG3 { address 0x093 @@ -826,7 +826,7 @@ register CMCRXMSG3 { } /* - * Overlay Recieve Message 3 + * Overlay Receive Message 3 */ register OVLYRXMSG3 { address 0x093 @@ -1249,7 +1249,7 @@ register TARGPCISTAT { /* * LQ Packet In - * The last LQ Packet recieved + * The last LQ Packet received */ register LQIN { address 0x020 @@ -2573,7 +2573,7 @@ register IOPDNCTL { } /* - * Shaddow Host Address. + * Shadow Host Address. */ register SHADDR { address 0x060 @@ -3983,7 +3983,7 @@ scratch_ram { /* * The maximum amount of time to wait, when interrupt coalescing - * is enabled, before issueing a CMDCMPLT interrupt for a completed + * is enabled, before issuing a CMDCMPLT interrupt for a completed * command. */ INT_COALESCING_TIMER { diff --git a/drivers/scsi/aic7xxx/aic79xx.seq b/drivers/scsi/aic7xxx/aic79xx.seq index 2fb78e35a9e5..3a36d9362a10 100644 --- a/drivers/scsi/aic7xxx/aic79xx.seq +++ b/drivers/scsi/aic7xxx/aic79xx.seq @@ -567,7 +567,7 @@ BEGIN_CRITICAL; shr SELOID, 4, SCB_SCSIID; /* * If we want to send a message to the device, ensure - * we are selecting with atn irregardless of our packetized + * we are selecting with atn regardless of our packetized * agreement. Since SPI4 only allows target reset or PPR * messages if this is a packetized connection, the change * to our negotiation table entry for this selection will @@ -960,7 +960,7 @@ p_status_okay: * This is done to allow the host to send messages outside of an identify * sequence while protecting the seqencer from testing the MK_MESSAGE bit * on an SCB that might not be for the current nexus. (For example, a - * BDR message in responce to a bad reselection would leave us pointed to + * BDR message in response to a bad reselection would leave us pointed to * an SCB that doesn't have anything to do with the current target). * * Otherwise, treat MSG_OUT as a 1 byte message to send (abort, abort tag, @@ -1507,7 +1507,7 @@ service_fifo: * If the other FIFO needs loading, then it * must not have claimed the S/G cache yet * (SG_CACHE_AVAIL would have been cleared in - * the orginal FIFO mode and we test this above). + * the original FIFO mode and we test this above). * Return to the idle loop so we can process the * FIFO not currently on the bus first. */ @@ -1521,7 +1521,7 @@ idle_sgfetch_okay: idle_sgfetch_start: /* * We fetch a "cacheline aligned" and sized amount of data - * so we don't end up referencing a non-existant page. + * so we don't end up referencing a non-existent page. * Cacheline aligned is in quotes because the kernel will * set the prefetch amount to a reasonable level if the * cacheline size is unknown. @@ -1551,7 +1551,7 @@ idle_sg_avail: test DFSTATUS, PRELOAD_AVAIL jz return; /* * On the A, preloading a segment before HDMAENACK - * comes true can clobber the shaddow address of the + * comes true can clobber the shadow address of the * first segment in the S/G FIFO. Wait until it is * safe to proceed. */ @@ -2004,10 +2004,10 @@ pkt_handle_xfer: * Defer handling of this NONPACKREQ until we * can be sure it pertains to this FIFO. SAVEPTRS * will not be asserted if the NONPACKREQ is for us, - * so we must simulate it if shaddow is valid. If - * shaddow is not valid, keep running this FIFO until we + * so we must simulate it if shadow is valid. If + * shadow is not valid, keep running this FIFO until we * have satisfied the transfer by loading segments and - * waiting for either shaddow valid or last_seg_done. + * waiting for either shadow valid or last_seg_done. */ test MDFFSTAT, SHVALID jnz pkt_saveptrs; pkt_service_fifo: @@ -2171,7 +2171,7 @@ pkt_status_check_nonpackreq: /* * The unexpected nonpkt phase handler assumes that any * data channel use will have a FIFO reference count. It - * turns out that the status handler doesn't need a refernce + * turns out that the status handler doesn't need a references * count since the status received flag, and thus completion * processing, cannot be set until the handler is finished. * We increment the count here to make the nonpkt handler diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c index 3233bf564435..5f8617dd43bb 100644 --- a/drivers/scsi/aic7xxx/aic79xx_core.c +++ b/drivers/scsi/aic7xxx/aic79xx_core.c @@ -562,7 +562,7 @@ ahd_targetcmd_offset(struct ahd_softc *ahd, u_int index) } #endif -/*********************** Miscelaneous Support Functions ***********************/ +/*********************** Miscellaneous Support Functions ***********************/ /* * Return pointers to the transfer negotiation information * for the specified our_id/remote_id pair. @@ -599,7 +599,7 @@ void ahd_outw(struct ahd_softc *ahd, u_int port, u_int value) { /* - * Write low byte first to accomodate registers + * Write low byte first to accommodate registers * such as PRGMCNT where the order maters. */ ahd_outb(ahd, port, value & 0xFF); @@ -2067,7 +2067,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) * that requires host assistance for completion. * While handling the message phase(s), we will be * notified by the sequencer after each byte is - * transfered so we can track bus phase changes. + * transferred so we can track bus phase changes. * * If this is the first time we've seen a HOST_MSG_LOOP * interrupt, initialize the state of the host message @@ -2487,7 +2487,7 @@ ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat) /* * Although the driver does not care about the * 'Selection in Progress' status bit, the busy - * LED does. SELINGO is only cleared by a successfull + * LED does. SELINGO is only cleared by a successful * selection, so we must manually clear it to insure * the LED turns off just incase no future successful * selections occur (e.g. no devices on the bus). @@ -3548,7 +3548,7 @@ ahd_clear_critical_section(struct ahd_softc *ahd) ahd_outb(ahd, SEQCTL0, ahd_inb(ahd, SEQCTL0) & ~STEP); ahd_outb(ahd, SIMODE1, simode1); /* - * SCSIINT seems to glitch occassionally when + * SCSIINT seems to glitch occasionally when * the interrupt masks are restored. Clear SCSIINT * one more time so that only persistent errors * are seen as a real interrupt. @@ -3838,7 +3838,7 @@ ahd_validate_width(struct ahd_softc *ahd, struct ahd_initiator_tinfo *tinfo, /* * Update the bitmask of targets for which the controller should - * negotiate with at the next convenient oportunity. This currently + * negotiate with at the next convenient opportunity. This currently * means the next time we send the initial identify messages for * a new transaction. */ @@ -4200,7 +4200,7 @@ ahd_update_neg_table(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, /* * During packetized transfers, the target will - * give us the oportunity to send command packets + * give us the opportunity to send command packets * without us asserting attention. */ if ((tinfo->ppr_options & MSG_EXT_PPR_IU_REQ) == 0) @@ -5651,7 +5651,7 @@ ahd_handle_msg_reject(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) /* * Requeue all tagged commands for this target - * currently in our posession so they can be + * currently in our possession so they can be * converted to untagged commands. */ ahd_search_qinfifo(ahd, SCB_GET_TARGET(ahd, scb), @@ -6245,7 +6245,7 @@ ahd_shutdown(void *arg) /* * Reset the controller and record some information about it * that is only available just after a reset. If "reinit" is - * non-zero, this reset occured after initial configuration + * non-zero, this reset occurred after initial configuration * and the caller requests that the chip be fully reinitialized * to a runable state. Chip interrupts are *not* enabled after * a reinitialization. The caller must enable interrupts via @@ -6495,7 +6495,7 @@ ahd_init_scbdata(struct ahd_softc *ahd) } /* - * Note that we were successfull + * Note that we were successful */ return (0); @@ -7079,7 +7079,7 @@ ahd_init(struct ahd_softc *ahd) return (ENOMEM); /* - * Verify that the compiler hasn't over-agressively + * Verify that the compiler hasn't over-aggressively * padded important structures. */ if (sizeof(struct hardware_scb) != 64) @@ -10087,7 +10087,7 @@ ahd_write_seeprom(struct ahd_softc *ahd, uint16_t *buf, return (error); /* - * Write the data. If we don't get throught the loop at + * Write the data. If we don't get through the loop at * least once, the arguments were invalid. */ retval = EINVAL; diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index 25d066624476..7d48700257a7 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c @@ -1441,7 +1441,7 @@ ahd_platform_set_tags(struct ahd_softc *ahd, struct scsi_device *sdev, usertags = ahd_linux_user_tagdepth(ahd, devinfo); if (!was_queuing) { /* - * Start out agressively and allow our + * Start out aggressively and allow our * dynamic queue depth algorithm to take * care of the rest. */ diff --git a/drivers/scsi/aic7xxx/aic7xxx.h b/drivers/scsi/aic7xxx/aic7xxx.h index 17444bc18bca..f695774645c1 100644 --- a/drivers/scsi/aic7xxx/aic7xxx.h +++ b/drivers/scsi/aic7xxx/aic7xxx.h @@ -440,7 +440,7 @@ struct hardware_scb { * o A residual has occurred if SG_FULL_RESID is set in sgptr, * or residual_sgptr does not have SG_LIST_NULL set. * - * o We are transfering the last segment if residual_datacnt has + * o We are transferring the last segment if residual_datacnt has * the SG_LAST_SEG flag set. * * Host: @@ -494,7 +494,7 @@ struct hardware_scb { */ /* - * Definition of a scatter/gather element as transfered to the controller. + * Definition of a scatter/gather element as transferred to the controller. * The aic7xxx chips only support a 24bit length. We use the top byte of * the length to store additional address bits and a flag to indicate * that a given segment terminates the transfer. This gives us an diff --git a/drivers/scsi/aic7xxx/aic7xxx.reg b/drivers/scsi/aic7xxx/aic7xxx.reg index 9a96e55da39a..ba0b411d03e2 100644 --- a/drivers/scsi/aic7xxx/aic7xxx.reg +++ b/drivers/scsi/aic7xxx/aic7xxx.reg @@ -351,7 +351,7 @@ register SSTAT2 { address 0x00d access_mode RO field OVERRUN 0x80 - field SHVALID 0x40 /* Shaddow Layer non-zero */ + field SHVALID 0x40 /* Shadow Layer non-zero */ field EXP_ACTIVE 0x10 /* SCSI Expander Active */ field CRCVALERR 0x08 /* CRC doesn't match (U3 only) */ field CRCENDERR 0x04 /* No terminal CRC packet (U3 only) */ diff --git a/drivers/scsi/aic7xxx/aic7xxx.seq b/drivers/scsi/aic7xxx/aic7xxx.seq index 5a4cfc954a9f..e60041e8f2d1 100644 --- a/drivers/scsi/aic7xxx/aic7xxx.seq +++ b/drivers/scsi/aic7xxx/aic7xxx.seq @@ -57,10 +57,10 @@ PREFIX = "ahc_" * a later time. This problem cannot be resolved by holding a single entry * in scratch ram since a reconnecting target can request sense and this will * create yet another SCB waiting for selection. The solution used here is to - * use byte 27 of the SCB as a psuedo-next pointer and to thread a list + * use byte 27 of the SCB as a pseudo-next pointer and to thread a list * of SCBs that are awaiting selection. Since 0-0xfe are valid SCB indexes, * SCB_LIST_NULL is 0xff which is out of range. An entry is also added to - * this list everytime a request sense occurs or after completing a non-tagged + * this list every time a request sense occurs or after completing a non-tagged * command for which a second SCB has been queued. The sequencer will * automatically consume the entries. */ @@ -752,7 +752,7 @@ idle_loop: /* * We fetch a "cacheline aligned" and sized amount of data - * so we don't end up referencing a non-existant page. + * so we don't end up referencing a non-existent page. * Cacheline aligned is in quotes because the kernel will * set the prefetch amount to a reasonable level if the * cacheline size is unknown. @@ -1485,7 +1485,7 @@ p_status_okay: * This is done to allow the host to send messages outside of an identify * sequence while protecting the seqencer from testing the MK_MESSAGE bit * on an SCB that might not be for the current nexus. (For example, a - * BDR message in responce to a bad reselection would leave us pointed to + * BDR message in response to a bad reselection would leave us pointed to * an SCB that doesn't have anything to do with the current target). * * Otherwise, treat MSG_OUT as a 1 byte message to send (abort, abort tag, @@ -1999,7 +1999,7 @@ if ((ahc->flags & AHC_TARGETROLE) != 0) { * from out to in, wait an additional data release delay before continuing. */ change_phase: - /* Wait for preceeding I/O session to complete. */ + /* Wait for preceding I/O session to complete. */ test SCSISIGI, ACKI jnz .; /* Change the phase */ diff --git a/drivers/scsi/aic7xxx/aic7xxx_core.c b/drivers/scsi/aic7xxx/aic7xxx_core.c index e021b4812d58..dc28b0a91b22 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_core.c +++ b/drivers/scsi/aic7xxx/aic7xxx_core.c @@ -427,7 +427,7 @@ ahc_targetcmd_offset(struct ahc_softc *ahc, u_int index) } #endif -/*********************** Miscelaneous Support Functions ***********************/ +/*********************** Miscellaneous Support Functions ***********************/ /* * Determine whether the sequencer reported a residual * for this SCB/transaction. @@ -1243,7 +1243,7 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat) * that requires host assistance for completion. * While handling the message phase(s), we will be * notified by the sequencer after each byte is - * transfered so we can track bus phase changes. + * transferred so we can track bus phase changes. * * If this is the first time we've seen a HOST_MSG_LOOP * interrupt, initialize the state of the host message @@ -1487,7 +1487,7 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat) scbptr, ahc_inb(ahc, ARG_1), ahc->scb_data->hscbs[scbptr].tag); ahc_dump_card_state(ahc); - panic("for saftey"); + panic("for safety"); break; } case OUT_OF_RANGE: @@ -1733,7 +1733,7 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat) /* * Although the driver does not care about the * 'Selection in Progress' status bit, the busy - * LED does. SELINGO is only cleared by a successfull + * LED does. SELINGO is only cleared by a successful * selection, so we must manually clear it to insure * the LED turns off just incase no future successful * selections occur (e.g. no devices on the bus). @@ -1943,7 +1943,7 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat) if (lastphase != P_BUSFREE) { /* * Renegotiate with this device at the - * next oportunity just in case this busfree + * next opportunity just in case this busfree * is due to a negotiation mismatch with the * device. */ @@ -2442,7 +2442,7 @@ ahc_validate_width(struct ahc_softc *ahc, struct ahc_initiator_tinfo *tinfo, /* * Update the bitmask of targets for which the controller should - * negotiate with at the next convenient oportunity. This currently + * negotiate with at the next convenient opportunity. This currently * means the next time we send the initial identify messages for * a new transaction. */ @@ -4131,7 +4131,7 @@ ahc_handle_msg_reject(struct ahc_softc *ahc, struct ahc_devinfo *devinfo) /* * Requeue all tagged commands for this target - * currently in our posession so they can be + * currently in our possession so they can be * converted to untagged commands. */ ahc_search_qinfifo(ahc, SCB_GET_TARGET(ahc, scb), @@ -4581,7 +4581,7 @@ ahc_shutdown(void *arg) /* * Reset the controller and record some information about it * that is only available just after a reset. If "reinit" is - * non-zero, this reset occured after initial configuration + * non-zero, this reset occurred after initial configuration * and the caller requests that the chip be fully reinitialized * to a runable state. Chip interrupts are *not* enabled after * a reinitialization. The caller must enable interrupts via @@ -4899,7 +4899,7 @@ ahc_init_scbdata(struct ahc_softc *ahc) ahc->next_queued_scb = ahc_get_scb(ahc); /* - * Note that we were successfull + * Note that we were successful */ return (0); diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index 4a359bb307c6..c6251bb4f438 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -294,7 +294,7 @@ static uint32_t aic7xxx_extended; * dubious at best. To my knowledge, this option has never actually * solved a PCI parity problem, but on certain machines with broken PCI * chipset configurations where stray PCI transactions with bad parity are - * the norm rather than the exception, the error messages can be overwelming. + * the norm rather than the exception, the error messages can be overwhelming. * It's included in the driver for completeness. * 0 = Shut off PCI parity check * non-0 = reverse polarity pci parity checking @@ -1318,7 +1318,7 @@ ahc_platform_set_tags(struct ahc_softc *ahc, struct scsi_device *sdev, usertags = ahc_linux_user_tagdepth(ahc, devinfo); if (!was_queuing) { /* - * Start out agressively and allow our + * Start out aggressively and allow our * dynamic queue depth algorithm to take * care of the rest. */ diff --git a/drivers/scsi/aic7xxx/aic7xxx_pci.c b/drivers/scsi/aic7xxx/aic7xxx_pci.c index 2b11a4272364..6917b4f5ac9e 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_pci.c +++ b/drivers/scsi/aic7xxx/aic7xxx_pci.c @@ -789,7 +789,7 @@ ahc_pci_config(struct ahc_softc *ahc, const struct ahc_pci_identity *entry) ahc->bus_intr = ahc_pci_intr; ahc->bus_chip_init = ahc_pci_chip_init; - /* Remeber how the card was setup in case there is no SEEPROM */ + /* Remember how the card was setup in case there is no SEEPROM */ if ((ahc_inb(ahc, HCNTRL) & POWRDN) == 0) { ahc_pause(ahc); if ((ahc->features & AHC_ULTRA2) != 0) @@ -860,7 +860,7 @@ ahc_pci_config(struct ahc_softc *ahc, const struct ahc_pci_identity *entry) } /* - * We cannot perform ULTRA speeds without the presense + * We cannot perform ULTRA speeds without the presence * of the external precision resistor. */ if ((ahc->features & AHC_ULTRA) != 0) { @@ -969,7 +969,7 @@ ahc_pci_config(struct ahc_softc *ahc, const struct ahc_pci_identity *entry) } /* - * Test for the presense of external sram in an + * Test for the presence of external sram in an * "unshared" configuration. */ static int diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y b/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y index e4064433842e..f1586a437906 100644 --- a/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y +++ b/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y @@ -803,7 +803,7 @@ macro_arglist: | macro_arglist ',' T_ARG { if ($1 == 0) { - stop("Comma without preceeding argument in arg list", + stop("Comma without preceding argument in arg list", EX_DATAERR); /* NOTREACHED */ } @@ -1319,8 +1319,8 @@ code: ; /* - * This grammer differs from the one in the aic7xxx - * reference manual since the grammer listed there is + * This grammar differs from the one in the aic7xxx + * reference manual since the grammar listed there is * ambiguous and causes a shift/reduce conflict. * It also seems more logical as the "immediate" * argument is listed as the second arg like the @@ -1799,7 +1799,7 @@ format_3_instr(int opcode, symbol_ref_t *src, instr = seq_alloc(); f3_instr = &instr->format.format3; if (address->symbol == NULL) { - /* 'dot' referrence. Use the current instruction pointer */ + /* 'dot' reference. Use the current instruction pointer */ addr = instruction_ptr + address->offset; } else if (address->symbol->type == UNINITIALIZED) { /* forward reference */ diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y b/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y index ff46aa6801bf..708326df0766 100644 --- a/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y +++ b/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y @@ -115,7 +115,7 @@ macro_arglist: | macro_arglist ',' T_ARG { if ($1 == 0) { - stop("Comma without preceeding argument in arg list", + stop("Comma without preceding argument in arg list", EX_DATAERR); /* NOTREACHED */ } diff --git a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c index 4ff60a08df0f..5b212f0df898 100644 --- a/drivers/scsi/aic7xxx_old.c +++ b/drivers/scsi/aic7xxx_old.c @@ -905,7 +905,7 @@ struct aic_dev_data { * problems with architectures I can't test on (because I don't have one, * such as the Alpha based systems) which happen to give faults for * non-aligned memory accesses, care was taken to align this structure - * in a way that gauranteed all accesses larger than 8 bits were aligned + * in a way that guaranteed all accesses larger than 8 bits were aligned * on the appropriate boundary. It's also organized to try and be more * cache line efficient. Be careful when changing this lest you might hurt * overall performance and bring down the wrath of the masses. @@ -1180,7 +1180,7 @@ static int aic7xxx_pci_parity = 0; * the card's registers in a hex dump format tailored to each model of * controller. * - * NOTE: THE CONTROLLER IS LEFT IN AN UNUSEABLE STATE BY THIS OPTION. + * NOTE: THE CONTROLLER IS LEFT IN AN UNUSABLE STATE BY THIS OPTION. * YOU CANNOT BOOT UP WITH THIS OPTION, IT IS FOR DEBUGGING PURPOSES * ONLY */ @@ -3467,7 +3467,7 @@ aic7xxx_reset_current_bus(struct aic7xxx_host *p) /* Turn off the bus' current operations, after all, we shouldn't have any * valid commands left to cause a RSELI and SELO once we've tossed the * bus away with this reset, so we might as well shut down the sequencer - * until the bus is restarted as oppossed to saving the current settings + * until the bus is restarted as opposed to saving the current settings * and restoring them (which makes no sense to me). */ /* Turn on the bus reset. */ @@ -4070,7 +4070,7 @@ aic7xxx_handle_seqint(struct aic7xxx_host *p, unsigned char intstat) aic_dev->max_q_depth = aic_dev->temp_q_depth = 1; /* * We set this command up as a bus device reset. However, we have - * to clear the tag type as it's causing us problems. We shouldnt + * to clear the tag type as it's causing us problems. We shouldn't * have to worry about any other commands being active, since if * the device is refusing tagged commands, this should be the * first tagged command sent to the device, however, we do have @@ -9748,7 +9748,7 @@ skip_pci_controller: } /* - * We are commited now, everything has been checked and this card + * We are committed now, everything has been checked and this card * has been found, now we just set it up */ @@ -9906,7 +9906,7 @@ skip_pci_controller: * 2: All PCI controllers with BIOS_ENABLED next, according to BIOS * address, going from lowest to highest. * 3: Remaining VLB/EISA controllers going in slot order. - * 4: Remaining PCI controllers, going in PCI device order (reversable) + * 4: Remaining PCI controllers, going in PCI device order (reversible) */ { diff --git a/drivers/scsi/aic7xxx_old/aic7xxx.seq b/drivers/scsi/aic7xxx_old/aic7xxx.seq index 1565be9ebd49..823ff2873229 100644 --- a/drivers/scsi/aic7xxx_old/aic7xxx.seq +++ b/drivers/scsi/aic7xxx_old/aic7xxx.seq @@ -51,7 +51,7 @@ * use byte 27 of the SCB as a pseudo-next pointer and to thread a list * of SCBs that are awaiting selection. Since 0-0xfe are valid SCB indexes, * SCB_LIST_NULL is 0xff which is out of range. An entry is also added to - * this list everytime a request sense occurs or after completing a non-tagged + * this list every time a request sense occurs or after completing a non-tagged * command for which a second SCB has been queued. The sequencer will * automatically consume the entries. */ @@ -696,7 +696,7 @@ p_status: * This is done to allow the hsot to send messages outside of an identify * sequence while protecting the seqencer from testing the MK_MESSAGE bit * on an SCB that might not be for the current nexus. (For example, a - * BDR message in responce to a bad reselection would leave us pointed to + * BDR message in response to a bad reselection would leave us pointed to * an SCB that doesn't have anything to do with the current target). * Otherwise, treat MSG_OUT as a 1 byte message to send (abort, abort tag, * bus device reset). @@ -716,8 +716,8 @@ p_mesgout_identify: } else { and SINDEX,0x7,SCB_TCL; /* lun */ } - and A,DISCENB,SCB_CONTROL; /* mask off disconnect privledge */ - or SINDEX,A; /* or in disconnect privledge */ + and A,DISCENB,SCB_CONTROL; /* mask off disconnect privilege */ + or SINDEX,A; /* or in disconnect privilege */ or SINDEX,MSG_IDENTIFYFLAG; p_mesgout_mk_message: test SCB_CONTROL,MK_MESSAGE jz p_mesgout_tag; diff --git a/drivers/scsi/aic94xx/aic94xx_reg_def.h b/drivers/scsi/aic94xx/aic94xx_reg_def.h index 40273a747d29..dd6cc8008b16 100644 --- a/drivers/scsi/aic94xx/aic94xx_reg_def.h +++ b/drivers/scsi/aic94xx/aic94xx_reg_def.h @@ -2134,7 +2134,7 @@ * The host accesses this scratch in a different manner from the * link sequencer. The sequencer has to use LSEQ registers * LmSCRPAGE and LmMnSCRPAGE to access the scratch memory. A flat -* mapping of the scratch memory is avaliable for software +* mapping of the scratch memory is available for software * convenience and to prevent corruption while the sequencer is * running. This memory is mapped onto addresses 800h - 9FFh. * diff --git a/drivers/scsi/arm/acornscsi.c b/drivers/scsi/arm/acornscsi.c index ec166726b314..c454e44cf51c 100644 --- a/drivers/scsi/arm/acornscsi.c +++ b/drivers/scsi/arm/acornscsi.c @@ -100,7 +100,7 @@ */ #define TIMEOUT_TIME 10 /* - * Define this if you want to have verbose explaination of SCSI + * Define this if you want to have verbose explanation of SCSI * status/messages. */ #undef CONFIG_ACORNSCSI_CONSTANTS @@ -1561,7 +1561,7 @@ void acornscsi_message(AS_Host *host) /* * If we were negociating sync transfer, we don't yet know if * this REJECT is for the sync transfer or for the tagged queue/wide - * transfer. Re-initiate sync transfer negociation now, and if + * transfer. Re-initiate sync transfer negotiation now, and if * we got a REJECT in response to SDTR, then it'll be set to DONE. */ if (host->device[host->SCpnt->device->id].sync_state == SYNC_SENT_REQUEST) diff --git a/drivers/scsi/arm/acornscsi.h b/drivers/scsi/arm/acornscsi.h index 8d2172a0b351..01bc715a3aec 100644 --- a/drivers/scsi/arm/acornscsi.h +++ b/drivers/scsi/arm/acornscsi.h @@ -223,8 +223,8 @@ typedef enum { * Synchronous transfer state */ typedef enum { /* Synchronous transfer state */ - SYNC_ASYNCHRONOUS, /* don't negociate synchronous transfers*/ - SYNC_NEGOCIATE, /* start negociation */ + SYNC_ASYNCHRONOUS, /* don't negotiate synchronous transfers*/ + SYNC_NEGOCIATE, /* start negotiation */ SYNC_SENT_REQUEST, /* sent SDTR message */ SYNC_COMPLETED, /* received SDTR reply */ } syncxfer_t; @@ -322,7 +322,7 @@ typedef struct acornscsi_hostdata { /* per-device info */ struct { unsigned char sync_xfer; /* synchronous transfer (SBIC value) */ - syncxfer_t sync_state; /* sync xfer negociation state */ + syncxfer_t sync_state; /* sync xfer negotiation state */ unsigned char disconnect_ok:1; /* device can disconnect */ } device[8]; unsigned long busyluns[64 / sizeof(unsigned long)];/* array of bits indicating LUNs busy */ diff --git a/drivers/scsi/arm/arxescsi.c b/drivers/scsi/arm/arxescsi.c index 2836fe248df9..a750aa72b8ef 100644 --- a/drivers/scsi/arm/arxescsi.c +++ b/drivers/scsi/arm/arxescsi.c @@ -228,7 +228,7 @@ static const char *arxescsi_info(struct Scsi_Host *host) * Params : buffer - a buffer to write information to * start - a pointer into this buffer set by this routine to the start * of the required information. - * offset - offset into information that we have read upto. + * offset - offset into information that we have read up to. * length - length of buffer * host_no - host number to return information for * inout - 0 for reading, 1 for writing. diff --git a/drivers/scsi/arm/cumana_2.c b/drivers/scsi/arm/cumana_2.c index c9902b5c1f2b..547987b86384 100644 --- a/drivers/scsi/arm/cumana_2.c +++ b/drivers/scsi/arm/cumana_2.c @@ -344,7 +344,7 @@ cumanascsi_2_set_proc_info(struct Scsi_Host *host, char *buffer, int length) * Params : buffer - a buffer to write information to * start - a pointer into this buffer set by this routine to the start * of the required information. - * offset - offset into information that we have read upto. + * offset - offset into information that we have read up to. * length - length of buffer * host_no - host number to return information for * inout - 0 for reading, 1 for writing. diff --git a/drivers/scsi/arm/eesox.c b/drivers/scsi/arm/eesox.c index d8435132f461..edfd12b48c28 100644 --- a/drivers/scsi/arm/eesox.c +++ b/drivers/scsi/arm/eesox.c @@ -429,7 +429,7 @@ eesoxscsi_set_proc_info(struct Scsi_Host *host, char *buffer, int length) * Params : buffer - a buffer to write information to * start - a pointer into this buffer set by this routine to the start * of the required information. - * offset - offset into information that we have read upto. + * offset - offset into information that we have read up to. * length - length of buffer * host_no - host number to return information for * inout - 0 for reading, 1 for writing. diff --git a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c index 2b2ce21e227e..e85c40b6e19b 100644 --- a/drivers/scsi/arm/fas216.c +++ b/drivers/scsi/arm/fas216.c @@ -2119,7 +2119,7 @@ request_sense: * executed, unless a target connects to us. */ if (info->reqSCpnt) - printk(KERN_WARNING "scsi%d.%c: loosing request command\n", + printk(KERN_WARNING "scsi%d.%c: losing request command\n", info->host->host_no, '0' + SCpnt->device->id); info->reqSCpnt = SCpnt; } @@ -2294,7 +2294,7 @@ static int fas216_noqueue_command_lck(struct scsi_cmnd *SCpnt, * If we don't have an IRQ, then we must poll the card for * it's interrupt, and use that to call this driver's * interrupt routine. That way, we keep the command - * progressing. Maybe we can add some inteligence here + * progressing. Maybe we can add some intelligence here * and go to sleep if we know that the device is going * to be some time (eg, disconnected). */ diff --git a/drivers/scsi/arm/fas216.h b/drivers/scsi/arm/fas216.h index f30f8d659dc4..84b7127c0121 100644 --- a/drivers/scsi/arm/fas216.h +++ b/drivers/scsi/arm/fas216.h @@ -203,11 +203,11 @@ typedef enum { } fasdmatype_t; typedef enum { - neg_wait, /* Negociate with device */ - neg_inprogress, /* Negociation sent */ - neg_complete, /* Negociation complete */ - neg_targcomplete, /* Target completed negociation */ - neg_invalid /* Negociation not supported */ + neg_wait, /* Negotiate with device */ + neg_inprogress, /* Negotiation sent */ + neg_complete, /* Negotiation complete */ + neg_targcomplete, /* Target completed negotiation */ + neg_invalid /* Negotiation not supported */ } neg_t; #define MAGIC 0x441296bdUL diff --git a/drivers/scsi/arm/powertec.c b/drivers/scsi/arm/powertec.c index e2297b4c1b9e..9274c0677b9c 100644 --- a/drivers/scsi/arm/powertec.c +++ b/drivers/scsi/arm/powertec.c @@ -232,7 +232,7 @@ powertecscsi_set_proc_info(struct Scsi_Host *host, char *buffer, int length) * Params : buffer - a buffer to write information to * start - a pointer into this buffer set by this routine to the start * of the required information. - * offset - offset into information that we have read upto. + * offset - offset into information that we have read up to. * length - length of buffer * inout - 0 for reading, 1 for writing. * Returns : length of data written to buffer. diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c index 88b2928b4d3b..ea439f93ed81 100644 --- a/drivers/scsi/atari_NCR5380.c +++ b/drivers/scsi/atari_NCR5380.c @@ -464,7 +464,7 @@ static void free_all_tags(void) * * Parameters: Scsi_Cmnd *cmd * The command to work on. The first scatter buffer's data are - * assumed to be already transfered into ptr/this_residual. + * assumed to be already transferred into ptr/this_residual. */ static void merge_contiguous_buffers(Scsi_Cmnd *cmd) @@ -1720,7 +1720,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag) * bytes to transfer, **data - pointer to data pointer. * * Returns : -1 when different phase is entered without transferring - * maximum number of bytes, 0 if all bytes are transfered or exit + * maximum number of bytes, 0 if all bytes are transferred or exit * is in same phase. * * Also, *phase, *count, *data are modified in place. @@ -1911,7 +1911,7 @@ static int do_abort(struct Scsi_Host *host) * bytes to transfer, **data - pointer to data pointer. * * Returns : -1 when different phase is entered without transferring - * maximum number of bytes, 0 if all bytes or transfered or exit + * maximum number of bytes, 0 if all bytes or transferred or exit * is in same phase. * * Also, *phase, *count, *data are modified in place. diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 76029d570beb..7e6eca4a125e 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -1228,7 +1228,7 @@ TCM_5: /* isolation complete.. */ printk(" \n%x %x %x %s\n ",assignid_map,mbuf[0],mbuf[1],&mbuf[2]); */ i = 15; j = mbuf[0]; - if ((j & 0x20) != 0) { /* bit5=1:ID upto 7 */ + if ((j & 0x20) != 0) { /* bit5=1:ID up to 7 */ i = 7; } if ((j & 0x06) == 0) { /* IDvalid? */ diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h index 5218de4ab35a..fbd1dc2c15f7 100644 --- a/drivers/scsi/be2iscsi/be_cmds.h +++ b/drivers/scsi/be2iscsi/be_cmds.h @@ -877,7 +877,7 @@ struct be_all_if_id { */ #define CXN_KILLED_PDU_SIZE_EXCEEDS_DSL 3 /* Connection got invalidated * internally - * due to a recieved PDU + * due to a received PDU * size > DSL */ #define CXN_KILLED_BURST_LEN_MISMATCH 4 /* Connection got invalidated @@ -886,7 +886,7 @@ struct be_all_if_id { * FBL/MBL. */ #define CXN_KILLED_AHS_RCVD 5 /* Connection got invalidated - * internally due to a recieved + * internally due to a received * PDU Hdr that has * AHS */ #define CXN_KILLED_HDR_DIGEST_ERR 6 /* Connection got invalidated @@ -899,12 +899,12 @@ struct be_all_if_id { * pdu hdr */ #define CXN_KILLED_STALE_ITT_TTT_RCVD 8 /* Connection got invalidated - * internally due to a recieved + * internally due to a received * ITT/TTT that does not belong * to this Connection */ #define CXN_KILLED_INVALID_ITT_TTT_RCVD 9 /* Connection got invalidated - * internally due to recieved + * internally due to received * ITT/TTT value > Max * Supported ITTs/TTTs */ @@ -936,21 +936,21 @@ struct be_all_if_id { * index. */ #define CXN_KILLED_OVER_RUN_RESIDUAL 16 /* Command got invalidated - * internally due to recived + * internally due to received * command has residual * over run bytes. */ #define CXN_KILLED_UNDER_RUN_RESIDUAL 17 /* Command got invalidated - * internally due to recived + * internally due to received * command has residual under * run bytes. */ #define CMD_KILLED_INVALID_STATSN_RCVD 18 /* Command got invalidated - * internally due to a recieved + * internally due to a received * PDU has an invalid StatusSN */ #define CMD_KILLED_INVALID_R2T_RCVD 19 /* Command got invalidated - * internally due to a recieved + * internally due to a received * an R2T with some invalid * fields in it */ @@ -973,7 +973,7 @@ struct be_all_if_id { */ #define CMD_CXN_KILLED_INVALID_DATASN_RCVD 24 /* Command got invalidated * internally due to a - * recieved PDU has an invalid + * received PDU has an invalid * DataSN */ #define CXN_INVALIDATE_NOTIFY 25 /* Connection invalidation diff --git a/drivers/scsi/bfa/bfa_core.c b/drivers/scsi/bfa/bfa_core.c index 1cd5c8b0618d..91838c51fb76 100644 --- a/drivers/scsi/bfa/bfa_core.c +++ b/drivers/scsi/bfa/bfa_core.c @@ -355,7 +355,7 @@ bfa_msix_lpu_err(struct bfa_s *bfa, int vec) /* * ERR_PSS bit needs to be cleared as well in case * interrups are shared so driver's interrupt handler is - * still called eventhough it is already masked out. + * still called even though it is already masked out. */ curr_value = readl( bfa->ioc.ioc_regs.pss_err_status_reg); diff --git a/drivers/scsi/bfa/bfa_defs_svc.h b/drivers/scsi/bfa/bfa_defs_svc.h index 648c84176722..207f598877c7 100644 --- a/drivers/scsi/bfa/bfa_defs_svc.h +++ b/drivers/scsi/bfa/bfa_defs_svc.h @@ -145,7 +145,7 @@ struct bfa_fw_io_stats_s { u32 ioh_data_oor_event; /* Data out of range */ u32 ioh_ro_ooo_event; /* Relative offset out of range */ u32 ioh_cpu_owned_event; /* IOH hit -iost owned by f/w */ - u32 ioh_unexp_frame_event; /* unexpected frame recieved + u32 ioh_unexp_frame_event; /* unexpected frame received * count */ u32 ioh_err_int; /* IOH error int during data-phase * for scsi write @@ -566,8 +566,8 @@ struct bfa_itnim_iostats_s { u32 input_reqs; /* Data in-bound requests */ u32 output_reqs; /* Data out-bound requests */ u32 io_comps; /* Total IO Completions */ - u32 wr_throughput; /* Write data transfered in bytes */ - u32 rd_throughput; /* Read data transfered in bytes */ + u32 wr_throughput; /* Write data transferred in bytes */ + u32 rd_throughput; /* Read data transferred in bytes */ u32 iocomp_ok; /* Slowpath IO completions */ u32 iocomp_underrun; /* IO underrun */ diff --git a/drivers/scsi/bfa/bfa_fc.h b/drivers/scsi/bfa/bfa_fc.h index 8e764fae8dc9..bf0067e0fd0d 100644 --- a/drivers/scsi/bfa/bfa_fc.h +++ b/drivers/scsi/bfa/bfa_fc.h @@ -315,7 +315,7 @@ struct fc_plogi_csp_s { query_dbc:1, hg_supp:1; #endif - __be16 rxsz; /* recieve data_field size */ + __be16 rxsz; /* receive data_field size */ __be16 conseq; __be16 ro_bitmap; __be32 e_d_tov; diff --git a/drivers/scsi/bfa/bfa_fcs.c b/drivers/scsi/bfa/bfa_fcs.c index f674f9318629..9b43ca4b6778 100644 --- a/drivers/scsi/bfa/bfa_fcs.c +++ b/drivers/scsi/bfa/bfa_fcs.c @@ -1033,7 +1033,7 @@ bfa_fcs_fabric_delvport(struct bfa_fcs_fabric_s *fabric, /* - * Lookup for a vport withing a fabric given its pwwn + * Lookup for a vport within a fabric given its pwwn */ struct bfa_fcs_vport_s * bfa_fcs_fabric_vport_lookup(struct bfa_fcs_fabric_s *fabric, wwn_t pwwn) diff --git a/drivers/scsi/bfa/bfa_fcs.h b/drivers/scsi/bfa/bfa_fcs.h index 0fd63168573f..61cdce4bd913 100644 --- a/drivers/scsi/bfa/bfa_fcs.h +++ b/drivers/scsi/bfa/bfa_fcs.h @@ -705,7 +705,7 @@ enum rport_event { RPSM_EVENT_ADDRESS_CHANGE = 15, /* Rport's PID has changed */ RPSM_EVENT_ADDRESS_DISC = 16, /* Need to Discover rport's PID */ RPSM_EVENT_PRLO_RCVD = 17, /* PRLO from remote device */ - RPSM_EVENT_PLOGI_RETRY = 18, /* Retry PLOGI continously */ + RPSM_EVENT_PLOGI_RETRY = 18, /* Retry PLOGI continuously */ }; /* diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c index 43fa986bb586..1d6be8c14473 100644 --- a/drivers/scsi/bfa/bfa_fcs_lport.c +++ b/drivers/scsi/bfa/bfa_fcs_lport.c @@ -1149,7 +1149,7 @@ bfa_fcs_lport_fdmi_sm_offline(struct bfa_fcs_lport_fdmi_s *fdmi, } else { /* * For a base port, we should first register the HBA - * atribute. The HBA attribute also contains the base + * attribute. The HBA attribute also contains the base * port registration. */ bfa_sm_set_state(fdmi, diff --git a/drivers/scsi/bfa/bfa_svc.c b/drivers/scsi/bfa/bfa_svc.c index 1d34921f88bf..16d9a5f61c18 100644 --- a/drivers/scsi/bfa/bfa_svc.c +++ b/drivers/scsi/bfa/bfa_svc.c @@ -1035,7 +1035,7 @@ bfa_fcxp_free(struct bfa_fcxp_s *fcxp) * @param[in] rport BFA rport pointer. Could be left NULL for WKA rports * @param[in] vf_id virtual Fabric ID * @param[in] lp_tag lport tag - * @param[in] cts use Continous sequence + * @param[in] cts use Continuous sequence * @param[in] cos fc Class of Service * @param[in] reqlen request length, does not include FCHS length * @param[in] fchs fc Header Pointer. The header content will be copied @@ -5022,7 +5022,7 @@ bfa_uf_start(struct bfa_s *bfa) } /* - * Register handler for all unsolicted recieve frames. + * Register handler for all unsolicted receive frames. * * @param[in] bfa BFA instance * @param[in] ufrecv receive handler function diff --git a/drivers/scsi/bfa/bfa_svc.h b/drivers/scsi/bfa/bfa_svc.h index 331ad992a581..5902a45c080f 100644 --- a/drivers/scsi/bfa/bfa_svc.h +++ b/drivers/scsi/bfa/bfa_svc.h @@ -127,7 +127,7 @@ struct bfa_fcxp_req_info_s { * rport nexus is established */ struct fchs_s fchs; /* request FC header structure */ - u8 cts; /* continous sequence */ + u8 cts; /* continuous sequence */ u8 class; /* FC class for the request/response */ u16 max_frmsz; /* max send frame size */ u16 vf_id; /* vsan tag if applicable */ diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c index 44524cf55d33..0fd510a01561 100644 --- a/drivers/scsi/bfa/bfad.c +++ b/drivers/scsi/bfa/bfad.c @@ -1278,7 +1278,7 @@ bfad_setup_intr(struct bfad_s *bfad) * interrupts into one vector, so even if we * can try to request less vectors, we don't * know how to associate interrupt events to - * vectors. Linux doesn't dupicate vectors + * vectors. Linux doesn't duplicate vectors * in the MSIX table for this case. */ diff --git a/drivers/scsi/bnx2fc/57xx_hsi_bnx2fc.h b/drivers/scsi/bnx2fc/57xx_hsi_bnx2fc.h index 69d031d98469..97a61b4d81b7 100644 --- a/drivers/scsi/bnx2fc/57xx_hsi_bnx2fc.h +++ b/drivers/scsi/bnx2fc/57xx_hsi_bnx2fc.h @@ -898,7 +898,7 @@ struct fcoe_confqe { /* - * FCoE conection data base + * FCoE connection data base */ struct fcoe_conn_db { #if defined(__BIG_ENDIAN) diff --git a/drivers/scsi/bnx2fc/bnx2fc_els.c b/drivers/scsi/bnx2fc/bnx2fc_els.c index 7a11a255157f..52c358427ce2 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_els.c +++ b/drivers/scsi/bnx2fc/bnx2fc_els.c @@ -397,7 +397,7 @@ void bnx2fc_process_els_compl(struct bnx2fc_cmd *els_req, &els_req->req_flags)) { BNX2FC_ELS_DBG("Timer context finished processing this " "els - 0x%x\n", els_req->xid); - /* This IO doesnt receive cleanup completion */ + /* This IO doesn't receive cleanup completion */ kref_put(&els_req->refcount, bnx2fc_cmd_release); return; } diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c index d3fc302c241a..1decefbf32e3 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_io.c +++ b/drivers/scsi/bnx2fc/bnx2fc_io.c @@ -1273,7 +1273,7 @@ static void bnx2fc_lun_reset_cmpl(struct bnx2fc_cmd *io_req) bnx2fc_cmd_release); /* timer hold */ rc = bnx2fc_initiate_abts(cmd); - /* abts shouldnt fail in this context */ + /* abts shouldn't fail in this context */ WARN_ON(rc != SUCCESS); } else printk(KERN_ERR PFX "lun_rst: abts already in" @@ -1308,7 +1308,7 @@ static void bnx2fc_tgt_reset_cmpl(struct bnx2fc_cmd *io_req) kref_put(&io_req->refcount, bnx2fc_cmd_release); /* timer hold */ rc = bnx2fc_initiate_abts(cmd); - /* abts shouldnt fail in this context */ + /* abts shouldn't fail in this context */ WARN_ON(rc != SUCCESS); } else diff --git a/drivers/scsi/bnx2fc/bnx2fc_tgt.c b/drivers/scsi/bnx2fc/bnx2fc_tgt.c index 7cc05e4e82d5..a2e3830bd268 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_tgt.c +++ b/drivers/scsi/bnx2fc/bnx2fc_tgt.c @@ -395,7 +395,7 @@ void bnx2fc_rport_event_handler(struct fc_lport *lport, rp = rport->dd_data; if (rport->port_id == FC_FID_DIR_SERV) { /* - * bnx2fc_rport structure doesnt exist for + * bnx2fc_rport structure doesn't exist for * directory server. * We should not come here, as lport will * take care of fabric login diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c index 1da34c019b8a..f0b89513faed 100644 --- a/drivers/scsi/bnx2i/bnx2i_hwi.c +++ b/drivers/scsi/bnx2i/bnx2i_hwi.c @@ -173,7 +173,7 @@ void bnx2i_arm_cq_event_coalescing(struct bnx2i_endpoint *ep, u8 action) /** * bnx2i_get_rq_buf - copy RQ buffer contents to driver buffer - * @conn: iscsi connection on which RQ event occured + * @conn: iscsi connection on which RQ event occurred * @ptr: driver buffer to which RQ buffer contents is to * be copied * @len: length of valid data inside RQ buf diff --git a/drivers/scsi/cxgbi/libcxgbi.h b/drivers/scsi/cxgbi/libcxgbi.h index 0a20fd5f7102..9267844519c9 100644 --- a/drivers/scsi/cxgbi/libcxgbi.h +++ b/drivers/scsi/cxgbi/libcxgbi.h @@ -262,9 +262,9 @@ struct cxgbi_skb_tx_cb { enum cxgbi_skcb_flags { SKCBF_TX_NEED_HDR, /* packet needs a header */ SKCBF_RX_COALESCED, /* received whole pdu */ - SKCBF_RX_HDR, /* recieved pdu header */ - SKCBF_RX_DATA, /* recieved pdu payload */ - SKCBF_RX_STATUS, /* recieved ddp status */ + SKCBF_RX_HDR, /* received pdu header */ + SKCBF_RX_DATA, /* received pdu payload */ + SKCBF_RX_STATUS, /* received ddp status */ SKCBF_RX_DATA_DDPD, /* pdu payload ddp'd */ SKCBF_RX_HCRC_ERR, /* header digest error */ SKCBF_RX_DCRC_ERR, /* data digest error */ diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c index b0f8523e665f..b10b3841535c 100644 --- a/drivers/scsi/dc395x.c +++ b/drivers/scsi/dc395x.c @@ -235,7 +235,7 @@ struct ScsiReqBlk { u8 sg_count; /* No of HW sg entries for this request */ u8 sg_index; /* Index of HW sg entry for this request */ - size_t total_xfer_length; /* Total number of bytes remaining to be transfered */ + size_t total_xfer_length; /* Total number of bytes remaining to be transferred */ size_t request_length; /* Total number of bytes in this request */ /* * The sense buffer handling function, request_sense, uses @@ -1774,7 +1774,7 @@ static void dc395x_handle_interrupt(struct AdapterCtlBlk *acb, dc395x_statev(acb, srb, &scsi_status); /* - * if there were any exception occured scsi_status + * if there were any exception occurred scsi_status * will be modify to bus free phase new scsi_status * transfer out from ... previous dc395x_statev */ @@ -1954,11 +1954,11 @@ static void sg_verify_length(struct ScsiReqBlk *srb) static void sg_update_list(struct ScsiReqBlk *srb, u32 left) { u8 idx; - u32 xferred = srb->total_xfer_length - left; /* bytes transfered */ + u32 xferred = srb->total_xfer_length - left; /* bytes transferred */ struct SGentry *psge = srb->segment_x + srb->sg_index; dprintkdbg(DBG_0, - "sg_update_list: Transfered %i of %i bytes, %i remain\n", + "sg_update_list: Transferred %i of %i bytes, %i remain\n", xferred, srb->total_xfer_length, left); if (xferred == 0) { /* nothing to update since we did not transfer any data */ @@ -1990,7 +1990,7 @@ static void sg_update_list(struct ScsiReqBlk *srb, u32 left) /* - * We have transfered a single byte (PIO mode?) and need to update + * We have transferred a single byte (PIO mode?) and need to update * the count of bytes remaining (total_xfer_length) and update the sg * entry to either point to next byte in the current sg entry, or of * already at the end to point to the start of the next sg entry @@ -2029,7 +2029,7 @@ static void cleanup_after_transfer(struct AdapterCtlBlk *acb, /* - * Those no of bytes will be transfered w/ PIO through the SCSI FIFO + * Those no of bytes will be transferred w/ PIO through the SCSI FIFO * Seems to be needed for unknown reasons; could be a hardware bug :-( */ #define DC395x_LASTPIO 4 @@ -2256,7 +2256,7 @@ static void data_in_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, DC395x_read32(acb, TRM_S1040_DMA_CXCNT), srb->total_xfer_length, d_left_counter); #if DC395x_LASTPIO - /* KG: Less than or equal to 4 bytes can not be transfered via DMA, it seems. */ + /* KG: Less than or equal to 4 bytes can not be transferred via DMA, it seems. */ if (d_left_counter && srb->total_xfer_length <= DC395x_LASTPIO) { size_t left_io = srb->total_xfer_length; diff --git a/drivers/scsi/dc395x.h b/drivers/scsi/dc395x.h index b38360e5fe4f..fbf35e37701e 100644 --- a/drivers/scsi/dc395x.h +++ b/drivers/scsi/dc395x.h @@ -617,7 +617,7 @@ struct ScsiInqData #define NTC_DO_SEND_START 0x08 /* Send start command SPINUP */ #define NTC_DO_DISCONNECT 0x04 /* Enable SCSI disconnect */ #define NTC_DO_SYNC_NEGO 0x02 /* Sync negotiation */ -#define NTC_DO_PARITY_CHK 0x01 /* (it sould define at NAC) */ +#define NTC_DO_PARITY_CHK 0x01 /* (it should define at NAC) */ /* Parity check enable */ /************************************************************************/ diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index 7cae0bc85390..42fe52902add 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -541,7 +541,7 @@ static int alua_check_sense(struct scsi_device *sdev, * * Evaluate the Target Port Group State. * Returns SCSI_DH_DEV_OFFLINED if the path is - * found to be unuseable. + * found to be unusable. */ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h) { @@ -620,7 +620,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h) break; case TPGS_STATE_OFFLINE: case TPGS_STATE_UNAVAILABLE: - /* Path unuseable for unavailable/offline */ + /* Path unusable for unavailable/offline */ err = SCSI_DH_DEV_OFFLINED; break; default: diff --git a/drivers/scsi/dpt/sys_info.h b/drivers/scsi/dpt/sys_info.h index a90c4cb8ea8b..a4aa1c31ff72 100644 --- a/drivers/scsi/dpt/sys_info.h +++ b/drivers/scsi/dpt/sys_info.h @@ -79,9 +79,9 @@ typedef struct { #endif - uSHORT cylinders; /* Upto 1024 */ - uCHAR heads; /* Upto 255 */ - uCHAR sectors; /* Upto 63 */ + uSHORT cylinders; /* Up to 1024 */ + uCHAR heads; /* Up to 255 */ + uCHAR sectors; /* Up to 63 */ #ifdef __cplusplus diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c index 53925ac178fd..0eb4fe6a4c8a 100644 --- a/drivers/scsi/eata.c +++ b/drivers/scsi/eata.c @@ -63,7 +63,7 @@ * ep:[y|n] eisa_probe=[1|0] CONFIG_EISA defined * pp:[y|n] pci_probe=[1|0] CONFIG_PCI defined * - * The default action is to perform probing if the corrisponding + * The default action is to perform probing if the corresponding * bus is configured and to skip probing otherwise. * * + If pci_probe is in effect and a list of I/O ports is specified diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c index c93f007e702f..9d38be2a41f9 100644 --- a/drivers/scsi/fcoe/fcoe_ctlr.c +++ b/drivers/scsi/fcoe/fcoe_ctlr.c @@ -656,7 +656,7 @@ int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct fc_lport *lport, * If non-FIP, we may have gotten an SID by accepting an FLOGI * from a point-to-point connection. Switch to using * the source mac based on the SID. The destination - * MAC in this case would have been set by receving the + * MAC in this case would have been set by receiving the * FLOGI. */ if (fip->state == FIP_ST_NON_FIP) { @@ -1876,7 +1876,7 @@ static void fcoe_ctlr_vn_send(struct fcoe_ctlr *fip, * fcoe_ctlr_vn_rport_callback - Event handler for rport events. * @lport: The lport which is receiving the event * @rdata: remote port private data - * @event: The event that occured + * @event: The event that occurred * * Locking Note: The rport lock must not be held when calling this function. */ diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c index 69b7aa54f43f..643f6d500fe7 100644 --- a/drivers/scsi/fdomain.c +++ b/drivers/scsi/fdomain.c @@ -174,7 +174,7 @@ Future Domain sold DOS BIOS source for $250 and the UN*X driver source was $750, but these required a non-disclosure agreement, so even if I could have afforded them, they would *not* have been useful for writing this - publically distributable driver. Future Domain technical support has + publicly distributable driver. Future Domain technical support has provided some information on the phone and have sent a few useful FAXs. They have been much more helpful since they started to recognize that the word "Linux" refers to an operating system :-). diff --git a/drivers/scsi/fnic/fnic_fcs.c b/drivers/scsi/fnic/fnic_fcs.c index 2b48d79bad94..3c53c3478ee7 100644 --- a/drivers/scsi/fnic/fnic_fcs.c +++ b/drivers/scsi/fnic/fnic_fcs.c @@ -411,7 +411,7 @@ int fnic_rq_cmpl_handler(struct fnic *fnic, int rq_work_to_do) err = vnic_rq_fill(&fnic->rq[i], fnic_alloc_rq_frame); if (err) shost_printk(KERN_ERR, fnic->lport->host, - "fnic_alloc_rq_frame cant alloc" + "fnic_alloc_rq_frame can't alloc" " frame\n"); } tot_rq_work_done += cur_work_done; diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index 22d02404d15f..538b31c2cf58 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -1123,7 +1123,7 @@ void fnic_rport_exch_reset(struct fnic *fnic, u32 port_id) fc_lun.scsi_lun, io_req)) { /* * Revert the cmd state back to old state, if - * it hasnt changed in between. This cmd will get + * it hasn't changed in between. This cmd will get * aborted later by scsi_eh, or cleaned up during * lun reset */ @@ -1208,7 +1208,7 @@ void fnic_terminate_rport_io(struct fc_rport *rport) fc_lun.scsi_lun, io_req)) { /* * Revert the cmd state back to old state, if - * it hasnt changed in between. This cmd will get + * it hasn't changed in between. This cmd will get * aborted later by scsi_eh, or cleaned up during * lun reset */ diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c index 427a56d3117e..81182badfeb1 100644 --- a/drivers/scsi/g_NCR5380.c +++ b/drivers/scsi/g_NCR5380.c @@ -566,7 +566,7 @@ generic_NCR5380_biosparam(struct scsi_device *sdev, struct block_device *bdev, * @dst: buffer to read into * @len: buffer length * - * Perform a psuedo DMA mode read from an NCR53C400 or equivalent + * Perform a pseudo DMA mode read from an NCR53C400 or equivalent * controller */ @@ -650,7 +650,7 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, * @dst: buffer to read into * @len: buffer length * - * Perform a psuedo DMA mode read from an NCR53C400 or equivalent + * Perform a pseudo DMA mode read from an NCR53C400 or equivalent * controller */ diff --git a/drivers/scsi/gdth.h b/drivers/scsi/gdth.h index 120a0625a7b5..d969855ac64a 100644 --- a/drivers/scsi/gdth.h +++ b/drivers/scsi/gdth.h @@ -895,7 +895,7 @@ typedef struct { u8 ldr_no; /* log. drive no. */ u8 rw_attribs; /* r/w attributes */ u8 cluster_type; /* cluster properties */ - u8 media_changed; /* Flag:MOUNT/UNMOUNT occured */ + u8 media_changed; /* Flag:MOUNT/UNMOUNT occurred */ u32 start_sec; /* start sector */ } hdr[MAX_LDRIVES]; /* host drives */ struct { diff --git a/drivers/scsi/gvp11.c b/drivers/scsi/gvp11.c index 2ce26eb7a1ec..50bb54150a78 100644 --- a/drivers/scsi/gvp11.c +++ b/drivers/scsi/gvp11.c @@ -300,7 +300,7 @@ static int __devinit gvp11_probe(struct zorro_dev *z, /* * Rumors state that some GVP ram boards use the same product * code as the SCSI controllers. Therefore if the board-size - * is not 64KB we asume it is a ram board and bail out. + * is not 64KB we assume it is a ram board and bail out. */ if (zorro_resource_len(z) != 0x10000) return -ENODEV; diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c index 99aa0e5699bc..26cd9d1d7571 100644 --- a/drivers/scsi/imm.c +++ b/drivers/scsi/imm.c @@ -3,7 +3,7 @@ * * (The IMM is the embedded controller in the ZIP Plus drive.) * - * My unoffical company acronym list is 21 pages long: + * My unofficial company acronym list is 21 pages long: * FLA: Four letter acronym with built in facility for * future expansion to five letters. */ diff --git a/drivers/scsi/initio.c b/drivers/scsi/initio.c index 9627d062e16b..dd741bcd6ccd 100644 --- a/drivers/scsi/initio.c +++ b/drivers/scsi/initio.c @@ -242,7 +242,7 @@ static u8 i91udftNvRam[64] = static u8 initio_rate_tbl[8] = /* fast 20 */ { - /* nanosecond devide by 4 */ + /* nanosecond divide by 4 */ 12, /* 50ns, 20M */ 18, /* 75ns, 13.3M */ 25, /* 100ns, 10M */ @@ -1917,7 +1917,7 @@ static int int_initio_scsi_rst(struct initio_host * host) } /** - * int_initio_scsi_resel - Reselection occured + * int_initio_scsi_resel - Reselection occurred * @host: InitIO host adapter * * A SCSI reselection event has been signalled and the interrupt diff --git a/drivers/scsi/initio.h b/drivers/scsi/initio.h index e58af9e95506..219b901bdc25 100644 --- a/drivers/scsi/initio.h +++ b/drivers/scsi/initio.h @@ -116,7 +116,7 @@ typedef struct { #define TUL_SBusId 0x89 /* 09 R SCSI BUS ID */ #define TUL_STimeOut 0x8A /* 0A W Sel/Resel Time Out Register */ #define TUL_SIdent 0x8A /* 0A R Identify Message Register */ -#define TUL_SAvail 0x8A /* 0A R Availiable Counter Register */ +#define TUL_SAvail 0x8A /* 0A R Available Counter Register */ #define TUL_SData 0x8B /* 0B R/W SCSI data in/out */ #define TUL_SFifo 0x8C /* 0C R/W FIFO */ #define TUL_SSignal 0x90 /* 10 R/W SCSI signal in/out */ @@ -389,7 +389,7 @@ struct scsi_ctrl_blk { /* Bit Definition for status */ #define SCB_RENT 0x01 #define SCB_PEND 0x02 -#define SCB_CONTIG 0x04 /* Contigent Allegiance */ +#define SCB_CONTIG 0x04 /* Contingent Allegiance */ #define SCB_SELECT 0x08 #define SCB_BUSY 0x10 #define SCB_DONE 0x20 diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c index b2511acd39bd..218f71a8726e 100644 --- a/drivers/scsi/ips.c +++ b/drivers/scsi/ips.c @@ -137,7 +137,7 @@ /* - Fix path/name for scsi_hosts.h include for 2.6 kernels */ /* - Fix sort order of 7k */ /* - Remove 3 unused "inline" functions */ -/* 7.12.xx - Use STATIC functions whereever possible */ +/* 7.12.xx - Use STATIC functions wherever possible */ /* - Clean up deprecated MODULE_PARM calls */ /* 7.12.05 - Remove Version Matching per IBM request */ /*****************************************************************************/ @@ -1665,7 +1665,7 @@ ips_flash_copperhead(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb) int datasize; /* Trombone is the only copperhead that can do packet flash, but only - * for firmware. No one said it had to make sence. */ + * for firmware. No one said it had to make sense. */ if (IPS_IS_TROMBONE(ha) && pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE) { if (ips_usrcmd(ha, pt, scb)) return IPS_SUCCESS; diff --git a/drivers/scsi/ips.h b/drivers/scsi/ips.h index 4e49fbcfe8af..f2df0593332b 100644 --- a/drivers/scsi/ips.h +++ b/drivers/scsi/ips.h @@ -1193,7 +1193,7 @@ typedef struct { #define IPS_VER_SEBRING "7.12.02" #define IPS_VER_KEYWEST "7.12.02" -/* Compatability IDs for various adapters */ +/* Compatibility IDs for various adapters */ #define IPS_COMPAT_UNKNOWN "" #define IPS_COMPAT_CURRENT "KW710" #define IPS_COMPAT_SERVERAID1 "2.25.01" diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index a860452a8f71..3df985305f69 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -295,7 +295,7 @@ static int iscsi_sw_tcp_xmit(struct iscsi_conn *conn) rc = iscsi_sw_tcp_xmit_segment(tcp_conn, segment); /* * We may not have been able to send data because the conn - * is getting stopped. libiscsi will know so propogate err + * is getting stopped. libiscsi will know so propagate err * for it to do the right thing. */ if (rc == -EAGAIN) diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c index 28231badd9e6..77035a746f60 100644 --- a/drivers/scsi/libfc/fc_exch.c +++ b/drivers/scsi/libfc/fc_exch.c @@ -1042,7 +1042,7 @@ static void fc_exch_set_addr(struct fc_exch *ep, } /** - * fc_seq_els_rsp_send() - Send an ELS response using infomation from + * fc_seq_els_rsp_send() - Send an ELS response using information from * the existing sequence/exchange. * @fp: The received frame * @els_cmd: The ELS command to be sent @@ -1153,7 +1153,7 @@ static void fc_seq_send_ack(struct fc_seq *sp, const struct fc_frame *rx_fp) * fc_exch_send_ba_rjt() - Send BLS Reject * @rx_fp: The frame being rejected * @reason: The reason the frame is being rejected - * @explan: The explaination for the rejection + * @explan: The explanation for the rejection * * This is for rejecting BA_ABTS only. */ diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c index b1b03af158bf..5b799a37ad09 100644 --- a/drivers/scsi/libfc/fc_fcp.c +++ b/drivers/scsi/libfc/fc_fcp.c @@ -870,7 +870,7 @@ static void fc_fcp_resp(struct fc_fcp_pkt *fsp, struct fc_frame *fp) fsp->scsi_resid = ntohl(rp_ex->fr_resid); /* * The cmnd->underflow is the minimum number of - * bytes that must be transfered for this + * bytes that must be transferred for this * command. Provided a sense condition is not * present, make sure the actual amount * transferred is at least the underflow value @@ -1306,7 +1306,7 @@ static int fc_lun_reset(struct fc_lport *lport, struct fc_fcp_pkt *fsp, } /** - * fc_tm_done() - Task Managment response handler + * fc_tm_done() - Task Management response handler * @seq: The sequence that the response is on * @fp: The response frame * @arg: The FCP packet the response is for diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c index 8c08b210001d..906bbcad0e2d 100644 --- a/drivers/scsi/libfc/fc_lport.c +++ b/drivers/scsi/libfc/fc_lport.c @@ -52,7 +52,7 @@ * while making the callback. To ensure that the rport is not free'd while * processing the callback the rport callbacks are serialized through a * single-threaded workqueue. An rport would never be free'd while in a - * callback handler becuase no other rport work in this queue can be executed + * callback handler because no other rport work in this queue can be executed * at the same time. * * When discovery succeeds or fails a callback is made to the lport as @@ -163,7 +163,7 @@ static int fc_frame_drop(struct fc_lport *lport, struct fc_frame *fp) * fc_lport_rport_callback() - Event handler for rport events * @lport: The lport which is receiving the event * @rdata: private remote port data - * @event: The event that occured + * @event: The event that occurred * * Locking Note: The rport lock should not be held when calling * this function. @@ -379,7 +379,7 @@ static void fc_lport_add_fc4_type(struct fc_lport *lport, enum fc_fh_type type) /** * fc_lport_recv_rlir_req() - Handle received Registered Link Incident Report. - * @lport: Fibre Channel local port recieving the RLIR + * @lport: Fibre Channel local port receiving the RLIR * @fp: The RLIR request frame * * Locking Note: The lport lock is expected to be held before calling @@ -396,7 +396,7 @@ static void fc_lport_recv_rlir_req(struct fc_lport *lport, struct fc_frame *fp) /** * fc_lport_recv_echo_req() - Handle received ECHO request - * @lport: The local port recieving the ECHO + * @lport: The local port receiving the ECHO * @fp: ECHO request frame * * Locking Note: The lport lock is expected to be held before calling @@ -432,7 +432,7 @@ static void fc_lport_recv_echo_req(struct fc_lport *lport, /** * fc_lport_recv_rnid_req() - Handle received Request Node ID data request - * @lport: The local port recieving the RNID + * @lport: The local port receiving the RNID * @fp: The RNID request frame * * Locking Note: The lport lock is expected to be held before calling @@ -491,7 +491,7 @@ static void fc_lport_recv_rnid_req(struct fc_lport *lport, /** * fc_lport_recv_logo_req() - Handle received fabric LOGO request - * @lport: The local port recieving the LOGO + * @lport: The local port receiving the LOGO * @fp: The LOGO request frame * * Locking Note: The lport lock is exected to be held before calling @@ -771,7 +771,7 @@ EXPORT_SYMBOL(fc_lport_set_local_id); /** * fc_lport_recv_flogi_req() - Receive a FLOGI request - * @lport: The local port that recieved the request + * @lport: The local port that received the request * @rx_fp: The FLOGI frame * * A received FLOGI request indicates a point-to-point connection. @@ -858,7 +858,7 @@ out: * if an rport should handle the request. * * Locking Note: This function should not be called with the lport - * lock held becuase it will grab the lock. + * lock held because it will grab the lock. */ static void fc_lport_recv_els_req(struct fc_lport *lport, struct fc_frame *fp) @@ -925,7 +925,7 @@ struct fc4_prov fc_lport_els_prov = { * @fp: The frame the request is in * * Locking Note: This function should not be called with the lport - * lock held becuase it may grab the lock. + * lock held because it may grab the lock. */ static void fc_lport_recv_req(struct fc_lport *lport, struct fc_frame *fp) diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index f3f693b772ac..874e29d9533f 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -240,7 +240,7 @@ static int sas_ex_phy_discover_helper(struct domain_device *dev, u8 *disc_req, disc_resp, DISCOVER_RESP_SIZE); if (res) return res; - /* This is detecting a failure to transmit inital + /* This is detecting a failure to transmit initial * dev to host FIS as described in section G.5 of * sas-2 r 04b */ dr = &((struct smp_resp *)disc_resp)->disc; diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 4e0faa00b96f..17d789325f40 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -4515,7 +4515,7 @@ static FC_RPORT_ATTR(field, S_IRUGO, lpfc_show_rport_##field, NULL) * Description: * This function is called by the transport after the @fc_vport's symbolic name * has been changed. This function re-registers the symbolic name with the - * switch to propogate the change into the fabric if the vport is active. + * switch to propagate the change into the fabric if the vport is active. **/ static void lpfc_set_vport_symbolic_name(struct fc_vport *fc_vport) diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c index 793b9f1131fb..77b2871d96b7 100644 --- a/drivers/scsi/lpfc/lpfc_bsg.c +++ b/drivers/scsi/lpfc/lpfc_bsg.c @@ -1939,7 +1939,7 @@ out: * @rxxri: Receive exchange id * @len: Number of data bytes * - * This function allocates and posts a data buffer of sufficient size to recieve + * This function allocates and posts a data buffer of sufficient size to receive * an unsolicted CT command. **/ static int lpfcdiag_loop_post_rxbufs(struct lpfc_hba *phba, uint16_t rxxri, diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index a753581509d6..3d967741c708 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c @@ -908,7 +908,7 @@ lpfc_debugfs_dumpData_open(struct inode *inode, struct file *file) if (!debug) goto out; - /* Round to page boundry */ + /* Round to page boundary */ printk(KERN_ERR "9059 BLKGRD: %s: _dump_buf_data=0x%p\n", __func__, _dump_buf_data); debug->buffer = _dump_buf_data; @@ -938,7 +938,7 @@ lpfc_debugfs_dumpDif_open(struct inode *inode, struct file *file) if (!debug) goto out; - /* Round to page boundry */ + /* Round to page boundary */ printk(KERN_ERR "9060 BLKGRD: %s: _dump_buf_dif=0x%p file=%s\n", __func__, _dump_buf_dif, file->f_dentry->d_name.name); debug->buffer = _dump_buf_dif; @@ -2158,7 +2158,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) debugfs_create_dir(name, phba->hba_debugfs_root); if (!vport->vport_debugfs_root) { lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, - "0417 Cant create debugfs\n"); + "0417 Can't create debugfs\n"); goto debug_failed; } atomic_inc(&phba->debugfs_vport_count); @@ -2211,7 +2211,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) vport, &lpfc_debugfs_op_nodelist); if (!vport->debug_nodelist) { lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, - "0409 Cant create debugfs nodelist\n"); + "0409 Can't create debugfs nodelist\n"); goto debug_failed; } diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 735028fedda5..d34b69f9cdb1 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -102,7 +102,7 @@ lpfc_els_chk_latt(struct lpfc_vport *vport) phba->pport->port_state); /* CLEAR_LA should re-enable link attention events and - * we should then imediately take a LATT event. The + * we should then immediately take a LATT event. The * LATT processing should call lpfc_linkdown() which * will cleanup any left over in-progress discovery * events. @@ -1599,7 +1599,7 @@ out: * This routine is the completion callback function for issuing the Port * Login (PLOGI) command. For PLOGI completion, there must be an active * ndlp on the vport node list that matches the remote node ID from the - * PLOGI reponse IOCB. If such ndlp does not exist, the PLOGI is simply + * PLOGI response IOCB. If such ndlp does not exist, the PLOGI is simply * ignored and command IOCB released. The PLOGI response IOCB status is * checked for error conditons. If there is error status reported, PLOGI * retry shall be attempted by invoking the lpfc_els_retry() routine. diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 154c715fb3af..301498301a8f 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -739,7 +739,7 @@ lpfc_do_work(void *p) /* * This is only called to handle FC worker events. Since this a rare - * occurance, we allocate a struct lpfc_work_evt structure here instead of + * occurrence, we allocate a struct lpfc_work_evt structure here instead of * embedding it in the IOCB. */ int @@ -1348,7 +1348,7 @@ lpfc_register_fcf(struct lpfc_hba *phba) int rc; spin_lock_irq(&phba->hbalock); - /* If the FCF is not availabe do nothing. */ + /* If the FCF is not available do nothing. */ if (!(phba->fcf.fcf_flag & FCF_AVAILABLE)) { phba->hba_flag &= ~(FCF_TS_INPROG | FCF_RR_INPROG); spin_unlock_irq(&phba->hbalock); @@ -1538,7 +1538,7 @@ lpfc_match_fcf_conn_list(struct lpfc_hba *phba, /* * If user did not specify any addressing mode, or if the - * prefered addressing mode specified by user is not supported + * preferred addressing mode specified by user is not supported * by FCF, allow fabric to pick the addressing mode. */ *addr_mode = bf_get(lpfc_fcf_record_mac_addr_prov, @@ -1553,7 +1553,7 @@ lpfc_match_fcf_conn_list(struct lpfc_hba *phba, FCFCNCT_AM_SPMA) ? LPFC_FCF_SPMA : LPFC_FCF_FPMA; /* - * If the user specified a prefered address mode, use the + * If the user specified a preferred address mode, use the * addr mode only if FCF support the addr_mode. */ else if ((conn_entry->conn_rec.flags & FCFCNCT_AM_VALID) && @@ -3117,7 +3117,7 @@ lpfc_mbx_cmpl_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) * back at reg login state so this * mbox needs to be ignored becase * there is another reg login in - * proccess. + * process. */ spin_lock_irq(shost->host_lock); ndlp->nlp_flag &= ~NLP_IGNR_REG_CMPL; @@ -4477,7 +4477,7 @@ lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did) if ((vport->fc_flag & FC_RSCN_MODE) && !(vport->fc_flag & FC_NDISC_ACTIVE)) { if (lpfc_rscn_payload_check(vport, did)) { - /* If we've already recieved a PLOGI from this NPort + /* If we've already received a PLOGI from this NPort * we don't need to try to discover it again. */ if (ndlp->nlp_flag & NLP_RCV_PLOGI) @@ -4493,7 +4493,7 @@ lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did) } else ndlp = NULL; } else { - /* If we've already recieved a PLOGI from this NPort, + /* If we've already received a PLOGI from this NPort, * or we are already in the process of discovery on it, * we don't need to try to discover it again. */ @@ -5756,7 +5756,7 @@ lpfc_read_fcoe_param(struct lpfc_hba *phba, * @size: Size of the data buffer. * @rec_type: Record type to be searched. * - * This function searches config region data to find the begining + * This function searches config region data to find the beginning * of the record specified by record_type. If record found, this * function return pointer to the record else return NULL. */ diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index e6ebe516cfbb..505f88443b5c 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -4466,7 +4466,7 @@ lpfc_sli4_driver_resource_unset(struct lpfc_hba *phba) } /** - * lpfc_init_api_table_setup - Set up init api fucntion jump table + * lpfc_init_api_table_setup - Set up init api function jump table * @phba: The hba struct for which this call is being executed. * @dev_grp: The HBA PCI-Device group number. * @@ -4850,7 +4850,7 @@ out_free_mem: * * Return codes * 0 - successful - * -ENOMEM - No availble memory + * -ENOMEM - No available memory * -EIO - The mailbox failed to complete successfully. **/ int @@ -5730,7 +5730,7 @@ lpfc_destroy_bootstrap_mbox(struct lpfc_hba *phba) * * Return codes * 0 - successful - * -ENOMEM - No availble memory + * -ENOMEM - No available memory * -EIO - The mailbox failed to complete successfully. **/ static int @@ -5835,7 +5835,7 @@ lpfc_sli4_read_config(struct lpfc_hba *phba) * * Return codes * 0 - successful - * -ENOMEM - No availble memory + * -ENOMEM - No available memory * -EIO - The mailbox failed to complete successfully. **/ static int @@ -5894,7 +5894,7 @@ lpfc_setup_endian_order(struct lpfc_hba *phba) * * Return codes * 0 - successful - * -ENOMEM - No availble memory + * -ENOMEM - No available memory * -EIO - The mailbox failed to complete successfully. **/ static int @@ -6189,7 +6189,7 @@ out_error: * * Return codes * 0 - successful - * -ENOMEM - No availble memory + * -ENOMEM - No available memory * -EIO - The mailbox failed to complete successfully. **/ static void @@ -6253,7 +6253,7 @@ lpfc_sli4_queue_destroy(struct lpfc_hba *phba) * * Return codes * 0 - successful - * -ENOMEM - No availble memory + * -ENOMEM - No available memory * -EIO - The mailbox failed to complete successfully. **/ int @@ -6498,7 +6498,7 @@ out_error: * * Return codes * 0 - successful - * -ENOMEM - No availble memory + * -ENOMEM - No available memory * -EIO - The mailbox failed to complete successfully. **/ void @@ -6543,7 +6543,7 @@ lpfc_sli4_queue_unset(struct lpfc_hba *phba) * * Return codes * 0 - successful - * -ENOMEM - No availble memory + * -ENOMEM - No available memory **/ static int lpfc_sli4_cq_event_pool_create(struct lpfc_hba *phba) @@ -6704,7 +6704,7 @@ lpfc_sli4_cq_event_release_all(struct lpfc_hba *phba) * * Return codes * 0 - successful - * -ENOMEM - No availble memory + * -ENOMEM - No available memory * -EIO - The mailbox failed to complete successfully. **/ int diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c index dba32dfdb59b..fbab9734e9b4 100644 --- a/drivers/scsi/lpfc/lpfc_mbox.c +++ b/drivers/scsi/lpfc/lpfc_mbox.c @@ -1834,7 +1834,7 @@ lpfc_sli4_mbox_opcode_get(struct lpfc_hba *phba, struct lpfcMboxq *mbox) * @fcf_index: index to fcf table. * * This routine routine allocates and constructs non-embedded mailbox command - * for reading a FCF table entry refered by @fcf_index. + * for reading a FCF table entry referred by @fcf_index. * * Return: pointer to the mailbox command constructed if successful, otherwise * NULL. diff --git a/drivers/scsi/lpfc/lpfc_nl.h b/drivers/scsi/lpfc/lpfc_nl.h index f3cfbe2ce986..f2b1bbcb196f 100644 --- a/drivers/scsi/lpfc/lpfc_nl.h +++ b/drivers/scsi/lpfc/lpfc_nl.h @@ -50,7 +50,7 @@ * and subcategory. The event type must come first. * The subcategory further defines the data that follows in the rest * of the payload. Each category will have its own unique header plus - * any addtional data unique to the subcategory. + * any additional data unique to the subcategory. * The payload sent via the fc transport is one-way driver->application. */ diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index 52b35159fc35..0d92d4205ea6 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -658,7 +658,7 @@ lpfc_disc_set_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) return 0; } /** - * lpfc_release_rpi - Release a RPI by issueing unreg_login mailbox cmd. + * lpfc_release_rpi - Release a RPI by issuing unreg_login mailbox cmd. * @phba : Pointer to lpfc_hba structure. * @vport: Pointer to lpfc_vport structure. * @rpi : rpi to be release. diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 2b962b020cfb..fe7cc84e773b 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -577,7 +577,7 @@ lpfc_new_scsi_buf_s3(struct lpfc_vport *vport, int num_to_alloc) iocb->un.fcpi64.bdl.addrHigh = 0; iocb->ulpBdeCount = 0; iocb->ulpLe = 0; - /* fill in responce BDE */ + /* fill in response BDE */ iocb->unsli3.fcp_ext.rbde.tus.f.bdeFlags = BUFF_TYPE_BDE_64; iocb->unsli3.fcp_ext.rbde.tus.f.bdeSize = @@ -1217,10 +1217,10 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) (2 * sizeof(struct ulp_bde64))); data_bde->addrHigh = putPaddrHigh(physaddr); data_bde->addrLow = putPaddrLow(physaddr); - /* ebde count includes the responce bde and data bpl */ + /* ebde count includes the response bde and data bpl */ iocb_cmd->unsli3.fcp_ext.ebde_count = 2; } else { - /* ebde count includes the responce bde and data bdes */ + /* ebde count includes the response bde and data bdes */ iocb_cmd->unsli3.fcp_ext.ebde_count = (num_bde + 1); } } else { @@ -2380,7 +2380,7 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, } /* * The cmnd->underflow is the minimum number of bytes that must - * be transfered for this command. Provided a sense condition + * be transferred for this command. Provided a sense condition * is not present, make sure the actual amount transferred is at * least the underflow value or fail. */ @@ -2873,7 +2873,7 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_vport *vport, } /** - * lpfc_scsi_api_table_setup - Set up scsi api fucntion jump table + * lpfc_scsi_api_table_setup - Set up scsi api function jump table * @phba: The hba struct for which this call is being executed. * @dev_grp: The HBA PCI-Device group number. * diff --git a/drivers/scsi/lpfc/lpfc_scsi.h b/drivers/scsi/lpfc/lpfc_scsi.h index 5932273870a5..ce645b20a6ad 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.h +++ b/drivers/scsi/lpfc/lpfc_scsi.h @@ -130,7 +130,7 @@ struct lpfc_scsi_buf { dma_addr_t nonsg_phys; /* Non scatter-gather physical address. */ /* - * data and dma_handle are the kernel virutal and bus address of the + * data and dma_handle are the kernel virtual and bus address of the * dma-able buffer containing the fcp_cmd, fcp_rsp and a scatter * gather bde list that supports the sg_tablesize value. */ diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 4746dcd756dd..dacabbe0a586 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -2817,7 +2817,7 @@ void lpfc_poll_eratt(unsigned long ptr) * This function is called from the interrupt context when there is a ring * event for the fcp ring. The caller does not hold any lock. * The function processes each response iocb in the response ring until it - * finds an iocb with LE bit set and chains all the iocbs upto the iocb with + * finds an iocb with LE bit set and chains all the iocbs up to the iocb with * LE bit set. The function will call the completion handler of the command iocb * if the response iocb indicates a completion for a command iocb or it is * an abort completion. The function will call lpfc_sli_process_unsol_iocb @@ -5117,7 +5117,7 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba) /* Setting state unknown so lpfc_sli_abort_iocb_ring * would get IOCB_ERROR from lpfc_sli_issue_iocb, allowing - * it to fail all oustanding SCSI IO. + * it to fail all outstanding SCSI IO. */ spin_lock_irq(&phba->pport->work_port_lock); phba->pport->work_port_events &= ~WORKER_MBOX_TMO; @@ -6031,7 +6031,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) } /** - * lpfc_mbox_api_table_setup - Set up mbox api fucntion jump table + * lpfc_mbox_api_table_setup - Set up mbox api function jump table * @phba: The hba struct for which this call is being executed. * @dev_grp: The HBA PCI-Device group number. * @@ -6847,7 +6847,7 @@ __lpfc_sli_issue_iocb(struct lpfc_hba *phba, uint32_t ring_number, } /** - * lpfc_sli_api_table_setup - Set up sli api fucntion jump table + * lpfc_sli_api_table_setup - Set up sli api function jump table * @phba: The hba struct for which this call is being executed. * @dev_grp: The HBA PCI-Device group number. * @@ -7521,7 +7521,7 @@ lpfc_sli_ring_taggedbuf_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, struct lpfc_dmabuf *mp, *next_mp; struct list_head *slp = &pring->postbufq; - /* Search postbufq, from the begining, looking for a match on tag */ + /* Search postbufq, from the beginning, looking for a match on tag */ spin_lock_irq(&phba->hbalock); list_for_each_entry_safe(mp, next_mp, &pring->postbufq, list) { if (mp->buffer_tag == tag) { @@ -7565,7 +7565,7 @@ lpfc_sli_ringpostbuf_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, struct lpfc_dmabuf *mp, *next_mp; struct list_head *slp = &pring->postbufq; - /* Search postbufq, from the begining, looking for a match on phys */ + /* Search postbufq, from the beginning, looking for a match on phys */ spin_lock_irq(&phba->hbalock); list_for_each_entry_safe(mp, next_mp, &pring->postbufq, list) { if (mp->phys == phys) { @@ -8438,7 +8438,7 @@ lpfc_sli_mbox_sys_shutdown(struct lpfc_hba *phba) * for possible error attention events. The caller must hold the hostlock * with spin_lock_irq(). * - * This fucntion returns 1 when there is Error Attention in the Host Attention + * This function returns 1 when there is Error Attention in the Host Attention * Register and returns 0 otherwise. **/ static int @@ -8491,7 +8491,7 @@ unplug_err: * for possible error attention events. The caller must hold the hostlock * with spin_lock_irq(). * - * This fucntion returns 1 when there is Error Attention in the Host Attention + * This function returns 1 when there is Error Attention in the Host Attention * Register and returns 0 otherwise. **/ static int @@ -8581,7 +8581,7 @@ lpfc_sli4_eratt_read(struct lpfc_hba *phba) * This function is called from timer soft interrupt context to check HBA's * error attention register bit for error attention events. * - * This fucntion returns 1 when there is Error Attention in the Host Attention + * This function returns 1 when there is Error Attention in the Host Attention * Register and returns 0 otherwise. **/ int @@ -9684,7 +9684,7 @@ out: * @cq: Pointer to the completion queue. * @wcqe: Pointer to a completion queue entry. * - * This routine process a slow-path work-queue or recieve queue completion queue + * This routine process a slow-path work-queue or receive queue completion queue * entry. * * Return: true if work posted to worker thread, otherwise false. @@ -12971,7 +12971,7 @@ lpfc_sli4_build_dflt_fcf_record(struct lpfc_hba *phba, * record and processing it one at a time starting from the @fcf_index * for initial FCF discovery or fast FCF failover rediscovery. * - * Return 0 if the mailbox command is submitted sucessfully, none 0 + * Return 0 if the mailbox command is submitted successfully, none 0 * otherwise. **/ int @@ -13032,7 +13032,7 @@ fail_fcf_scan: * This routine is invoked to read an FCF record indicated by @fcf_index * and to use it for FLOGI roundrobin FCF failover. * - * Return 0 if the mailbox command is submitted sucessfully, none 0 + * Return 0 if the mailbox command is submitted successfully, none 0 * otherwise. **/ int @@ -13078,7 +13078,7 @@ fail_fcf_read: * This routine is invoked to read an FCF record indicated by @fcf_index to * determine whether it's eligible for FLOGI roundrobin failover list. * - * Return 0 if the mailbox command is submitted sucessfully, none 0 + * Return 0 if the mailbox command is submitted successfully, none 0 * otherwise. **/ int diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index c212694a9714..f2684dd09ed0 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -284,7 +284,7 @@ mega_query_adapter(adapter_t *adapter) adapter->host->max_id = 16; /* max targets per channel */ - adapter->host->max_lun = 7; /* Upto 7 luns for non disk devices */ + adapter->host->max_lun = 7; /* Up to 7 luns for non disk devices */ adapter->host->cmd_per_lun = max_cmd_per_lun; @@ -3734,7 +3734,7 @@ mega_m_to_n(void __user *arg, nitioctl_t *uioc) * check is the application conforms to NIT. We do not have to do much * in that case. * We exploit the fact that the signature is stored in the very - * begining of the structure. + * beginning of the structure. */ if( copy_from_user(signature, arg, 7) ) diff --git a/drivers/scsi/megaraid.h b/drivers/scsi/megaraid.h index 853411911b2e..9a7897f8ca43 100644 --- a/drivers/scsi/megaraid.h +++ b/drivers/scsi/megaraid.h @@ -532,9 +532,9 @@ struct uioctl_t { /* * struct mcontroller is used to pass information about the controllers in the - * system. Its upto the application how to use the information. We are passing + * system. Its up to the application how to use the information. We are passing * as much info about the cards as possible and useful. Before issuing the - * call to find information about the cards, the applicaiton needs to issue a + * call to find information about the cards, the application needs to issue a * ioctl first to find out the number of controllers in the system. */ #define MAX_CONTROLLERS 32 @@ -804,7 +804,7 @@ typedef struct { unsigned long base; void __iomem *mmio_base; - /* mbox64 with mbox not aligned on 16-byte boundry */ + /* mbox64 with mbox not aligned on 16-byte boundary */ mbox64_t *una_mbox64; dma_addr_t una_mbox64_dma; diff --git a/drivers/scsi/megaraid/mbox_defs.h b/drivers/scsi/megaraid/mbox_defs.h index ce2487a888ed..e01c6f7c2cac 100644 --- a/drivers/scsi/megaraid/mbox_defs.h +++ b/drivers/scsi/megaraid/mbox_defs.h @@ -660,7 +660,7 @@ typedef struct { * @lparam : logical drives parameters * @span : span * - * 8-LD logical drive with upto 8 spans + * 8-LD logical drive with up to 8 spans */ typedef struct { logdrv_param_t lparam; @@ -673,7 +673,7 @@ typedef struct { * @lparam : logical drives parameters * @span : span * - * 8-LD logical drive with upto 4 spans + * 8-LD logical drive with up to 4 spans */ typedef struct { logdrv_param_t lparam; @@ -720,7 +720,7 @@ typedef struct { * @ldrv : logical drives information * @pdrv : physical drives information * - * Disk array for 8LD logical drives with upto 8 spans + * Disk array for 8LD logical drives with up to 8 spans */ typedef struct { uint8_t numldrv; @@ -737,7 +737,7 @@ typedef struct { * @ldrv : logical drives information * @pdrv : physical drives information * - * Disk array for 8LD logical drives with upto 4 spans + * Disk array for 8LD logical drives with up to 4 spans */ typedef struct { uint8_t numldrv; diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c index 5708cb27d078..1dba32870b4c 100644 --- a/drivers/scsi/megaraid/megaraid_mbox.c +++ b/drivers/scsi/megaraid/megaraid_mbox.c @@ -2689,7 +2689,7 @@ megaraid_reset_handler(struct scsi_cmnd *scp) (MBOX_RESET_WAIT + MBOX_RESET_EXT_WAIT) - i)); } - // bailout if no recovery happended in reset time + // bailout if no recovery happened in reset time if (adapter->outstanding_cmds == 0) { break; } @@ -3452,7 +3452,7 @@ megaraid_mbox_display_scb(adapter_t *adapter, scb_t *scb) * megaraid_mbox_setup_device_map - manage device ids * @adapter : Driver's soft state * - * Manange the device ids to have an appropraite mapping between the kernel + * Manange the device ids to have an appropriate mapping between the kernel * scsi addresses and megaraid scsi and logical drive addresses. We export * scsi devices on their actual addresses, whereas the logical drives are * exported on a virtual scsi channel. @@ -3973,7 +3973,7 @@ megaraid_sysfs_get_ldmap_timeout(unsigned long data) * NOTE: The commands issuance functionality is not generalized and * implemented in context of "get ld map" command only. If required, the * command issuance logical can be trivially pulled out and implemented as a - * standalone libary. For now, this should suffice since there is no other + * standalone library. For now, this should suffice since there is no other * user of this interface. * * Return 0 on success. diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 635b228c3ead..046dcc672ec1 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -1347,7 +1347,7 @@ struct megasas_instance { struct timer_list io_completion_timer; struct list_head internal_reset_pending_q; - /* Ptr to hba specfic information */ + /* Ptr to hba specific information */ void *ctrl_context; u8 msi_flag; struct msix_entry msixentry; diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index bbd10c81fd9c..66d4cea4df98 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -1698,7 +1698,7 @@ void megasas_do_ocr(struct megasas_instance *instance) * megasas_wait_for_outstanding - Wait for all outstanding cmds * @instance: Adapter soft state * - * This function waits for upto MEGASAS_RESET_WAIT_TIME seconds for FW to + * This function waits for up to MEGASAS_RESET_WAIT_TIME seconds for FW to * complete all its outstanding commands. Returns error if one or more IOs * are pending after this time period. It also marks the controller dead. */ diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_init.h b/drivers/scsi/mpt2sas/mpi/mpi2_init.h index 20e6b8869341..165454d52591 100644 --- a/drivers/scsi/mpt2sas/mpi/mpi2_init.h +++ b/drivers/scsi/mpt2sas/mpi/mpi2_init.h @@ -21,7 +21,7 @@ * 05-21-08 02.00.05 Fixed typo in name of Mpi2SepRequest_t. * 10-02-08 02.00.06 Removed Untagged and No Disconnect values from SCSI IO * Control field Task Attribute flags. - * Moved LUN field defines to mpi2.h becasue they are + * Moved LUN field defines to mpi2.h because they are * common to many structures. * 05-06-09 02.00.07 Changed task management type of Query Unit Attention to * Query Asynchronous Event. diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index 5e001ffd4c13..3346357031e9 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c @@ -925,7 +925,7 @@ _base_interrupt(int irq, void *bus_id) } /** - * mpt2sas_base_release_callback_handler - clear interupt callback handler + * mpt2sas_base_release_callback_handler - clear interrupt callback handler * @cb_idx: callback index * * Return nothing. @@ -1113,7 +1113,7 @@ _base_restore_msix_table(struct MPT2SAS_ADAPTER *ioc) * @ioc: per adapter object * * Check to see if card is capable of MSIX, and set number - * of avaliable msix vectors + * of available msix vectors */ static int _base_check_enable_msix(struct MPT2SAS_ADAPTER *ioc) @@ -1595,7 +1595,7 @@ mpt2sas_base_put_smid_scsi_io(struct MPT2SAS_ADAPTER *ioc, u16 smid, u16 handle) /** - * mpt2sas_base_put_smid_hi_priority - send Task Managment request to firmware + * mpt2sas_base_put_smid_hi_priority - send Task Management request to firmware * @ioc: per adapter object * @smid: system request message index * @@ -2599,7 +2599,7 @@ _base_wait_for_doorbell_int(struct MPT2SAS_ADAPTER *ioc, int timeout, int_status = readl(&ioc->chip->HostInterruptStatus); if (int_status & MPI2_HIS_IOC2SYS_DB_STATUS) { dhsprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: " - "successfull count(%d), timeout(%d)\n", ioc->name, + "successful count(%d), timeout(%d)\n", ioc->name, __func__, count, timeout)); return 0; } @@ -2640,7 +2640,7 @@ _base_wait_for_doorbell_ack(struct MPT2SAS_ADAPTER *ioc, int timeout, int_status = readl(&ioc->chip->HostInterruptStatus); if (!(int_status & MPI2_HIS_SYS2IOC_DB_STATUS)) { dhsprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: " - "successfull count(%d), timeout(%d)\n", ioc->name, + "successful count(%d), timeout(%d)\n", ioc->name, __func__, count, timeout)); return 0; } else if (int_status & MPI2_HIS_IOC2SYS_DB_STATUS) { @@ -2688,7 +2688,7 @@ _base_wait_for_doorbell_not_used(struct MPT2SAS_ADAPTER *ioc, int timeout, doorbell_reg = readl(&ioc->chip->Doorbell); if (!(doorbell_reg & MPI2_DOORBELL_USED)) { dhsprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: " - "successfull count(%d), timeout(%d)\n", ioc->name, + "successful count(%d), timeout(%d)\n", ioc->name, __func__, count, timeout)); return 0; } diff --git a/drivers/scsi/mpt2sas/mpt2sas_config.c b/drivers/scsi/mpt2sas/mpt2sas_config.c index 6afd67b324fe..6861244249a3 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_config.c +++ b/drivers/scsi/mpt2sas/mpt2sas_config.c @@ -93,7 +93,7 @@ struct config_request{ * @mpi_reply: reply message frame * Context: none. * - * Function for displaying debug info helpfull when debugging issues + * Function for displaying debug info helpful when debugging issues * in this module. */ static void diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c index e92b77af5484..1c6d2b405eef 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_ctl.c +++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.c @@ -116,7 +116,7 @@ _ctl_sas_device_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle) * @mpi_reply: reply message frame * Context: none. * - * Function for displaying debug info helpfull when debugging issues + * Function for displaying debug info helpful when debugging issues * in this module. */ static void diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index 6ceb7759bfe5..d2064a0533ae 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c @@ -397,7 +397,7 @@ _scsih_get_sas_address(struct MPT2SAS_ADAPTER *ioc, u16 handle, * @is_raid: [flag] 1 = raid object, 0 = sas object * * Determines whether this device should be first reported device to - * to scsi-ml or sas transport, this purpose is for persistant boot device. + * to scsi-ml or sas transport, this purpose is for persistent boot device. * There are primary, alternate, and current entries in bios page 2. The order * priority is primary, alternate, then current. This routine saves * the corresponding device object and is_raid flag in the ioc object. @@ -2671,10 +2671,10 @@ _scsih_block_io_to_children_attached_directly(struct MPT2SAS_ADAPTER *ioc, * @handle: device handle * Context: interrupt time. * - * This code is to initiate the device removal handshake protocal + * This code is to initiate the device removal handshake protocol * with controller firmware. This function will issue target reset * using high priority request queue. It will send a sas iounit - * controll request (MPI2_SAS_OP_REMOVE_DEVICE) from this completion. + * control request (MPI2_SAS_OP_REMOVE_DEVICE) from this completion. * * This is designed to send muliple task management request at the same * time to the fifo. If the fifo is full, we will append the request, @@ -2749,9 +2749,9 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle) * @reply: reply message frame(lower 32bit addr) * Context: interrupt time. * - * This is the sas iounit controll completion routine. + * This is the sas iounit control completion routine. * This code is part of the code to initiate the device removal - * handshake protocal with controller firmware. + * handshake protocol with controller firmware. * * Return 1 meaning mf should be freed from _base_interrupt * 0 means the mf is freed from this function. @@ -2878,8 +2878,8 @@ _scsih_tm_volume_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, * * This is the target reset completion routine. * This code is part of the code to initiate the device removal - * handshake protocal with controller firmware. - * It will send a sas iounit controll request (MPI2_SAS_OP_REMOVE_DEVICE) + * handshake protocol with controller firmware. + * It will send a sas iounit control request (MPI2_SAS_OP_REMOVE_DEVICE) * * Return 1 meaning mf should be freed from _base_interrupt * 0 means the mf is freed from this function. @@ -2984,7 +2984,7 @@ _scsih_check_for_pending_tm(struct MPT2SAS_ADAPTER *ioc, u16 smid) * * This routine added to better handle cable breaker. * - * This handles the case where driver recieves multiple expander + * This handles the case where driver receives multiple expander * add and delete events in a single shot. When there is a delete event * the routine will void any pending add events waiting in the event queue. * @@ -3511,7 +3511,7 @@ _scsih_normalize_sense(char *sense_buffer, struct sense_info *data) #ifdef CONFIG_SCSI_MPT2SAS_LOGGING /** - * _scsih_scsi_ioc_info - translated non-successfull SCSI_IO request + * _scsih_scsi_ioc_info - translated non-successful SCSI_IO request * @ioc: per adapter object * @scmd: pointer to scsi command object * @mpi_reply: reply mf payload returned from firmware @@ -5138,7 +5138,7 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, unsigned long flags; int r; - dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "broadcast primative: " + dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "broadcast primitive: " "phy number(%d), width(%d)\n", ioc->name, event_data->PhyNum, event_data->PortWidth)); dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name, diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c index 46cc3825638d..835d8d66e696 100644 --- a/drivers/scsi/ncr53c8xx.c +++ b/drivers/scsi/ncr53c8xx.c @@ -2679,7 +2679,7 @@ static struct script script0 __initdata = { }/*-------------------------< RESEL_TAG >-------------------*/,{ /* ** Read IDENTIFY + SIMPLE + TAG using a single MOVE. - ** Agressive optimization, is'nt it? + ** Aggressive optimization, is'nt it? ** No need to test the SIMPLE TAG message, since the ** driver only supports conformant devices for tags. ;-) */ diff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c index 6b8b021400f8..f6a50c98c36f 100644 --- a/drivers/scsi/nsp32.c +++ b/drivers/scsi/nsp32.c @@ -1288,7 +1288,7 @@ static irqreturn_t do_nsp32_isr(int irq, void *dev_id) nsp32_dbg(NSP32_DEBUG_INTR, "SSACK=0x%lx", nsp32_read4(base, SAVED_SACK_CNT)); - scsi_set_resid(SCpnt, 0); /* all data transfered! */ + scsi_set_resid(SCpnt, 0); /* all data transferred! */ } /* @@ -1630,7 +1630,7 @@ static int nsp32_busfree_occur(struct scsi_cmnd *SCpnt, unsigned short execph) /* * If SAVEDSACKCNT == 0, it means SavedDataPointer is - * come after data transfering. + * come after data transferring. */ if (s_sacklen > 0) { /* @@ -1785,7 +1785,7 @@ static void nsp32_adjust_busfree(struct scsi_cmnd *SCpnt, unsigned int s_sacklen the head element of the sg. restlen is correctly calculated. */ } - /* calculate the rest length for transfering */ + /* calculate the rest length for transferring */ restlen = sentlen - s_sacklen; /* update adjusting current SG table entry */ diff --git a/drivers/scsi/nsp32.h b/drivers/scsi/nsp32.h index 9565acf1aa72..c0221829069c 100644 --- a/drivers/scsi/nsp32.h +++ b/drivers/scsi/nsp32.h @@ -507,7 +507,7 @@ typedef struct _nsp32_lunt { /* * SCSI TARGET/LUN definition */ -#define NSP32_HOST_SCSIID 7 /* SCSI initiator is everytime defined as 7 */ +#define NSP32_HOST_SCSIID 7 /* SCSI initiator is every time defined as 7 */ #define MAX_TARGET 8 #define MAX_LUN 8 /* XXX: In SPI3, max number of LUN is 64. */ diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c index 521e2182d45b..58f5be4740e9 100644 --- a/drivers/scsi/osst.c +++ b/drivers/scsi/osst.c @@ -1366,7 +1366,7 @@ error: /* The values below are based on the OnStream frame payload size of 32K == 2**15, * that is, OSST_FRAME_SHIFT + OSST_SECTOR_SHIFT must be 15. With a minimum block * size of 512 bytes, we need to be able to resolve 32K/512 == 64 == 2**6 positions - * inside each frame. Finaly, OSST_SECTOR_MASK == 2**OSST_FRAME_SHIFT - 1. + * inside each frame. Finally, OSST_SECTOR_MASK == 2**OSST_FRAME_SHIFT - 1. */ #define OSST_FRAME_SHIFT 6 #define OSST_SECTOR_SHIFT 9 @@ -3131,7 +3131,7 @@ static int osst_flush_write_buffer(struct osst_tape *STp, struct osst_request ** } #if DEBUG if (debugging) - printk(OSST_DEB_MSG "%s:D: Flushing %d bytes, Transfering %d bytes in %d lblocks.\n", + printk(OSST_DEB_MSG "%s:D: Flushing %d bytes, Transferring %d bytes in %d lblocks.\n", name, offset, transfer, blks); #endif @@ -3811,7 +3811,7 @@ static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, lo if (transfer == 0) { printk(KERN_WARNING - "%s:W: Nothing can be transfered, requested %Zd, tape block size (%d%c).\n", + "%s:W: Nothing can be transferred, requested %Zd, tape block size (%d%c).\n", name, count, STp->block_size < 1024? STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k'); diff --git a/drivers/scsi/osst.h b/drivers/scsi/osst.h index 11d26c57f3f8..b4fea98ba276 100644 --- a/drivers/scsi/osst.h +++ b/drivers/scsi/osst.h @@ -413,7 +413,7 @@ typedef struct os_dat_s { * AUX */ typedef struct os_aux_s { - __be32 format_id; /* hardware compability AUX is based on */ + __be32 format_id; /* hardware compatibility AUX is based on */ char application_sig[4]; /* driver used to write this media */ __be32 hdwr; /* reserved */ __be32 update_frame_cntr; /* for configuration frame */ diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c index be3f33d31a99..54bdf6d85c6d 100644 --- a/drivers/scsi/pcmcia/nsp_cs.c +++ b/drivers/scsi/pcmcia/nsp_cs.c @@ -742,7 +742,7 @@ static void nsp_pio_read(struct scsi_cmnd *SCpnt) res = nsp_fifo_count(SCpnt) - ocount; //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this=0x%x ocount=0x%x res=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, ocount, res); - if (res == 0) { /* if some data avilable ? */ + if (res == 0) { /* if some data available ? */ if (stat == BUSPHASE_DATA_IN) { /* phase changed? */ //nsp_dbg(NSP_DEBUG_DATA_IO, " wait for data this=%d", SCpnt->SCp.this_residual); continue; diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index 18b6c55cd08c..8b7db1e53c10 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -339,7 +339,7 @@ update_outbnd_queue_table(struct pm8001_hba_info *pm8001_ha, int number) /** * bar4_shift - function is called to shift BAR base address - * @pm8001_ha : our hba card infomation + * @pm8001_ha : our hba card information * @shiftValue : shifting value in memory bar. */ static int bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shiftValue) diff --git a/drivers/scsi/pm8001/pm8001_hwi.h b/drivers/scsi/pm8001/pm8001_hwi.h index 833a5201eda4..909132041c07 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.h +++ b/drivers/scsi/pm8001/pm8001_hwi.h @@ -209,7 +209,7 @@ struct pio_setup_fis { /* * brief the data structure of SATA Completion Response - * use to discribe the sata task response (64 bytes) + * use to describe the sata task response (64 bytes) */ struct sata_completion_resp { __le32 tag; @@ -951,7 +951,7 @@ struct set_dev_state_resp { #define PCIE_EVENT_INTERRUPT 0x003044 #define PCIE_ERROR_INTERRUPT_ENABLE 0x003048 #define PCIE_ERROR_INTERRUPT 0x00304C -/* signature defintion for host scratch pad0 register */ +/* signature definition for host scratch pad0 register */ #define SPC_SOFT_RESET_SIGNATURE 0x252acbcd /* Signature for Soft Reset */ diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h index bdb6b27dedd6..aa05e661d113 100644 --- a/drivers/scsi/pm8001/pm8001_sas.h +++ b/drivers/scsi/pm8001/pm8001_sas.h @@ -445,7 +445,7 @@ struct fw_control_info { struct fw_control_ex { struct fw_control_info *fw_control; void *buffer;/* keep buffer pointer to be - freed when the responce comes*/ + freed when the response comes*/ void *virtAddr;/* keep virtual address of the data */ void *usrAddr;/* keep virtual address of the user data */ diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index bcf858e88c64..96d5ad0c1e42 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c @@ -213,7 +213,7 @@ static int pmcraid_slave_alloc(struct scsi_device *scsi_dev) * pmcraid_slave_configure - Configures a SCSI device * @scsi_dev: scsi device struct * - * This fucntion is executed by SCSI mid layer just after a device is first + * This function is executed by SCSI mid layer just after a device is first * scanned (i.e. it has responded to an INQUIRY). For VSET resources, the * timeout value (default 30s) will be over-written to a higher value (60s) * and max_sectors value will be over-written to 512. It also sets queue depth @@ -2122,7 +2122,7 @@ static void pmcraid_fail_outstanding_cmds(struct pmcraid_instance *pinstance) * * This function executes most of the steps required for IOA reset. This gets * called by user threads (modprobe/insmod/rmmod) timer, tasklet and midlayer's - * 'eh_' thread. Access to variables used for controling the reset sequence is + * 'eh_' thread. Access to variables used for controlling the reset sequence is * synchronized using host lock. Various functions called during reset process * would make use of a single command block, pointer to which is also stored in * adapter instance structure. @@ -2994,7 +2994,7 @@ static int pmcraid_abort_complete(struct pmcraid_cmd *cancel_cmd) /* If the abort task is not timed out we will get a Good completion * as sense_key, otherwise we may get one the following responses - * due to subsquent bus reset or device reset. In case IOASC is + * due to subsequent bus reset or device reset. In case IOASC is * NR_SYNC_REQUIRED, set sync_reqd flag for the corresponding resource */ if (ioasc == PMCRAID_IOASC_UA_BUS_WAS_RESET || @@ -3933,7 +3933,7 @@ static long pmcraid_ioctl_passthrough( /* if abort task couldn't find the command i.e it got * completed prior to aborting, return good completion. - * if command got aborted succesfully or there was IOA + * if command got aborted successfully or there was IOA * reset due to abort task itself getting timedout then * return -ETIMEDOUT */ @@ -5932,7 +5932,7 @@ static int __devinit pmcraid_probe( * However, firmware supports 64-bit streaming DMA buffers, whereas * coherent buffers are to be 32-bit. Since pci_alloc_consistent always * returns memory within 4GB (if not, change this logic), coherent - * buffers are within firmware acceptible address ranges. + * buffers are within firmware acceptable address ranges. */ if ((sizeof(dma_addr_t) == 4) || pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) diff --git a/drivers/scsi/pmcraid.h b/drivers/scsi/pmcraid.h index 4db210d93947..34e4c915002e 100644 --- a/drivers/scsi/pmcraid.h +++ b/drivers/scsi/pmcraid.h @@ -1024,7 +1024,7 @@ static struct pmcraid_ioasc_error pmcraid_ioasc_error_table[] = { /* - * pmcraid_ioctl_header - definition of header structure that preceeds all the + * pmcraid_ioctl_header - definition of header structure that precedes all the * buffers given as ioctl arguments. * * .signature : always ASCII string, "PMCRAID" diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index 5dec684bf010..8ba5744c267e 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c @@ -78,7 +78,7 @@ - Clean up vchan handling Rev 3.23.33 July 3, 2003, Jes Sorensen - Don't define register access macros before define determining MMIO. - This just happend to work out on ia64 but not elsewhere. + This just happened to work out on ia64 but not elsewhere. - Don't try and read from the card while it is in reset as it won't respond and causes an MCA Rev 3.23.32 June 23, 2003, Jes Sorensen diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 6c51c0a35b9e..ee20353c8550 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2086,7 +2086,7 @@ struct ct_sns_pkt { }; /* - * SNS command structures -- for 2200 compatability. + * SNS command structures -- for 2200 compatibility. */ #define RFT_ID_SNS_SCMD_LEN 22 #define RFT_ID_SNS_CMD_SIZE 60 diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index 631fefc8482d..f5ba09c8a663 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h @@ -539,7 +539,7 @@ struct sts_entry_24xx { * If DIF Error is set in comp_status, these additional fields are * defined: * &data[10] : uint8_t report_runt_bg[2]; - computed guard - * &data[12] : uint8_t actual_dif[8]; - DIF Data recieved + * &data[12] : uint8_t actual_dif[8]; - DIF Data received * &data[20] : uint8_t expected_dif[8]; - DIF Data computed */ }; diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index d17ed9a94a0c..712518d05128 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -414,7 +414,7 @@ skip_rio: "marked OFFLINE!\n"); vha->flags.online = 0; } else { - /* Check to see if MPI timeout occured */ + /* Check to see if MPI timeout occurred */ if ((mbx & MBX_3) && (ha->flags.port0)) set_bit(MPI_RESET_NEEDED, &vha->dpc_flags); diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 7a7c0ecfe7dd..34893397ac84 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -303,7 +303,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) { qla_printk(KERN_WARNING, ha, - "Mailbox command timeout occured. " + "Mailbox command timeout occurred. " "Scheduling ISP " "abort. eeh_busy: 0x%x\n", ha->flags.eeh_busy); set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); @@ -321,7 +321,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) { qla_printk(KERN_WARNING, ha, - "Mailbox command timeout occured. " + "Mailbox command timeout occurred. " "Issuing ISP abort.\n"); set_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags); @@ -3789,7 +3789,7 @@ qla2x00_loopback_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq, mcp->mb[20] = LSW(MSD(mreq->send_dma)); mcp->mb[21] = MSW(MSD(mreq->send_dma)); - /* recieve data address */ + /* receive data address */ mcp->mb[16] = LSW(mreq->rcv_dma); mcp->mb[17] = MSW(mreq->rcv_dma); mcp->mb[6] = LSW(MSD(mreq->rcv_dma)); diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index 76ec876e6b21..455fe134d31d 100644 --- a/drivers/scsi/qla2xxx/qla_nx.c +++ b/drivers/scsi/qla2xxx/qla_nx.c @@ -2598,7 +2598,7 @@ qla82xx_calc_dsd_lists(uint16_t dsds) * qla82xx_start_scsi() - Send a SCSI command to the ISP * @sp: command to send to the ISP * - * Returns non-zero if a failure occured, else zero. + * Returns non-zero if a failure occurred, else zero. */ int qla82xx_start_scsi(srb_t *sp) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 75a966c94860..aa7747529165 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1046,7 +1046,7 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) eh_bus_reset_done: qla_printk(KERN_INFO, vha->hw, "%s: reset %s\n", __func__, - (ret == FAILED) ? "failed" : "succeded"); + (ret == FAILED) ? "failed" : "succeeded"); return ret; } @@ -1136,7 +1136,7 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) eh_host_reset_lock: qla_printk(KERN_INFO, ha, "%s: reset %s\n", __func__, - (ret == FAILED) ? "failed" : "succeded"); + (ret == FAILED) ? "failed" : "succeeded"); return ret; } @@ -3902,7 +3902,7 @@ uint32_t qla82xx_error_recovery(scsi_qla_host_t *base_vha) continue; if (atomic_read(&other_pdev->enable_cnt)) { DEBUG17(qla_printk(KERN_INFO, ha, - "Found PCI func availabe and enabled at 0x%x\n", + "Found PCI func available and enabled at 0x%x\n", fn)); pci_dev_put(other_pdev); break; diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h index c1f8d1b150f7..4757878d59dd 100644 --- a/drivers/scsi/qla4xxx/ql4_def.h +++ b/drivers/scsi/qla4xxx/ql4_def.h @@ -182,7 +182,7 @@ struct srb { uint16_t flags; /* (1) Status flags. */ #define SRB_DMA_VALID BIT_3 /* DMA Buffer mapped. */ -#define SRB_GOT_SENSE BIT_4 /* sense data recieved. */ +#define SRB_GOT_SENSE BIT_4 /* sense data received. */ uint8_t state; /* (1) Status flags. */ #define SRB_NO_QUEUE_STATE 0 /* Request is in between states */ diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c index bbb2e903d38a..48e2241ddaf4 100644 --- a/drivers/scsi/qla4xxx/ql4_init.c +++ b/drivers/scsi/qla4xxx/ql4_init.c @@ -1338,7 +1338,7 @@ exit_init_hba: } DEBUG2(printk("scsi%ld: initialize adapter: %s\n", ha->host_no, - status == QLA_ERROR ? "FAILED" : "SUCCEDED")); + status == QLA_ERROR ? "FAILED" : "SUCCEEDED")); return status; } diff --git a/drivers/scsi/qla4xxx/ql4_nvram.h b/drivers/scsi/qla4xxx/ql4_nvram.h index b3831bd29479..945cc328f57f 100644 --- a/drivers/scsi/qla4xxx/ql4_nvram.h +++ b/drivers/scsi/qla4xxx/ql4_nvram.h @@ -28,7 +28,7 @@ #define FM93C56A_ERASE 0x3 #define FM93C56A_ERASE_ALL 0x0 -/* Command Extentions */ +/* Command Extensions */ #define FM93C56A_WEN_EXT 0x3 #define FM93C56A_WRITE_ALL_EXT 0x1 #define FM93C56A_WDS_EXT 0x0 diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index a4acb0dd7beb..230ba097d28c 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -1213,7 +1213,7 @@ recover_ha_init_adapter: clear_bit(DPC_RESET_ACTIVE, &ha->dpc_flags); DEBUG2(printk("scsi%ld: recover adapter: %s\n", ha->host_no, - status == QLA_ERROR ? "FAILED" : "SUCCEDED")); + status == QLA_ERROR ? "FAILED" : "SUCCEEDED")); return status; } @@ -2110,7 +2110,7 @@ static int qla4xxx_eh_abort(struct scsi_cmnd *cmd) ql4_printk(KERN_INFO, ha, "scsi%ld:%d:%d: Abort command - %s\n", - ha->host_no, id, lun, (ret == SUCCESS) ? "succeded" : "failed"); + ha->host_no, id, lun, (ret == SUCCESS) ? "succeeded" : "failed"); return ret; } @@ -2278,7 +2278,7 @@ static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd) return_status = SUCCESS; ql4_printk(KERN_INFO, ha, "HOST RESET %s.\n", - return_status == FAILED ? "FAILED" : "SUCCEDED"); + return_status == FAILED ? "FAILED" : "SUCCEEDED"); return return_status; } @@ -2492,7 +2492,7 @@ qla4xxx_pci_slot_reset(struct pci_dev *pdev) /* Initialize device or resume if in suspended state */ rc = pci_enable_device(pdev); if (rc) { - ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: Cant re-enable " + ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: Can't re-enable " "device after reset\n", ha->host_no, __func__); goto exit_slot_reset; } diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index fa5758cbdedb..6888b2ca5bfc 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -2454,7 +2454,7 @@ static void scsi_debug_slave_destroy(struct scsi_device *sdp) printk(KERN_INFO "scsi_debug: slave_destroy <%u %u %u %u>\n", sdp->host->host_no, sdp->channel, sdp->id, sdp->lun); if (devip) { - /* make this slot avaliable for re-use */ + /* make this slot available for re-use */ devip->used = 0; sdp->hostdata = NULL; } diff --git a/drivers/scsi/scsi_netlink.c b/drivers/scsi/scsi_netlink.c index a2ed201885ae..26a8a45584ef 100644 --- a/drivers/scsi/scsi_netlink.c +++ b/drivers/scsi/scsi_netlink.c @@ -499,7 +499,7 @@ scsi_netlink_init(void) SCSI_NL_GRP_CNT, scsi_nl_rcv_msg, NULL, THIS_MODULE); if (!scsi_nl_sock) { - printk(KERN_ERR "%s: register of recieve handler failed\n", + printk(KERN_ERR "%s: register of receive handler failed\n", __func__); netlink_unregister_notifier(&scsi_netlink_notifier); return; diff --git a/drivers/scsi/scsi_tgt_lib.c b/drivers/scsi/scsi_tgt_lib.c index f67282058ba1..8bca8c25ba69 100644 --- a/drivers/scsi/scsi_tgt_lib.c +++ b/drivers/scsi/scsi_tgt_lib.c @@ -93,7 +93,7 @@ struct scsi_cmnd *scsi_host_get_command(struct Scsi_Host *shost, /* * The blk helpers are used to the READ/WRITE requests - * transfering data from a initiator point of view. Since + * transferring data from a initiator point of view. Since * we are in target mode we want the opposite. */ rq = blk_get_request(shost->uspace_req_q, !write, gfp_mask); diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 2941d2d92c94..fdf3fa639056 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -2378,7 +2378,7 @@ fc_flush_devloss(struct Scsi_Host *shost) * fc_remove_host - called to terminate any fc_transport-related elements for a scsi host. * @shost: Which &Scsi_Host * - * This routine is expected to be called immediately preceeding the + * This routine is expected to be called immediately preceding the * a driver's call to scsi_remove_host(). * * WARNING: A driver utilizing the fc_transport, which fails to call @@ -2458,7 +2458,7 @@ static void fc_terminate_rport_io(struct fc_rport *rport) } /** - * fc_starget_delete - called to delete the scsi decendents of an rport + * fc_starget_delete - called to delete the scsi descendants of an rport * @work: remote port to be operated on. * * Deletes target and all sdevs. diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index b61ebec6bca7..bd0806e64e85 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1055,7 +1055,7 @@ static int sd_getgeo(struct block_device *bdev, struct hd_geometry *geo) * @arg: this is third argument given to ioctl(2) system call. * Often contains a pointer. * - * Returns 0 if successful (some ioctls return postive numbers on + * Returns 0 if successful (some ioctls return positive numbers on * success as well). Returns a negated errno value in case of error. * * Note: most ioctls are forward onto the block subsystem or further diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index aefadc6a1607..95019c747cc1 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -567,7 +567,7 @@ static const struct block_device_operations sr_bdops = .revalidate_disk = sr_block_revalidate_disk, /* * No compat_ioctl for now because sr_block_ioctl never - * seems to pass arbitary ioctls down to host drivers. + * seems to pass arbitrary ioctls down to host drivers. */ }; diff --git a/drivers/scsi/sun3_NCR5380.c b/drivers/scsi/sun3_NCR5380.c index 4f0e5485ffde..07eaef1c722b 100644 --- a/drivers/scsi/sun3_NCR5380.c +++ b/drivers/scsi/sun3_NCR5380.c @@ -467,7 +467,7 @@ static void free_all_tags( void ) * * Parameters: struct scsi_cmnd *cmd * The command to work on. The first scatter buffer's data are - * assumed to be already transfered into ptr/this_residual. + * assumed to be already transferred into ptr/this_residual. */ static void merge_contiguous_buffers(struct scsi_cmnd *cmd) @@ -1717,7 +1717,7 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd, * bytes to transfer, **data - pointer to data pointer. * * Returns : -1 when different phase is entered without transferring - * maximum number of bytes, 0 if all bytes are transfered or exit + * maximum number of bytes, 0 if all bytes are transferred or exit * is in same phase. * * Also, *phase, *count, *data are modified in place. @@ -1904,7 +1904,7 @@ static int do_abort (struct Scsi_Host *host) * bytes to transfer, **data - pointer to data pointer. * * Returns : -1 when different phase is entered without transferring - * maximum number of bytes, 0 if all bytes or transfered or exit + * maximum number of bytes, 0 if all bytes or transferred or exit * is in same phase. * * Also, *phase, *count, *data are modified in place. diff --git a/drivers/scsi/sym53c416.c b/drivers/scsi/sym53c416.c index 190107ae120b..012c86edd59f 100644 --- a/drivers/scsi/sym53c416.c +++ b/drivers/scsi/sym53c416.c @@ -774,7 +774,7 @@ static int sym53c416_host_reset(Scsi_Cmnd *SCpnt) /* printk("sym53c416_reset\n"); */ base = SCpnt->device->host->io_port; - /* search scsi_id - fixme, we shouldnt need to iterate for this! */ + /* search scsi_id - fixme, we shouldn't need to iterate for this! */ for(i = 0; i < host_index && scsi_id == -1; i++) if(hosts[i].base == base) scsi_id = hosts[i].scsi_id; diff --git a/drivers/scsi/sym53c8xx_2/sym_fw1.h b/drivers/scsi/sym53c8xx_2/sym_fw1.h index 7b08d6caaa99..63952ee300b5 100644 --- a/drivers/scsi/sym53c8xx_2/sym_fw1.h +++ b/drivers/scsi/sym53c8xx_2/sym_fw1.h @@ -1449,7 +1449,7 @@ static struct SYM_FWB_SCR SYM_FWB_SCR = { PADDR_B (msg_weird_seen), /* * We donnot handle extended messages from SCRIPTS. - * Read the amount of data correponding to the + * Read the amount of data corresponding to the * message length and call the C code. */ SCR_COPY (1), diff --git a/drivers/scsi/sym53c8xx_2/sym_fw2.h b/drivers/scsi/sym53c8xx_2/sym_fw2.h index ae1fb179b88e..c87d72443a16 100644 --- a/drivers/scsi/sym53c8xx_2/sym_fw2.h +++ b/drivers/scsi/sym53c8xx_2/sym_fw2.h @@ -1326,7 +1326,7 @@ static struct SYM_FWB_SCR SYM_FWB_SCR = { PADDR_B (msg_weird_seen), /* * We donnot handle extended messages from SCRIPTS. - * Read the amount of data correponding to the + * Read the amount of data corresponding to the * message length and call the C code. */ SCR_STORE_REL (scratcha, 1), diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c index 2c3e89ddf069..d92fe4037e94 100644 --- a/drivers/scsi/sym53c8xx_2/sym_hipd.c +++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c @@ -2457,7 +2457,7 @@ static void sym_int_ma (struct sym_hcb *np) } /* - * The data in the dma fifo has not been transfered to + * The data in the dma fifo has not been transferred to * the target -> add the amount to the rest * and clear the data. * Check the sstat2 register in case of wide transfer. @@ -5094,7 +5094,7 @@ fail: } /* - * Lun control block deallocation. Returns the number of valid remaing LCBs + * Lun control block deallocation. Returns the number of valid remaining LCBs * for the target. */ int sym_free_lcb(struct sym_hcb *np, u_char tn, u_char ln) diff --git a/drivers/scsi/sym53c8xx_2/sym_malloc.c b/drivers/scsi/sym53c8xx_2/sym_malloc.c index 883cac10daf9..6f9af0de7ec3 100644 --- a/drivers/scsi/sym53c8xx_2/sym_malloc.c +++ b/drivers/scsi/sym53c8xx_2/sym_malloc.c @@ -50,7 +50,7 @@ * from the SCRIPTS code. In addition, cache line alignment * is guaranteed for power of 2 cache line size. * - * This allocator has been developped for the Linux sym53c8xx + * This allocator has been developed for the Linux sym53c8xx * driver, since this O/S does not provide naturally aligned * allocations. * It has the advantage of allowing the driver to use private diff --git a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c index 5f697e0bd009..4468ae3610f7 100644 --- a/drivers/scsi/wd33c93.c +++ b/drivers/scsi/wd33c93.c @@ -1843,7 +1843,7 @@ check_setup_args(char *key, int *flags, int *val, char *buf) * * The original driver used to rely on a fixed sx_table, containing periods * for (only) the lower limits of the respective input-clock-frequency ranges - * (8-10/12-15/16-20 MHz). Although it seems, that no problems ocurred with + * (8-10/12-15/16-20 MHz). Although it seems, that no problems occurred with * this setting so far, it might be desirable to adjust the transfer periods * closer to the really attached, possibly 25% higher, input-clock, since * - the wd33c93 may really use a significant shorter period, than it has diff --git a/drivers/scsi/wd7000.c b/drivers/scsi/wd7000.c index db451ae0a368..9ee0afef2d16 100644 --- a/drivers/scsi/wd7000.c +++ b/drivers/scsi/wd7000.c @@ -837,7 +837,7 @@ static inline Scb *alloc_scbs(struct Scsi_Host *host, int needed) } } - /* Take the lock, then check we didnt get beaten, if so try again */ + /* Take the lock, then check we didn't get beaten, if so try again */ spin_lock_irqsave(&scbpool_lock, flags); if (freescbs < needed) { spin_unlock_irqrestore(&scbpool_lock, flags); diff --git a/drivers/sfi/sfi_core.c b/drivers/sfi/sfi_core.c index 04113e5304a0..1e824fb1649b 100644 --- a/drivers/sfi/sfi_core.c +++ b/drivers/sfi/sfi_core.c @@ -515,7 +515,7 @@ void __init sfi_init_late(void) } /* - * The reason we put it here becasue we need wait till the /sys/firmware + * The reason we put it here because we need wait till the /sys/firmware * is setup, then our interface can be registered in /sys/firmware/sfi */ core_initcall(sfi_sysfs_init); diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c index 5a4e0afb9ad6..5825370bad25 100644 --- a/drivers/spi/amba-pl022.c +++ b/drivers/spi/amba-pl022.c @@ -661,7 +661,7 @@ static void readwriter(struct pl022 *pl022) { /* - * The FIFO depth is different inbetween primecell variants. + * The FIFO depth is different between primecell variants. * I believe filling in too much in the FIFO might cause * errons in 8bit wide transfers on ARM variants (just 8 words * FIFO, means only 8x8 = 64 bits in FIFO) at least. @@ -722,7 +722,7 @@ static void readwriter(struct pl022 *pl022) * This inner reader takes care of things appearing in the RX * FIFO as we're transmitting. This will happen a lot since the * clock starts running when you put things into the TX FIFO, - * and then things are continously clocked into the RX FIFO. + * and then things are continuously clocked into the RX FIFO. */ while ((readw(SSP_SR(pl022->virtbase)) & SSP_SR_MASK_RNE) && (pl022->rx < pl022->rx_end)) { @@ -842,7 +842,7 @@ static void dma_callback(void *data) unmap_free_dma_scatter(pl022); - /* Update total bytes transfered */ + /* Update total bytes transferred */ msg->actual_length += pl022->cur_transfer->len; if (pl022->cur_transfer->cs_change) pl022->cur_chip-> @@ -1224,7 +1224,7 @@ static irqreturn_t pl022_interrupt_handler(int irq, void *dev_id) "number of bytes on a 16bit bus?)\n", (u32) (pl022->rx - pl022->rx_end)); } - /* Update total bytes transfered */ + /* Update total bytes transferred */ msg->actual_length += pl022->cur_transfer->len; if (pl022->cur_transfer->cs_change) pl022->cur_chip-> @@ -1415,11 +1415,11 @@ static void do_polling_transfer(struct pl022 *pl022) SSP_CR1(pl022->virtbase)); dev_dbg(&pl022->adev->dev, "polling transfer ongoing ...\n"); - /* FIXME: insert a timeout so we don't hang here indefinately */ + /* FIXME: insert a timeout so we don't hang here indefinitely */ while (pl022->tx < pl022->tx_end || pl022->rx < pl022->rx_end) readwriter(pl022); - /* Update total byte transfered */ + /* Update total byte transferred */ message->actual_length += pl022->cur_transfer->len; if (pl022->cur_transfer->cs_change) pl022->cur_chip->cs_control(SSP_CHIP_DESELECT); @@ -2129,7 +2129,7 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) "probe - problem registering spi master\n"); goto err_spi_register; } - dev_dbg(dev, "probe succeded\n"); + dev_dbg(dev, "probe succeeded\n"); /* * Disable the silicon block pclk and any voltage domain and just * power it up and clock it when it's needed @@ -2184,7 +2184,7 @@ pl022_remove(struct amba_device *adev) spi_unregister_master(pl022->master); spi_master_put(pl022->master); amba_set_drvdata(adev, NULL); - dev_dbg(&adev->dev, "remove succeded\n"); + dev_dbg(&adev->dev, "remove succeeded\n"); return 0; } diff --git a/drivers/spi/au1550_spi.c b/drivers/spi/au1550_spi.c index 3c9ade69643f..b50563d320e1 100644 --- a/drivers/spi/au1550_spi.c +++ b/drivers/spi/au1550_spi.c @@ -480,7 +480,7 @@ static irqreturn_t au1550_spi_dma_irq_callback(struct au1550_spi *hw) au1xxx_dbdma_stop(hw->dma_rx_ch); au1xxx_dbdma_stop(hw->dma_tx_ch); - /* get number of transfered bytes */ + /* get number of transferred bytes */ hw->rx_count = hw->len - au1xxx_get_dma_residue(hw->dma_rx_ch); hw->tx_count = hw->len - au1xxx_get_dma_residue(hw->dma_tx_ch); diff --git a/drivers/spi/dw_spi.c b/drivers/spi/dw_spi.c index 9a6196461b27..b1a4b9f503ae 100644 --- a/drivers/spi/dw_spi.c +++ b/drivers/spi/dw_spi.c @@ -345,7 +345,7 @@ static void int_error_stop(struct dw_spi *dws, const char *msg) void dw_spi_xfer_done(struct dw_spi *dws) { - /* Update total byte transfered return count actual bytes read */ + /* Update total byte transferred return count actual bytes read */ dws->cur_msg->actual_length += dws->len; /* Move to next transfer */ diff --git a/drivers/spi/dw_spi.h b/drivers/spi/dw_spi.h index fb0bce564844..b23e452adaf7 100644 --- a/drivers/spi/dw_spi.h +++ b/drivers/spi/dw_spi.h @@ -46,7 +46,7 @@ #define SPI_INT_RXFI (1 << 4) #define SPI_INT_MSTI (1 << 5) -/* TX RX interrupt level threshhold, max can be 256 */ +/* TX RX interrupt level threshold, max can be 256 */ #define SPI_INT_THRESHOLD 32 enum dw_ssi_type { diff --git a/drivers/spi/ep93xx_spi.c b/drivers/spi/ep93xx_spi.c index 0ba35df9a6df..d3570071e98f 100644 --- a/drivers/spi/ep93xx_spi.c +++ b/drivers/spi/ep93xx_spi.c @@ -512,7 +512,7 @@ static int ep93xx_spi_read_write(struct ep93xx_spi *espi) * * This function processes one SPI transfer given in @t. Function waits until * transfer is complete (may sleep) and updates @msg->status based on whether - * transfer was succesfully processed or not. + * transfer was successfully processed or not. */ static void ep93xx_spi_process_transfer(struct ep93xx_spi *espi, struct spi_message *msg, diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index a429b01d0285..9c74aad6be93 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c @@ -700,7 +700,7 @@ static void int_transfer_complete(struct driver_data *drv_data) if (!pxa25x_ssp_comp(drv_data)) write_SSTO(0, reg); - /* Update total byte transfered return count actual bytes read */ + /* Update total byte transferred return count actual bytes read */ drv_data->cur_msg->actual_length += drv_data->len - (drv_data->rx_end - drv_data->rx); @@ -759,7 +759,7 @@ static irqreturn_t interrupt_transfer(struct driver_data *drv_data) /* * PXA25x_SSP has no timeout, set up rx threshould for the - * remaing RX bytes. + * remaining RX bytes. */ if (pxa25x_ssp_comp(drv_data)) { diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 34bb17f03019..82b9a428c323 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -957,7 +957,7 @@ EXPORT_SYMBOL_GPL(spi_sync); * drivers may DMA directly into and out of the message buffers. * * This call should be used by drivers that require exclusive access to the - * SPI bus. It has to be preceeded by a spi_bus_lock call. The SPI bus must + * SPI bus. It has to be preceded by a spi_bus_lock call. The SPI bus must * be released by a spi_bus_unlock call when the exclusive access is over. * * It returns zero on success, else a negative error code. diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c index a28462486df8..bdb7289a1d22 100644 --- a/drivers/spi/spi_bfin5xx.c +++ b/drivers/spi/spi_bfin5xx.c @@ -905,7 +905,7 @@ static void bfin_spi_pump_transfers(unsigned long data) "IO write error!\n"); message->state = ERROR_STATE; } else { - /* Update total byte transfered */ + /* Update total byte transferred */ message->actual_length += drv_data->len_in_bytes; /* Move to next transfer of this msg */ message->state = bfin_spi_next_transfer(drv_data); diff --git a/drivers/spi/spi_fsl_espi.c b/drivers/spi/spi_fsl_espi.c index 900e921ab80e..496f895a0024 100644 --- a/drivers/spi/spi_fsl_espi.c +++ b/drivers/spi/spi_fsl_espi.c @@ -474,7 +474,7 @@ static int fsl_espi_setup(struct spi_device *spi) mpc8xxx_spi = spi_master_get_devdata(spi->master); reg_base = mpc8xxx_spi->reg_base; - hw_mode = cs->hw_mode; /* Save orginal settings */ + hw_mode = cs->hw_mode; /* Save original settings */ cs->hw_mode = mpc8xxx_spi_read_reg( ®_base->csmode[spi->chip_select]); /* mask out bits we are going to set */ diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index a467b20baac8..6f34963b3c64 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c @@ -670,7 +670,7 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus, ssb_printk(KERN_ERR PFX "No SPROM available!\n"); return -ENODEV; } - if (bus->chipco.dev) { /* can be unavailible! */ + if (bus->chipco.dev) { /* can be unavailable! */ /* * get SPROM offset: SSB_SPROM_BASE1 except for * chipcommon rev >= 31 or chip ID is 0x4312 and diff --git a/drivers/ssb/sprom.c b/drivers/ssb/sprom.c index 4f7cc8d13277..5f34d7a3e3a5 100644 --- a/drivers/ssb/sprom.c +++ b/drivers/ssb/sprom.c @@ -185,7 +185,7 @@ bool ssb_is_sprom_available(struct ssb_bus *bus) /* this routine differs from specs as we do not access SPROM directly on PCMCIA */ if (bus->bustype == SSB_BUSTYPE_PCI && - bus->chipco.dev && /* can be unavailible! */ + bus->chipco.dev && /* can be unavailable! */ bus->chipco.dev->id.revision >= 31) return bus->chipco.capabilities & SSB_CHIPCO_CAP_SPROM; diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c index c6488e0d1305..41223f953589 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c @@ -237,7 +237,7 @@ static int CreditsAvailableCallback(void *pContext, int Credits, bool CreditIRQE pProt->CreditsCurrentSeek)); if (pProt->CreditsAvailable >= pProt->CreditsCurrentSeek) { - /* we have enough credits to fullfill at least 1 packet waiting in the queue */ + /* we have enough credits to fulfill at least 1 packet waiting in the queue */ pProt->CreditsCurrentSeek = 0; pProt->SendStateFlags &= ~HCI_SEND_WAIT_CREDITS; doPendingSends = true; @@ -285,7 +285,7 @@ static void FailureCallback(void *pContext, int Status) { struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)pContext; - /* target assertion occured */ + /* target assertion occurred */ NotifyTransportFailure(pProt, Status); } @@ -507,7 +507,7 @@ static int HCIUartMessagePending(void *pContext, u8 LookAheadBytes[], int ValidB } while (false); - /* check if we need to disable the reciever */ + /* check if we need to disable the receiver */ if (status || blockRecv) { DevGMboxIRQAction(pProt->pDev, GMBOX_RECV_IRQ_DISABLE, PROC_IO_SYNC); } diff --git a/drivers/staging/ath6kl/include/aggr_recv_api.h b/drivers/staging/ath6kl/include/aggr_recv_api.h index 67a058492c4d..5ead58d5febd 100644 --- a/drivers/staging/ath6kl/include/aggr_recv_api.h +++ b/drivers/staging/ath6kl/include/aggr_recv_api.h @@ -72,7 +72,7 @@ aggr_process_bar(void *cntxt, u8 tid, u16 seq_no); * This event is to initiate/modify the receive side window. * Target will send WMI_ADDBA_REQ_EVENTID event to host - to setup * recv re-ordering queues. Target will negotiate ADDBA with peer, - * and indicate via this event after succesfully completing the + * and indicate via this event after successfully completing the * negotiation. This happens in two situations: * 1. Initial setup of aggregation * 2. Renegotiation of current recv window. diff --git a/drivers/staging/ath6kl/include/common/a_hci.h b/drivers/staging/ath6kl/include/common/a_hci.h index 08cb013090be..379d65224e3a 100644 --- a/drivers/staging/ath6kl/include/common/a_hci.h +++ b/drivers/staging/ath6kl/include/common/a_hci.h @@ -124,7 +124,7 @@ #define PAL_NUM_COMPL_DATA_BLOCK_EVENT 0x48 #define PAL_SHORT_RANGE_MODE_CHANGE_COMPL_EVENT 0x4C #define PAL_AMP_STATUS_CHANGE_EVENT 0x4D -/*======== End of PAL events definiton =================*/ +/*======== End of PAL events definition =================*/ /*======== Timeouts (not part of HCI cmd, but input to PAL engine) =========*/ @@ -430,7 +430,7 @@ typedef struct hci_event_hw_err_t { u8 hw_err_code; } POSTPACK HCI_EVENT_HW_ERR; -/* Flush occured event */ +/* Flush occurred event */ /* Qos Violation event */ typedef struct hci_event_handle_t { u8 event_code; diff --git a/drivers/staging/ath6kl/include/common/dbglog.h b/drivers/staging/ath6kl/include/common/dbglog.h index 3a3d00da0b81..b7a123086ccf 100644 --- a/drivers/staging/ath6kl/include/common/dbglog.h +++ b/drivers/staging/ath6kl/include/common/dbglog.h @@ -44,7 +44,7 @@ extern "C" { #define DBGLOG_MODULEID_NUM_MAX 16 /* Upper limit is width of mask */ /* - * Please ensure that the definition of any new module intrduced is captured + * Please ensure that the definition of any new module introduced is captured * between the DBGLOG_MODULEID_START and DBGLOG_MODULEID_END defines. The * structure is required for the parser to correctly pick up the values for * different modules. diff --git a/drivers/staging/ath6kl/include/common/epping_test.h b/drivers/staging/ath6kl/include/common/epping_test.h index 5c40d8a2229d..7027fac8f37e 100644 --- a/drivers/staging/ath6kl/include/common/epping_test.h +++ b/drivers/staging/ath6kl/include/common/epping_test.h @@ -92,7 +92,7 @@ typedef PREPACK struct { #define EPPING_CMD_RESET_RECV_CNT 2 /* reset recv count */ #define EPPING_CMD_CAPTURE_RECV_CNT 3 /* fetch recv count, 4-byte count returned in CmdBuffer_t */ #define EPPING_CMD_NO_ECHO 4 /* non-echo packet test (tx-only) */ -#define EPPING_CMD_CONT_RX_START 5 /* continous RX packets, parameters are in CmdBuffer_h */ +#define EPPING_CMD_CONT_RX_START 5 /* continuous RX packets, parameters are in CmdBuffer_h */ #define EPPING_CMD_CONT_RX_STOP 6 /* stop continuous RX packet transmission */ /* test command parameters may be no more than 8 bytes */ diff --git a/drivers/staging/ath6kl/include/common/ini_dset.h b/drivers/staging/ath6kl/include/common/ini_dset.h index 8bfc75940c8f..a9e05fa0f659 100644 --- a/drivers/staging/ath6kl/include/common/ini_dset.h +++ b/drivers/staging/ath6kl/include/common/ini_dset.h @@ -31,7 +31,7 @@ */ typedef enum { #if defined(AR6002_REV4) || defined(AR6003) -/* Add these definitions for compatability */ +/* Add these definitions for compatibility */ #define WHAL_INI_DATA_ID_BB_RFGAIN_LNA1 WHAL_INI_DATA_ID_BB_RFGAIN #define WHAL_INI_DATA_ID_BB_RFGAIN_LNA2 WHAL_INI_DATA_ID_BB_RFGAIN WHAL_INI_DATA_ID_NULL =0, diff --git a/drivers/staging/ath6kl/include/common/testcmd.h b/drivers/staging/ath6kl/include/common/testcmd.h index 9ca1f2ac2cbf..7d94aee508b3 100644 --- a/drivers/staging/ath6kl/include/common/testcmd.h +++ b/drivers/staging/ath6kl/include/common/testcmd.h @@ -43,8 +43,8 @@ typedef enum { PN15_PATTERN }TX_DATA_PATTERN; -/* Continous tx - mode : TCMD_CONT_TX_OFF - Disabling continous tx +/* Continuous tx + mode : TCMD_CONT_TX_OFF - Disabling continuous tx TCMD_CONT_TX_SINE - Enable continuous unmodulated tx TCMD_CONT_TX_FRAME- Enable continuous modulated tx freq : Channel freq in Mhz. (e.g 2412 for channel 1 in 11 g) diff --git a/drivers/staging/ath6kl/include/common/wmi.h b/drivers/staging/ath6kl/include/common/wmi.h index c645af373442..4e6343485362 100644 --- a/drivers/staging/ath6kl/include/common/wmi.h +++ b/drivers/staging/ath6kl/include/common/wmi.h @@ -1568,8 +1568,8 @@ typedef PREPACK struct { switch to ps-poll mode default = 3 */ - u32 scoContStompMax; /* max number of continous stomp allowed in opt mode. - if excedded switch to pspoll mode + u32 scoContStompMax; /* max number of continuous stomp allowed in opt mode. + if exceeded switch to pspoll mode default = 3 */ u32 scoMinlowRateMbps; /* Low rate threshold */ @@ -2084,7 +2084,7 @@ typedef PREPACK struct { /* * BSS INFO HDR version 2.0 * With 6 bytes HTC header and 6 bytes of WMI header - * WMI_BSS_INFO_HDR cannot be accomodated in the removed 802.11 management + * WMI_BSS_INFO_HDR cannot be accommodated in the removed 802.11 management * header space. * - Reduce the ieMask to 2 bytes as only two bit flags are used * - Remove rssi and compute it on the host. rssi = snr - 95 @@ -2911,7 +2911,7 @@ typedef PREPACK struct { u8 pktID; /* packet ID to identify parent packet */ u8 rateIdx; /* rate index on successful transmission */ u8 ackFailures; /* number of ACK failures in tx attempt */ -#if 0 /* optional params currently ommitted. */ +#if 0 /* optional params currently omitted. */ u32 queueDelay; // usec delay measured Tx Start time - host delivery time u32 mediaDelay; // usec delay measured ACK rx time - host delivery time #endif diff --git a/drivers/staging/ath6kl/include/common/wmix.h b/drivers/staging/ath6kl/include/common/wmix.h index 5ebb8285d135..36acba66d49f 100644 --- a/drivers/staging/ath6kl/include/common/wmix.h +++ b/drivers/staging/ath6kl/include/common/wmix.h @@ -191,7 +191,7 @@ typedef PREPACK struct { } POSTPACK WMIX_GPIO_INTR_ACK_CMD; /* - * Target informs Host of GPIO interrupts that have ocurred since the + * Target informs Host of GPIO interrupts that have occurred since the * last WMIX_GIPO_INTR_ACK_CMD was received. Additional information -- * the current GPIO input values is provided -- in order to support * use of a GPIO interrupt as a Data Valid signal for other GPIO pins. diff --git a/drivers/staging/ath6kl/include/htc_api.h b/drivers/staging/ath6kl/include/htc_api.h index 1bc2488788ab..4fb767559f82 100644 --- a/drivers/staging/ath6kl/include/htc_api.h +++ b/drivers/staging/ath6kl/include/htc_api.h @@ -209,7 +209,7 @@ struct htc_endpoint_credit_dist { typedef enum _HTC_CREDIT_DIST_REASON { HTC_CREDIT_DIST_SEND_COMPLETE = 0, /* credits available as a result of completed send operations (MANDATORY) resulting in credit reports */ - HTC_CREDIT_DIST_ACTIVITY_CHANGE = 1, /* a change in endpoint activity occured (OPTIONAL) */ + HTC_CREDIT_DIST_ACTIVITY_CHANGE = 1, /* a change in endpoint activity occurred (OPTIONAL) */ HTC_CREDIT_DIST_SEEK_CREDITS, /* an endpoint needs to "seek" credits (OPTIONAL) */ HTC_DUMP_CREDIT_STATE /* for debugging, dump any state information that is kept by the distribution function */ @@ -253,7 +253,7 @@ struct htc_endpoint_stats { u32 RxPacketsBundled; /* count of recv packets received in a bundle */ u32 RxBundleLookAheads; /* count of number of bundled lookaheads */ u32 RxBundleIndFromHdr; /* count of the number of bundle indications from the HTC header */ - u32 RxAllocThreshHit; /* count of the number of times the recv allocation threshhold was hit */ + u32 RxAllocThreshHit; /* count of the number of times the recv allocation threshold was hit */ u32 RxAllocThreshBytes; /* total number of bytes */ }; @@ -391,7 +391,7 @@ int HTCSendPkt(HTC_HANDLE HTCHandle, struct htc_packet *pPacket); +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ void HTCStop(HTC_HANDLE HTCHandle); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @desc: Destory HTC service + @desc: Destroy HTC service @function name: HTCDestroy @input: HTCHandle @output: diff --git a/drivers/staging/ath6kl/miscdrv/credit_dist.c b/drivers/staging/ath6kl/miscdrv/credit_dist.c index ae54e1f48e50..33fa0209026d 100644 --- a/drivers/staging/ath6kl/miscdrv/credit_dist.c +++ b/drivers/staging/ath6kl/miscdrv/credit_dist.c @@ -341,7 +341,7 @@ static void SeekCredits(struct common_credit_state_info *pCredInfo, credits = min(pCredInfo->CurrentFreeCredits,pEPDist->TxCreditsSeek); if (credits >= pEPDist->TxCreditsSeek) { - /* we found some to fullfill the seek request */ + /* we found some to fulfill the seek request */ break; } @@ -364,8 +364,8 @@ static void SeekCredits(struct common_credit_state_info *pCredInfo, if ((pCurEpDist->TxCreditsAssigned - need) >= pCurEpDist->TxCreditsMin) { /* the current one has been allocated more than it's minimum and it - * has enough credits assigned above it's minimum to fullfill our need - * try to take away just enough to fullfill our need */ + * has enough credits assigned above it's minimum to fulfill our need + * try to take away just enough to fulfill our need */ ReduceCredits(pCredInfo, pCurEpDist, pCurEpDist->TxCreditsAssigned - need); diff --git a/drivers/staging/ath6kl/os/linux/ar6000_android.c b/drivers/staging/ath6kl/os/linux/ar6000_android.c index c96f6e9c99c6..4aa75ee2cb13 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_android.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_android.c @@ -372,7 +372,7 @@ void android_ar6k_check_wow_status(struct ar6_softc *ar, struct sk_buff *skb, bo } } if (needWake) { - /* keep host wake up if there is any event and packate comming in*/ + /* keep host wake up if there is any event and packate coming in*/ if (wowledon) { char buf[32]; int len = sprintf(buf, "on"); diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 27cb02dfad3c..97d6ce63b5c0 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -520,7 +520,7 @@ dbglog_parse_debug_logs(s8 *datap, u32 len) int ar6000_dbglog_get_debug_logs(struct ar6_softc *ar) { - u32 data[8]; /* Should be able to accomodate struct dbglog_buf_s */ + u32 data[8]; /* Should be able to accommodate struct dbglog_buf_s */ u32 address; u32 length; u32 dropped; @@ -2063,7 +2063,7 @@ ar6000_stop_endpoint(struct net_device *dev, bool keepprofile, bool getdbglogs) * - In case of surprise removal, the hcd already frees up the pending * for the device and hence there is no need to unregister the function * driver inorder to get these requests. For planned removal, the function - * driver has to explictly unregister itself to have the hcd return all the + * driver has to explicitly unregister itself to have the hcd return all the * pending requests before the data structures for the devices are freed up. * Note that as per the current implementation, the function driver will * end up releasing all the devices since there is no API to selectively @@ -2982,7 +2982,7 @@ ar6000_data_tx(struct sk_buff *skb, struct net_device *dev) /* If target is not associated */ if( (!ar->arConnected && !bypasswmi) #ifdef CONFIG_HOST_TCMD_SUPPORT - /* TCMD doesnt support any data, free the buf and return */ + /* TCMD doesn't support any data, free the buf and return */ || (ar->arTargetMode == AR6000_TCMD_MODE) #endif ) { @@ -6393,7 +6393,7 @@ static void DoHTCSendPktsTest(struct ar6_softc *ar, int MapNo, HTC_ENDPOINT_ID e /* * Add support for adding and removing a virtual adapter for soft AP. * Some OS requires different adapters names for station and soft AP mode. - * To support these requirement, create and destory a netdevice instance + * To support these requirement, create and destroy a netdevice instance * when the AP mode is operational. A full fledged support for virual device * is not implemented. Rather a virtual interface is created and is linked * with the existing physical device instance during the operation of the diff --git a/drivers/staging/ath6kl/wmi/wmi.c b/drivers/staging/ath6kl/wmi/wmi.c index 0ddaee21f9d7..a00bf0a59871 100644 --- a/drivers/staging/ath6kl/wmi/wmi.c +++ b/drivers/staging/ath6kl/wmi/wmi.c @@ -4867,7 +4867,7 @@ wmi_set_country(struct wmi_t *wmip, u8 *countryCode) #ifdef CONFIG_HOST_TCMD_SUPPORT /* WMI layer doesn't need to know the data type of the test cmd. This would be beneficial for customers like Qualcomm, who might - have different test command requirements from differnt manufacturers + have different test command requirements from different manufacturers */ int wmi_test_cmd(struct wmi_t *wmip, u8 *buf, u32 len) diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h index 32909e2938d5..20cca24ff5f0 100644 --- a/drivers/staging/bcm/Adapter.h +++ b/drivers/staging/bcm/Adapter.h @@ -412,7 +412,7 @@ struct _MINI_ADAPTER // this to keep track of the Tx and Rx MailBox Registers. atomic_t CurrNumFreeTxDesc; - // to keep track the no of byte recieved + // to keep track the no of byte received USHORT PrevNumRecvDescs; USHORT CurrNumRecvDescs; UINT u32TotalDSD; @@ -527,7 +527,7 @@ struct _MINI_ADAPTER BOOLEAN bStatusWrite; UINT uiNVMDSDSize; UINT uiVendorExtnFlag; - //it will always represent choosed DSD at any point of time. + //it will always represent chosen DSD at any point of time. // Generally it is Active DSD but in case of NVM RD/WR it might be different. UINT ulFlashCalStart; ULONG ulFlashControlSectionStart; @@ -546,10 +546,10 @@ struct _MINI_ADAPTER PFLASH_CS_INFO psFlashCSInfo ; PFLASH2X_VENDORSPECIFIC_INFO psFlash2xVendorInfo; UINT uiFlashBaseAdd; //Flash start address - UINT uiActiveISOOffset; //Active ISO offset choosen before f/w download + UINT uiActiveISOOffset; //Active ISO offset chosen before f/w download FLASH2X_SECTION_VAL eActiveISO; //Active ISO section val - FLASH2X_SECTION_VAL eActiveDSD; //Active DSD val choosen before f/w download - UINT uiActiveDSDOffsetAtFwDld; //For accessing Active DSD choosen before f/w download + FLASH2X_SECTION_VAL eActiveDSD; //Active DSD val chosen before f/w download + UINT uiActiveDSDOffsetAtFwDld; //For accessing Active DSD chosen before f/w download UINT uiFlashLayoutMajorVersion ; UINT uiFlashLayoutMinorVersion; BOOLEAN bAllDSDWriteAllow ; diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c index 9be184f143e5..c0ee95a71343 100644 --- a/drivers/staging/bcm/CmHost.c +++ b/drivers/staging/bcm/CmHost.c @@ -384,7 +384,7 @@ static inline VOID CopyClassifierRuleToSF(PMINI_ADAPTER Adapter,stConvergenceSLT } if(psfCSType->cCPacketClassificationRule.u8Protocol == 0) { - //we didnt get protocol field filled in by the BS + //we didn't get protocol field filled in by the BS pstClassifierEntry->ucProtocolLength=0; } else @@ -879,7 +879,7 @@ static VOID CopyToAdapter( register PMINI_ADAPTER Adapter, /**sfAuthorizedSet.u8TrafficIndicationPreference); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " Total Classifiers Recieved : 0x%X",pstAddIndication->sfAuthorizedSet.u8TotalClassifiers); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " Total Classifiers Received : 0x%X",pstAddIndication->sfAuthorizedSet.u8TotalClassifiers); nCurClassifierCnt = pstAddIndication->sfAuthorizedSet.u8TotalClassifiers; @@ -1305,7 +1305,7 @@ static VOID DumpCmControlPacket(PVOID pvBuffer) BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficIndicationPreference : 0x%02X", pstAddIndication->sfAdmittedSet.u8TrafficIndicationPreference); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " Total Classifiers Recieved : 0x%X",pstAddIndication->sfAdmittedSet.u8TotalClassifiers); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " Total Classifiers Received : 0x%X",pstAddIndication->sfAdmittedSet.u8TotalClassifiers); nCurClassifierCnt = pstAddIndication->sfAdmittedSet.u8TotalClassifiers; @@ -1502,7 +1502,7 @@ static VOID DumpCmControlPacket(PVOID pvBuffer) BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8TrafficIndicationPreference : 0x%X", pstAddIndication->sfActiveSet.u8TrafficIndicationPreference); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " Total Classifiers Recieved : 0x%X",pstAddIndication->sfActiveSet.u8TotalClassifiers); + BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " Total Classifiers Received : 0x%X",pstAddIndication->sfActiveSet.u8TotalClassifiers); nCurClassifierCnt = pstAddIndication->sfActiveSet.u8TotalClassifiers; @@ -1696,7 +1696,7 @@ ULONG StoreCmControlResponseMessage(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT *p //No Special handling send the message as it is return 1; } - // For DSA_REQ, only upto "psfAuthorizedSet" parameter should be accessed by driver! + // For DSA_REQ, only up to "psfAuthorizedSet" parameter should be accessed by driver! pstAddIndication=kmalloc(sizeof(*pstAddIndication), GFP_KERNEL); if(NULL==pstAddIndication) @@ -1788,7 +1788,7 @@ static inline stLocalSFAddIndicationAlt BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Inside RestoreCmControlResponseMessage "); /* //Need to Allocate memory to contain the SUPER Large structures - //Our driver cant create these structures on Stack :( + //Our driver can't create these structures on Stack :( */ pstAddIndicationDest=kmalloc(sizeof(stLocalSFAddIndicationAlt), GFP_KERNEL); @@ -1957,7 +1957,7 @@ INT AllocAdapterDsxBuffer(PMINI_ADAPTER Adapter) { /* //Need to Allocate memory to contain the SUPER Large structures - //Our driver cant create these structures on Stack + //Our driver can't create these structures on Stack */ Adapter->caDsxReqResp=kmalloc(sizeof(stLocalSFAddIndicationAlt)+LEADER_SIZE, GFP_KERNEL); if(!Adapter->caDsxReqResp) diff --git a/drivers/staging/bcm/HostMIBSInterface.h b/drivers/staging/bcm/HostMIBSInterface.h index f17a4f13474c..e34531b638e8 100644 --- a/drivers/staging/bcm/HostMIBSInterface.h +++ b/drivers/staging/bcm/HostMIBSInterface.h @@ -62,7 +62,7 @@ typedef struct _S_MIBS_HOST_INFO ULONG NumDesUsed; ULONG CurrNumFreeDesc; ULONG PrevNumFreeDesc; - // to keep track the no of byte recieved + // to keep track the no of byte received ULONG PrevNumRcevBytes; ULONG CurrNumRcevBytes; diff --git a/drivers/staging/bcm/IPv6Protocol.c b/drivers/staging/bcm/IPv6Protocol.c index 91b6fbe33c91..5b4fd372ec36 100644 --- a/drivers/staging/bcm/IPv6Protocol.c +++ b/drivers/staging/bcm/IPv6Protocol.c @@ -287,7 +287,7 @@ static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Head for(uiLoopIndex=0;uiLoopIndexstSrcIpAddress.ulIpv6Mask[uiLoopIndex]); @@ -340,7 +340,7 @@ static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Hea for(uiLoopIndex=0;uiLoopIndexstDestIpAddress.ulIpv6Mask[uiLoopIndex]); diff --git a/drivers/staging/bcm/InterfaceIdleMode.c b/drivers/staging/bcm/InterfaceIdleMode.c index bf5c0ad86610..96fa4ead7930 100644 --- a/drivers/staging/bcm/InterfaceIdleMode.c +++ b/drivers/staging/bcm/InterfaceIdleMode.c @@ -11,7 +11,7 @@ Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context Return: BCM_STATUS_SUCCESS - If Wakeup of the HW Interface was successful. - Other - If an error occured. + Other - If an error occurred. */ @@ -26,7 +26,7 @@ Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context Return: BCM_STATUS_SUCCESS - If Idle mode response related HW configuration was successful. - Other - If an error occured. + Other - If an error occurred. */ /* diff --git a/drivers/staging/bcm/InterfaceIsr.c b/drivers/staging/bcm/InterfaceIsr.c index 220ff922bdcf..67719d57256d 100644 --- a/drivers/staging/bcm/InterfaceIsr.c +++ b/drivers/staging/bcm/InterfaceIsr.c @@ -80,8 +80,8 @@ static void read_int_callback(struct urb *urb/*, struct pt_regs *regs*/) } case -EINPROGRESS: { - //This situation may happend when URBunlink is used. for detail check usb_unlink_urb documentation. - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Impossibe condition has occured... something very bad is going on"); + //This situation may happened when URBunlink is used. for detail check usb_unlink_urb documentation. + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Impossibe condition has occurred... something very bad is going on"); break ; //return; } diff --git a/drivers/staging/bcm/InterfaceRx.c b/drivers/staging/bcm/InterfaceRx.c index 533f8ebe0f84..806ef5d18522 100644 --- a/drivers/staging/bcm/InterfaceRx.c +++ b/drivers/staging/bcm/InterfaceRx.c @@ -34,7 +34,7 @@ GetBulkInRcb(PS_INTERFACE_ADAPTER psIntfAdapter) return pRcb; } -/*this is receive call back - when pkt avilable for receive (BULK IN- end point)*/ +/*this is receive call back - when pkt available for receive (BULK IN- end point)*/ static void read_bulk_callback(struct urb *urb) { struct sk_buff *skb = NULL; @@ -123,7 +123,7 @@ static void read_bulk_callback(struct urb *urb) if((ntohs(pLeader->Vcid) == VCID_CONTROL_PACKET) || (!(pLeader->Status >= 0x20 && pLeader->Status <= 0x3F))) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_CTRL, DBG_LVL_ALL, "Recived control pkt..."); + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_CTRL, DBG_LVL_ALL, "Received control pkt..."); *(PUSHORT)skb->data = pLeader->Status; memcpy(skb->data+sizeof(USHORT), urb->transfer_buffer + (sizeof(LEADER)), pLeader->PLength); @@ -142,7 +142,7 @@ static void read_bulk_callback(struct urb *urb) * Data Packet, Format a proper Ethernet Header * and give it to the stack */ - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "Recived Data pkt..."); + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "Received Data pkt..."); skb_reserve(skb, 2 + SKB_RESERVE_PHS_BYTES); memcpy(skb->data+ETH_HLEN, (PUCHAR)urb->transfer_buffer + sizeof(LEADER), pLeader->PLength); skb->dev = Adapter->dev; @@ -151,7 +151,7 @@ static void read_bulk_callback(struct urb *urb) skb_put (skb, pLeader->PLength + ETH_HLEN); Adapter->PackInfo[QueueIndex].uiTotalRxBytes+=pLeader->PLength; Adapter->PackInfo[QueueIndex].uiThisPeriodRxBytes+= pLeader->PLength; - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "Recived Data pkt of len :0x%X", pLeader->PLength); + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "Received Data pkt of len :0x%X", pLeader->PLength); if(netif_running(Adapter->dev)) { @@ -237,7 +237,7 @@ Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context Return: TRUE - If Rx was successful. - Other - If an error occured. + Other - If an error occurred. */ BOOLEAN InterfaceRx (PS_INTERFACE_ADAPTER psIntfAdapter) diff --git a/drivers/staging/bcm/Ioctl.h b/drivers/staging/bcm/Ioctl.h index e4f8eb70be1e..f859cf1c47b0 100644 --- a/drivers/staging/bcm/Ioctl.h +++ b/drivers/staging/bcm/Ioctl.h @@ -241,7 +241,7 @@ typedef struct bulkwrmbuffer typedef enum _FLASH2X_SECTION_VAL { - NO_SECTION_VAL = 0, //no section is choosen when absolute offset is given for RD/WR + NO_SECTION_VAL = 0, //no section is chosen when absolute offset is given for RD/WR ISO_IMAGE1, ISO_IMAGE2, DSD0, diff --git a/drivers/staging/bcm/LeakyBucket.c b/drivers/staging/bcm/LeakyBucket.c index f4cf41c0e46b..a55d4228e8e0 100644 --- a/drivers/staging/bcm/LeakyBucket.c +++ b/drivers/staging/bcm/LeakyBucket.c @@ -213,7 +213,7 @@ static VOID CheckAndSendPacketFromIndex(PMINI_ADAPTER Adapter, PacketInfo *psSF) BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "For Queue: %zd\n", psSF-Adapter->PackInfo); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "\nAvailable Tokens = %d required = %d\n", psSF->uiCurrentTokenCount, iPacketLen); - //this part indicates that becuase of non-availability of the tokens + //this part indicates that because of non-availability of the tokens //pkt has not been send out hence setting the pending flag indicating the host to send it out //first next iteration . psSF->uiPendedLast = TRUE; diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index d624f35d0551..c5003b62234c 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -602,7 +602,7 @@ VOID LinkControlResponseMessage(PMINI_ADAPTER Adapter,PUCHAR pucBuffer) Adapter->LinkStatus=LINKUP_DONE; Adapter->bPHSEnabled = *(pucBuffer+3); Adapter->bETHCSEnabled = *(pucBuffer+4) & ETH_CS_MASK; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "PHS Support Status Recieved In LinkUp Ack : %x \n",Adapter->bPHSEnabled); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "PHS Support Status Received In LinkUp Ack : %x \n",Adapter->bPHSEnabled); if((FALSE == Adapter->bShutStatus)&& (FALSE == Adapter->IdleMode)) { @@ -1153,7 +1153,7 @@ int InitCardAndDownloadFirmware(PMINI_ADAPTER ps_adapter) /* * 1. If the LED Settings fails, do not stop and do the Firmware download. - * 2. This init would happend only if the cfg file is present, else + * 2. This init would happened only if the cfg file is present, else * call from the ioctl context. */ @@ -1185,7 +1185,7 @@ int InitCardAndDownloadFirmware(PMINI_ADAPTER ps_adapter) status = PropagateCalParamsFromFlashToMemory(ps_adapter); if(status) { - BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL," Propogation of Cal param failed .." ); + BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL," Propagation of Cal param failed .." ); goto OUT; } } diff --git a/drivers/staging/bcm/Qos.c b/drivers/staging/bcm/Qos.c index feade9451b2e..c97020f0fb6a 100644 --- a/drivers/staging/bcm/Qos.c +++ b/drivers/staging/bcm/Qos.c @@ -727,7 +727,7 @@ static BOOLEAN EthCSMatchVLANRules(S_CLASSIFIER_RULE *pstClassifierRule,struct s BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s CLS UserPrio:%x CLS VLANID:%x\n",__FUNCTION__,ntohs(*((USHORT *)pstClassifierRule->usUserPriority)),pstClassifierRule->usVLANID); - /* In case FW didn't recieve the TLV, the priority field should be ignored */ + /* In case FW didn't receive the TLV, the priority field should be ignored */ if(pstClassifierRule->usValidityBitMap & (1<eNwpktEthFrameType!=eEth802QVLANFrame) diff --git a/drivers/staging/bcm/cntrl_SignalingInterface.h b/drivers/staging/bcm/cntrl_SignalingInterface.h index 890778450a86..ab131806e2c9 100644 --- a/drivers/staging/bcm/cntrl_SignalingInterface.h +++ b/drivers/staging/bcm/cntrl_SignalingInterface.h @@ -21,7 +21,7 @@ #define VENDOR_PHS_PARAM_LENGTH 10 #define MAX_NUM_ACTIVE_BS 10 #define AUTH_TOKEN_LENGTH 10 -#define NUM_HARQ_CHANNELS 16 //Changed from 10 to 16 to accomodate all HARQ channels +#define NUM_HARQ_CHANNELS 16 //Changed from 10 to 16 to accommodate all HARQ channels #define VENDOR_CLASSIFIER_PARAM_LENGTH 1 //Changed the size to 1 byte since we dnt use it #define VENDOR_SPECIF_QOS_PARAM 1 #define VENDOR_PHS_PARAM_LENGTH 10 @@ -109,13 +109,13 @@ typedef struct _stPhsRuleSI { B_UINT8 u8PHSI; /** PHSF Length Of The Service Flow*/ B_UINT8 u8PHSFLength; - /** String of bytes containing header information to be supressed by the sending CS and reconstructed by the receiving CS*/ + /** String of bytes containing header information to be suppressed by the sending CS and reconstructed by the receiving CS*/ B_UINT8 u8PHSF[MAX_PHS_LENGTHS]; /** PHSM Length Of The Service Flow*/ B_UINT8 u8PHSMLength; /** PHS Mask for the SF*/ B_UINT8 u8PHSM[MAX_PHS_LENGTHS]; - /** 8bit Total number of bytes to be supressed for the Service Flow*/ + /** 8bit Total number of bytes to be suppressed for the Service Flow*/ B_UINT8 u8PHSS; /** 8bit Indicates whether or not Packet Header contents need to be verified prior to supression */ B_UINT8 u8PHSV; diff --git a/drivers/staging/bcm/nvm.c b/drivers/staging/bcm/nvm.c index c7292373a65f..4da5b7b54a1a 100644 --- a/drivers/staging/bcm/nvm.c +++ b/drivers/staging/bcm/nvm.c @@ -313,7 +313,7 @@ INT ReadMacAddressFromNVM(PMINI_ADAPTER Adapter) // uiNumBytes - Number of bytes to be read from the EEPROM. // // Returns: -// OSAL_STATUS_SUCCESS - if EEPROM read is successfull. +// OSAL_STATUS_SUCCESS - if EEPROM read is successful. // - if failed. //----------------------------------------------------------------------------- @@ -431,7 +431,7 @@ INT BeceemEEPROMBulkRead( // uiNumBytes - Number of bytes to be read from the FLASH. // // Returns: -// OSAL_STATUS_SUCCESS - if FLASH read is successfull. +// OSAL_STATUS_SUCCESS - if FLASH read is successful. // - if failed. //----------------------------------------------------------------------------- @@ -1174,7 +1174,7 @@ static INT BeceemFlashBulkWrite( if(NULL == pTempBuff) goto BeceemFlashBulkWrite_EXIT; // -// check if the data to be written is overlapped accross sectors +// check if the data to be written is overlapped across sectors // if(uiOffset+uiNumBytes < uiSectBoundary) { @@ -1390,7 +1390,7 @@ static INT BeceemFlashBulkWriteStatus( goto BeceemFlashBulkWriteStatus_EXIT; // -// check if the data to be written is overlapped accross sectors +// check if the data to be written is overlapped across sectors // if(uiOffset+uiNumBytes < uiSectBoundary) { @@ -2020,7 +2020,7 @@ INT BeceemEEPROMBulkWrite( // uiNumBytes - Number of bytes to be read from the NVM. // // Returns: -// OSAL_STATUS_SUCCESS - if NVM read is successfull. +// OSAL_STATUS_SUCCESS - if NVM read is successful. // - if failed. //----------------------------------------------------------------------------- @@ -2083,7 +2083,7 @@ INT BeceemNVMRead( // uiNumBytes - Number of bytes to be written.. // // Returns: -// OSAL_STATUS_SUCCESS - if NVM write is successfull. +// OSAL_STATUS_SUCCESS - if NVM write is successful. // - if failed. //----------------------------------------------------------------------------- @@ -2218,7 +2218,7 @@ INT BeceemNVMWrite( // uiSectorSize - sector size // // Returns: -// OSAL_STATUS_SUCCESS - if NVM write is successfull. +// OSAL_STATUS_SUCCESS - if NVM write is successful. // - if failed. //----------------------------------------------------------------------------- @@ -2430,7 +2430,7 @@ INT BcmInitNVM(PMINI_ADAPTER ps_adapter) *Input Parameter: * Adapter data structure *Return Value : -* 0. means sucess; +* 0. means success; */ /***************************************************************************/ @@ -2998,7 +2998,7 @@ INT BcmGetSectionValStartOffset(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlas /* * Considering all the section for which end offset can be calculated or directly given * in CS Structure. if matching case does not exist, return STATUS_FAILURE indicating section - * endoffset can't be calculated or given in CS Stucture. + * endoffset can't be calculated or given in CS Structure. */ INT SectStartOffset = 0 ; @@ -3173,7 +3173,7 @@ INT BcmGetSectionValEndOffset(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2 * @uiNumBytes : Number of Bytes for Read * * Return value:- -* return true on sucess and STATUS_FAILURE on fail. +* return true on success and STATUS_FAILURE on fail. */ INT BcmFlash2xBulkRead( @@ -3241,7 +3241,7 @@ INT BcmFlash2xBulkRead( * @uiNumBytes : Number of Bytes for Write * * Return value:- -* return true on sucess and STATUS_FAILURE on fail. +* return true on success and STATUS_FAILURE on fail. * */ @@ -3308,7 +3308,7 @@ INT BcmFlash2xBulkWrite( * @Adapter :-Drivers private Data Structure * * Return Value:- -* Return STATUS_SUCESS if get sucess in setting the right DSD else negaive error code +* Return STATUS_SUCESS if get success in setting the right DSD else negaive error code * **/ static INT BcmGetActiveDSD(PMINI_ADAPTER Adapter) @@ -3384,7 +3384,7 @@ static INT BcmGetActiveISO(PMINI_ADAPTER Adapter) * @uiOffset : Offset provided in the Flash * * Return Value:- -* Sucess:-TRUE , offset is writable +* Success:-TRUE , offset is writable * Failure:-FALSE, offset is RO * **/ @@ -3441,7 +3441,7 @@ static INT BcmDumpFlash2xSectionBitMap(PFLASH2X_BITMAP psFlash2xBitMap) @Adapter:-Driver private Data Structure * * Return value:- -* Sucess:- STATUS_SUCESS +* Success:- STATUS_SUCESS * Failure:- negative error code **/ @@ -3783,7 +3783,7 @@ INT BcmSetActiveSection(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectV // This is a SPECIAL Case which will only happen if the current highest priority ISO has priority value = 0x7FFFFFFF. // We will write 1 to the current Highest priority ISO And then shall increase the priority of the requested ISO // by user - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happend, eFlash2xSectVal: 0x%x\n",eFlash2xSectVal); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happened, eFlash2xSectVal: 0x%x\n",eFlash2xSectVal); SectImagePriority = htonl(0x1); Status = BcmFlash2xBulkWrite(Adapter, &SectImagePriority, @@ -3853,7 +3853,7 @@ INT BcmSetActiveSection(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectV // This is a SPECIAL Case which will only happen if the current highest priority DSD has priority value = 0x7FFFFFFF. // We will write 1 to the current Highest priority DSD And then shall increase the priority of the requested DSD // by user - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happend, eFlash2xSectVal: 0x%x\n",eFlash2xSectVal); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happened, eFlash2xSectVal: 0x%x\n",eFlash2xSectVal); SectImagePriority = htonl(0x1); Status = BcmFlash2xBulkWrite(Adapter, @@ -4119,7 +4119,7 @@ INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut) MAX_RW_SIZE); IsThisHeaderSector = FALSE ; } - //substracting the written Data + //subtracting the written Data uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize ; } @@ -4250,7 +4250,7 @@ INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut) IsThisHeaderSector = FALSE ; } - //substracting the written Data + //subtracting the written Data uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize ; } @@ -4268,7 +4268,7 @@ BcmFlash2xCorruptSig : this API is used to corrupt the written sig in Bcm Header @eFlash2xSectionVal :- Flash section val which has header Return Value :- - Sucess :- If Section is present and writable, corrupt the sig and return STATUS_SUCCESS + Success :- If Section is present and writable, corrupt the sig and return STATUS_SUCCESS Failure :-Return negative error code @@ -4301,7 +4301,7 @@ BcmFlash2xWriteSig :-this API is used to Write the sig if requested Section has @eFlashSectionVal :- Flash section val which has header Return Value :- - Sucess :- If Section is present and writable write the sig and return STATUS_SUCCESS + Success :- If Section is present and writable write the sig and return STATUS_SUCCESS Failure :-Return negative error code **/ @@ -4504,7 +4504,7 @@ BcmCopySection :- This API is used to copy the One section in another. Both sect in case of numofBytes equal zero complete section will be copied. Return Values- - Sucess : Return STATUS_SUCCESS + Success : Return STATUS_SUCCESS Faillure :- return negative error code **/ @@ -4621,7 +4621,7 @@ SaveHeaderIfPresent :- This API is use to Protect the Header in case of Header S @uiOffset :- Flash offset that has to be written. Return value :- - Sucess :- On sucess return STATUS_SUCCESS + Success :- On success return STATUS_SUCCESS Faillure :- Return negative error code **/ @@ -4634,7 +4634,7 @@ INT SaveHeaderIfPresent(PMINI_ADAPTER Adapter, PUCHAR pBuff, UINT uiOffset) UINT uiSectAlignAddr = 0; UINT sig = 0; - //making the offset sector alligned + //making the offset sector aligned uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1); @@ -4643,7 +4643,7 @@ INT SaveHeaderIfPresent(PMINI_ADAPTER Adapter, PUCHAR pBuff, UINT uiOffset) (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter,DSD0)- Adapter->uiSectorSize)) { - //offset from the sector boundry having the header map + //offset from the sector boundary having the header map offsetToProtect = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader % Adapter->uiSectorSize; HeaderSizeToProtect = sizeof(DSD_HEADER); bHasHeader = TRUE ; @@ -4697,7 +4697,7 @@ BcmDoChipSelect : This will selcet the appropriate chip for writing. @Adapater :- Bcm Driver Private Data Structure OutPut:- - Select the Appropriate chip and retrn status Sucess + Select the Appropriate chip and retrn status Success **/ static INT BcmDoChipSelect(PMINI_ADAPTER Adapter, UINT offset) { @@ -5086,7 +5086,7 @@ static INT CorruptDSDSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSect { if(IsSectionWritable(Adapter,eFlash2xSectionVal) != TRUE) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section is not Writable...Hence cant Corrupt signature"); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section is not Writable...Hence can't Corrupt signature"); return SECTOR_IS_NOT_WRITABLE; } } @@ -5155,7 +5155,7 @@ static INT CorruptISOSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSect if(IsSectionWritable(Adapter,eFlash2xSectionVal) != TRUE) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section is not Writable...Hence cant Corrupt signature"); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section is not Writable...Hence can't Corrupt signature"); return SECTOR_IS_NOT_WRITABLE; } diff --git a/drivers/staging/brcm80211/README b/drivers/staging/brcm80211/README index 99e67669f26b..f8facb0786ec 100644 --- a/drivers/staging/brcm80211/README +++ b/drivers/staging/brcm80211/README @@ -71,7 +71,7 @@ the driver. The devices use a single worldwide regulatory domain, with channels passive operation. Transmission on those channels is suppressed until appropriate other traffic is observed on those channels. -Within the driver, we use the ficticious country code "X2" to represent this +Within the driver, we use the fictitious country code "X2" to represent this worldwide regulatory domain. There is currently no interface to configure a different domain. diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c index 65313fa0cf4a..71c3571ee143 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -264,7 +264,7 @@ extern SDIOH_API_RC sdioh_disable_func_intr(void) } #endif /* defined(OOB_INTR_ONLY) && defined(HW_OOB) */ -/* Configure callback to client when we recieve client interrupt */ +/* Configure callback to client when we receive client interrupt */ extern SDIOH_API_RC sdioh_interrupt_register(sdioh_info_t *sd, sdioh_cb_fn_t fn, void *argh) { diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c b/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c index cbfa1c1b7059..1cf6c5dc2bb7 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c @@ -46,7 +46,7 @@ extern int sdioh_mmc_irq(int irq); #include #endif -/* Customer specific Host GPIO defintion */ +/* Customer specific Host GPIO definition */ static int dhd_oob_gpio_num = -1; /* GG 19 */ module_param(dhd_oob_gpio_num, int, 0644); diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index 02c6d446934c..dd0375793875 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -478,7 +478,7 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd) dhd_set_packet_filter(1, dhd); /* if dtim skip setup as default force it - * to wake each thrid dtim + * to wake each third dtim * for better power saving. * Note that side effect is chance to miss BC/MC * packet diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c index 106627040db0..464f52af1315 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c @@ -3659,7 +3659,7 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) * control pkt receives. * Later we use buffer-poll for data as well * as control packets. - * This is required becuase dhd receives full + * This is required because dhd receives full * frame in gSPI unlike SDIO. * After the frame is received we have to * distinguish whether it is data @@ -3744,7 +3744,7 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) bus->dhd->rx_errors++; dhd_os_sdunlock_rxq(bus->dhd); /* Force retry w/normal header read. - * Don't attemp NAK for + * Don't attempt NAK for * gSPI */ dhdsdio_rxfail(bus, true, diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index 774b4e916b29..c1b07ae31674 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -1079,7 +1079,7 @@ static int ieee_hw_init(struct ieee80211_hw *hw) */ hw->max_rates = 2; /* Primary rate and 1 fallback rate */ - hw->channel_change_time = 7 * 1000; /* channel change time is dependant on chip and band */ + hw->channel_change_time = 7 * 1000; /* channel change time is dependent on chip and band */ hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); hw->rate_control_algorithm = "minstrel_ht"; diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c index c6cdcd940956..f00865957881 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c @@ -89,7 +89,7 @@ u32 wl_ampdu_dbg = /* structure to hold tx fifo information and pre-loading state * counters specific to tx underflows of ampdus * some counters might be redundant with the ones in wlc or ampdu structures. - * This allows to maintain a specific state independantly of + * This allows to maintain a specific state independently of * how often and/or when the wlc counters are updated. */ typedef struct wlc_fifo_info { @@ -265,7 +265,7 @@ static void scb_ampdu_update_config(struct ampdu_info *ampdu, struct scb *scb) scb_ampdu->max_pdu = (u8) ampdu->wlc->pub->tunables->ampdunummpdu; - /* go back to legacy size if some preloading is occuring */ + /* go back to legacy size if some preloading is occurring */ for (i = 0; i < NUM_FFPLD_FIFO; i++) { if (ampdu->fifo_tb[i].ampdu_pld_size > FFPLD_PLD_INCR) scb_ampdu->max_pdu = AMPDU_NUM_MPDU_LEGACY; @@ -406,7 +406,7 @@ static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int fid) /* compute a new dma xfer rate for max_mpdu @ max mcs. This is the minimum dma rate that - can acheive no unferflow condition for the current mpdu size. + can achieve no unferflow condition for the current mpdu size. */ /* note : we divide/multiply by 100 to avoid integer overflows */ fifo->dmaxferrate = diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c index 5a96dc3cdb36..4b6e181c7dc9 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c @@ -1915,7 +1915,7 @@ void wlc_bmac_phy_reset(struct wlc_hw_info *wlc_hw) phy_bw_clkbits = wlc_phy_clk_bwbits(wlc_hw->band->pi); - /* Specfic reset sequence required for NPHY rev 3 and 4 */ + /* Specific reset sequence required for NPHY rev 3 and 4 */ if (WLCISNPHY(wlc_hw->band) && NREV_GE(wlc_hw->band->phyrev, 3) && NREV_LE(wlc_hw->band->phyrev, 4)) { /* Set the PHY bandwidth */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.c b/drivers/staging/brcm80211/brcmsmac/wlc_main.c index 639b5d7c9603..717fced45801 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_main.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_main.c @@ -8295,7 +8295,7 @@ wlc_txflowcontrol_prio_isset(struct wlc_info *wlc, struct wlc_txq_info *q, return (q->stopped & prio_mask) == prio_mask; } -/* propogate the flow control to all interfaces using the given tx queue */ +/* propagate the flow control to all interfaces using the given tx queue */ void wlc_txflowcontrol(struct wlc_info *wlc, struct wlc_txq_info *qi, bool on, int prio) { @@ -8462,7 +8462,7 @@ static void wlc_txq_free(struct wlc_info *wlc, struct wlc_txq_info *qi) } /* - * Flag 'scan in progress' to withold dynamic phy calibration + * Flag 'scan in progress' to withhold dynamic phy calibration */ void wlc_scan_start(struct wlc_info *wlc) { diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_rate.c b/drivers/staging/brcm80211/brcmsmac/wlc_rate.c index 0cfa36023cf1..d284f1ac49cc 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_rate.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_rate.c @@ -332,7 +332,7 @@ wlc_rate_hwrs_filter_sort_validate(wlc_rateset_t *rs, return false; } -/* caluclate the rate of a rx'd frame and return it as a ratespec */ +/* calculate the rate of a rx'd frame and return it as a ratespec */ ratespec_t BCMFASTPATH wlc_compute_rspec(d11rxhdr_t *rxh, u8 *plcp) { int phy_type; diff --git a/drivers/staging/brcm80211/include/bcmsrom_fmt.h b/drivers/staging/brcm80211/include/bcmsrom_fmt.h index ae2bff828607..4768968f910a 100644 --- a/drivers/staging/brcm80211/include/bcmsrom_fmt.h +++ b/drivers/staging/brcm80211/include/bcmsrom_fmt.h @@ -103,7 +103,7 @@ #define SROM_CRCREV 63 -/* SROM Rev 4: Reallocate the software part of the srom to accomodate +/* SROM Rev 4: Reallocate the software part of the srom to accommodate * MIMO features. It assumes up to two PCIE functions and 440 bytes * of useable srom i.e. the useable storage in chips with OTP that * implements hardware redundancy. diff --git a/drivers/staging/brcm80211/include/hndsoc.h b/drivers/staging/brcm80211/include/hndsoc.h index 9747cc46ca96..6435686b329f 100644 --- a/drivers/staging/brcm80211/include/hndsoc.h +++ b/drivers/staging/brcm80211/include/hndsoc.h @@ -181,7 +181,7 @@ * conventions for the use the flash space: */ -/* Minumum amount of flash we support */ +/* Minimum amount of flash we support */ #define FLASH_MIN 0x00020000 /* Minimum flash size */ /* A boot/binary may have an embedded block that describes its size */ diff --git a/drivers/staging/brcm80211/util/bcmotp.c b/drivers/staging/brcm80211/util/bcmotp.c index ba71c108b366..17991212a22d 100644 --- a/drivers/staging/brcm80211/util/bcmotp.c +++ b/drivers/staging/brcm80211/util/bcmotp.c @@ -213,7 +213,7 @@ static u16 ipxotp_read_bit(void *oh, chipcregs_t *cc, uint off) return (int)st; } -/* Calculate max HW/SW region byte size by substracting fuse region and checksum size, +/* Calculate max HW/SW region byte size by subtracting fuse region and checksum size, * osizew is oi->wsize (OTP size - GU size) in words */ static int ipxotp_max_rgnsz(si_t *sih, int osizew) @@ -229,7 +229,7 @@ static int ipxotp_max_rgnsz(si_t *sih, int osizew) ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM; break; default: - ASSERT(0); /* Don't konw about this chip */ + ASSERT(0); /* Don't know about this chip */ } return ret; diff --git a/drivers/staging/brcm80211/util/bcmsrom.c b/drivers/staging/brcm80211/util/bcmsrom.c index eca35b94e96c..850bfa6593e0 100644 --- a/drivers/staging/brcm80211/util/bcmsrom.c +++ b/drivers/staging/brcm80211/util/bcmsrom.c @@ -1859,7 +1859,7 @@ static int initvars_srom_pci(si_t *sih, void *curmap, char **vars, uint *count) /* * Apply CRC over SROM content regardless SROM is present or not, - * and use variable sromrev's existance in flash to decide + * and use variable sromrev's existence in flash to decide * if we should return an error when CRC fails or read SROM variables * from flash. */ diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c index 8a81eb997f99..be339feae77d 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/util/hnddma.c @@ -1179,7 +1179,7 @@ static void BCMFASTPATH dma64_txreclaim(dma_info_t *di, txd_range_t range) (range == HNDDMA_RANGE_ALL) ? "all" : ((range == HNDDMA_RANGE_TRANSMITTED) ? "transmitted" : - "transfered"))); + "transferred"))); if (di->txin == di->txout) return; @@ -1549,7 +1549,7 @@ static int BCMFASTPATH dma64_txfast(dma_info_t *di, struct sk_buff *p0, * If range is HNDDMA_RANGE_TRANSMITTED, reclaim descriptors that have be * transmitted as noted by the hardware "CurrDescr" pointer. * If range is HNDDMA_RANGE_TRANSFERED, reclaim descriptors that have be - * transfered by the DMA as noted by the hardware "ActiveDescr" pointer. + * transferred by the DMA as noted by the hardware "ActiveDescr" pointer. * If range is HNDDMA_RANGE_ALL, reclaim all txd(s) posted to the ring and * return associated packet regardless of the value of hardware pointers. */ @@ -1563,7 +1563,7 @@ static void *BCMFASTPATH dma64_getnexttxp(dma_info_t *di, txd_range_t range) (range == HNDDMA_RANGE_ALL) ? "all" : ((range == HNDDMA_RANGE_TRANSMITTED) ? "transmitted" : - "transfered"))); + "transferred"))); if (di->ntxd == 0) return NULL; diff --git a/drivers/staging/brcm80211/util/sbpcmcia.h b/drivers/staging/brcm80211/util/sbpcmcia.h index 6b9923f551a9..d4c156586e81 100644 --- a/drivers/staging/brcm80211/util/sbpcmcia.h +++ b/drivers/staging/brcm80211/util/sbpcmcia.h @@ -109,7 +109,7 @@ #define CISTPL_CFTABLE 0x1b /* Config table entry */ #define CISTPL_END 0xff /* End of the CIS tuple chain */ -/* Function identifier provides context for the function extentions tuple */ +/* Function identifier provides context for the function extensions tuple */ #define CISTPL_FID_SDIO 0x0c /* Extensions defined by SDIO spec */ /* Function extensions for LANs (assumed for extensions other than SDIO) */ diff --git a/drivers/staging/brcm80211/util/siutils.c b/drivers/staging/brcm80211/util/siutils.c index ed168ceba5f0..6ebd7f58af81 100644 --- a/drivers/staging/brcm80211/util/siutils.c +++ b/drivers/staging/brcm80211/util/siutils.c @@ -1319,7 +1319,7 @@ int si_clkctl_xtal(si_t *sih, uint what, bool on) } /* - * clock control policy function throught chipcommon + * clock control policy function through chipcommon * * set dynamic clk control mode (forceslow, forcefast, dynamic) * returns true if we are forcing fast clock diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index a4ceb29c358e..e7e72b8d8cde 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -2064,7 +2064,7 @@ void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s) COMEDI_CB_OVERFLOW)) { runflags_mask |= SRF_RUNNING; } - /* remember if an error event has occured, so an error + /* remember if an error event has occurred, so an error * can be returned the next time the user does a read() */ if (s->async->events & (COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW)) { runflags_mask |= SRF_ERROR; diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c index 644bda44556e..482a412aa652 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c @@ -124,9 +124,9 @@ You should also find the complete GPL in the COPYING file accompanying this sour | -5: The selected PCI input clock is wrong | | -6: Timing unity selection is wrong | | -7: Base timing selection is wrong | -| -8: You can not used the 40MHz clock selection wich | +| -8: You can not used the 40MHz clock selection with | | this board | -| -9: You can not used the 40MHz clock selection wich | +| -9: You can not used the 40MHz clock selection with | | this CHRONOS version | +----------------------------------------------------------------------------+ */ @@ -721,10 +721,10 @@ int i_APCI1710_InsnConfigInitChrono(struct comedi_device *dev, struct comedi_sub } } else { /**************************************************************/ - /* You can not used the 40MHz clock selection wich this board */ + /* You can not use the 40MHz clock selection with this board */ /**************************************************************/ - DPRINTK("You can not used the 40MHz clock selection wich this board\n"); + DPRINTK("You can not used the 40MHz clock selection with this board\n"); i_ReturnValue = -8; } diff --git a/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c b/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c index 90e71e12784a..b973095146f9 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c @@ -59,7 +59,7 @@ You should also find the complete GPL in the COPYING file accompanying this sour /*+----------------------------------------------------------------------------+*/ /*| Input Parameters : int i_NbOfWordsToRead : Nbr. of word to read |*/ /*| unsigned int dw_PCIBoardEepromAddress : Address of the eeprom |*/ -/*| unsigned short w_EepromStartAddress : Eeprom strat address |*/ +/*| unsigned short w_EepromStartAddress : Eeprom start address |*/ /*+----------------------------------------------------------------------------+*/ /*| Output Parameters : unsigned short * pw_DataRead : Read data |*/ /*+----------------------------------------------------------------------------+*/ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c index 9dd857df93c8..002297dfe33f 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c @@ -498,7 +498,7 @@ void v_APCI2032_Interrupt(int irq, void *d) struct comedi_device *dev = d; unsigned int ui_DO; - ui_DO = inl(devpriv->iobase + APCI2032_DIGITAL_OP_IRQ) & 0x1; /* Check if VCC OR CC interrupt has occured. */ + ui_DO = inl(devpriv->iobase + APCI2032_DIGITAL_OP_IRQ) & 0x1; /* Check if VCC OR CC interrupt has occurred. */ if (ui_DO == 0) { printk("\nInterrupt from unKnown source\n"); diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index a813fdbbd96e..fc61214151b7 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -148,7 +148,7 @@ int i_APCI3120_InsnReadAnalogInput(struct comedi_device *dev, struct comedi_subd unsigned short us_ConvertTiming, us_TmpValue, i; unsigned char b_Tmp; - /* fix convertion time to 10 us */ + /* fix conversion time to 10 us */ if (!devpriv->ui_EocEosConversionTime) { printk("No timer0 Value using 10 us\n"); us_ConvertTiming = 10; @@ -251,7 +251,7 @@ int i_APCI3120_InsnReadAnalogInput(struct comedi_device *dev, struct comedi_subd APCI3120_SELECT_TIMER_0_WORD; outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0); - /* Set the convertion time */ + /* Set the conversion time */ outw(us_ConvertTiming, devpriv->iobase + APCI3120_TIMER_VALUE); @@ -311,7 +311,7 @@ int i_APCI3120_InsnReadAnalogInput(struct comedi_device *dev, struct comedi_subd APCI3120_SELECT_TIMER_0_WORD; outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0); - /* Set the convertion time */ + /* Set the conversion time */ outw(us_ConvertTiming, devpriv->iobase + APCI3120_TIMER_VALUE); @@ -354,9 +354,9 @@ int i_APCI3120_InsnReadAnalogInput(struct comedi_device *dev, struct comedi_subd /* Start conversion */ outw(0, devpriv->iobase + APCI3120_START_CONVERSION); - /* Waiting of end of convertion if interrupt is not installed */ + /* Waiting of end of conversion if interrupt is not installed */ if (devpriv->b_EocEosInterrupt == APCI3120_DISABLE) { - /* Waiting the end of convertion */ + /* Waiting the end of conversion */ do { us_TmpValue = inw(devpriv->iobase + @@ -854,7 +854,7 @@ int i_APCI3120_CyclicAnalogInput(int mode, struct comedi_device *dev, b_DigitalOutputRegister) & 0xF0) | APCI3120_SELECT_TIMER_0_WORD; outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); - /* Set the convertion time */ + /* Set the conversion time */ outw(((unsigned short) ui_TimerValue0), dev->iobase + APCI3120_TIMER_VALUE); break; @@ -872,7 +872,7 @@ int i_APCI3120_CyclicAnalogInput(int mode, struct comedi_device *dev, b_DigitalOutputRegister) & 0xF0) | APCI3120_SELECT_TIMER_1_WORD; outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); - /* Set the convertion time */ + /* Set the conversion time */ outw(((unsigned short) ui_TimerValue1), dev->iobase + APCI3120_TIMER_VALUE); @@ -889,7 +889,7 @@ int i_APCI3120_CyclicAnalogInput(int mode, struct comedi_device *dev, APCI3120_SELECT_TIMER_0_WORD; outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0); - /* Set the convertion time */ + /* Set the conversion time */ outw(((unsigned short) ui_TimerValue0), dev->iobase + APCI3120_TIMER_VALUE); break; @@ -1104,7 +1104,7 @@ int i_APCI3120_CyclicAnalogInput(int mode, struct comedi_device *dev, /* * 4 - * amount of bytes to be transfered set transfer count used ADDON + * amount of bytes to be transferred set transfer count used ADDON * MWTC register commented testing * outl(devpriv->ui_DmaBufferUsesize[0], * devpriv->i_IobaseAddon+AMCC_OP_REG_AMWTC); diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.h index b3c81979f14d..50eb0a0a0a05 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.h +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.h @@ -169,7 +169,7 @@ struct str_AnalogReadInformation { unsigned char b_Type; /* EOC or EOS */ unsigned char b_InterruptFlag; /* Interrupt use or not */ - unsigned int ui_ConvertTiming; /* Selection of the convertion time */ + unsigned int ui_ConvertTiming; /* Selection of the conversion time */ unsigned char b_NbrOfChannel; /* Number of channel to read */ unsigned int ui_ChannelList[MAX_ANALOGINPUT_CHANNELS]; /* Number of the channel to be read */ unsigned int ui_RangeList[MAX_ANALOGINPUT_CHANNELS]; /* Gain of each channel */ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c index a93e2349ad3a..c75a1a1fd775 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c @@ -103,7 +103,7 @@ struct str_BoardInfos s_BoardInfos[100]; /* 100 will be the max number of board /*+----------------------------------------------------------------------------+*/ /*| Input Parameters : int i_NbOfWordsToRead : Nbr. of word to read |*/ /*| unsigned int dw_PCIBoardEepromAddress : Address of the eeprom |*/ -/*| unsigned short w_EepromStartAddress : Eeprom strat address |*/ +/*| unsigned short w_EepromStartAddress : Eeprom start address |*/ /*+----------------------------------------------------------------------------+*/ /*| Output Parameters : unsigned short * pw_DataRead : Read data |*/ /*+----------------------------------------------------------------------------+*/ @@ -849,7 +849,7 @@ int i_APCI3200_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdev | 0:Single Read | 1:Read more channel 2:Single scan - | 3:Continous Scan + | 3:Continuous Scan data[13] :Number of channels to read | data[14] :RTD connection type :0:RTD not used diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index 766103c882ad..632d5d0721cd 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -23,7 +23,7 @@ For AI: - If cmd->scan_begin_src=TRIG_EXT then trigger input is TGIN (pin 46). - If cmd->convert_src=TRIG_EXT then trigger input is EXTTRG (pin 44). - If cmd->start_src/stop_src=TRIG_EXT then trigger input is TGIN (pin 46). -- It is not neccessary to have cmd.scan_end_arg=cmd.chanlist_len but +- It is not necessary to have cmd.scan_end_arg=cmd.chanlist_len but cmd.scan_end_arg modulo cmd.chanlist_len must by 0. - If return value of cmdtest is 5 then you've bad channel list (it isn't possible mixture S.E. and DIFF inputs or bipolar and unipolar @@ -823,7 +823,7 @@ static void interrupt_pci9118_ai_dma(struct comedi_device *dev, move_block_from_dma(dev, s, devpriv->dmabuf_virt[devpriv->dma_actbuf], samplesinbuf); - m = m - sampls; /* m= how many samples was transfered */ + m = m - sampls; /* m= how many samples was transferred */ } /* DPRINTK("YYY\n"); */ @@ -1297,7 +1297,7 @@ static int Compute_and_setup_dma(struct comedi_device *dev) DPRINTK("3 dmalen0=%d dmalen1=%d\n", dmalen0, dmalen1); /* transfer without TRIG_WAKE_EOS */ if (!(devpriv->ai_flags & TRIG_WAKE_EOS)) { - /* if it's possible then allign DMA buffers to length of scan */ + /* if it's possible then align DMA buffers to length of scan */ i = dmalen0; dmalen0 = (dmalen0 / (devpriv->ai_n_realscanlen << 1)) * diff --git a/drivers/staging/comedi/drivers/adq12b.c b/drivers/staging/comedi/drivers/adq12b.c index 4b470000b69c..5361f318b010 100644 --- a/drivers/staging/comedi/drivers/adq12b.c +++ b/drivers/staging/comedi/drivers/adq12b.c @@ -65,7 +65,7 @@ If you do not specify any options, they will default to written by jeremy theler instituto balseiro - comision nacional de energia atomica + commission nacional de energia atomica universidad nacional de cuyo argentina @@ -342,7 +342,7 @@ static int adq12b_ai_rinsn(struct comedi_device *dev, /* convert n samples */ for (n = 0; n < insn->n; n++) { - /* wait for end of convertion */ + /* wait for end of conversion */ i = 0; do { /* udelay(1); */ diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 466e69f94ef2..da2b75b15d4e 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -98,7 +98,7 @@ Configuration options: #define Status_FE 0x0100 /* 1=FIFO is empty */ #define Status_FH 0x0200 /* 1=FIFO is half full */ #define Status_FF 0x0400 /* 1=FIFO is full, fatal error */ -#define Status_IRQ 0x0800 /* 1=IRQ occured */ +#define Status_IRQ 0x0800 /* 1=IRQ occurred */ /* bits from control register (PCI171x_CONTROL) */ #define Control_CNT0 0x0040 /* 1=CNT0 have external source, * 0=have internal 100kHz source */ @@ -1161,7 +1161,7 @@ static int check_channel_list(struct comedi_device *dev, } if (n_chan > 1) { - chansegment[0] = chanlist[0]; /* first channel is everytime ok */ + chansegment[0] = chanlist[0]; /* first channel is every time ok */ for (i = 1, seglen = 1; i < n_chan; i++, seglen++) { /* build part of chanlist */ /* printk("%d. %d %d\n",i,CR_CHAN(chanlist[i]),CR_RANGE(chanlist[i])); */ if (chanlist[0] == chanlist[i]) @@ -1176,9 +1176,9 @@ static int check_channel_list(struct comedi_device *dev, (CR_CHAN(chansegment[i - 1]) + 1) % s->n_chan; if (CR_AREF(chansegment[i - 1]) == AREF_DIFF) nowmustbechan = (nowmustbechan + 1) % s->n_chan; - if (nowmustbechan != CR_CHAN(chanlist[i])) { /* channel list isn't continous :-( */ + if (nowmustbechan != CR_CHAN(chanlist[i])) { /* channel list isn't continuous :-( */ printk - ("channel list must be continous! chanlist[%i]=%d but must be %d or %d!\n", + ("channel list must be continuous! chanlist[%i]=%d but must be %d or %d!\n", i, CR_CHAN(chanlist[i]), nowmustbechan, CR_CHAN(chanlist[0])); return 0; diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index 0941643b3869..61968a505f24 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -115,7 +115,7 @@ analog triggering on 1602 series #define INT_MASK 0x3 /* mask of interrupt select bits */ #define INTE 0x4 /* interrupt enable */ #define DAHFIE 0x8 /* dac half full interrupt enable */ -#define EOAIE 0x10 /* end of aquisition interrupt enable */ +#define EOAIE 0x10 /* end of acquisition interrupt enable */ #define DAHFI 0x20 /* dac half full read status / write interrupt clear */ #define EOAI 0x40 /* read end of acq. interrupt status / write clear */ #define INT 0x80 /* read interrupt status / write clear */ @@ -440,7 +440,7 @@ struct cb_pcidas_private { unsigned int divisor1; unsigned int divisor2; volatile unsigned int count; /* number of analog input samples remaining */ - volatile unsigned int adc_fifo_bits; /* bits to write to interupt/adcfifo register */ + volatile unsigned int adc_fifo_bits; /* bits to write to interrupt/adcfifo register */ volatile unsigned int s5933_intcsr_bits; /* bits to write to amcc s5933 interrupt control/status register */ volatile unsigned int ao_control_bits; /* bits to write to ao control and status register */ short ai_buffer[AI_BUFFER_SIZE]; @@ -1653,7 +1653,7 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d) spin_unlock_irqrestore(&dev->spinlock, flags); } else if (status & EOAI) { comedi_error(dev, - "bug! encountered end of aquisition interrupt?"); + "bug! encountered end of acquisition interrupt?"); /* clear EOA interrupt latch */ spin_lock_irqsave(&dev->spinlock, flags); outw(devpriv->adc_fifo_bits | EOAI, diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 2583e16cd02a..1e324198996c 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -104,7 +104,7 @@ TODO: #endif #define TIMER_BASE 25 /* 40MHz master clock */ -#define PRESCALED_TIMER_BASE 10000 /* 100kHz 'prescaled' clock for slow aquisition, maybe I'll support this someday */ +#define PRESCALED_TIMER_BASE 10000 /* 100kHz 'prescaled' clock for slow acquisition, maybe I'll support this someday */ #define DMA_BUFFER_SIZE 0x1000 #define PCI_VENDOR_ID_COMPUTERBOARDS 0x1307 @@ -136,7 +136,7 @@ enum write_only_registers { ADC_DELAY_INTERVAL_UPPER_REG = 0x1c, /* upper 8 bits of delay interval counter */ ADC_COUNT_LOWER_REG = 0x1e, /* lower 16 bits of hardware conversion/scan counter */ ADC_COUNT_UPPER_REG = 0x20, /* upper 8 bits of hardware conversion/scan counter */ - ADC_START_REG = 0x22, /* software trigger to start aquisition */ + ADC_START_REG = 0x22, /* software trigger to start acquisition */ ADC_CONVERT_REG = 0x24, /* initiates single conversion */ ADC_QUEUE_CLEAR_REG = 0x26, /* clears adc queue */ ADC_QUEUE_LOAD_REG = 0x28, /* loads adc queue */ @@ -199,7 +199,7 @@ enum intr_enable_contents { ADC_INTR_EOSCAN_BITS = 0x2, /* interrupt end of scan */ ADC_INTR_EOSEQ_BITS = 0x3, /* interrupt end of sequence (probably wont use this it's pretty fancy) */ EN_ADC_INTR_SRC_BIT = 0x4, /* enable adc interrupt source */ - EN_ADC_DONE_INTR_BIT = 0x8, /* enable adc aquisition done interrupt */ + EN_ADC_DONE_INTR_BIT = 0x8, /* enable adc acquisition done interrupt */ DAC_INTR_SRC_MASK = 0x30, DAC_INTR_QEMPTY_BITS = 0x0, DAC_INTR_HIGH_CHAN_BITS = 0x10, @@ -2867,7 +2867,7 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) spin_unlock_irqrestore(&dev->spinlock, flags); - /* start aquisition */ + /* start acquisition */ if (cmd->start_src == TRIG_NOW) { writew(0, priv(dev)->main_iobase + ADC_START_REG); DEBUG_PRINT("soft trig\n"); @@ -2942,7 +2942,7 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev) /* Read from 32 bit wide ai fifo of 4020 - deal with insane grey coding of pointers. * The pci-4020 hardware only supports * dma transfers (it only supports the use of pio for draining the last remaining - * points from the fifo when a data aquisition operation has completed). + * points from the fifo when a data acquisition operation has completed). */ static void pio_drain_ai_fifo_32(struct comedi_device *dev) { @@ -3046,7 +3046,7 @@ static void handle_ai_interrupt(struct comedi_device *dev, comedi_error(dev, "fifo overrun"); async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; } - /* spin lock makes sure noone else changes plx dma control reg */ + /* spin lock makes sure no one else changes plx dma control reg */ spin_lock_irqsave(&dev->spinlock, flags); dma1_status = readb(priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG); if (plx_status & ICS_DMA1_A) { /* dma chan 1 interrupt */ @@ -3170,7 +3170,7 @@ static void handle_ao_interrupt(struct comedi_device *dev, async = s->async; cmd = &async->cmd; - /* spin lock makes sure noone else changes plx dma control reg */ + /* spin lock makes sure no one else changes plx dma control reg */ spin_lock_irqsave(&dev->spinlock, flags); dma0_status = readb(priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG); if (plx_status & ICS_DMA0_A) { /* dma chan 0 interrupt */ diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c index b220b3055412..a804742b8022 100644 --- a/drivers/staging/comedi/drivers/comedi_test.c +++ b/drivers/staging/comedi/drivers/comedi_test.c @@ -81,7 +81,7 @@ static const struct waveform_board waveform_boards[] = { /* Data unique to this driver */ struct waveform_private { struct timer_list timer; - struct timeval last; /* time at which last timer interrupt occured */ + struct timeval last; /* time at which last timer interrupt occurred */ unsigned int uvolt_amplitude; /* waveform amplitude in microvolts */ unsigned long usec_period; /* waveform period in microseconds */ unsigned long usec_current; /* current time (modulo waveform period) */ diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index 6ea93f9c0b48..60c2b12d6ffb 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -1087,7 +1087,7 @@ static void das1800_flush_dma_channel(struct comedi_device *dev, return; } -/* flushes remaining data from board when external trigger has stopped aquisition +/* flushes remaining data from board when external trigger has stopped acquisition * and we are using dma transfers */ static void das1800_flush_dma(struct comedi_device *dev, struct comedi_subdevice *s) diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c index aecaedc5027e..96d41ad76956 100644 --- a/drivers/staging/comedi/drivers/das800.c +++ b/drivers/staging/comedi/drivers/das800.c @@ -391,7 +391,7 @@ static irqreturn_t das800_interrupt(int irq, void *d) spin_lock_irqsave(&dev->spinlock, irq_flags); outb(CONTROL1, dev->iobase + DAS800_GAIN); /* select base address + 7 to be STATUS2 register */ status = inb(dev->iobase + DAS800_STATUS2) & STATUS2_HCEN; - /* don't release spinlock yet since we want to make sure noone else disables hardware conversions */ + /* don't release spinlock yet since we want to make sure no one else disables hardware conversions */ if (status == 0) { spin_unlock_irqrestore(&dev->spinlock, irq_flags); return IRQ_HANDLED; diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c index 693728e14bdb..2b4e6e6eb825 100644 --- a/drivers/staging/comedi/drivers/dmm32at.c +++ b/drivers/staging/comedi/drivers/dmm32at.c @@ -532,7 +532,7 @@ static int dmm32at_ai_rinsn(struct comedi_device *dev, msb = dmm_inb(dev, DMM32AT_AIMSB); /* invert sign bit to make range unsigned, this is an - idiosyncracy of the diamond board, it return + idiosyncrasy of the diamond board, it return conversions as a signed value, i.e. -32768 to 32767, flipping the bit and interpreting it as signed gives you a range of 0 to 65535 which is diff --git a/drivers/staging/comedi/drivers/dt2811.c b/drivers/staging/comedi/drivers/dt2811.c index a1664caa1d96..0131d5225b52 100644 --- a/drivers/staging/comedi/drivers/dt2811.c +++ b/drivers/staging/comedi/drivers/dt2811.c @@ -560,7 +560,7 @@ int dt2811_adtrig(kdev_t minor, comedi_adtrig *adtrig) switch (dev->i_admode) { case COMEDI_MDEMAND: dev->ntrig = adtrig->n - 1; - /* not neccessary */ + /* not necessary */ /*printk("dt2811: AD soft trigger\n"); */ /*outb(DT2811_CLRERROR|DT2811_INTENB, dev->iobase+DT2811_ADCSR); */ diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c index 06059850dae2..32d9c42e9659 100644 --- a/drivers/staging/comedi/drivers/dt9812.c +++ b/drivers/staging/comedi/drivers/dt9812.c @@ -773,7 +773,7 @@ static int dt9812_probe(struct usb_interface *interface, retval = dt9812_read_info(dev, 1, &fw, sizeof(fw)); if (retval == 0) { dev_info(&interface->dev, - "usb_reset_configuration succeded " + "usb_reset_configuration succeeded " "after %d iterations\n", i); break; } diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index 1661b57ca2ad..bc020dea141b 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -1031,7 +1031,7 @@ static irqreturn_t handle_interrupt(int irq, void *d) writel(hpdi_intr_status, priv(dev)->hpdi_iobase + INTERRUPT_STATUS_REG); } - /* spin lock makes sure noone else changes plx dma control reg */ + /* spin lock makes sure no one else changes plx dma control reg */ spin_lock_irqsave(&dev->spinlock, flags); dma0_status = readb(priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG); if (plx_status & ICS_DMA0_A) { /* dma chan 0 interrupt */ @@ -1045,7 +1045,7 @@ static irqreturn_t handle_interrupt(int irq, void *d) } spin_unlock_irqrestore(&dev->spinlock, flags); - /* spin lock makes sure noone else changes plx dma control reg */ + /* spin lock makes sure no one else changes plx dma control reg */ spin_lock_irqsave(&dev->spinlock, flags); dma1_status = readb(priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG); if (plx_status & ICS_DMA1_A) { /* XXX *//* dma chan 1 interrupt */ diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index 0bab39b3409b..126550f3c02b 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -715,7 +715,7 @@ Description: is built correctly Parameters: - struct comedi_device *dev Pointer to current sevice structure + struct comedi_device *dev Pointer to current service structure struct comedi_subdevice *s Pointer to current subdevice structure unsigned int *chanlist Pointer to packed channel list unsigned int n_chan Number of channels to scan @@ -772,7 +772,7 @@ Description: Status register. Parameters: - struct comedi_device *dev Pointer to current sevice structure + struct comedi_device *dev Pointer to current service structure struct comedi_subdevice *s Pointer to current subdevice structure unsigned int *chanlist Pointer to packed channel list unsigned int n_chan Number of channels to scan @@ -848,7 +848,7 @@ Description: This function resets the icp multi device to a 'safe' state Parameters: - struct comedi_device *dev Pointer to current sevice structure + struct comedi_device *dev Pointer to current service structure Returns:int 0 = success diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 75511bae0191..b692fea0d2b0 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -1810,7 +1810,7 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) ai_context->irq_status_reg) & ME4000_IRQ_STATUS_BIT_AI_HF) { ISR_PDEBUG - ("me4000_ai_isr(): Fifo half full interrupt occured\n"); + ("me4000_ai_isr(): Fifo half full interrupt occurred\n"); /* Read status register to find out what happened */ tmp = me4000_inl(dev, ai_context->ctrl_reg); @@ -1903,7 +1903,7 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) if (me4000_inl(dev, ai_context->irq_status_reg) & ME4000_IRQ_STATUS_BIT_SC) { ISR_PDEBUG - ("me4000_ai_isr(): Sample counter interrupt occured\n"); + ("me4000_ai_isr(): Sample counter interrupt occurred\n"); s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOA; diff --git a/drivers/staging/comedi/drivers/mpc624.c b/drivers/staging/comedi/drivers/mpc624.c index a89eebd23f65..dd09a6d46e5c 100644 --- a/drivers/staging/comedi/drivers/mpc624.c +++ b/drivers/staging/comedi/drivers/mpc624.c @@ -39,8 +39,8 @@ Status: working Configuration Options: [0] - I/O base address - [1] - convertion rate - Convertion rate RMS noise Effective Number Of Bits + [1] - conversion rate + Conversion rate RMS noise Effective Number Of Bits 0 3.52kHz 23uV 17 1 1.76kHz 3.5uV 20 2 880Hz 2uV 21.3 @@ -93,8 +93,8 @@ Configuration Options: #define MPC624_DMY_BIT (1<<30) #define MPC624_SGN_BIT (1<<29) -/* Convertion speeds */ -/* OSR4 OSR3 OSR2 OSR1 OSR0 Convertion rate RMS noise ENOB^ +/* Conversion speeds */ +/* OSR4 OSR3 OSR2 OSR1 OSR0 Conversion rate RMS noise ENOB^ * X 0 0 0 1 3.52kHz 23uV 17 * X 0 0 1 0 1.76kHz 3.5uV 20 * X 0 0 1 1 880Hz 2uV 21.3 @@ -227,7 +227,7 @@ static int mpc624_attach(struct comedi_device *dev, struct comedi_devconfig *it) break; default: printk - (KERN_ERR "illegal convertion rate setting!" + (KERN_ERR "illegal conversion rate setting!" " Valid numbers are 0..9. Using 9 => 6.875 Hz, "); devpriv->ulConvertionRate = MPC624_SPEED_3_52_kHz; } @@ -296,7 +296,7 @@ static int mpc624_ai_rinsn(struct comedi_device *dev, } for (n = 0; n < insn->n; n++) { - /* Trigger the convertion */ + /* Trigger the conversion */ outb(MPC624_ADSCK, dev->iobase + MPC624_ADC); udelay(1); outb(MPC624_ADCS | MPC624_ADSCK, dev->iobase + MPC624_ADC); @@ -304,7 +304,7 @@ static int mpc624_ai_rinsn(struct comedi_device *dev, outb(0, dev->iobase + MPC624_ADC); udelay(1); - /* Wait for the convertion to end */ + /* Wait for the conversion to end */ for (i = 0; i < TIMEOUT; i++) { ucPort = inb(dev->iobase + MPC624_ADC); if (ucPort & MPC624_ADBUSY) diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c index 4d0053ea2465..c192b71ec04f 100644 --- a/drivers/staging/comedi/drivers/ni_at_a2150.c +++ b/drivers/staging/comedi/drivers/ni_at_a2150.c @@ -104,10 +104,10 @@ TRIG_WAKE_EOS #define STATUS_REG 0x12 /* read only */ #define FNE_BIT 0x1 /* fifo not empty */ #define OVFL_BIT 0x8 /* fifo overflow */ -#define EDAQ_BIT 0x10 /* end of aquisition interrupt */ +#define EDAQ_BIT 0x10 /* end of acquisition interrupt */ #define DCAL_BIT 0x20 /* offset calibration in progress */ -#define INTR_BIT 0x40 /* interrupt has occured */ -#define DMA_TC_BIT 0x80 /* dma terminal count interrupt has occured */ +#define INTR_BIT 0x40 /* interrupt has occurred */ +#define DMA_TC_BIT 0x80 /* dma terminal count interrupt has occurred */ #define ID_BITS(x) (((x) >> 8) & 0x3) #define IRQ_DMA_CNTRL_REG 0x12 /* write only */ #define DMA_CHAN_BITS(x) ((x) & 0x7) /* sets dma channel */ @@ -434,7 +434,7 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->cancel = a2150_cancel; /* need to do this for software counting of completed conversions, to - * prevent hardware count from stopping aquisition */ + * prevent hardware count from stopping acquisition */ outw(HW_COUNT_DISABLE, dev->iobase + I8253_MODE_REG); /* set card's irq and dma levels */ @@ -729,7 +729,7 @@ static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* send trigger config bits */ outw(trigger_bits, dev->iobase + TRIGGER_REG); - /* start aquisition for soft trigger */ + /* start acquisition for soft trigger */ if (cmd->start_src == TRIG_NOW) { outw(0, dev->iobase + FIFO_START_REG); } @@ -768,7 +768,7 @@ static int a2150_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, /* setup start triggering */ outw(0, dev->iobase + TRIGGER_REG); - /* start aquisition for soft trigger */ + /* start acquisition for soft trigger */ outw(0, dev->iobase + FIFO_START_REG); /* there is a 35.6 sample delay for data to get through the antialias filter */ diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index 241fe525abf0..ab8f37022a3c 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -183,11 +183,11 @@ NI manuals: #define OVERRUN_BIT 0x2 /* fifo overflow */ #define OVERFLOW_BIT 0x4 -/* timer interrupt has occured */ +/* timer interrupt has occurred */ #define TIMER_BIT 0x8 -/* dma terminal count has occured */ +/* dma terminal count has occurred */ #define DMATC_BIT 0x10 -/* external trigger has occured */ +/* external trigger has occurred */ #define EXT_TRIG_BIT 0x40 /* 1200 boards only */ #define STATUS2_REG 0x1d @@ -1149,7 +1149,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) range = CR_RANGE(cmd->chanlist[0]); aref = CR_AREF(cmd->chanlist[0]); - /* make sure board is disabled before setting up aquisition */ + /* make sure board is disabled before setting up acquisition */ spin_lock_irqsave(&dev->spinlock, flags); devpriv->command2_bits &= ~SWTRIG_BIT & ~HWTRIG_BIT & ~PRETRIG_BIT; devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG); @@ -1349,7 +1349,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->command3_bits &= ~ADC_FNE_INTR_EN_BIT; devpriv->write_byte(devpriv->command3_bits, dev->iobase + COMMAND3_REG); - /* startup aquisition */ + /* startup acquisition */ /* command2 reg */ /* use 2 cascaded counters for pacing */ @@ -1571,8 +1571,8 @@ static void handle_isa_dma(struct comedi_device *dev) devpriv->write_byte(0x1, dev->iobase + DMATC_CLEAR_REG); } -/* makes sure all data acquired by board is transfered to comedi (used - * when aquisition is terminated by stop_src == TRIG_EXT). */ +/* makes sure all data acquired by board is transferred to comedi (used + * when acquisition is terminated by stop_src == TRIG_EXT). */ static void labpc_drain_dregs(struct comedi_device *dev) { if (devpriv->current_transfer == isa_dma_transfer) diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index 005d2fe86ee4..8dd3a01d48dd 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -821,7 +821,7 @@ static int ni_pcidio_cmdtest(struct comedi_device *dev, cmd->scan_begin_arg = MAX_SPEED; err++; } - /* no minumum speed */ + /* no minimum speed */ } else { /* TRIG_EXT */ /* should be level/edge, hi/lo specification here */ diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index c6dce4a1425e..09ff4723b225 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -34,7 +34,7 @@ * and I cann't test all features.) * * This driver supports insn and cmd interfaces. Some boards support only insn - * becouse their hardware don't allow more (PCL-813/B, ACL-8113, ISO-813). + * because their hardware don't allow more (PCL-813/B, ACL-8113, ISO-813). * Data transfer over DMA is supported only when you measure only one * channel, this is too hardware limitation of these boards. * diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index ef3cc4f3be6e..8f3fc6ee088b 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -954,7 +954,7 @@ check_channel_list(struct comedi_device *dev, } if (chanlen > 1) { - /* first channel is everytime ok */ + /* first channel is every time ok */ chansegment[0] = chanlist[0]; for (i = 1, seglen = 1; i < chanlen; i++, seglen++) { /* build part of chanlist */ @@ -968,10 +968,10 @@ check_channel_list(struct comedi_device *dev, nowmustbechan = (CR_CHAN(chansegment[i - 1]) + 1) % chanlen; if (nowmustbechan != CR_CHAN(chanlist[i])) { - /* channel list isn't continous :-( */ + /* channel list isn't continuous :-( */ printk(KERN_WARNING "comedi%d: pcl816: channel list must " - "be continous! chanlist[%i]=%d but " + "be continuous! chanlist[%i]=%d but " "must be %d or %d!\n", dev->minor, i, CR_CHAN(chanlist[i]), nowmustbechan, CR_CHAN(chanlist[0])); diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c index f58d75be7295..e3eea09ae1fb 100644 --- a/drivers/staging/comedi/drivers/pcl818.c +++ b/drivers/staging/comedi/drivers/pcl818.c @@ -1231,7 +1231,7 @@ static int check_channel_list(struct comedi_device *dev, } if (n_chan > 1) { - /* first channel is everytime ok */ + /* first channel is every time ok */ chansegment[0] = chanlist[0]; /* build part of chanlist */ for (i = 1, seglen = 1; i < n_chan; i++, seglen++) { @@ -1245,9 +1245,9 @@ static int check_channel_list(struct comedi_device *dev, break; nowmustbechan = (CR_CHAN(chansegment[i - 1]) + 1) % s->n_chan; - if (nowmustbechan != CR_CHAN(chanlist[i])) { /* channel list isn't continous :-( */ + if (nowmustbechan != CR_CHAN(chanlist[i])) { /* channel list isn't continuous :-( */ printk - ("comedi%d: pcl818: channel list must be continous! chanlist[%i]=%d but must be %d or %d!\n", + ("comedi%d: pcl818: channel list must be continuous! chanlist[%i]=%d but must be %d or %d!\n", dev->minor, i, CR_CHAN(chanlist[i]), nowmustbechan, CR_CHAN(chanlist[0])); return 0; diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c index 5c832d7ed45d..f2e88e57d558 100644 --- a/drivers/staging/comedi/drivers/pcmmio.c +++ b/drivers/staging/comedi/drivers/pcmmio.c @@ -733,7 +733,7 @@ static int pcmmio_dio_insn_config(struct comedi_device *dev, break; case INSN_CONFIG_DIO_QUERY: - /* retreive from shadow register */ + /* retrieve from shadow register */ data[1] = (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT; return insn->n; @@ -1279,7 +1279,7 @@ static int wait_dac_ready(unsigned long iobase) "no busy waiting" policy. The fact is that the hardware is normally so fast that we usually only need one time through the loop anyway. The longer timeout is for rare occasions and for detecting - non-existant hardware. */ + non-existent hardware. */ while (retry--) { if (inb(iobase + 3) & 0x80) diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c index 7a9287433b2e..b2c2c8971a32 100644 --- a/drivers/staging/comedi/drivers/pcmuio.c +++ b/drivers/staging/comedi/drivers/pcmuio.c @@ -605,7 +605,7 @@ static int pcmuio_dio_insn_config(struct comedi_device *dev, break; case INSN_CONFIG_DIO_QUERY: - /* retreive from shadow register */ + /* retrieve from shadow register */ data[1] = (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT; return insn->n; diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c index ebba9bb47777..82942e5728a5 100644 --- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c +++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c @@ -390,7 +390,7 @@ static int daqp_ai_insn_read(struct comedi_device *dev, outb(v, dev->iobase + DAQP_CONTROL); - /* Reset any pending interrupts (my card has a tendancy to require + /* Reset any pending interrupts (my card has a tendency to require * require multiple reads on the status register to achieve this) */ @@ -752,7 +752,7 @@ static int daqp_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) outb(v, dev->iobase + DAQP_CONTROL); - /* Reset any pending interrupts (my card has a tendancy to require + /* Reset any pending interrupts (my card has a tendency to require * require multiple reads on the status register to achieve this) */ counter = 100; diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 357858d27441..7f09ed755fe6 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -75,7 +75,7 @@ Configuration options: das1800, since they have the best documented code. Driver cb_pcidas64.c uses the same DMA controller. - As far as I can tell, the About interrupt doesnt work if Sample is + As far as I can tell, the About interrupt doesn't work if Sample is also enabled. It turns out that About really isn't needed, since we always count down samples read. @@ -370,7 +370,7 @@ struct rtdPrivate { /* timer gate (when enabled) */ u8 utcGate[4]; /* 1 extra allows simple range check */ - /* shadow registers affect other registers, but cant be read back */ + /* shadow registers affect other registers, but can't be read back */ /* The macros below update these on writes */ u16 intMask; /* interrupt mask */ u16 intClearMask; /* interrupt clear mask */ @@ -485,7 +485,7 @@ struct rtdPrivate { #define RtdAdcFifoGet(dev) \ readw(devpriv->las1+LAS1_ADC_FIFO) -/* Read two ADC data values (DOESNT WORK) */ +/* Read two ADC data values (DOESN'T WORK) */ #define RtdAdcFifoGet2(dev) \ readl(devpriv->las1+LAS1_ADC_FIFO) @@ -857,7 +857,7 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) DPRINTK("rtd520: PCI latency = %d\n", pci_latency); } - /* Undocumented EPLD version (doesnt match RTD driver results) */ + /* Undocumented EPLD version (doesn't match RTD driver results) */ /*DPRINTK ("rtd520: Reading epld from %p\n", devpriv->las0+0); epld_version = readl (devpriv->las0+0); @@ -1291,7 +1291,7 @@ static int rtd520_probe_fifo_depth(struct comedi_device *dev) /* "instructions" read/write data in "one-shot" or "software-triggered" mode (simplest case). - This doesnt use interrupts. + This doesn't use interrupts. Note, we don't do any settling delays. Use a instruction list to select, delay, then read. @@ -2120,7 +2120,7 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) } /* - Stop a running data aquisition. + Stop a running data acquisition. */ static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index d5ba3ab357a3..23fc64b9988e 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -139,7 +139,7 @@ struct s626_private { int got_regions; short allocatedBuf; uint8_t ai_cmd_running; /* ai_cmd is running */ - uint8_t ai_continous; /* continous aquisition */ + uint8_t ai_continous; /* continous acquisition */ int ai_sample_count; /* number of samples to acquire */ unsigned int ai_sample_timer; /* time between samples in units of the timer */ @@ -1048,7 +1048,7 @@ static irqreturn_t s626_irq_handler(int irq, void *d) uint8_t group; uint16_t irqbit; - DEBUG("s626_irq_handler: interrupt request recieved!!!\n"); + DEBUG("s626_irq_handler: interrupt request received!!!\n"); if (dev->attached == 0) return IRQ_NONE; @@ -1165,14 +1165,14 @@ static irqreturn_t s626_irq_handler(int irq, void *d) (16 * group))) == 1 && cmd->start_src == TRIG_EXT) { DEBUG - ("s626_irq_handler: Edge capture interrupt recieved from channel %d\n", + ("s626_irq_handler: Edge capture interrupt received from channel %d\n", cmd->start_arg); /* Start executing the RPS program. */ MC_ENABLE(P_MC1, MC1_ERPS1); DEBUG - ("s626_irq_handler: aquisition start triggered!!!\n"); + ("s626_irq_handler: acquisition start triggered!!!\n"); if (cmd->scan_begin_src == TRIG_EXT) { @@ -1194,7 +1194,7 @@ static irqreturn_t s626_irq_handler(int irq, void *d) && cmd->scan_begin_src == TRIG_EXT) { DEBUG - ("s626_irq_handler: Edge capture interrupt recieved from channel %d\n", + ("s626_irq_handler: Edge capture interrupt received from channel %d\n", cmd->scan_begin_arg); /* Trigger ADC scan loop start by setting RPS Signal 0. */ @@ -1236,7 +1236,7 @@ static irqreturn_t s626_irq_handler(int irq, void *d) == 1 && cmd->convert_src == TRIG_EXT) { DEBUG - ("s626_irq_handler: Edge capture interrupt recieved from channel %d\n", + ("s626_irq_handler: Edge capture interrupt received from channel %d\n", cmd->convert_arg); /* Trigger ADC scan loop start by setting RPS Signal 0. */ @@ -1805,7 +1805,7 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) DEBUG("s626_ai_cmd: NULL command\n"); return -EINVAL; } else { - DEBUG("s626_ai_cmd: command recieved!!!\n"); + DEBUG("s626_ai_cmd: command received!!!\n"); } if (dev->irq == 0) { @@ -1880,7 +1880,7 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->ai_continous = 0; break; case TRIG_NONE: - /* continous aquisition */ + /* continous acquisition */ devpriv->ai_continous = 1; devpriv->ai_sample_count = 0; break; @@ -2570,7 +2570,7 @@ static uint32_t I2Chandshake(struct comedi_device *dev, uint32_t val) while ((RR7146(P_I2CCTRL) & (I2C_BUSY | I2C_ERR)) == I2C_BUSY) ; - /* Return non-zero if I2C error occured. */ + /* Return non-zero if I2C error occurred. */ return RR7146(P_I2CCTRL) & I2C_ERR; } diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index be93c30e4b15..e543e6c2b1bb 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -285,7 +285,7 @@ struct usbduxsub { short int ao_cmd_running; /* pwm is running */ short int pwm_cmd_running; - /* continous aquisition */ + /* continous acquisition */ short int ai_continous; short int ao_continous; /* number of samples to acquire */ @@ -500,7 +500,7 @@ static void usbduxsub_ai_IsocIrq(struct urb *urb) /* test, if we transmit only a fixed number of samples */ if (!(this_usbduxsub->ai_continous)) { - /* not continous, fixed number of samples */ + /* not continuous, fixed number of samples */ this_usbduxsub->ai_sample_count--; /* all samples received? */ if (this_usbduxsub->ai_sample_count < 0) { @@ -653,7 +653,7 @@ static void usbduxsub_ao_IsocIrq(struct urb *urb) /* timer zero */ this_usbduxsub->ao_counter = this_usbduxsub->ao_timer; - /* handle non continous aquisition */ + /* handle non continous acquisition */ if (!(this_usbduxsub->ao_continous)) { /* fixed number of samples */ this_usbduxsub->ao_sample_count--; @@ -957,7 +957,7 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev, if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) err++; - /* scanning is continous */ + /* scanning is continuous */ tmp = cmd->convert_src; cmd->convert_src &= TRIG_NOW; if (!cmd->convert_src || tmp != cmd->convert_src) @@ -1222,7 +1222,7 @@ static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) up(&this_usbduxsub->sem); return -EBUSY; } - /* set current channel of the running aquisition to zero */ + /* set current channel of the running acquisition to zero */ s->async->cur_chan = 0; this_usbduxsub->dux_commands[1] = cmd->chanlist_len; @@ -1284,7 +1284,7 @@ static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) this_usbduxsub->ai_sample_count = cmd->stop_arg; this_usbduxsub->ai_continous = 0; } else { - /* continous aquisition */ + /* continous acquisition */ this_usbduxsub->ai_continous = 1; this_usbduxsub->ai_sample_count = 0; } @@ -1515,7 +1515,7 @@ static int usbdux_ao_cmdtest(struct comedi_device *dev, /* just now we scan also in the high speed mode every frame */ /* this is due to ehci driver limitations */ if (0) { /* (this_usbduxsub->high_speed) */ - /* start immidiately a new scan */ + /* start immediately a new scan */ /* the sampling rate is set by the coversion rate */ cmd->scan_begin_src &= TRIG_FOLLOW; } else { @@ -1525,7 +1525,7 @@ static int usbdux_ao_cmdtest(struct comedi_device *dev, if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) err++; - /* scanning is continous */ + /* scanning is continuous */ tmp = cmd->convert_src; /* we always output at 1kHz just now all channels at once */ if (0) { /* (this_usbduxsub->high_speed) */ @@ -1645,7 +1645,7 @@ static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) dev_dbg(&this_usbduxsub->interface->dev, "comedi%d: %s\n", dev->minor, __func__); - /* set current channel of the running aquisition to zero */ + /* set current channel of the running acquisition to zero */ s->async->cur_chan = 0; for (i = 0; i < cmd->chanlist_len; ++i) { chan = CR_CHAN(cmd->chanlist[i]); @@ -1694,7 +1694,7 @@ static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) this_usbduxsub->ao_counter = this_usbduxsub->ao_timer; if (cmd->stop_src == TRIG_COUNT) { - /* not continous */ + /* not continuous */ /* counter */ /* high speed also scans everything at once */ if (0) { /* (this_usbduxsub->high_speed) */ @@ -1708,7 +1708,7 @@ static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) } this_usbduxsub->ao_continous = 0; } else { - /* continous aquisition */ + /* continous acquisition */ this_usbduxsub->ao_continous = 1; this_usbduxsub->ao_sample_count = 0; } diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index 5b15e6df54e6..2a8e725b7859 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -180,7 +180,7 @@ struct usbduxfastsub_s { /* comedi device for the interrupt context */ struct comedi_device *comedidev; short int ai_cmd_running; /* asynchronous command is running */ - short int ai_continous; /* continous aquisition */ + short int ai_continous; /* continous acquisition */ long int ai_sample_count; /* number of samples to acquire */ uint8_t *dux_commands; /* commands */ int ignore; /* counter which ignores the first @@ -392,7 +392,7 @@ static void usbduxfastsub_ai_Irq(struct urb *urb) p = urb->transfer_buffer; if (!udfs->ignore) { if (!udfs->ai_continous) { - /* not continous, fixed number of samples */ + /* not continuous, fixed number of samples */ n = urb->actual_length / sizeof(uint16_t); if (unlikely(udfs->ai_sample_count < n)) { /* @@ -775,7 +775,7 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev, up(&udfs->sem); return -EBUSY; } - /* set current channel of the running aquisition to zero */ + /* set current channel of the running acquisition to zero */ s->async->cur_chan = 0; /* @@ -1182,7 +1182,7 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev, } udfs->ai_continous = 0; } else { - /* continous aquisition */ + /* continous acquisition */ udfs->ai_continous = 1; udfs->ai_sample_count = 0; } diff --git a/drivers/staging/cptm1217/clearpad_tm1217.c b/drivers/staging/cptm1217/clearpad_tm1217.c index 76e4b782d2fb..0fe713e72e9d 100644 --- a/drivers/staging/cptm1217/clearpad_tm1217.c +++ b/drivers/staging/cptm1217/clearpad_tm1217.c @@ -52,7 +52,7 @@ #define TMA1217_DEV_STATUS 0x13 /* Device Status */ #define TMA1217_INT_STATUS 0x14 /* Interrupt Status */ -/* Controller can detect upto 2 possible finger touches. +/* Controller can detect up to 2 possible finger touches. * Each finger touch provides 12 bit X Y co-ordinates, the values are split * across 2 registers, and an 8 bit Z value */ #define TMA1217_FINGER_STATE 0x18 /* Finger State */ diff --git a/drivers/staging/crystalhd/crystalhd_cmds.c b/drivers/staging/crystalhd/crystalhd_cmds.c index 1429608544d6..3735ed3da4c6 100644 --- a/drivers/staging/crystalhd/crystalhd_cmds.c +++ b/drivers/staging/crystalhd/crystalhd_cmds.c @@ -914,7 +914,7 @@ enum BC_STATUS crystalhd_user_open(struct crystalhd_cmd *ctx, * Return: * status * - * Closer aplication handle and release app specific + * Closer application handle and release app specific * resources. */ enum BC_STATUS crystalhd_user_close(struct crystalhd_cmd *ctx, struct crystalhd_user *uc) diff --git a/drivers/staging/crystalhd/crystalhd_hw.c b/drivers/staging/crystalhd/crystalhd_hw.c index 13a514dd0f79..5acf39e7cdef 100644 --- a/drivers/staging/crystalhd/crystalhd_hw.c +++ b/drivers/staging/crystalhd/crystalhd_hw.c @@ -302,7 +302,7 @@ static bool crystalhd_start_device(struct crystalhd_adp *adp) crystalhd_enable_interrupts(adp); /* Enable the option for getting the total no. of DWORDS - * that have been transfered by the RXDMA engine + * that have been transferred by the RXDMA engine */ dbg_options = crystalhd_reg_rd(adp, MISC1_DMA_DEBUG_OPTIONS_REG); dbg_options |= 0x10; @@ -1776,7 +1776,7 @@ enum BC_STATUS crystalhd_do_fw_cmd(struct crystalhd_hw *hw, return sts; } - /*Get the Responce Address*/ + /*Get the Response Address*/ cmd_res_addr = bc_dec_reg_rd(hw->adp, Cpu2HstMbx1); /*Read the Response*/ @@ -2367,7 +2367,7 @@ enum BC_STATUS crystalhd_hw_set_core_clock(struct crystalhd_hw *hw) BCMLOG(BCMLOG_INFO, "clock is moving to %d with n %d with vco_mg %d\n", hw->core_clock_mhz, n, vco_mg); - /* Change the DRAM refresh rate to accomodate the new frequency */ + /* Change the DRAM refresh rate to accommodate the new frequency */ /* refresh reg = ((refresh_rate * clock_rate)/16) - 1; rounding up*/ refresh_reg = (7 * hw->core_clock_mhz / 16); bc_dec_reg_wr(hw->adp, SDRAM_REF_PARAM, ((1 << 12) | refresh_reg)); diff --git a/drivers/staging/cxt1e1/musycc.c b/drivers/staging/cxt1e1/musycc.c index f274c77fb3fc..5cc3423a6646 100644 --- a/drivers/staging/cxt1e1/musycc.c +++ b/drivers/staging/cxt1e1/musycc.c @@ -1455,7 +1455,7 @@ musycc_intr_bh_tasklet (ci_t * ci) /* * If the descriptor has not recovered, then leaving the EMPTY * entry set will not signal to the MUSYCC that this descriptor - * has been serviced. The Interrupt Queue can then start loosing + * has been serviced. The Interrupt Queue can then start losing * available descriptors and MUSYCC eventually encounters and * reports the INTFULL condition. Per manual, changing any bit * marks descriptor as available, thus the use of different diff --git a/drivers/staging/cxt1e1/musycc.h b/drivers/staging/cxt1e1/musycc.h index d2c91ef686d1..68f3660f4477 100644 --- a/drivers/staging/cxt1e1/musycc.h +++ b/drivers/staging/cxt1e1/musycc.h @@ -74,7 +74,7 @@ extern "C" #define INT_QUEUE_SIZE MUSYCC_NIQD -/* RAM image of MUSYCC registers layed out as a C structure */ +/* RAM image of MUSYCC registers laid out as a C structure */ struct musycc_groupr { VINT32 thp[32]; /* Transmit Head Pointer [5-29] */ @@ -96,7 +96,7 @@ extern "C" VINT32 pcd; /* Port Configuration Descriptor [5-19] */ }; -/* hardware MUSYCC registers layed out as a C structure */ +/* hardware MUSYCC registers laid out as a C structure */ struct musycc_globalr { VINT32 gbp; /* Group Base Pointer */ diff --git a/drivers/staging/cxt1e1/pmcc4_defs.h b/drivers/staging/cxt1e1/pmcc4_defs.h index 186347b8d565..a39505f45c29 100644 --- a/drivers/staging/cxt1e1/pmcc4_defs.h +++ b/drivers/staging/cxt1e1/pmcc4_defs.h @@ -54,8 +54,8 @@ #define MUSYCC_MTU 2048 /* default */ #define MUSYCC_TXDESC_MIN 10 /* HDLC mode default */ #define MUSYCC_RXDESC_MIN 18 /* HDLC mode default */ -#define MUSYCC_TXDESC_TRANS 4 /* Transparent mode minumum # of TX descriptors */ -#define MUSYCC_RXDESC_TRANS 12 /* Transparent mode minumum # of RX descriptors */ +#define MUSYCC_TXDESC_TRANS 4 /* Transparent mode minimum # of TX descriptors */ +#define MUSYCC_RXDESC_TRANS 12 /* Transparent mode minimum # of RX descriptors */ #define MAX_DEFAULT_IFQLEN 32 /* network qlen */ diff --git a/drivers/staging/cxt1e1/sbecrc.c b/drivers/staging/cxt1e1/sbecrc.c index 51232948091f..3f3cd60ac367 100644 --- a/drivers/staging/cxt1e1/sbecrc.c +++ b/drivers/staging/cxt1e1/sbecrc.c @@ -95,7 +95,7 @@ sbeCrc (u_int8_t *buffer, /* data buffer to crc */ /* * if table not yet created, do so. Don't care about "extra" time - * checking this everytime sbeCrc() is called, since CRC calculations are + * checking this every time sbeCrc() is called, since CRC calculations are * already time consuming */ if (!crcTableInit) diff --git a/drivers/staging/cxt1e1/sbeproc.c b/drivers/staging/cxt1e1/sbeproc.c index 70b9b33f3522..f42531c3d8da 100644 --- a/drivers/staging/cxt1e1/sbeproc.c +++ b/drivers/staging/cxt1e1/sbeproc.c @@ -239,7 +239,7 @@ sbecom_proc_get_sbe_info (char *buffer, char **start, off_t offset, */ #if 1 - /* #4 - intepretation of above = set EOF, return len */ + /* #4 - interpretation of above = set EOF, return len */ *eof = 1; #endif diff --git a/drivers/staging/et131x/et1310_address_map.h b/drivers/staging/et131x/et1310_address_map.h index e6c8cb3828e9..425e9274f28a 100644 --- a/drivers/staging/et131x/et1310_address_map.h +++ b/drivers/staging/et131x/et1310_address_map.h @@ -856,7 +856,7 @@ typedef union _RXMAC_UNI_PF_ADDR3_t { */ /* - * structure for space availiable reg in rxmac address map. + * structure for space available reg in rxmac address map. * located at address 0x4094 * * 31-17: reserved @@ -1031,7 +1031,7 @@ typedef struct _RXMAC_t { /* Location: */ * 31: reset MII mgmt * 30-6: unused * 5: scan auto increment - * 4: preamble supress + * 4: preamble suppress * 3: undefined * 2-0: mgmt clock reset */ diff --git a/drivers/staging/et131x/et1310_phy.h b/drivers/staging/et131x/et1310_phy.h index 78349adc7d8e..946c0c547404 100644 --- a/drivers/staging/et131x/et1310_phy.h +++ b/drivers/staging/et131x/et1310_phy.h @@ -468,7 +468,7 @@ typedef union _MI_ANAR_t { #define TRUEPHY_ANEG_COMPLETE 1 #define TRUEPHY_ANEG_DISABLED 2 -/* Define duplex advertisment flags */ +/* Define duplex advertisement flags */ #define TRUEPHY_ADV_DUPLEX_NONE 0x00 #define TRUEPHY_ADV_DUPLEX_FULL 0x01 #define TRUEPHY_ADV_DUPLEX_HALF 0x02 diff --git a/drivers/staging/et131x/et1310_rx.c b/drivers/staging/et131x/et1310_rx.c index 339136f64be1..fc6bd438366d 100644 --- a/drivers/staging/et131x/et1310_rx.c +++ b/drivers/staging/et131x/et1310_rx.c @@ -122,7 +122,7 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) * number of entries in FBR1. * * FBR1 holds "large" frames, FBR0 holds "small" frames. If FBR1 - * entries are huge in order to accomodate a "jumbo" frame, then it + * entries are huge in order to accommodate a "jumbo" frame, then it * will have less entries. Conversely, FBR1 will now be relied upon * to carry more "normal" frames, thus it's entry size also increases * and the number of entries goes up too (since it now carries diff --git a/drivers/staging/et131x/et131x_isr.c b/drivers/staging/et131x/et131x_isr.c index ce4d93042679..f716e408712b 100644 --- a/drivers/staging/et131x/et131x_isr.c +++ b/drivers/staging/et131x/et131x_isr.c @@ -466,7 +466,7 @@ void et131x_isr_handler(struct work_struct *work) /* Handle SLV Timeout Interrupt */ if (status & ET_INTR_SLV_TIMEOUT) { /* - * This means a timeout has occured on a read or + * This means a timeout has occurred on a read or * write request to one of the JAGCore registers. The * Global Resources block has terminated the request * and on a read request, returned a "fake" value. diff --git a/drivers/staging/et131x/et131x_netdev.c b/drivers/staging/et131x/et131x_netdev.c index 0c298cae90d9..b25bae29042e 100644 --- a/drivers/staging/et131x/et131x_netdev.c +++ b/drivers/staging/et131x/et131x_netdev.c @@ -415,7 +415,7 @@ void et131x_multicast(struct net_device *netdev) */ PacketFilter = adapter->PacketFilter; - /* Clear the 'multicast' flag locally; becuase we only have a single + /* Clear the 'multicast' flag locally; because we only have a single * flag to check multicast, and multiple multicast addresses can be * set, this is the easiest way to determine if more than one * multicast address is being set. diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dev.h b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dev.h index 4a89bd1bbf74..0b63f051f27c 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dev.h +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dev.h @@ -30,7 +30,7 @@ //--------------------------------------------------------------------------- // // Function: ft1000_read_reg -// Descripton: This function will read the value of a given ASIC register. +// Description: This function will read the value of a given ASIC register. // Input: // dev - device structure // offset - ASIC register offset @@ -49,7 +49,7 @@ static inline u16 ft1000_read_reg (struct net_device *dev, u16 offset) { //--------------------------------------------------------------------------- // // Function: ft1000_write_reg -// Descripton: This function will set the value for a given ASIC register. +// Description: This function will set the value for a given ASIC register. // Input: // dev - device structure // offset - ASIC register offset diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c index ff691d9b984e..eeb7dd43f9a8 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c @@ -90,7 +90,7 @@ MODULE_SUPPORTED_DEVICE("FT1000"); //--------------------------------------------------------------------------- // // Function: ft1000_asic_read -// Descripton: This function will retrieve the value of a specific ASIC +// Description: This function will retrieve the value of a specific ASIC // register. // Input: // dev - network device structure @@ -107,7 +107,7 @@ inline u16 ft1000_asic_read(struct net_device *dev, u16 offset) //--------------------------------------------------------------------------- // // Function: ft1000_asic_write -// Descripton: This function will set the value of a specific ASIC +// Description: This function will set the value of a specific ASIC // register. // Input: // dev - network device structure @@ -124,7 +124,7 @@ inline void ft1000_asic_write(struct net_device *dev, u16 offset, u16 value) //--------------------------------------------------------------------------- // // Function: ft1000_read_fifo_len -// Descripton: This function will read the ASIC Uplink FIFO status register +// Description: This function will read the ASIC Uplink FIFO status register // which will return the number of bytes remaining in the Uplink FIFO. // Sixteen bytes are subtracted to make sure that the ASIC does not // reach its threshold. @@ -148,7 +148,7 @@ static inline u16 ft1000_read_fifo_len(struct net_device *dev) //--------------------------------------------------------------------------- // // Function: ft1000_read_dpram -// Descripton: This function will read the specific area of dpram +// Description: This function will read the specific area of dpram // (Electrabuzz ASIC only) // Input: // dev - device structure @@ -175,7 +175,7 @@ u16 ft1000_read_dpram(struct net_device * dev, int offset) //--------------------------------------------------------------------------- // // Function: ft1000_write_dpram -// Descripton: This function will write to a specific area of dpram +// Description: This function will write to a specific area of dpram // (Electrabuzz ASIC only) // Input: // dev - device structure @@ -201,7 +201,7 @@ static inline void ft1000_write_dpram(struct net_device *dev, //--------------------------------------------------------------------------- // // Function: ft1000_read_dpram_mag_16 -// Descripton: This function will read the specific area of dpram +// Description: This function will read the specific area of dpram // (Magnemite ASIC only) // Input: // dev - device structure @@ -233,7 +233,7 @@ u16 ft1000_read_dpram_mag_16(struct net_device *dev, int offset, int Index) //--------------------------------------------------------------------------- // // Function: ft1000_write_dpram_mag_16 -// Descripton: This function will write to a specific area of dpram +// Description: This function will write to a specific area of dpram // (Magnemite ASIC only) // Input: // dev - device structure @@ -263,7 +263,7 @@ static inline void ft1000_write_dpram_mag_16(struct net_device *dev, //--------------------------------------------------------------------------- // // Function: ft1000_read_dpram_mag_32 -// Descripton: This function will read the specific area of dpram +// Description: This function will read the specific area of dpram // (Magnemite ASIC only) // Input: // dev - device structure @@ -290,7 +290,7 @@ u32 ft1000_read_dpram_mag_32(struct net_device *dev, int offset) //--------------------------------------------------------------------------- // // Function: ft1000_write_dpram_mag_32 -// Descripton: This function will write to a specific area of dpram +// Description: This function will write to a specific area of dpram // (Magnemite ASIC only) // Input: // dev - device structure @@ -315,7 +315,7 @@ void ft1000_write_dpram_mag_32(struct net_device *dev, int offset, u32 value) //--------------------------------------------------------------------------- // // Function: ft1000_enable_interrupts -// Descripton: This function will enable interrupts base on the current interrupt mask. +// Description: This function will enable interrupts base on the current interrupt mask. // Input: // dev - device structure // Output: @@ -340,7 +340,7 @@ static void ft1000_enable_interrupts(struct net_device *dev) //--------------------------------------------------------------------------- // // Function: ft1000_disable_interrupts -// Descripton: This function will disable all interrupts. +// Description: This function will disable all interrupts. // Input: // dev - device structure // Output: @@ -364,7 +364,7 @@ static void ft1000_disable_interrupts(struct net_device *dev) //--------------------------------------------------------------------------- // // Function: ft1000_reset_asic -// Descripton: This function will call the Card Service function to reset the +// Description: This function will call the Card Service function to reset the // ASIC. // Input: // dev - device structure @@ -408,7 +408,7 @@ static void ft1000_reset_asic(struct net_device *dev) //--------------------------------------------------------------------------- // // Function: ft1000_reset_card -// Descripton: This function will reset the card +// Description: This function will reset the card // Input: // dev - device structure // Output: @@ -571,7 +571,7 @@ static int ft1000_reset_card(struct net_device *dev) //--------------------------------------------------------------------------- // // Function: ft1000_chkcard -// Descripton: This function will check if the device is presently available on +// Description: This function will check if the device is presently available on // the system. // Input: // dev - device structure @@ -607,7 +607,7 @@ static int ft1000_chkcard(struct net_device *dev) //--------------------------------------------------------------------------- // // Function: ft1000_hbchk -// Descripton: This function will perform the heart beat check of the DSP as +// Description: This function will perform the heart beat check of the DSP as // well as the ASIC. // Input: // dev - device structure @@ -828,7 +828,7 @@ static void ft1000_hbchk(u_long data) //--------------------------------------------------------------------------- // // Function: ft1000_send_cmd -// Descripton: +// Description: // Input: // Output: // @@ -908,7 +908,7 @@ void ft1000_send_cmd (struct net_device *dev, u16 *ptempbuffer, int size, u16 qt //--------------------------------------------------------------------------- // // Function: ft1000_receive_cmd -// Descripton: This function will read a message from the dpram area. +// Description: This function will read a message from the dpram area. // Input: // dev - network device structure // pbuffer - caller supply address to buffer @@ -1003,7 +1003,7 @@ BOOLEAN ft1000_receive_cmd(struct net_device *dev, u16 * pbuffer, int maxsz, u16 //--------------------------------------------------------------------------- // // Function: ft1000_proc_drvmsg -// Descripton: This function will process the various driver messages. +// Description: This function will process the various driver messages. // Input: // dev - device structure // pnxtph - pointer to next pseudo header @@ -1285,7 +1285,7 @@ void ft1000_proc_drvmsg(struct net_device *dev) //--------------------------------------------------------------------------- // // Function: ft1000_parse_dpram_msg -// Descripton: This function will parse the message received from the DSP +// Description: This function will parse the message received from the DSP // via the DPRAM interface. // Input: // dev - device structure @@ -1442,7 +1442,7 @@ int ft1000_parse_dpram_msg(struct net_device *dev) //--------------------------------------------------------------------------- // // Function: ft1000_flush_fifo -// Descripton: This function will flush one packet from the downlink +// Description: This function will flush one packet from the downlink // FIFO. // Input: // dev - device structure @@ -1587,7 +1587,7 @@ static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum) //--------------------------------------------------------------------------- // // Function: ft1000_copy_up_pkt -// Descripton: This function will pull Flarion packets out of the Downlink +// Description: This function will pull Flarion packets out of the Downlink // FIFO and convert it to an ethernet packet. The ethernet packet will // then be deliver to the TCP/IP stack. // Input: @@ -1773,7 +1773,7 @@ int ft1000_copy_up_pkt(struct net_device *dev) //--------------------------------------------------------------------------- // // Function: ft1000_copy_down_pkt -// Descripton: This function will take an ethernet packet and convert it to +// Description: This function will take an ethernet packet and convert it to // a Flarion packet prior to sending it to the ASIC Downlink // FIFO. // Input: diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c index 8e622425aa13..1972b72450d4 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c @@ -488,7 +488,7 @@ static int check_buffers(u16 *buff_w, u16 *buff_r, int len, int offset) // Parameters: struct ft1000_device - device structure // u16 **pUsFile - DSP image file pointer in u16 // u8 **pUcFile - DSP image file pointer in u8 -// long word_length - lenght of the buffer to be written +// long word_length - length of the buffer to be written // to DPRAM // // Returns: STATUS_SUCCESS - success @@ -628,7 +628,7 @@ static void usb_dnld_complete (struct urb *urb) // Parameters: struct ft1000_device - device structure // u16 **pUsFile - DSP image file pointer in u16 // u8 **pUcFile - DSP image file pointer in u8 -// long word_length - lenght of the buffer to be written +// long word_length - length of the buffer to be written // to DPRAM // // Returns: STATUS_SUCCESS - success @@ -817,7 +817,7 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, * Error, beyond boot code range. */ DEBUG - ("FT1000:download:Download error: Requested len=%d exceeds BOOT code boundry.\n", + ("FT1000:download:Download error: Requested len=%d exceeds BOOT code boundary.\n", (int)word_length); status = STATUS_FAILURE; break; @@ -950,7 +950,7 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, * Error, beyond boot code range. */ DEBUG - ("FT1000:download:Download error: Requested len=%d exceeds DSP code boundry.\n", + ("FT1000:download:Download error: Requested len=%d exceeds DSP code boundary.\n", (int)word_length); status = STATUS_FAILURE; break; diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 78dcd49bb985..684e69eacb71 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -585,7 +585,7 @@ int dsp_reload(struct ft1000_device *ft1000dev) //--------------------------------------------------------------------------- // // Function: ft1000_reset_asic -// Descripton: This function will call the Card Service function to reset the +// Description: This function will call the Card Service function to reset the // ASIC. // Input: // dev - device structure @@ -626,7 +626,7 @@ static void ft1000_reset_asic(struct net_device *dev) //--------------------------------------------------------------------------- // // Function: ft1000_reset_card -// Descripton: This function will reset the card +// Description: This function will reset the card // Input: // dev - device structure // Output: @@ -917,7 +917,7 @@ static void ft1000_usb_transmit_complete(struct urb *urb) //--------------------------------------------------------------------------- // // Function: ft1000_copy_down_pkt -// Descripton: This function will take an ethernet packet and convert it to +// Description: This function will take an ethernet packet and convert it to // a Flarion packet prior to sending it to the ASIC Downlink // FIFO. // Input: @@ -1075,10 +1075,10 @@ err: //--------------------------------------------------------------------------- // // Function: ft1000_copy_up_pkt -// Descripton: This function will take a packet from the FIFO up link and +// Description: This function will take a packet from the FIFO up link and // convert it into an ethernet packet and deliver it to the IP stack // Input: -// urb - the receving usb urb +// urb - the receiving usb urb // // Output: // status - FAILURE @@ -1182,7 +1182,7 @@ static int ft1000_copy_up_pkt(struct urb *urb) //--------------------------------------------------------------------------- // // Function: ft1000_submit_rx_urb -// Descripton: the receiving function of the network driver +// Description: the receiving function of the network driver // // Input: // info - a private structure contains the device information @@ -1316,7 +1316,7 @@ Jim //--------------------------------------------------------------------------- // // Function: ft1000_chkcard -// Descripton: This function will check if the device is presently available on +// Description: This function will check if the device is presently available on // the system. // Input: // dev - device structure @@ -1363,7 +1363,7 @@ static int ft1000_chkcard(struct ft1000_device *dev) //--------------------------------------------------------------------------- // // Function: ft1000_receive_cmd -// Descripton: This function will read a message from the dpram area. +// Description: This function will read a message from the dpram area. // Input: // dev - network device structure // pbuffer - caller supply address to buffer diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_ioctl.h b/drivers/staging/ft1000/ft1000-usb/ft1000_ioctl.h index 3f72d5bb3f92..6a8a1969f9e1 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_ioctl.h +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_ioctl.h @@ -55,7 +55,7 @@ struct pseudo_hdr { unsigned char seq_num; //sequence number unsigned char rsvd2; //reserved unsigned short qos_class; //Quality of Service class (Not applicable on Mobile) - unsigned short checksum; //Psuedo header checksum + unsigned short checksum; //Pseudo header checksum } __attribute__ ((packed)); typedef struct _IOCTL_GET_VER diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h index e047c03fbf3a..f2ecb3eae9cd 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h @@ -364,7 +364,7 @@ struct prov_record { #define ISR_EMPTY (u8)0x00 // no bits set in ISR -#define ISR_DOORBELL_ACK (u8)0x01 // the doorbell i sent has been recieved. +#define ISR_DOORBELL_ACK (u8)0x01 // the doorbell i sent has been received. #define ISR_DOORBELL_PEND (u8)0x02 // doorbell for me diff --git a/drivers/staging/generic_serial/generic_serial.c b/drivers/staging/generic_serial/generic_serial.c index 466988dbc37d..f29dda4e9f20 100644 --- a/drivers/staging/generic_serial/generic_serial.c +++ b/drivers/staging/generic_serial/generic_serial.c @@ -113,7 +113,7 @@ int gs_write(struct tty_struct * tty, c = count; - /* This is safe because we "OWN" the "head". Noone else can + /* This is safe because we "OWN" the "head". No one else can change the "head": we own the port_write_mutex. */ /* Don't overrun the end of the buffer */ t = SERIAL_XMIT_SIZE - port->xmit_head; diff --git a/drivers/staging/generic_serial/rio/map.h b/drivers/staging/generic_serial/rio/map.h index 8366978578c1..28a66129293e 100644 --- a/drivers/staging/generic_serial/rio/map.h +++ b/drivers/staging/generic_serial/rio/map.h @@ -87,7 +87,7 @@ struct Map { ** The Topology array contains the ID of the unit connected to each of the ** four links on this unit. The entry will be 0xFFFF if NOTHING is connected ** to the link, or will be 0xFF00 if an UNKNOWN unit is connected to the link. -** The Name field is a null-terminated string, upto 31 characters, containing +** The Name field is a null-terminated string, up to 31 characters, containing ** the 'cute' name that the sysadmin/users know the RTA by. It is permissible ** for this string to contain any character in the range \040 to \176 inclusive. ** In particular, ctrl sequences and DEL (0x7F, \177) are not allowed. The diff --git a/drivers/staging/generic_serial/rio/rioboot.c b/drivers/staging/generic_serial/rio/rioboot.c index d956dd316005..ffa01c590216 100644 --- a/drivers/staging/generic_serial/rio/rioboot.c +++ b/drivers/staging/generic_serial/rio/rioboot.c @@ -109,7 +109,7 @@ int RIOBootCodeRTA(struct rio_info *p, struct DownLoad * rbp) rio_dprintk(RIO_DEBUG_BOOT, "Data at user address %p\n", rbp->DataP); /* - ** Check that we have set asside enough memory for this + ** Check that we have set aside enough memory for this */ if (rbp->Count > SIXTY_FOUR_K) { rio_dprintk(RIO_DEBUG_BOOT, "RTA Boot Code Too Large!\n"); @@ -293,7 +293,7 @@ int RIOBootCodeHOST(struct rio_info *p, struct DownLoad *rbp) /* ** S T O P ! ** - ** Upto this point the code has been fairly rational, and possibly + ** Up to this point the code has been fairly rational, and possibly ** even straight forward. What follows is a pile of crud that will ** magically turn into six bytes of transputer assembler. Normally ** you would expect an array or something, but, being me, I have @@ -419,7 +419,7 @@ int RIOBootCodeHOST(struct rio_info *p, struct DownLoad *rbp) rio_dprintk(RIO_DEBUG_BOOT, "Set control port\n"); /* - ** Now, wait for upto five seconds for the Tp to setup the parmmap + ** Now, wait for up to five seconds for the Tp to setup the parmmap ** pointer: */ for (wait_count = 0; (wait_count < p->RIOConf.StartupTime) && (readw(&HostP->__ParmMapR) == OldParmMap); wait_count++) { @@ -475,7 +475,7 @@ int RIOBootCodeHOST(struct rio_info *p, struct DownLoad *rbp) /* ** now wait for the card to set all the parmmap->XXX stuff - ** this is a wait of upto two seconds.... + ** this is a wait of up to two seconds.... */ rio_dprintk(RIO_DEBUG_BOOT, "Looking for init_done - %d ticks\n", p->RIOConf.StartupTime); HostP->timeout_id = 0; diff --git a/drivers/staging/generic_serial/rio/riocmd.c b/drivers/staging/generic_serial/rio/riocmd.c index f121357e5af0..61efd538e850 100644 --- a/drivers/staging/generic_serial/rio/riocmd.c +++ b/drivers/staging/generic_serial/rio/riocmd.c @@ -863,7 +863,7 @@ int RIOUnUse(unsigned long iPortP, struct CmdBlk *CmdBlkP) ** being transferred from the write queue into the transmit packets ** (add_transmit) and no furthur transmit interrupt will be sent for that ** data. The next interrupt will occur up to 500ms later (RIOIntr is called - ** twice a second as a saftey measure). This was the case when kermit was + ** twice a second as a safety measure). This was the case when kermit was ** used to send data into a RIO port. After each packet was sent, TCFLSH ** was called to flush the read queue preemptively. PortP->InUse was ** incremented, thereby blocking the 6 byte acknowledgement packet diff --git a/drivers/staging/generic_serial/rio/rioroute.c b/drivers/staging/generic_serial/rio/rioroute.c index f9b936ac3394..8757378e8320 100644 --- a/drivers/staging/generic_serial/rio/rioroute.c +++ b/drivers/staging/generic_serial/rio/rioroute.c @@ -450,7 +450,7 @@ int RIORouteRup(struct rio_info *p, unsigned int Rup, struct Host *HostP, struct ** we reset the unit, because we didn't boot it. ** However, if the table is full, it could be that we did boot ** this unit, and so we won't reboot it, because it isn't really - ** all that disasterous to keep the old bins in most cases. This + ** all that disastrous to keep the old bins in most cases. This ** is a rather tacky feature, but we are on the edge of reallity ** here, because the implication is that someone has connected ** 16+MAX_EXTRA_UNITS onto one host. @@ -678,7 +678,7 @@ static int RIOCheck(struct Host *HostP, unsigned int UnitId) HostP->Mapping[UnitId].Flags &= ~BEEN_HERE; - /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d DOESNT KNOW THE HOST!\n", UnitId)); */ + /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d DOESN'T KNOW THE HOST!\n", UnitId)); */ return 0; } diff --git a/drivers/staging/generic_serial/rio/riotty.c b/drivers/staging/generic_serial/rio/riotty.c index 8a90393faf3c..e7e9911d7a72 100644 --- a/drivers/staging/generic_serial/rio/riotty.c +++ b/drivers/staging/generic_serial/rio/riotty.c @@ -124,7 +124,7 @@ int riotopen(struct tty_struct *tty, struct file *filp) } /* - ** Grab pointer to the port stucture + ** Grab pointer to the port structure */ PortP = p->RIOPortp[SysPort]; /* Get control struc */ rio_dprintk(RIO_DEBUG_TTY, "PortP: %p\n", PortP); @@ -161,7 +161,7 @@ int riotopen(struct tty_struct *tty, struct file *filp) } /* - ** If the RTA has not booted yet and the user has choosen to block + ** If the RTA has not booted yet and the user has chosen to block ** until the RTA is present then we must spin here waiting for ** the RTA to boot. */ diff --git a/drivers/staging/generic_serial/sx.c b/drivers/staging/generic_serial/sx.c index 1291462bcddb..4f94aaffbe83 100644 --- a/drivers/staging/generic_serial/sx.c +++ b/drivers/staging/generic_serial/sx.c @@ -158,13 +158,13 @@ * Readying for release on 2.0.x (sorry David, 1.01 becomes 1.1 for RCS). * * Revision 0.12 1999/03/28 09:20:10 wolff - * Fixed problem in 0.11, continueing cleanup. + * Fixed problem in 0.11, continuing cleanup. * * Revision 0.11 1999/03/28 08:46:44 wolff * cleanup. Not good. * * Revision 0.10 1999/03/28 08:09:43 wolff - * Fixed loosing characters on close. + * Fixed losing characters on close. * * Revision 0.9 1999/03/21 22:52:01 wolff * Ported back to 2.2.... (minor things) @@ -1588,7 +1588,7 @@ static void sx_close(void *ptr) #define R0 if (read_sx_byte(board, i) != 0x55) return 1 #define R1 if (read_sx_byte(board, i) != 0xaa) return 1 -/* This memtest takes a human-noticable time. You normally only do it +/* This memtest takes a human-noticeable time. You normally only do it once a boot, so I guess that it is worth it. */ static int do_memtest(struct sx_board *board, int min, int max) { @@ -1645,7 +1645,7 @@ static int do_memtest(struct sx_board *board, int min, int max) #define R1 if (read_sx_word(board, i) != 0xaa55) return 1 #if 0 -/* This memtest takes a human-noticable time. You normally only do it +/* This memtest takes a human-noticeable time. You normally only do it once a boot, so I guess that it is worth it. */ static int do_memtest_w(struct sx_board *board, int min, int max) { diff --git a/drivers/staging/gma500/psb_drm.h b/drivers/staging/gma500/psb_drm.h index fb9b4245bada..a339406052ef 100644 --- a/drivers/staging/gma500/psb_drm.h +++ b/drivers/staging/gma500/psb_drm.h @@ -131,7 +131,7 @@ struct drm_psb_reloc { u32 pre_add; /* Destination format: */ u32 background; /* Destination add */ u32 dst_buffer; /* Destination buffer. Index into buffer_list */ - u32 arg0; /* Reloc-op dependant */ + u32 arg0; /* Reloc-op dependent */ u32 arg1; }; diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c index 44cd095d2862..d01d45e7a14d 100644 --- a/drivers/staging/gma500/psb_drv.c +++ b/drivers/staging/gma500/psb_drv.c @@ -561,7 +561,7 @@ static int psb_driver_unload(struct drm_device *dev) kfree(dev_priv); dev->dev_private = NULL; - /*destory VBT data*/ + /*destroy VBT data*/ psb_intel_destroy_bios(dev); } diff --git a/drivers/staging/gma500/psb_intel_bios.c b/drivers/staging/gma500/psb_intel_bios.c index f5bcd119b87d..48ac8ba7f40b 100644 --- a/drivers/staging/gma500/psb_intel_bios.c +++ b/drivers/staging/gma500/psb_intel_bios.c @@ -271,7 +271,7 @@ bool psb_intel_init_bios(struct drm_device *dev) } /** - * Destory and free VBT data + * Destroy and free VBT data */ void psb_intel_destroy_bios(struct drm_device *dev) { diff --git a/drivers/staging/gma500/psb_intel_sdvo.c b/drivers/staging/gma500/psb_intel_sdvo.c index 731a5a2261d3..1d2bb021c0a5 100644 --- a/drivers/staging/gma500/psb_intel_sdvo.c +++ b/drivers/staging/gma500/psb_intel_sdvo.c @@ -573,7 +573,7 @@ static bool psb_sdvo_set_current_inoutmap(struct psb_intel_output *output, /* Make all fields of the args/ret to zero */ memset(byArgs, 0, sizeof(byArgs)); - /* Fill up the arguement values; */ + /* Fill up the argument values; */ byArgs[0] = (u8) (in0outputmask & 0xFF); byArgs[1] = (u8) ((in0outputmask >> 8) & 0xFF); byArgs[2] = (u8) (in1outputmask & 0xFF); diff --git a/drivers/staging/gma500/psb_intel_sdvo_regs.h b/drivers/staging/gma500/psb_intel_sdvo_regs.h index a1d1475a9315..c7107a37e33d 100644 --- a/drivers/staging/gma500/psb_intel_sdvo_regs.h +++ b/drivers/staging/gma500/psb_intel_sdvo_regs.h @@ -217,7 +217,7 @@ struct psb_intel_sdvo_set_target_input_args { } __attribute__ ((packed)); /** - * Takes a struct psb_intel_sdvo_output_flags of which outputs are targetted by + * Takes a struct psb_intel_sdvo_output_flags of which outputs are targeted by * future output commands. * * Affected commands inclue SET_OUTPUT_TIMINGS_PART[12], diff --git a/drivers/staging/gma500/psb_ttm_fence_user.h b/drivers/staging/gma500/psb_ttm_fence_user.h index fc13f89c6e12..762a05728632 100644 --- a/drivers/staging/gma500/psb_ttm_fence_user.h +++ b/drivers/staging/gma500/psb_ttm_fence_user.h @@ -130,7 +130,7 @@ struct ttm_fence_unref_arg { }; /* - * Ioctl offsets frome extenstion start. + * Ioctl offsets from extenstion start. */ #define TTM_FENCE_SIGNALED 0x01 diff --git a/drivers/staging/go7007/go7007.txt b/drivers/staging/go7007/go7007.txt index 06a76da32128..9db1f3952fd2 100644 --- a/drivers/staging/go7007/go7007.txt +++ b/drivers/staging/go7007/go7007.txt @@ -2,7 +2,7 @@ This is a driver for the WIS GO7007SB multi-format video encoder. Pete Eberlein -The driver was orignally released under the GPL and is currently hosted at: +The driver was originally released under the GPL and is currently hosted at: http://nikosapi.org/wiki/index.php/WIS_Go7007_Linux_driver The go7007 firmware can be acquired from the package on the site above. diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index af789937be4e..68ad17d67098 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -894,7 +894,7 @@ static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req, /* * We break the request into 1 or more blkvsc_requests and submit - * them. If we cant submit them all, we put them on the + * them. If we can't submit them all, we put them on the * pending_list. The blkvsc_request() will work on the pending_list. */ static int blkvsc_do_request(struct block_device_context *blkdev, diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index bc0393a41d29..06b573227e8d 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c @@ -166,7 +166,7 @@ EXPORT_SYMBOL(prep_negotiate_resp); * from Hyper-V. This stub responds to the default negotiate messages * that come in for every non IDE/SCSI/Network request. * This behavior is normally overwritten in the hv_utils driver. That - * driver handles requests like gracefull shutdown, heartbeats etc. + * driver handles requests like graceful shutdown, heartbeats etc. * * Mainly used by Hyper-V drivers. */ diff --git a/drivers/staging/hv/hv.c b/drivers/staging/hv/hv.c index 2d492adb95bb..0b06f4fe5838 100644 --- a/drivers/staging/hv/hv.c +++ b/drivers/staging/hv/hv.c @@ -37,7 +37,7 @@ struct hv_context hv_context = { /* * query_hypervisor_presence - * - Query the cpuid for presense of windows hypervisor + * - Query the cpuid for presence of windows hypervisor */ static int query_hypervisor_presence(void) { diff --git a/drivers/staging/hv/hv_api.h b/drivers/staging/hv/hv_api.h index 7114fceab21e..43a722888dc4 100644 --- a/drivers/staging/hv/hv_api.h +++ b/drivers/staging/hv/hv_api.h @@ -53,14 +53,14 @@ struct hv_guid { /* * HV_STATUS_INVALID_ALIGNMENT - * The hypervisor could not perform the operation beacuse a parameter has an + * The hypervisor could not perform the operation because a parameter has an * invalid alignment. */ #define HV_STATUS_INVALID_ALIGNMENT ((u16)0x0004) /* * HV_STATUS_INVALID_PARAMETER - * The hypervisor could not perform the operation beacuse an invalid parameter + * The hypervisor could not perform the operation because an invalid parameter * was specified. */ #define HV_STATUS_INVALID_PARAMETER ((u16)0x0005) diff --git a/drivers/staging/hv/hv_kvp.h b/drivers/staging/hv/hv_kvp.h index e069f59b5135..8c402f357d37 100644 --- a/drivers/staging/hv/hv_kvp.h +++ b/drivers/staging/hv/hv_kvp.h @@ -36,7 +36,7 @@ * registry. * * Note: This value is used in defining the KVP exchange message - this value - * cannot be modified without affecting the message size and compatability. + * cannot be modified without affecting the message size and compatibility. */ /* diff --git a/drivers/staging/hv/hv_util.c b/drivers/staging/hv/hv_util.c index 4792f2c402b2..2df15683f8fa 100644 --- a/drivers/staging/hv/hv_util.c +++ b/drivers/staging/hv/hv_util.c @@ -80,7 +80,7 @@ static void shutdown_onchannelcallback(void *context) execute_shutdown = true; DPRINT_INFO(VMBUS, "Shutdown request received -" - " gracefull shutdown initiated"); + " graceful shutdown initiated"); break; default: icmsghdrp->status = HV_E_FAIL; diff --git a/drivers/staging/hv/rndis_filter.c b/drivers/staging/hv/rndis_filter.c index e7189cd324ca..048376b2b676 100644 --- a/drivers/staging/hv/rndis_filter.c +++ b/drivers/staging/hv/rndis_filter.c @@ -585,7 +585,7 @@ static int rndis_filter_set_packet_filter(struct rndis_device *dev, ret = -1; DPRINT_ERR(NETVSC, "timeout before we got a set response..."); /* - * We cant deallocate the request since we may still receive a + * We can't deallocate the request since we may still receive a * send completion for it. */ goto Exit; diff --git a/drivers/staging/hv/tools/hv_kvp_daemon.c b/drivers/staging/hv/tools/hv_kvp_daemon.c index f5a2dd694611..aa77a971aace 100644 --- a/drivers/staging/hv/tools/hv_kvp_daemon.c +++ b/drivers/staging/hv/tools/hv_kvp_daemon.c @@ -202,7 +202,7 @@ kvp_get_ip_address(int family, char *buffer, int length) /* * We only support AF_INET and AF_INET6 - * and the list of addresses is seperated by a ";". + * and the list of addresses is separated by a ";". */ struct sockaddr_in6 *addr = (struct sockaddr_in6 *) curp->ifa_addr; diff --git a/drivers/staging/iio/Documentation/iio_utils.h b/drivers/staging/iio/Documentation/iio_utils.h index 8095727b3966..fd78e4ff99ae 100644 --- a/drivers/staging/iio/Documentation/iio_utils.h +++ b/drivers/staging/iio/Documentation/iio_utils.h @@ -556,7 +556,7 @@ int _write_sysfs_string(char *filename, char *basedir, char *val, int verify) if (strcmp(temp, val) != 0) { printf("Possible failure in string write of %s " "Should be %s " - "writen to %s\%s\n", + "written to %s\%s\n", temp, val, basedir, diff --git a/drivers/staging/iio/accel/adis16201.h b/drivers/staging/iio/accel/adis16201.h index c9bf22c13428..23fe54d09d12 100644 --- a/drivers/staging/iio/accel/adis16201.h +++ b/drivers/staging/iio/accel/adis16201.h @@ -70,7 +70,7 @@ * @indio_dev: industrial I/O device structure * @trig: data ready trigger registered with iio * @tx: transmit buffer - * @rx: recieve buffer + * @rx: receive buffer * @buf_lock: mutex to protect tx and rx **/ struct adis16201_state { diff --git a/drivers/staging/iio/accel/adis16203.h b/drivers/staging/iio/accel/adis16203.h index b39323eac9e3..b88688128d61 100644 --- a/drivers/staging/iio/accel/adis16203.h +++ b/drivers/staging/iio/accel/adis16203.h @@ -65,7 +65,7 @@ * @indio_dev: industrial I/O device structure * @trig: data ready trigger registered with iio * @tx: transmit buffer - * @rx: recieve buffer + * @rx: receive buffer * @buf_lock: mutex to protect tx and rx **/ struct adis16203_state { diff --git a/drivers/staging/iio/accel/adis16204.h b/drivers/staging/iio/accel/adis16204.h index e9ed7cb048cf..e61844684f99 100644 --- a/drivers/staging/iio/accel/adis16204.h +++ b/drivers/staging/iio/accel/adis16204.h @@ -73,7 +73,7 @@ * @indio_dev: industrial I/O device structure * @trig: data ready trigger registered with iio * @tx: transmit buffer - * @rx: recieve buffer + * @rx: receive buffer * @buf_lock: mutex to protect tx and rx **/ struct adis16204_state { diff --git a/drivers/staging/iio/accel/adis16209.h b/drivers/staging/iio/accel/adis16209.h index 4e97596620ef..8b0da1349555 100644 --- a/drivers/staging/iio/accel/adis16209.h +++ b/drivers/staging/iio/accel/adis16209.h @@ -109,7 +109,7 @@ * @indio_dev: industrial I/O device structure * @trig: data ready trigger registered with iio * @tx: transmit buffer - * @rx: recieve buffer + * @rx: receive buffer * @buf_lock: mutex to protect tx and rx **/ struct adis16209_state { diff --git a/drivers/staging/iio/accel/adis16220.h b/drivers/staging/iio/accel/adis16220.h index 7013314a9d77..4d5758c2c047 100644 --- a/drivers/staging/iio/accel/adis16220.h +++ b/drivers/staging/iio/accel/adis16220.h @@ -132,7 +132,7 @@ * @indio_dev: industrial I/O device structure * @trig: data ready trigger registered with iio * @tx: transmit buffer - * @rx: recieve buffer + * @rx: receive buffer * @buf_lock: mutex to protect tx and rx **/ struct adis16220_state { diff --git a/drivers/staging/iio/accel/adis16240.h b/drivers/staging/iio/accel/adis16240.h index 51a807dde27c..76a45797b9dd 100644 --- a/drivers/staging/iio/accel/adis16240.h +++ b/drivers/staging/iio/accel/adis16240.h @@ -132,7 +132,7 @@ * @indio_dev: industrial I/O device structure * @trig: data ready trigger registered with iio * @tx: transmit buffer - * @rx: recieve buffer + * @rx: receive buffer * @buf_lock: mutex to protect tx and rx **/ struct adis16240_state { diff --git a/drivers/staging/iio/accel/lis3l02dq.h b/drivers/staging/iio/accel/lis3l02dq.h index 579b3a26e5d7..11402187f9ae 100644 --- a/drivers/staging/iio/accel/lis3l02dq.h +++ b/drivers/staging/iio/accel/lis3l02dq.h @@ -57,7 +57,7 @@ /* Reboot memory content */ #define LIS3L02DQ_REG_CTRL_2_REBOOT_MEMORY 0x10 -/* Interupt Enable - applies data ready to the RDY pad */ +/* Interrupt Enable - applies data ready to the RDY pad */ #define LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT 0x08 /* Enable Data Ready Generation - relationship with previous unclear in docs */ @@ -70,34 +70,34 @@ * - option for 16 bit left justified */ #define LIS3L02DQ_REG_CTRL_2_DATA_ALIGNMENT_16_BIT_LEFT_JUSTIFIED 0x01 -/* Interupt related stuff */ +/* Interrupt related stuff */ #define LIS3L02DQ_REG_WAKE_UP_CFG_ADDR 0x23 /* Switch from or combination fo conditions to and */ #define LIS3L02DQ_REG_WAKE_UP_CFG_BOOLEAN_AND 0x80 -/* Latch interupt request, +/* Latch interrupt request, * if on ack must be given by reading the ack register */ #define LIS3L02DQ_REG_WAKE_UP_CFG_LATCH_SRC 0x40 -/* Z Interupt on High (above threshold)*/ +/* Z Interrupt on High (above threshold)*/ #define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Z_HIGH 0x20 -/* Z Interupt on Low */ +/* Z Interrupt on Low */ #define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Z_LOW 0x10 -/* Y Interupt on High */ +/* Y Interrupt on High */ #define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Y_HIGH 0x08 -/* Y Interupt on Low */ +/* Y Interrupt on Low */ #define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Y_LOW 0x04 -/* X Interupt on High */ +/* X Interrupt on High */ #define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_X_HIGH 0x02 -/* X Interupt on Low */ +/* X Interrupt on Low */ #define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_X_LOW 0x01 -/* Register that gives description of what caused interupt +/* Register that gives description of what caused interrupt * - latched if set in CFG_ADDRES */ #define LIS3L02DQ_REG_WAKE_UP_SRC_ADDR 0x24 /* top bit ignored */ -/* Interupt Active */ +/* Interrupt Active */ #define LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_ACTIVATED 0x40 /* Interupts that have been triggered */ #define LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Z_HIGH 0x20 @@ -123,7 +123,7 @@ #define LIS3L02DQ_REG_STATUS_X_NEW_DATA 0x01 /* The accelerometer readings - low and high bytes. -Form of high byte dependant on justification set in ctrl reg */ +Form of high byte dependent on justification set in ctrl reg */ #define LIS3L02DQ_REG_OUT_X_L_ADDR 0x28 #define LIS3L02DQ_REG_OUT_X_H_ADDR 0x29 #define LIS3L02DQ_REG_OUT_Y_L_ADDR 0x2A @@ -155,7 +155,7 @@ Form of high byte dependant on justification set in ctrl reg */ * @inter: used to check if new interrupt has been triggered * @trig: data ready trigger registered with iio * @tx: transmit buffer - * @rx: recieve buffer + * @rx: receive buffer * @buf_lock: mutex to protect tx and rx **/ struct lis3l02dq_state { diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c index c4b4ab7e6423..3067f9662d20 100644 --- a/drivers/staging/iio/accel/lis3l02dq_core.c +++ b/drivers/staging/iio/accel/lis3l02dq_core.c @@ -77,7 +77,7 @@ int lis3l02dq_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val) /** * lis3l02dq_spi_write_reg_8() - write single byte to a register * @dev: device associated with child of actual device (iio_dev or iio_trig) - * @reg_address: the address of the register to be writen + * @reg_address: the address of the register to be written * @val: the value to write **/ int lis3l02dq_spi_write_reg_8(struct device *dev, diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c index 2c461a31f129..529a3cc6d0c7 100644 --- a/drivers/staging/iio/accel/lis3l02dq_ring.c +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c @@ -217,7 +217,7 @@ static const u8 read_all_tx_array[] = { /** * lis3l02dq_read_all() Reads all channels currently selected * @st: device specific state - * @rx_array: (dma capable) recieve array, must be at least + * @rx_array: (dma capable) receive array, must be at least * 4*number of channels **/ static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array) @@ -409,7 +409,7 @@ static const struct attribute_group lis3l02dq_trigger_attr_group = { * * As the trigger may occur on any data element being updated it is * really rather likely to occur during the read from the previous - * trigger event. The only way to discover if this has occured on + * trigger event. The only way to discover if this has occurred on * boards not supporting level interrupts is to take a look at the line. * If it is indicating another interrupt and we don't seem to have a * handler looking at it, then we need to notify the core that we need diff --git a/drivers/staging/iio/accel/sca3000.h b/drivers/staging/iio/accel/sca3000.h index 23892848f5ae..db710334b99b 100644 --- a/drivers/staging/iio/accel/sca3000.h +++ b/drivers/staging/iio/accel/sca3000.h @@ -185,7 +185,7 @@ struct sca3000_state { }; /** - * struct sca3000_chip_info - model dependant parameters + * struct sca3000_chip_info - model dependent parameters * @name: model identification * @scale: string containing floating point scale factor * @temp_output: some devices have temperature sensors. @@ -213,7 +213,7 @@ struct sca3000_chip_info { * sca3000_read_data() read a series of values from the device * @dev: device * @reg_address_high: start address (decremented read) - * @rx: pointer where recieved data is placed. Callee + * @rx: pointer where received data is placed. Callee * responsible for freeing this. * @len: number of bytes to read * diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c index c872fddfb2bf..a730a7638de1 100644 --- a/drivers/staging/iio/accel/sca3000_ring.c +++ b/drivers/staging/iio/accel/sca3000_ring.c @@ -43,7 +43,7 @@ * leading byte used in bus comms. * * Currently does not provide timestamps. As the hardware doesn't add them they - * can only be inferred aproximately from ring buffer events such as 50% full + * can only be inferred approximately from ring buffer events such as 50% full * and knowledge of when buffer was last emptied. This is left to userspace. **/ static int sca3000_rip_hw_rb(struct iio_ring_buffer *r, diff --git a/drivers/staging/iio/adc/ad7298_ring.c b/drivers/staging/iio/adc/ad7298_ring.c index 19d1aced1e6c..9068d7f54d15 100644 --- a/drivers/staging/iio/adc/ad7298_ring.c +++ b/drivers/staging/iio/adc/ad7298_ring.c @@ -157,7 +157,7 @@ static int ad7298_ring_preenable(struct iio_dev *indio_dev) /** * ad7298_poll_func_th() th of trigger launched polling to ring buffer * - * As sampling only occurs on spi comms occuring, leave timestamping until + * As sampling only occurs on spi comms occurring, leave timestamping until * then. Some triggers will generate their own time stamp. Currently * there is no way of notifying them when no one cares. **/ diff --git a/drivers/staging/iio/adc/ad7476_ring.c b/drivers/staging/iio/adc/ad7476_ring.c index 1d654c86099d..92d93787d5b8 100644 --- a/drivers/staging/iio/adc/ad7476_ring.c +++ b/drivers/staging/iio/adc/ad7476_ring.c @@ -112,7 +112,7 @@ static int ad7476_ring_preenable(struct iio_dev *indio_dev) /** * ad7476_poll_func_th() th of trigger launched polling to ring buffer * - * As sampling only occurs on i2c comms occuring, leave timestamping until + * As sampling only occurs on i2c comms occurring, leave timestamping until * then. Some triggers will generate their own time stamp. Currently * there is no way of notifying them when no one cares. **/ diff --git a/drivers/staging/iio/adc/ad7887_ring.c b/drivers/staging/iio/adc/ad7887_ring.c index 2d7fe65049dd..da77f266c16b 100644 --- a/drivers/staging/iio/adc/ad7887_ring.c +++ b/drivers/staging/iio/adc/ad7887_ring.c @@ -165,7 +165,7 @@ static int ad7887_ring_postdisable(struct iio_dev *indio_dev) /** * ad7887_poll_func_th() th of trigger launched polling to ring buffer * - * As sampling only occurs on spi comms occuring, leave timestamping until + * As sampling only occurs on spi comms occurring, leave timestamping until * then. Some triggers will generate their own time stamp. Currently * there is no way of notifying them when no one cares. **/ diff --git a/drivers/staging/iio/adc/ad799x_core.c b/drivers/staging/iio/adc/ad799x_core.c index e50841b3ac69..f04e642e7272 100644 --- a/drivers/staging/iio/adc/ad799x_core.c +++ b/drivers/staging/iio/adc/ad799x_core.c @@ -184,7 +184,7 @@ static ssize_t ad799x_read_single_channel(struct device *dev, mutex_lock(&dev_info->mlock); mask = 1 << this_attr->address; - /* If ring buffer capture is occuring, query the buffer */ + /* If ring buffer capture is occurring, query the buffer */ if (iio_ring_enabled(dev_info)) { data = ret = ad799x_single_channel_from_ring(st, mask); if (ret < 0) diff --git a/drivers/staging/iio/adc/ad799x_ring.c b/drivers/staging/iio/adc/ad799x_ring.c index 56abc395f177..0875a7ef67a5 100644 --- a/drivers/staging/iio/adc/ad799x_ring.c +++ b/drivers/staging/iio/adc/ad799x_ring.c @@ -101,7 +101,7 @@ static int ad799x_ring_preenable(struct iio_dev *indio_dev) /** * ad799x_poll_func_th() th of trigger launched polling to ring buffer * - * As sampling only occurs on i2c comms occuring, leave timestamping until + * As sampling only occurs on i2c comms occurring, leave timestamping until * then. Some triggers will generate their own time stamp. Currently * there is no way of notifying them when no one cares. **/ diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c index dde097afb430..de83c3b37a2d 100644 --- a/drivers/staging/iio/adc/max1363_core.c +++ b/drivers/staging/iio/adc/max1363_core.c @@ -255,7 +255,7 @@ static ssize_t max1363_read_single_channel(struct device *dev, goto error_ret; } - /* If ring buffer capture is occuring, query the buffer */ + /* If ring buffer capture is occurring, query the buffer */ if (iio_ring_enabled(dev_info)) { mask = max1363_mode_table[this_attr->address].modemask; data = max1363_single_channel_from_ring(mask, st); @@ -1425,7 +1425,7 @@ error_ret: } /* - * To keep this managable we always use one of 3 scan modes. + * To keep this manageable we always use one of 3 scan modes. * Scan 0...3, 0-1,2-3 and 1-0,3-2 */ static inline int __max1363_check_event_mask(int thismask, int checkmask) diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c index 5532f3e466bc..d36fcc62e976 100644 --- a/drivers/staging/iio/adc/max1363_ring.c +++ b/drivers/staging/iio/adc/max1363_ring.c @@ -108,7 +108,7 @@ static int max1363_ring_preenable(struct iio_dev *indio_dev) /** * max1363_poll_func_th() - th of trigger launched polling to ring buffer * - * As sampling only occurs on i2c comms occuring, leave timestamping until + * As sampling only occurs on i2c comms occurring, leave timestamping until * then. Some triggers will generate their own time stamp. Currently * there is no way of notifying them when no one cares. **/ diff --git a/drivers/staging/iio/chrdev.h b/drivers/staging/iio/chrdev.h index 98d1a2c12df2..4fcb99c816f9 100644 --- a/drivers/staging/iio/chrdev.h +++ b/drivers/staging/iio/chrdev.h @@ -33,7 +33,7 @@ struct iio_handler { /** * struct iio_event_data - The actual event being pushed to userspace * @id: event identifier - * @timestamp: best estimate of time of event occurance (often from + * @timestamp: best estimate of time of event occurrence (often from * the interrupt handler) */ struct iio_event_data { @@ -42,7 +42,7 @@ struct iio_event_data { }; /** - * struct iio_detected_event_list - list element for events that have occured + * struct iio_detected_event_list - list element for events that have occurred * @list: linked list header * @ev: the event itself * @shared_pointer: used when the event is shared - i.e. can be escallated @@ -98,7 +98,7 @@ struct iio_event_interface { * @list: list header * @refcount: as the handler may be shared between multiple device * side events, reference counting ensures clean removal - * @exist_lock: prevents race conditions related to refcount useage. + * @exist_lock: prevents race conditions related to refcount usage. * @handler: event handler function - called on event if this * event_handler is enabled. * diff --git a/drivers/staging/iio/gyro/adis16060_core.c b/drivers/staging/iio/gyro/adis16060_core.c index 700eb3980f9e..ae53e71d1c2f 100644 --- a/drivers/staging/iio/gyro/adis16060_core.c +++ b/drivers/staging/iio/gyro/adis16060_core.c @@ -30,7 +30,7 @@ * @us_w: actual spi_device to write config * @us_r: actual spi_device to read back data * @indio_dev: industrial I/O device structure - * @buf: transmit or recieve buffer + * @buf: transmit or receive buffer * @buf_lock: mutex to protect tx and rx **/ struct adis16060_state { diff --git a/drivers/staging/iio/gyro/adis16080_core.c b/drivers/staging/iio/gyro/adis16080_core.c index fb4336c7d2a6..ef9e304a226d 100644 --- a/drivers/staging/iio/gyro/adis16080_core.c +++ b/drivers/staging/iio/gyro/adis16080_core.c @@ -35,7 +35,7 @@ * struct adis16080_state - device instance specific data * @us: actual spi_device to write data * @indio_dev: industrial I/O device structure - * @buf: transmit or recieve buffer + * @buf: transmit or receive buffer * @buf_lock: mutex to protect tx and rx **/ struct adis16080_state { diff --git a/drivers/staging/iio/gyro/adis16260.h b/drivers/staging/iio/gyro/adis16260.h index c1fd4364287f..1369501b4096 100644 --- a/drivers/staging/iio/gyro/adis16260.h +++ b/drivers/staging/iio/gyro/adis16260.h @@ -91,7 +91,7 @@ * @indio_dev: industrial I/O device structure * @trig: data ready trigger registered with iio * @tx: transmit buffer - * @rx: recieve buffer + * @rx: receive buffer * @buf_lock: mutex to protect tx and rx * @negate: negate the scale parameter **/ diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h index 248bdd2846fd..7127f26f8d26 100644 --- a/drivers/staging/iio/iio.h +++ b/drivers/staging/iio/iio.h @@ -92,7 +92,7 @@ void iio_remove_event_from_list(struct iio_event_handler_list *el, * changes * @available_scan_masks: [DRIVER] optional array of allowed bitmasks * @trig: [INTERN] current device trigger (ring buffer modes) - * @pollfunc: [DRIVER] function run on trigger being recieved + * @pollfunc: [DRIVER] function run on trigger being received **/ struct iio_dev { int id; diff --git a/drivers/staging/iio/imu/adis16300.h b/drivers/staging/iio/imu/adis16300.h index 1f25d68064a0..c0957591aed7 100644 --- a/drivers/staging/iio/imu/adis16300.h +++ b/drivers/staging/iio/imu/adis16300.h @@ -99,7 +99,7 @@ * @indio_dev: industrial I/O device structure * @trig: data ready trigger registered with iio * @tx: transmit buffer - * @rx: recieve buffer + * @rx: receive buffer * @buf_lock: mutex to protect tx and rx **/ struct adis16300_state { diff --git a/drivers/staging/iio/imu/adis16350.h b/drivers/staging/iio/imu/adis16350.h index b00001e3edd0..b1ad48662a2c 100644 --- a/drivers/staging/iio/imu/adis16350.h +++ b/drivers/staging/iio/imu/adis16350.h @@ -105,7 +105,7 @@ * @indio_dev: industrial I/O device structure * @trig: data ready trigger registered with iio * @tx: transmit buffer - * @rx: recieve buffer + * @rx: receive buffer * @buf_lock: mutex to protect tx and rx **/ struct adis16350_state { diff --git a/drivers/staging/iio/imu/adis16400.h b/drivers/staging/iio/imu/adis16400.h index 6ff33e1ad8c1..7a127029e099 100644 --- a/drivers/staging/iio/imu/adis16400.h +++ b/drivers/staging/iio/imu/adis16400.h @@ -131,7 +131,7 @@ * @indio_dev: industrial I/O device structure * @trig: data ready trigger registered with iio * @tx: transmit buffer - * @rx: recieve buffer + * @rx: receive buffer * @buf_lock: mutex to protect tx and rx **/ struct adis16400_state { diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c index f3bf111f354f..1795ee1e8207 100644 --- a/drivers/staging/iio/industrialio-core.c +++ b/drivers/staging/iio/industrialio-core.c @@ -258,7 +258,7 @@ static ssize_t iio_event_chrdev_read(struct file *filep, ->det_events.list)); if (ret) goto error_ret; - /* Single access device so noone else can get the data */ + /* Single access device so no one else can get the data */ mutex_lock(&ev_int->event_list_lock); } diff --git a/drivers/staging/iio/meter/ade7753.h b/drivers/staging/iio/meter/ade7753.h index 70dabae6efe9..3b9c7f6a50e7 100644 --- a/drivers/staging/iio/meter/ade7753.h +++ b/drivers/staging/iio/meter/ade7753.h @@ -62,7 +62,7 @@ * @us: actual spi_device * @indio_dev: industrial I/O device structure * @tx: transmit buffer - * @rx: recieve buffer + * @rx: receive buffer * @buf_lock: mutex to protect tx and rx **/ struct ade7753_state { diff --git a/drivers/staging/iio/meter/ade7754.h b/drivers/staging/iio/meter/ade7754.h index 8faa9b3b48b6..0aa0522a33a3 100644 --- a/drivers/staging/iio/meter/ade7754.h +++ b/drivers/staging/iio/meter/ade7754.h @@ -80,7 +80,7 @@ * @us: actual spi_device * @indio_dev: industrial I/O device structure * @tx: transmit buffer - * @rx: recieve buffer + * @rx: receive buffer * @buf_lock: mutex to protect tx and rx **/ struct ade7754_state { diff --git a/drivers/staging/iio/meter/ade7758.h b/drivers/staging/iio/meter/ade7758.h index df5bb7ba5a0f..c6fd94f3b3ee 100644 --- a/drivers/staging/iio/meter/ade7758.h +++ b/drivers/staging/iio/meter/ade7758.h @@ -98,7 +98,7 @@ * @indio_dev: industrial I/O device structure * @trig: data ready trigger registered with iio * @tx: transmit buffer - * @rx: recieve buffer + * @rx: receive buffer * @buf_lock: mutex to protect tx and rx **/ struct ade7758_state { diff --git a/drivers/staging/iio/meter/ade7759.h b/drivers/staging/iio/meter/ade7759.h index e9d1c43336fe..cc76c2c4c039 100644 --- a/drivers/staging/iio/meter/ade7759.h +++ b/drivers/staging/iio/meter/ade7759.h @@ -43,7 +43,7 @@ * @us: actual spi_device * @indio_dev: industrial I/O device structure * @tx: transmit buffer - * @rx: recieve buffer + * @rx: receive buffer * @buf_lock: mutex to protect tx and rx **/ struct ade7759_state { diff --git a/drivers/staging/iio/meter/ade7854.h b/drivers/staging/iio/meter/ade7854.h index 4ad84a3bb462..79a21109f4e2 100644 --- a/drivers/staging/iio/meter/ade7854.h +++ b/drivers/staging/iio/meter/ade7854.h @@ -149,7 +149,7 @@ * @spi: actual spi_device * @indio_dev: industrial I/O device structure * @tx: transmit buffer - * @rx: recieve buffer + * @rx: receive buffer * @buf_lock: mutex to protect tx and rx **/ struct ade7854_state { diff --git a/drivers/staging/iio/ring_generic.h b/drivers/staging/iio/ring_generic.h index f21ac09373cf..32948e55dc81 100644 --- a/drivers/staging/iio/ring_generic.h +++ b/drivers/staging/iio/ring_generic.h @@ -30,7 +30,7 @@ int iio_push_ring_event(struct iio_ring_buffer *ring_buf, * @event_code: event indentification code * @timestamp: time of event * - * Typical usecase is to escalate a 50% ring full to 75% full if noone has yet + * Typical usecase is to escalate a 50% ring full to 75% full if no one has yet * read the first event. Clearly the 50% full is no longer of interest in * typical use case. **/ diff --git a/drivers/staging/intel_sst/TODO b/drivers/staging/intel_sst/TODO index a24e5ed5689c..c733d7011091 100644 --- a/drivers/staging/intel_sst/TODO +++ b/drivers/staging/intel_sst/TODO @@ -1,7 +1,7 @@ TODO ---- -Get the memrar driver cleaned up and upstream (dependancy blocking SST) +Get the memrar driver cleaned up and upstream (dependency blocking SST) Replace long/short press with two virtual buttons Review the printks and kill off any left over ST_ERR: messages Review the misc device ioctls for 32/64bit safety and sanity diff --git a/drivers/staging/intel_sst/intel_sst.c b/drivers/staging/intel_sst/intel_sst.c index ce4a9f79ccd2..81c24d19eb9e 100644 --- a/drivers/staging/intel_sst/intel_sst.c +++ b/drivers/staging/intel_sst/intel_sst.c @@ -263,7 +263,7 @@ static int __devinit intel_sst_probe(struct pci_dev *pci, /* Init the device */ ret = pci_enable_device(pci); if (ret) { - pr_err("device cant be enabled\n"); + pr_err("device can't be enabled\n"); goto do_free_mem; } sst_drv_ctx->pci = pci_dev_get(pci); @@ -453,7 +453,7 @@ int intel_sst_resume(struct pci_dev *pci) pci_restore_state(pci); ret = pci_enable_device(pci); if (ret) - pr_err("device cant be enabled\n"); + pr_err("device can't be enabled\n"); mutex_lock(&sst_drv_ctx->sst_lock); sst_drv_ctx->sst_state = SST_UN_INIT; diff --git a/drivers/staging/intel_sst/intel_sst_app_interface.c b/drivers/staging/intel_sst/intel_sst_app_interface.c index a367991d5600..1d0621260ea8 100644 --- a/drivers/staging/intel_sst/intel_sst_app_interface.c +++ b/drivers/staging/intel_sst/intel_sst_app_interface.c @@ -236,7 +236,7 @@ int intel_sst_mmap(struct file *file_ptr, struct vm_area_struct *vma) if (!sst_drv_ctx->mmap_mem) return -EIO; - /* round it up to the page bondary */ + /* round it up to the page boundary */ /*mem_area = (void *)((((unsigned long)sst_drv_ctx->mmap_mem) + PAGE_SIZE - 1) & PAGE_MASK);*/ mem_area = (void *) PAGE_ALIGN((unsigned int) sst_drv_ctx->mmap_mem); @@ -871,7 +871,7 @@ int sst_send_algo_ipc(struct ipc_post **msg) } /** - * intel_sst_ioctl_dsp - recieves the device ioctl's + * intel_sst_ioctl_dsp - receives the device ioctl's * * @cmd:Ioctl cmd * @arg:data @@ -1067,7 +1067,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } - pr_debug("SET_VOLUME recieved for %d!\n", + pr_debug("SET_VOLUME received for %d!\n", set_vol.stream_id); if (minor == STREAM_MODULE && set_vol.stream_id == 0) { pr_debug("invalid operation!\n"); @@ -1085,7 +1085,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } - pr_debug("IOCTL_GET_VOLUME recieved for stream = %d!\n", + pr_debug("IOCTL_GET_VOLUME received for stream = %d!\n", get_vol.stream_id); if (minor == STREAM_MODULE && get_vol.stream_id == 0) { pr_debug("invalid operation!\n"); @@ -1117,7 +1117,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } - pr_debug("SNDRV_SST_SET_VOLUME recieved for %d!\n", + pr_debug("SNDRV_SST_SET_VOLUME received for %d!\n", set_mute.stream_id); if (minor == STREAM_MODULE && set_mute.stream_id == 0) { retval = -EPERM; @@ -1153,7 +1153,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) case _IOC_NR(SNDRV_SST_MMAP_CAPTURE): { struct snd_sst_mmap_buffs mmap_buf; - pr_debug("SNDRV_SST_MMAP_PLAY/CAPTURE recieved!\n"); + pr_debug("SNDRV_SST_MMAP_PLAY/CAPTURE received!\n"); if (minor != STREAM_MODULE) { retval = -EBADRQC; break; @@ -1239,7 +1239,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) case _IOC_NR(SNDRV_SST_SET_TARGET_DEVICE): { struct snd_sst_target_device target_device; - pr_debug("SET_TARGET_DEVICE recieved!\n"); + pr_debug("SET_TARGET_DEVICE received!\n"); if (copy_from_user(&target_device, (void __user *)arg, sizeof(target_device))) { retval = -EFAULT; @@ -1256,7 +1256,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) case _IOC_NR(SNDRV_SST_DRIVER_INFO): { struct snd_sst_driver_info info; - pr_debug("SNDRV_SST_DRIVER_INFO recived\n"); + pr_debug("SNDRV_SST_DRIVER_INFO received\n"); info.version = SST_VERSION_NUM; /* hard coding, shud get sumhow later */ info.active_pcm_streams = sst_drv_ctx->stream_cnt - diff --git a/drivers/staging/intel_sst/intel_sst_drv_interface.c b/drivers/staging/intel_sst/intel_sst_drv_interface.c index ea8e251b5099..e9c182108243 100644 --- a/drivers/staging/intel_sst/intel_sst_drv_interface.c +++ b/drivers/staging/intel_sst/intel_sst_drv_interface.c @@ -315,7 +315,7 @@ int sst_open_pcm_stream(struct snd_sst_params *str_param) pm_runtime_get_sync(&sst_drv_ctx->pci->dev); if (sst_drv_ctx->sst_state == SST_SUSPENDED) { - /* LPE is suspended, resume it before proceding*/ + /* LPE is suspended, resume it before proceeding*/ pr_debug("Resuming from Suspended state\n"); retval = intel_sst_resume(sst_drv_ctx->pci); if (retval) { diff --git a/drivers/staging/intel_sst/intel_sst_dsp.c b/drivers/staging/intel_sst/intel_sst_dsp.c index 6e5c9152da9f..bffe4c6e2928 100644 --- a/drivers/staging/intel_sst/intel_sst_dsp.c +++ b/drivers/staging/intel_sst/intel_sst_dsp.c @@ -350,7 +350,7 @@ static int sst_download_library(const struct firmware *fw_lib, } -/* This function is called befoer downloading the codec/postprocessing +/* This function is called before downloading the codec/postprocessing library is set for download to SST DSP*/ static int sst_validate_library(const struct firmware *fw_lib, struct lib_slot_info *slot, @@ -405,7 +405,7 @@ exit: } -/* This function is called when FW requests for a particular libary download +/* This function is called when FW requests for a particular library download This function prepares the library to download*/ int sst_load_library(struct snd_sst_lib_download *lib, u8 ops) { diff --git a/drivers/staging/intel_sst/intel_sst_fw_ipc.h b/drivers/staging/intel_sst/intel_sst_fw_ipc.h index 8df313d10d2a..0f0c5bbc5f4b 100644 --- a/drivers/staging/intel_sst/intel_sst_fw_ipc.h +++ b/drivers/staging/intel_sst/intel_sst_fw_ipc.h @@ -111,7 +111,7 @@ #define IPC_SST_PERIOD_ELAPSED 0x97 /* period elapsed */ #define IPC_IA_TARGET_DEV_CHNGD 0x98 /* error in processing a stream */ -#define IPC_SST_ERROR_EVENT 0x99 /* Buffer over run occured */ +#define IPC_SST_ERROR_EVENT 0x99 /* Buffer over run occurred */ /* L2S messages */ #define IPC_SC_DDR_LINK_UP 0xC0 #define IPC_SC_DDR_LINK_DOWN 0xC1 diff --git a/drivers/staging/intel_sst/intel_sst_stream.c b/drivers/staging/intel_sst/intel_sst_stream.c index 795e42ab7360..dd58be5b1975 100644 --- a/drivers/staging/intel_sst/intel_sst_stream.c +++ b/drivers/staging/intel_sst/intel_sst_stream.c @@ -98,7 +98,7 @@ static unsigned int get_mrst_stream_id(void) if (sst_drv_ctx->streams[i].status == STREAM_UN_INIT) return i; } - pr_debug("Didnt find empty stream for mrst\n"); + pr_debug("Didn't find empty stream for mrst\n"); return -EBUSY; } diff --git a/drivers/staging/intel_sst/intel_sst_stream_encoded.c b/drivers/staging/intel_sst/intel_sst_stream_encoded.c index 29753c7519a7..d5f07b878828 100644 --- a/drivers/staging/intel_sst/intel_sst_stream_encoded.c +++ b/drivers/staging/intel_sst/intel_sst_stream_encoded.c @@ -914,7 +914,7 @@ static int sst_prepare_input_buffers_rar(struct stream_info *str_info, (void *) ((unsigned long) rar_buffers.bus_address); pr_debug("RAR buf addr in DnR (input buffer function)0x%lu", (unsigned long) str_info->decode_ibuf); - pr_debug("rar in DnR decode funtion/output b_add rar =0x%lu", + pr_debug("rar in DnR decode function/output b_add rar =0x%lu", (unsigned long) rar_buffers.bus_address); *input_index = i + 1; str_info->decode_isize = dbufs->ibufs->buff_entry[i].size; diff --git a/drivers/staging/intel_sst/intelmid.c b/drivers/staging/intel_sst/intelmid.c index fb2292186703..d207636a7b6d 100644 --- a/drivers/staging/intel_sst/intelmid.c +++ b/drivers/staging/intel_sst/intelmid.c @@ -773,7 +773,7 @@ static int __devinit snd_intelmad_sst_register( if (ret_val) return ret_val; sst_card_vendor_id = (vendor_addr.value & (MASK2|MASK1|MASK0)); - pr_debug("orginal n extrated vendor id = 0x%x %d\n", + pr_debug("original n extrated vendor id = 0x%x %d\n", vendor_addr.value, sst_card_vendor_id); if (sst_card_vendor_id < 0 || sst_card_vendor_id > 2) { pr_err("vendor card not supported!!\n"); diff --git a/drivers/staging/intel_sst/intelmid.h b/drivers/staging/intel_sst/intelmid.h index ca881b790cb2..e77da87e1df0 100644 --- a/drivers/staging/intel_sst/intelmid.h +++ b/drivers/staging/intel_sst/intelmid.h @@ -90,7 +90,7 @@ struct mad_jack_msg_wq { * @card_index: sound card index * @card_id: sound card id detected * @sstdrv_ops: ptr to sst driver ops - * @pdev: ptr to platfrom device + * @pdev: ptr to platform device * @irq: interrupt number detected * @pmic_status: Device status of sound card * @int_base: ptr to MMIO interrupt region diff --git a/drivers/staging/keucr/init.c b/drivers/staging/keucr/init.c index 5c01f28f0734..8af7c84daee2 100644 --- a/drivers/staging/keucr/init.c +++ b/drivers/staging/keucr/init.c @@ -90,7 +90,7 @@ int ENE_MSInit(struct us_data *us) result = ENE_SendScsiCmd(us, FDIR_READ, &buf, 0); if (result != USB_STOR_XFER_GOOD) { - printk(KERN_ERR "Exection MS Init Code Fail !!\n"); + printk(KERN_ERR "Execution MS Init Code Fail !!\n"); return USB_STOR_TRANSPORT_ERROR; } @@ -145,7 +145,7 @@ int ENE_SMInit(struct us_data *us) result = ENE_SendScsiCmd(us, FDIR_READ, &buf, 0); if (result != USB_STOR_XFER_GOOD) { printk(KERN_ERR - "Exection SM Init Code Fail !! result = %x\n", result); + "Execution SM Init Code Fail !! result = %x\n", result); return USB_STOR_TRANSPORT_ERROR; } diff --git a/drivers/staging/keucr/smilmain.c b/drivers/staging/keucr/smilmain.c index 2cbe9f897eef..95c688a5c95a 100644 --- a/drivers/staging/keucr/smilmain.c +++ b/drivers/staging/keucr/smilmain.c @@ -64,7 +64,7 @@ extern struct SSFDCTYPE Ssfdc; extern struct ADDRESS Media; extern struct CIS_AREA CisArea; -//BIT Controll Macro +//BIT Control Macro BYTE BitData[] = { 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80 } ; #define Set_D_Bit(a,b) (a[(BYTE)((b)/8)]|= BitData[(b)%8]) #define Clr_D_Bit(a,b) (a[(BYTE)((b)/8)]&=~BitData[(b)%8]) @@ -76,7 +76,7 @@ extern BYTE IsXDCompliance; // -////Power Controll & Media Exist Check Function +////Power Control & Media Exist Check Function ////----- Init_D_SmartMedia() -------------------------------------------- //int Init_D_SmartMedia(void) //{ @@ -575,7 +575,7 @@ int Media_D_OneSectWriteFlush(PFDO_DEVICE_EXTENSION fdoExt) // return(SUCCESS); //} // -////Power Controll & Media Exist Check Subroutine +////Power Control & Media Exist Check Subroutine ////----- Initialize_D_Media() ------------------------------------------- //void Initialize_D_Media(void) //{ @@ -738,7 +738,7 @@ int Check_D_MediaFmt(struct us_data *us) // return(SUCCESS); //} */ -//SmartMedia Physical Address Controll Subroutine +//SmartMedia Physical Address Control Subroutine //----- Conv_D_MediaAddr() --------------------------------------------- int Conv_D_MediaAddr(struct us_data *us, DWORD addr) { diff --git a/drivers/staging/keucr/smilsub.c b/drivers/staging/keucr/smilsub.c index 80da61c37bff..4fe47422eb79 100644 --- a/drivers/staging/keucr/smilsub.c +++ b/drivers/staging/keucr/smilsub.c @@ -57,7 +57,7 @@ extern WORD WriteBlock; #define ODD 1 // Odd Page for 256byte/page -//SmartMedia Redundant buffer data Controll Subroutine +//SmartMedia Redundant buffer data Control Subroutine //----- Check_D_DataBlank() -------------------------------------------- int Check_D_DataBlank(BYTE *redundant) { @@ -1367,7 +1367,7 @@ BYTE _Check_D_DevCode(BYTE dcode) } } /* -////SmartMedia Power Controll Subroutine +////SmartMedia Power Control Subroutine ////----- Cnt_D_Reset() ---------------------------------------------- //void Cnt_D_Reset(void) //{ @@ -1478,7 +1478,7 @@ BYTE _Check_D_DevCode(BYTE dcode) //} // */ -//SmartMedia ECC Controll Subroutine +//SmartMedia ECC Control Subroutine //----- Check_D_ReadError() ---------------------------------------------- int Check_D_ReadError(BYTE *redundant) { diff --git a/drivers/staging/lirc/lirc_ene0100.h b/drivers/staging/lirc/lirc_ene0100.h index 776b693bb307..06bebd6acc46 100644 --- a/drivers/staging/lirc/lirc_ene0100.h +++ b/drivers/staging/lirc/lirc_ene0100.h @@ -81,7 +81,7 @@ /* CIR block settings */ #define ENE_CIR_CONF1 0xFEC0 -#define ENE_CIR_CONF1_ADC_ON 0x7 /* reciever on gpio40 enabled */ +#define ENE_CIR_CONF1_ADC_ON 0x7 /* receiver on gpio40 enabled */ #define ENE_CIR_CONF1_LEARN1 (1 << 3) /* enabled on learning mode */ #define ENE_CIR_CONF1_TX_ON 0x30 /* enabled on transmit */ #define ENE_CIR_CONF1_TX_CARR (1 << 7) /* send TX carrier or not */ @@ -96,7 +96,7 @@ /* transmitter - not implemented yet */ /* KB3926C and higher */ -/* transmission is very similiar to recieving, a byte is written to */ +/* transmission is very similar to receiving, a byte is written to */ /* ENE_TX_INPUT, in same manner as it is read from sample buffer */ /* sample period is fixed*/ diff --git a/drivers/staging/memrar/memrar_handler.c b/drivers/staging/memrar/memrar_handler.c index cfcaa8e5b8e6..1d9399d6f10f 100644 --- a/drivers/staging/memrar/memrar_handler.c +++ b/drivers/staging/memrar/memrar_handler.c @@ -690,7 +690,7 @@ static int memrar_mmap(struct file *filp, struct vm_area_struct *vma) * @inode: inode to open * @filp: file handle * - * As we support multiple arbitary opens there is no work to be done + * As we support multiple arbitrary opens there is no work to be done * really. */ diff --git a/drivers/staging/msm/mdp4_overlay.c b/drivers/staging/msm/mdp4_overlay.c index de284c28faa1..b9acf5299297 100644 --- a/drivers/staging/msm/mdp4_overlay.c +++ b/drivers/staging/msm/mdp4_overlay.c @@ -696,7 +696,7 @@ void mdp4_mixer_stage_down(struct mdp4_overlay_pipe *pipe) stage = pipe->mixer_stage; mixer = pipe->mixer_num; - if (pipe != ctrl->stage[mixer][stage]) /* not runing */ + if (pipe != ctrl->stage[mixer][stage]) /* not running */ return; /* MDP_LAYERMIXER_IN_CFG, shard by both mixer 0 and 1 */ diff --git a/drivers/staging/msm/mdp_ppp_dq.c b/drivers/staging/msm/mdp_ppp_dq.c index 3dc1c0cc61f9..3a687c7a5695 100644 --- a/drivers/staging/msm/mdp_ppp_dq.c +++ b/drivers/staging/msm/mdp_ppp_dq.c @@ -200,7 +200,7 @@ static void mdp_ppp_flush_dirty_djobs(void *cond) msm_fb_ensure_mem_coherency_after_dma(job->info, &job->req, 1); /* Schedule jobs for cleanup - * A seperate worker thread does this */ + * A separate worker thread does this */ queue_delayed_work(mdp_ppp_djob_clnr, &job->cleaner, mdp_timer_duration); } diff --git a/drivers/staging/msm/msm_fb.c b/drivers/staging/msm/msm_fb.c index a2f29d464051..e7ef836eb8de 100644 --- a/drivers/staging/msm/msm_fb.c +++ b/drivers/staging/msm/msm_fb.c @@ -859,7 +859,7 @@ static int msm_fb_register(struct msm_fb_data_type *mfd) break; default: - MSM_FB_ERR("msm_fb_init: fb %d unkown image type!\n", + MSM_FB_ERR("msm_fb_init: fb %d unknown image type!\n", mfd->index); return ret; } @@ -1793,9 +1793,9 @@ static int msmfb_async_blit(struct fb_info *info, void __user *p) /* * NOTE: The userspace issues blit operations in a sequence, the sequence * start with a operation marked START and ends in an operation marked - * END. It is guranteed by the userspace that all the blit operations + * END. It is guaranteed by the userspace that all the blit operations * between START and END are only within the regions of areas designated - * by the START and END operations and that the userspace doesnt modify + * by the START and END operations and that the userspace doesn't modify * those areas. Hence it would be enough to perform barrier/cache operations * only on the START and END operations. */ diff --git a/drivers/staging/octeon/cvmx-cmd-queue.h b/drivers/staging/octeon/cvmx-cmd-queue.h index 59d221422293..614653b686a0 100644 --- a/drivers/staging/octeon/cvmx-cmd-queue.h +++ b/drivers/staging/octeon/cvmx-cmd-queue.h @@ -214,7 +214,7 @@ static inline int __cvmx_cmd_queue_get_index(cvmx_cmd_queue_id_t queue_id) /* * Warning: This code currently only works with devices that * have 256 queues or less. Devices with more than 16 queues - * are layed out in memory to allow cores quick access to + * are laid out in memory to allow cores quick access to * every 16th queue. This reduces cache thrashing when you are * running 16 queues per port to support lockless operation. */ diff --git a/drivers/staging/octeon/cvmx-fpa.h b/drivers/staging/octeon/cvmx-fpa.h index 50a8c91778fa..1f04f9658736 100644 --- a/drivers/staging/octeon/cvmx-fpa.h +++ b/drivers/staging/octeon/cvmx-fpa.h @@ -195,7 +195,7 @@ static inline void cvmx_fpa_async_alloc(uint64_t scr_addr, uint64_t pool) cvmx_fpa_iobdma_data_t data; /* - * Hardware only uses 64 bit alligned locations, so convert + * Hardware only uses 64 bit aligned locations, so convert * from byte address to 64-bit index */ data.s.scraddr = scr_addr >> 3; diff --git a/drivers/staging/octeon/cvmx-helper-board.h b/drivers/staging/octeon/cvmx-helper-board.h index 611a8e03c216..b465bec43553 100644 --- a/drivers/staging/octeon/cvmx-helper-board.h +++ b/drivers/staging/octeon/cvmx-helper-board.h @@ -81,7 +81,7 @@ extern int cvmx_helper_board_get_mii_address(int ipd_port); * @phy_addr: The address of the PHY to program * @link_flags: * Flags to control autonegotiation. Bit 0 is autonegotiation - * enable/disable to maintain backware compatability. + * enable/disable to maintain backware compatibility. * @link_info: Link speed to program. If the speed is zero and autonegotiation * is enabled, all possible negotiation speeds are advertised. * diff --git a/drivers/staging/octeon/cvmx-helper-util.c b/drivers/staging/octeon/cvmx-helper-util.c index 41ef8a40bb03..131182bf5abb 100644 --- a/drivers/staging/octeon/cvmx-helper-util.c +++ b/drivers/staging/octeon/cvmx-helper-util.c @@ -362,7 +362,7 @@ int __cvmx_helper_setup_gmx(int interface, int num_ports) } /** - * Returns the IPD/PKO port number for a port on teh given + * Returns the IPD/PKO port number for a port on the given * interface. * * @interface: Interface to use diff --git a/drivers/staging/octeon/cvmx-helper.c b/drivers/staging/octeon/cvmx-helper.c index 591506643d02..e9c5c836ceff 100644 --- a/drivers/staging/octeon/cvmx-helper.c +++ b/drivers/staging/octeon/cvmx-helper.c @@ -691,7 +691,7 @@ int __cvmx_helper_errata_fix_ipd_ptr_alignment(void) if (!retry_cnt) cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT " - "get_work() timeout occured.\n"); + "get_work() timeout occurred.\n"); /* Free packet */ if (work) diff --git a/drivers/staging/octeon/cvmx-mdio.h b/drivers/staging/octeon/cvmx-mdio.h index f45dc49512f2..d88ab8d8e37d 100644 --- a/drivers/staging/octeon/cvmx-mdio.h +++ b/drivers/staging/octeon/cvmx-mdio.h @@ -254,7 +254,7 @@ typedef union { #define MDIO_CLAUSE_45_READ_INC 2 #define MDIO_CLAUSE_45_READ 3 -/* MMD identifiers, mostly for accessing devices withing XENPAK modules. */ +/* MMD identifiers, mostly for accessing devices within XENPAK modules. */ #define CVMX_MMD_DEVICE_PMA_PMD 1 #define CVMX_MMD_DEVICE_WIS 2 #define CVMX_MMD_DEVICE_PCS 3 diff --git a/drivers/staging/octeon/cvmx-pko.h b/drivers/staging/octeon/cvmx-pko.h index f068c1982497..de3412aada5d 100644 --- a/drivers/staging/octeon/cvmx-pko.h +++ b/drivers/staging/octeon/cvmx-pko.h @@ -98,7 +98,7 @@ typedef enum { /* * PKO doesn't do any locking. It is the responsibility of the * application to make sure that no other core is accessing - * the same queue at the smae time + * the same queue at the same time */ CVMX_PKO_LOCK_NONE = 0, /* @@ -324,7 +324,7 @@ static inline void cvmx_pko_doorbell(uint64_t port, uint64_t queue, * - CVMX_PKO_LOCK_NONE * - PKO doesn't do any locking. It is the responsibility * of the application to make sure that no other core - * is accessing the same queue at the smae time. + * is accessing the same queue at the same time. * - CVMX_PKO_LOCK_ATOMIC_TAG * - PKO performs an atomic tagswitch to insure exclusive * access to the output queue. This will maintain diff --git a/drivers/staging/octeon/cvmx-pow.h b/drivers/staging/octeon/cvmx-pow.h index bf9e069a898c..999aefe3274c 100644 --- a/drivers/staging/octeon/cvmx-pow.h +++ b/drivers/staging/octeon/cvmx-pow.h @@ -1492,8 +1492,8 @@ static inline void cvmx_pow_tag_sw_full(cvmx_wqe_t *wqp, uint32_t tag, /** * Switch to a NULL tag, which ends any ordering or * synchronization provided by the POW for the current - * work queue entry. This operation completes immediatly, - * so completetion should not be waited for. + * work queue entry. This operation completes immediately, + * so completion should not be waited for. * This function does NOT wait for previous tag switches to complete, * so the caller must ensure that any previous tag switches have completed. */ @@ -1532,8 +1532,8 @@ static inline void cvmx_pow_tag_sw_null_nocheck(void) /** * Switch to a NULL tag, which ends any ordering or * synchronization provided by the POW for the current - * work queue entry. This operation completes immediatly, - * so completetion should not be waited for. + * work queue entry. This operation completes immediately, + * so completion should not be waited for. * This function waits for any pending tag switches to complete * before requesting the switch to NULL. */ @@ -1672,7 +1672,7 @@ static inline void cvmx_pow_set_priority(uint64_t core_num, /** * Performs a tag switch and then an immediate deschedule. This completes - * immediatly, so completion must not be waited for. This function does NOT + * immediately, so completion must not be waited for. This function does NOT * update the wqe in DRAM to match arguments. * * This function does NOT wait for any prior tag switches to complete, so the @@ -1758,7 +1758,7 @@ static inline void cvmx_pow_tag_sw_desched_nocheck( /** * Performs a tag switch and then an immediate deschedule. This completes - * immediatly, so completion must not be waited for. This function does NOT + * immediately, so completion must not be waited for. This function does NOT * update the wqe in DRAM to match arguments. * * This function waits for any prior tag switches to complete, so the diff --git a/drivers/staging/octeon/ethernet-util.h b/drivers/staging/octeon/ethernet-util.h index 23467563fe57..c745a72a0594 100644 --- a/drivers/staging/octeon/ethernet-util.h +++ b/drivers/staging/octeon/ethernet-util.h @@ -55,7 +55,7 @@ static inline int INTERFACE(int ipd_port) return 2; else if (ipd_port < 40) /* Interface 3 for loopback */ return 3; - else if (ipd_port == 40) /* Non existant interface for POW0 */ + else if (ipd_port == 40) /* Non existent interface for POW0 */ return 4; else panic("Illegal ipd_port %d passed to INTERFACE\n", ipd_port); diff --git a/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c b/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c index b154be7a2fe6..b5d21f6497f9 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c +++ b/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c @@ -80,7 +80,7 @@ static int dcon_init_xo_1(struct dcon_priv *dcon) lob &= ~(1 << DCON_IRQ); outb(lob, 0x4d0); - /* Register the interupt handler */ + /* Register the interrupt handler */ if (request_irq(DCON_IRQ, &dcon_interrupt, 0, "DCON", dcon)) { printk(KERN_ERR "olpc-dcon: failed to request DCON's irq\n"); goto err_req_irq; diff --git a/drivers/staging/pohmelfs/crypto.c b/drivers/staging/pohmelfs/crypto.c index 6540864216c8..5cca24fcf6ca 100644 --- a/drivers/staging/pohmelfs/crypto.c +++ b/drivers/staging/pohmelfs/crypto.c @@ -745,7 +745,7 @@ static int pohmelfs_crypto_init_handshake(struct pohmelfs_sb *psb) /* * At this point NETFS_CAPABILITIES response command - * should setup superblock in a way, which is acceptible + * should setup superblock in a way, which is acceptable * for both client and server, so if server refuses connection, * it will send error in transaction response. */ diff --git a/drivers/staging/quatech_usb2/quatech_usb2.c b/drivers/staging/quatech_usb2/quatech_usb2.c index c45b09ed0d35..ca098cabc2bc 100644 --- a/drivers/staging/quatech_usb2/quatech_usb2.c +++ b/drivers/staging/quatech_usb2/quatech_usb2.c @@ -148,7 +148,7 @@ static struct usb_driver quausb2_usb_driver = { * value of the line status flags from the port * @shadowMSR: Last received state of the modem status register, holds * the value of the modem status received from the port - * @rcv_flush: Flag indicating that a receive flush has occured on + * @rcv_flush: Flag indicating that a receive flush has occurred on * the hardware. * @xmit_flush: Flag indicating that a transmit flush has been processed by * the hardware. @@ -156,7 +156,7 @@ static struct usb_driver quausb2_usb_driver = { * includes the size (excluding header) of URBs that have been submitted but * have not yet been sent to to the device, and bytes that have been sent out * of the port but not yet reported sent by the "xmit_empty" messages (which - * indicate the number of bytes sent each time they are recieved, despite the + * indicate the number of bytes sent each time they are received, despite the * misleading name). * - Starts at zero when port is initialised. * - is incremented by the size of the data to be written (no headers) @@ -649,7 +649,7 @@ static void qt2_close(struct usb_serial_port *port) /* although the USB side is now empty, the UART itself may * still be pushing characters out over the line, so we have to * wait testing the actual line status until the lines change - * indicating that the data is done transfering. */ + * indicating that the data is done transferring. */ /* FIXME: slow this polling down so it doesn't run the USB bus flat out * if it actually has to spend any time in this loop (which it normally * doesn't because the buffer is nearly empty) */ @@ -726,7 +726,7 @@ static int qt2_write(struct tty_struct *tty, struct usb_serial_port *port, return 0; } else if (port_extra->tx_pending_bytes >= QT2_FIFO_DEPTH) { /* buffer is full (==). > should not occur, but would indicate - * that an overflow had occured */ + * that an overflow had occurred */ dbg("%s(): port transmit buffer is full!", __func__); /* schedule_work(&port->work); commented in vendor driver */ return 0; @@ -823,7 +823,7 @@ static int qt2_write_room(struct tty_struct *tty) * reduce the free space count by the size of the dispatched write. * When a "transmit empty" message comes back up the USB read stream, * we decrement the count by the number of bytes reported sent, thus - * keeping track of the difference between sent and recieved bytes. + * keeping track of the difference between sent and received bytes. */ room = (QT2_FIFO_DEPTH - port_extra->tx_pending_bytes); @@ -1795,7 +1795,7 @@ static void qt2_process_rx_char(struct usb_serial_port *port, } } -/** @brief Retreive the value of a register from the device +/** @brief Retrieve the value of a register from the device * * Issues a GET_REGISTER vendor-spcific request over the USB control * pipe to obtain a value back from a specific register on a specific diff --git a/drivers/staging/rt2860/chip/rtmp_phy.h b/drivers/staging/rt2860/chip/rtmp_phy.h index 98454df30a22..a52221f1294e 100644 --- a/drivers/staging/rt2860/chip/rtmp_phy.h +++ b/drivers/staging/rt2860/chip/rtmp_phy.h @@ -467,7 +467,7 @@ DBGPRINT_ERR("BBP write R%d=0x%x fail. BusyCnt= %d.bPCIclkOff = %d. \n", _I, BbpCsr.word, BusyCnt, (_A)->bPCIclkOff); \ } \ } else { \ - DBGPRINT_ERR("****** BBP_Write_Latch Buffer exceeds max boundry ****** \n"); \ + DBGPRINT_ERR("****** BBP_Write_Latch Buffer exceeds max boundary ****** \n"); \ } \ } #endif /* RTMP_MAC_PCI // */ diff --git a/drivers/staging/rt2860/common/ba_action.c b/drivers/staging/rt2860/common/ba_action.c index 62f6f6be4acb..133bc1b87d2c 100644 --- a/drivers/staging/rt2860/common/ba_action.c +++ b/drivers/staging/rt2860/common/ba_action.c @@ -28,7 +28,7 @@ #include "../rt_config.h" #include -#define BA_ORI_INIT_SEQ (pEntry->TxSeq[TID]) /*1 // inital sequence number of BA session */ +#define BA_ORI_INIT_SEQ (pEntry->TxSeq[TID]) /*1 // initial sequence number of BA session */ #define ORI_SESSION_MAX_RETRY 8 #define ORI_BA_SESSION_TIMEOUT (2000) /* ms */ @@ -1487,7 +1487,7 @@ static void ba_enqueue_reordering_packet(struct rt_rtmp_adapter *pAd, /* * flush all pending reordering mpdus - * and receving mpdu to upper layer + * and receiving mpdu to upper layer * make tcp/ip to take care reordering mechanism */ /*ba_refresh_reordering_mpdus(pAd, pBAEntry); */ diff --git a/drivers/staging/rt2860/common/cmm_aes.c b/drivers/staging/rt2860/common/cmm_aes.c index a99879bada42..d70d229a6e53 100644 --- a/drivers/staging/rt2860/common/cmm_aes.c +++ b/drivers/staging/rt2860/common/cmm_aes.c @@ -858,7 +858,7 @@ static uint32 KT1[256]; static uint32 KT2[256]; static uint32 KT3[256]; -/* platform-independant 32-bit integer manipulation macros */ +/* platform-independent 32-bit integer manipulation macros */ #define GET_UINT32(n,b,i) \ { \ diff --git a/drivers/staging/rt2860/common/cmm_cfg.c b/drivers/staging/rt2860/common/cmm_cfg.c index 24f439378439..727f79929258 100644 --- a/drivers/staging/rt2860/common/cmm_cfg.c +++ b/drivers/staging/rt2860/common/cmm_cfg.c @@ -223,7 +223,7 @@ int RT_CfgSetWepKey(struct rt_rtmp_adapter *pAd, pAdapter Pointer to our adapter keyString WPA pre-shared key string pHashStr String used for password hash function - hashStrLen Lenght of the hash string + hashStrLen Length of the hash string pPMKBuf Output buffer of WPAPSK key Return: diff --git a/drivers/staging/rt2860/common/cmm_data.c b/drivers/staging/rt2860/common/cmm_data.c index f6c193cb84ee..33799e1449ae 100644 --- a/drivers/staging/rt2860/common/cmm_data.c +++ b/drivers/staging/rt2860/common/cmm_data.c @@ -337,7 +337,7 @@ int MlmeHardTransmitMgmtRing(struct rt_rtmp_adapter *pAd, /* */ /* In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame */ - /* Data-Null packets alse pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD */ + /* Data-Null packets also pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD */ /* if ((pHeader_802_11->FC.Type != BTYPE_DATA) && (pHeader_802_11->FC.Type != BTYPE_CNTL)) */ { if ((pHeader_802_11->FC.SubType == SUBTYPE_ACTION) || @@ -1933,7 +1933,7 @@ BOOLEAN RTMPCheckEtherType(struct rt_rtmp_adapter *pAd, void *pPacket) if (TypeLen <= 1500) { /* 802.3, 802.3 LLC */ /* - DestMAC(6) + SrcMAC(6) + Lenght(2) + + DestMAC(6) + SrcMAC(6) + Length(2) + DSAP(1) + SSAP(1) + Control(1) + if the DSAP = 0xAA, SSAP=0xAA, Contorl = 0x03, it has a 5-bytes SNAP header. => + SNAP (5, OriginationID(3) + etherType(2)) diff --git a/drivers/staging/rt2860/common/cmm_data_pci.c b/drivers/staging/rt2860/common/cmm_data_pci.c index 7af59ff9e220..bef0bbd8cef7 100644 --- a/drivers/staging/rt2860/common/cmm_data_pci.c +++ b/drivers/staging/rt2860/common/cmm_data_pci.c @@ -438,13 +438,13 @@ int RTMPCheckRxError(struct rt_rtmp_adapter *pAd, /* Add Rx size to channel load counter, we should ignore error counts */ pAd->StaCfg.CLBusyBytes += (pRxD->SDL0 + 14); - /* Drop ToDs promiscous frame, it is opened due to CCX 2 channel load statistics */ + /* Drop ToDs promiscuous frame, it is opened due to CCX 2 channel load statistics */ if (pHeader != NULL) { if (pHeader->FC.ToDs) { return (NDIS_STATUS_FAILURE); } } - /* Drop not U2M frames, cant's drop here because we will drop beacon in this case */ + /* Drop not U2M frames, can't's drop here because we will drop beacon in this case */ /* I am kind of doubting the U2M bit operation */ /* if (pRxD->U2M == 0) */ /* return(NDIS_STATUS_FAILURE); */ @@ -939,7 +939,7 @@ int MlmeHardTransmitTxRing(struct rt_rtmp_adapter *pAd, /* */ /* */ /* In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame */ - /* Data-Null packets alse pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD */ + /* Data-Null packets also pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD */ if (pHeader_802_11->FC.Type != BTYPE_DATA) { if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_REQ) || !(pAd->CommonCfg.bAPSDCapable diff --git a/drivers/staging/rt2860/common/cmm_data_usb.c b/drivers/staging/rt2860/common/cmm_data_usb.c index 7c56c2f51987..5637857ae9eb 100644 --- a/drivers/staging/rt2860/common/cmm_data_usb.c +++ b/drivers/staging/rt2860/common/cmm_data_usb.c @@ -702,7 +702,7 @@ Arguments: *pRxPending pending received packet flag Return Value: - the recieved packet + the received packet Note: ======================================================================== @@ -850,7 +850,7 @@ int RTMPCheckRxError(struct rt_rtmp_adapter *pAd, /* Add Rx size to channel load counter, we should ignore error counts */ pAd->StaCfg.CLBusyBytes += (pRxWI->MPDUtotalByteCount + 14); - /* Drop ToDs promiscous frame, it is opened due to CCX 2 channel load statistics */ + /* Drop ToDs promiscuous frame, it is opened due to CCX 2 channel load statistics */ if (pHeader->FC.ToDs) { DBGPRINT_RAW(RT_DEBUG_ERROR, ("Err;FC.ToDs\n")); return NDIS_STATUS_FAILURE; @@ -860,7 +860,7 @@ int RTMPCheckRxError(struct rt_rtmp_adapter *pAd, DBGPRINT_RAW(RT_DEBUG_ERROR, ("received packet too long\n")); return NDIS_STATUS_FAILURE; } - /* Drop not U2M frames, cant's drop here because we will drop beacon in this case */ + /* Drop not U2M frames, can't's drop here because we will drop beacon in this case */ /* I am kind of doubting the U2M bit operation */ /* if (pRxD->U2M == 0) */ /* return(NDIS_STATUS_FAILURE); */ diff --git a/drivers/staging/rt2860/common/cmm_mac_pci.c b/drivers/staging/rt2860/common/cmm_mac_pci.c index 21eed2507e1c..d06f0a6dc379 100644 --- a/drivers/staging/rt2860/common/cmm_mac_pci.c +++ b/drivers/staging/rt2860/common/cmm_mac_pci.c @@ -1446,7 +1446,7 @@ BOOLEAN RT28xxPciAsicRadioOff(struct rt_rtmp_adapter *pAd, pAd->CheckDmaBusyCount = 0; } */ -/*KH Debug:My original codes have the follwoing codes, but currecnt codes do not have it. */ +/*KH Debug:My original codes have the following codes, but currecnt codes do not have it. */ /* Disable for stability. If PCIE Link Control is modified for advance power save, re-covery this code segment. */ RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x1280); /*OPSTATUS_SET_FLAG(pAd, fOP_STATUS_CLKSELECT_40MHZ); */ diff --git a/drivers/staging/rt2860/common/cmm_sanity.c b/drivers/staging/rt2860/common/cmm_sanity.c index 6b003c903444..3bfb4ad00c1a 100644 --- a/drivers/staging/rt2860/common/cmm_sanity.c +++ b/drivers/staging/rt2860/common/cmm_sanity.c @@ -67,7 +67,7 @@ BOOLEAN MlmeAddBAReqSanity(struct rt_rtmp_adapter *pAd, if ((MsgLen != sizeof(struct rt_mlme_addba_req))) { DBGPRINT(RT_DEBUG_TRACE, - ("MlmeAddBAReqSanity fail - message lenght not correct.\n")); + ("MlmeAddBAReqSanity fail - message length not correct.\n")); return FALSE; } @@ -104,7 +104,7 @@ BOOLEAN MlmeDelBAReqSanity(struct rt_rtmp_adapter *pAd, void * Msg, unsigned lon if ((MsgLen != sizeof(struct rt_mlme_delba_req))) { DBGPRINT(RT_DEBUG_ERROR, - ("MlmeDelBAReqSanity fail - message lenght not correct.\n")); + ("MlmeDelBAReqSanity fail - message length not correct.\n")); return FALSE; } diff --git a/drivers/staging/rt2860/common/cmm_sync.c b/drivers/staging/rt2860/common/cmm_sync.c index f84194da47bc..aefe1b774650 100644 --- a/drivers/staging/rt2860/common/cmm_sync.c +++ b/drivers/staging/rt2860/common/cmm_sync.c @@ -694,7 +694,7 @@ void ScanNextChannel(struct rt_rtmp_adapter *pAd) MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); } - /* For SCAN_CISCO_PASSIVE, do nothing and silently wait for beacon or other probe reponse */ + /* For SCAN_CISCO_PASSIVE, do nothing and silently wait for beacon or other probe response */ pAd->Mlme.SyncMachine.CurrState = SCAN_LISTEN; } diff --git a/drivers/staging/rt2860/common/cmm_wpa.c b/drivers/staging/rt2860/common/cmm_wpa.c index 0040f45b629b..616ebec50c61 100644 --- a/drivers/staging/rt2860/common/cmm_wpa.c +++ b/drivers/staging/rt2860/common/cmm_wpa.c @@ -1222,7 +1222,7 @@ void PeerGroupMsg2Action(struct rt_rtmp_adapter *pAd, Note: All these constants are defined in wpa.h - For supplicant, there is only EAPOL Key message avaliable + For supplicant, there is only EAPOL Key message available ======================================================================== */ @@ -1267,7 +1267,7 @@ BOOLEAN WpaMsgTypeSubst(u8 EAPType, int * MsgType) int prefix_len - the length of the label u8 *data - a specific data with variable length int data_len - the length of a specific data - int len - the output lenght + int len - the output length Return Value: u8 *output - the calculated result diff --git a/drivers/staging/rt2860/common/mlme.c b/drivers/staging/rt2860/common/mlme.c index d9c3fd5c2166..e48eac0f3a29 100644 --- a/drivers/staging/rt2860/common/mlme.c +++ b/drivers/staging/rt2860/common/mlme.c @@ -632,7 +632,7 @@ void MlmeHalt(struct rt_rtmp_adapter *pAd) pChipOps->AsicHaltAction(pAd); } - RTMPusecDelay(5000); /* 5 msec to gurantee Ant Diversity timer canceled */ + RTMPusecDelay(5000); /* 5 msec to guarantee Ant Diversity timer canceled */ MlmeQueueDestroy(&pAd->Mlme.Queue); NdisFreeSpinLock(&pAd->Mlme.TaskLock); @@ -1107,14 +1107,14 @@ void MlmeSelectTxRateTable(struct rt_rtmp_adapter *pAd, *pInitTxRateIdx = RateSwitchTable11N1S[1]; DBGPRINT_RAW(RT_DEBUG_ERROR, - ("DRS: unkown mode,default use 11N 1S AP \n")); + ("DRS: unknown mode,default use 11N 1S AP \n")); } else { *ppTable = RateSwitchTable11N2S; *pTableSize = RateSwitchTable11N2S[0]; *pInitTxRateIdx = RateSwitchTable11N2S[1]; DBGPRINT_RAW(RT_DEBUG_ERROR, - ("DRS: unkown mode,default use 11N 2S AP \n")); + ("DRS: unknown mode,default use 11N 2S AP \n")); } } else { if (pAd->CommonCfg.TxStream == 1) { @@ -1123,7 +1123,7 @@ void MlmeSelectTxRateTable(struct rt_rtmp_adapter *pAd, *pInitTxRateIdx = RateSwitchTable11N1S[1]; DBGPRINT_RAW(RT_DEBUG_ERROR, - ("DRS: unkown mode,default use 11N 1S AP \n")); + ("DRS: unknown mode,default use 11N 1S AP \n")); } else { *ppTable = RateSwitchTable11N2SForABand; *pTableSize = @@ -1131,11 +1131,11 @@ void MlmeSelectTxRateTable(struct rt_rtmp_adapter *pAd, *pInitTxRateIdx = RateSwitchTable11N2SForABand[1]; DBGPRINT_RAW(RT_DEBUG_ERROR, - ("DRS: unkown mode,default use 11N 2S AP \n")); + ("DRS: unknown mode,default use 11N 2S AP \n")); } } DBGPRINT_RAW(RT_DEBUG_ERROR, - ("DRS: unkown mode (SupRateLen=%d, ExtRateLen=%d, MCSSet[0]=0x%x, MCSSet[1]=0x%x)\n", + ("DRS: unknown mode (SupRateLen=%d, ExtRateLen=%d, MCSSet[0]=0x%x, MCSSet[1]=0x%x)\n", pAd->StaActive.SupRateLen, pAd->StaActive.ExtRateLen, pAd->StaActive.SupportedPhyInfo.MCSSet[0], @@ -1368,7 +1368,7 @@ void STAMlmePeriodicExec(struct rt_rtmp_adapter *pAd) if ((pAd->StaCfg.LastScanTime + 10 * OS_HZ) < pAd->Mlme.Now32) { DBGPRINT(RT_DEBUG_TRACE, - ("MMCHK - Roaming, No eligable entry, try new scan!\n")); + ("MMCHK - Roaming, No eligible entry, try new scan!\n")); pAd->StaCfg.ScanCnt = 2; pAd->StaCfg.LastScanTime = pAd->Mlme.Now32; @@ -2828,7 +2828,7 @@ void UpdateBasicRateBitmap(struct rt_rtmp_adapter *pAdapter) /* IRQL = PASSIVE_LEVEL */ /* IRQL = DISPATCH_LEVEL */ -/* bLinkUp is to identify the inital link speed. */ +/* bLinkUp is to identify the initial link speed. */ /* TRUE indicates the rate update at linkup, we should not try to set the rate at 54Mbps. */ void MlmeUpdateTxRates(struct rt_rtmp_adapter *pAd, IN BOOLEAN bLinkUp, u8 apidx) { diff --git a/drivers/staging/rt2860/common/rtmp_init.c b/drivers/staging/rt2860/common/rtmp_init.c index d359a14f5d4d..5fa193eac0d3 100644 --- a/drivers/staging/rt2860/common/rtmp_init.c +++ b/drivers/staging/rt2860/common/rtmp_init.c @@ -2037,7 +2037,7 @@ void NICUpdateFifoStaCounters(struct rt_rtmp_adapter *pAd) pEntry->FIFOCount = 0; pEntry->OneSecTxNoRetryOkCount++; - /* update NoDataIdleCount when sucessful send packet to STA. */ + /* update NoDataIdleCount when successful send packet to STA. */ pEntry->NoDataIdleCount = 0; pEntry->ContinueTxFailCnt = 0; } @@ -2516,7 +2516,7 @@ void UserCfgInit(struct rt_rtmp_adapter *pAd) /*pAd->TurnAggrBulkInCount = 0; */ pAd->bUsbTxBulkAggre = 0; - /* init as unsed value to ensure driver will set to MCU once. */ + /* init as unused value to ensure driver will set to MCU once. */ pAd->LedIndicatorStrength = 0xFF; pAd->CommonCfg.MaxPktOneTxBulk = 2; @@ -3076,11 +3076,11 @@ void RTMPSetLED(struct rt_rtmp_adapter *pAd, u8 Status) ======================================================================== Routine Description: - Set LED Signal Stregth + Set LED Signal Strength Arguments: pAd Pointer to our adapter - Dbm Signal Stregth + Dbm Signal Strength Return Value: None @@ -3090,7 +3090,7 @@ void RTMPSetLED(struct rt_rtmp_adapter *pAd, u8 Status) Note: Can be run on any IRQL level. - According to Microsoft Zero Config Wireless Signal Stregth definition as belows. + According to Microsoft Zero Config Wireless Signal Strength definition as belows. <= -90 No Signal <= -81 Very Low <= -71 Low @@ -3118,7 +3118,7 @@ void RTMPSetSignalLED(struct rt_rtmp_adapter *pAd, IN NDIS_802_11_RSSI Dbm) nLed = 31; /* */ - /* Update Signal Stregth to firmware if changed. */ + /* Update Signal Strength to firmware if changed. */ /* */ if (pAd->LedIndicatorStrength != nLed) { AsicSendCommandToMcu(pAd, 0x51, 0xff, nLed, @@ -3166,7 +3166,7 @@ void RTMPEnableRxTx(struct rt_rtmp_adapter *pAd) if (pAd->CommonCfg.PSPXlink) rx_filter_flag = PSPXLINK; else - rx_filter_flag = STANORMAL; /* Staion not drop control frame will fail WiFi Certification. */ + rx_filter_flag = STANORMAL; /* Station not drop control frame will fail WiFi Certification. */ RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, rx_filter_flag); } diff --git a/drivers/staging/rt2860/common/spectrum.c b/drivers/staging/rt2860/common/spectrum.c index c0d2f428069c..ceb622df12d7 100644 --- a/drivers/staging/rt2860/common/spectrum.c +++ b/drivers/staging/rt2860/common/spectrum.c @@ -1058,8 +1058,8 @@ static void InsertMeasureReqIE(struct rt_rtmp_adapter *pAd, 3. Measure Token. 4. Measure Request Mode. 5. Measure Request Type. - 6. Length of Report Infomation - 7. Pointer of Report Infomation Buffer. + 6. Length of Report Information + 7. Pointer of Report Information Buffer. Return : None. ========================================================================== @@ -1400,7 +1400,7 @@ static void StartDFSProcedure(struct rt_rtmp_adapter *pAd, Parametrs: 1. MLME message containing the received frame 2. message length. - 3. Channel switch announcement infomation buffer. + 3. Channel switch announcement information buffer. Return : None. ========================================================================== @@ -1465,7 +1465,7 @@ static BOOLEAN PeerChSwAnnSanity(struct rt_rtmp_adapter *pAd, Parametrs: 1. MLME message containing the received frame 2. message length. - 3. Measurement request infomation buffer. + 3. Measurement request information buffer. Return : None. ========================================================================== @@ -1538,8 +1538,8 @@ static BOOLEAN PeerMeasureReqSanity(struct rt_rtmp_adapter *pAd, Parametrs: 1. MLME message containing the received frame 2. message length. - 3. Measurement report infomation buffer. - 4. basic report infomation buffer. + 3. Measurement report information buffer. + 4. basic report information buffer. Return : None. ========================================================================== diff --git a/drivers/staging/rt2860/mlme.h b/drivers/staging/rt2860/mlme.h index cd1ee3d7a91d..a285851692ee 100644 --- a/drivers/staging/rt2860/mlme.h +++ b/drivers/staging/rt2860/mlme.h @@ -374,7 +374,7 @@ struct PACKED rt_sec_cha_offset_ie { struct rt_ht_phy_info { BOOLEAN bHtEnable; /* If we should use ht rate. */ BOOLEAN bPreNHt; /* If we should use ht rate. */ - /*Substract from HT Capability IE */ + /*Subtract from HT Capability IE */ u8 MCSSet[16]; }; @@ -392,7 +392,7 @@ struct rt_ht_capability { u16 AmsduSize:1; /* Max receiving A-MSDU size */ u16 rsv:5; - /*Substract from Addiont HT INFO IE */ + /*Subtract from Addiont HT INFO IE */ u8 MaxRAmpduFactor:2; u8 MpduDensity:3; u8 ExtChanOffset:2; /* Please note the difference with following u8 NewExtChannelOffset; from 802.11n */ @@ -410,7 +410,7 @@ struct rt_ht_capability { u8 BSSCoexist2040; }; -/* field in Addtional HT Information IE . */ +/* field in Additional HT Information IE . */ struct PACKED rt_add_htinfo { u8 ExtChanOffset:2; u8 RecomWidth:1; @@ -857,7 +857,7 @@ struct rt_state_machine { }; /* MLME AUX data structure that holds temporarliy settings during a connection attempt. */ -/* Once this attemp succeeds, all settings will be copy to pAd->StaActive. */ +/* Once this attempt succeeds, all settings will be copy to pAd->StaActive. */ /* A connection attempt (user set OID, roaming, CCX fast roaming,..) consists of */ /* several steps (JOIN, AUTH, ASSOC or REASSOC) and may fail at any step. We purposely */ /* separate this under-trial settings away from pAd->StaActive so that once */ diff --git a/drivers/staging/rt2860/rt_linux.c b/drivers/staging/rt2860/rt_linux.c index e5b042712430..1583347fcd52 100644 --- a/drivers/staging/rt2860/rt_linux.c +++ b/drivers/staging/rt2860/rt_linux.c @@ -283,7 +283,7 @@ BOOLEAN OS_Need_Clone_Packet(void) Arguments: pAd Pointer to our adapter pInsAMSDUHdr EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU. - *pSrcTotalLen return total packet length. This lenght is calculated with 802.3 format packet. + *pSrcTotalLen return total packet length. This length is calculated with 802.3 format packet. Return Value: NDIS_STATUS_SUCCESS diff --git a/drivers/staging/rt2860/rt_pci_rbus.c b/drivers/staging/rt2860/rt_pci_rbus.c index e5fb67cd9a68..f80ab4e6a0ac 100644 --- a/drivers/staging/rt2860/rt_pci_rbus.c +++ b/drivers/staging/rt2860/rt_pci_rbus.c @@ -619,7 +619,7 @@ IRQ_HANDLE_TYPE rt2860_interrupt(int irq, void *dev_instance) Or kernel will panic after ifconfig ra0 down sometimes */ /* */ - /* Inital the Interrupt source. */ + /* Initial the Interrupt source. */ /* */ IntSource.word = 0x00000000L; /* McuIntSource.word = 0x00000000L; */ diff --git a/drivers/staging/rt2860/rtmp.h b/drivers/staging/rt2860/rtmp.h index d16b06a6e2ac..3c31340c946a 100644 --- a/drivers/staging/rt2860/rtmp.h +++ b/drivers/staging/rt2860/rtmp.h @@ -756,7 +756,7 @@ struct rt_tkip_key_info { /* */ struct rt_private { u32 SystemResetCnt; /* System reset counter */ - u32 TxRingFullCnt; /* Tx ring full occurrance number */ + u32 TxRingFullCnt; /* Tx ring full occurrence number */ u32 PhyRxErrCnt; /* PHY Rx error count, for debug purpose, might move to global counter */ /* Variables for WEP encryption / decryption in rtmp_wep.c */ u32 FCSCRC32; @@ -925,7 +925,7 @@ struct rt_mlme { **************************************************************************/ struct reordering_mpdu { struct reordering_mpdu *next; - void *pPacket; /* coverted to 802.3 frame */ + void *pPacket; /* converted to 802.3 frame */ int Sequence; /* sequence number of MPDU */ BOOLEAN bAMSDU; }; diff --git a/drivers/staging/rt2860/sta_ioctl.c b/drivers/staging/rt2860/sta_ioctl.c index 5717e12a9544..49b1013e7a03 100644 --- a/drivers/staging/rt2860/sta_ioctl.c +++ b/drivers/staging/rt2860/sta_ioctl.c @@ -2460,7 +2460,7 @@ int rt28xx_sta_ioctl(IN struct net_device *net_dev, } } - { /* determine this ioctl command is comming from which interface. */ + { /* determine this ioctl command is coming from which interface. */ pObj->ioctl_if_type = INT_MAIN; pObj->ioctl_if = MAIN_MBSSID; } diff --git a/drivers/staging/rt2870/common/rtusb_bulk.c b/drivers/staging/rt2870/common/rtusb_bulk.c index d2746f8732e6..679b802d2169 100644 --- a/drivers/staging/rt2870/common/rtusb_bulk.c +++ b/drivers/staging/rt2870/common/rtusb_bulk.c @@ -298,7 +298,7 @@ void RTUSBBulkOutDataPacket(struct rt_rtmp_adapter *pAd, /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0)) */ ) { /* For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size. */ - /* For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04. */ + /* For performance in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04. */ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; @@ -311,7 +311,7 @@ void RTUSBBulkOutDataPacket(struct rt_rtmp_adapter *pAd, TmpBulkEndPos; break; } else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize & 0xfffff800) != 0)) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0)) */) { /* For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size. */ - /* For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04. */ + /* For performance in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04. */ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; @@ -1016,7 +1016,7 @@ void RTUSBKickBulkOut(struct rt_rtmp_adapter *pAd) RTUSBBulkOutNullFrame(pAd); } } - /* 8. No data avaliable */ + /* 8. No data available */ else ; } diff --git a/drivers/staging/rt2870/common/rtusb_data.c b/drivers/staging/rt2870/common/rtusb_data.c index 69368862217c..5b72bcdaa78f 100644 --- a/drivers/staging/rt2870/common/rtusb_data.c +++ b/drivers/staging/rt2870/common/rtusb_data.c @@ -71,7 +71,7 @@ void REPORT_AMSDU_FRAMES_TO_LLC(struct rt_rtmp_adapter *pAd, Routine Description: This subroutine will scan through releative ring descriptor to find - out avaliable free ring descriptor and compare with request size. + out available free ring descriptor and compare with request size. Arguments: pAd Pointer to our adapter diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211.h b/drivers/staging/rtl8187se/ieee80211/ieee80211.h index dc608c70deb1..16aa6a8952fd 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211.h @@ -1099,7 +1099,7 @@ struct ieee80211_device { * not set. As some cards may have different HW queues that * one might want to use for data and management frames * the option to have two callbacks might be useful. - * This fucntion can't sleep. + * This function can't sleep. */ int (*softmac_hard_start_xmit)(struct sk_buff *skb, struct net_device *dev); @@ -1138,9 +1138,9 @@ struct ieee80211_device { * it is called in a work_queue when swithcing to ad-hoc mode * or in behalf of iwlist scan when the card is associated * and root user ask for a scan. - * the fucntion stop_scan should stop both the syncro and + * the function stop_scan should stop both the syncro and * background scanning and can sleep. - * The fucntion start_scan should initiate the background + * The function start_scan should initiate the background * scanning and can't sleep. */ void (*scan_syncro)(struct net_device *dev); diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c index 771e0196842e..736a1404f287 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c @@ -1954,7 +1954,7 @@ associate_complete: -/* following are for a simplier TX queue management. +/* following are for a simpler TX queue management. * Instead of using netif_[stop/wake]_queue the driver * will uses these two function (plus a reset one), that * will internally uses the kernel netif_* and takes diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index 70ab0084e5f5..2155a771c339 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c @@ -1591,7 +1591,7 @@ void rtl8180_rx(struct net_device *dev) priv->RSSI = RSSI; /* SQ translation formula is provided by SD3 DZ. 2006.06.27 */ if (quality >= 127) - quality = 1; /*0; */ /* 0 will cause epc to show signal zero , walk aroud now; */ + quality = 1; /*0; */ /* 0 will cause epc to show signal zero , walk around now; */ else if (quality < 27) quality = 100; else @@ -3883,7 +3883,7 @@ void rtl8180_tx_isr(struct net_device *dev, int pri, short error) * If the packet previous of the nic pointer has been * processed this doesn't matter: it will be checked * here at the next round. Anyway if no more packet are - * TXed no memory leak occour at all. + * TXed no memory leak occur at all. */ switch (pri) { diff --git a/drivers/staging/rtl8187se/r8180_dm.c b/drivers/staging/rtl8187se/r8180_dm.c index fc4907839c58..261085d4b74a 100644 --- a/drivers/staging/rtl8187se/r8180_dm.c +++ b/drivers/staging/rtl8187se/r8180_dm.c @@ -123,7 +123,7 @@ DoTxHighPower( // // Description: // Callback function of UpdateTxPowerWorkItem. -// Because of some event happend, e.g. CCX TPC, High Power Mechanism, +// Because of some event happened, e.g. CCX TPC, High Power Mechanism, // We update Tx power of current channel again. // void rtl8180_tx_pw_wq (struct work_struct *work) @@ -984,7 +984,7 @@ StaRateAdaptive87SE( { priv->TryupingCount = 0; // - // When transfering from CCK to OFDM, DIG is an important issue. + // When transferring from CCK to OFDM, DIG is an important issue. // if(priv->CurrentOperaRate == 22) bUpdateInitialGain = true; diff --git a/drivers/staging/rtl8187se/r8180_rtl8225z2.c b/drivers/staging/rtl8187se/r8180_rtl8225z2.c index 2a2afd51cf42..3f09f76080af 100644 --- a/drivers/staging/rtl8187se/r8180_rtl8225z2.c +++ b/drivers/staging/rtl8187se/r8180_rtl8225z2.c @@ -378,7 +378,7 @@ static u32 read_rtl8225(struct net_device *dev, u8 adr) mask = (low2high) ? 0x01 : (((u32)0x01) << (12-1)); /* - * We must set data pin to HW controled, otherwise RF can't driver it + * We must set data pin to HW controlled, otherwise RF can't driver it * and value RF register won't be able to read back properly. */ write_nic_word(dev, RFPinsEnable, (oval2 & (~0x01))); diff --git a/drivers/staging/rtl8187se/r8185b_init.c b/drivers/staging/rtl8187se/r8185b_init.c index 3bdf9b31cc4e..4b0b830f9ab6 100644 --- a/drivers/staging/rtl8187se/r8185b_init.c +++ b/drivers/staging/rtl8187se/r8185b_init.c @@ -1273,7 +1273,7 @@ MgntDisconnectIBSS( /* Stop Beacon. - Vista add a Adhoc profile, HW radio off untill OID_DOT11_RESET_REQUEST + Vista add a Adhoc profile, HW radio off until OID_DOT11_RESET_REQUEST Driver would set MSR=NO_LINK, then HW Radio ON, MgntQueue Stuck. Because Bcn DMA isn't complete, mgnt queue would stuck until Bcn packet send. diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211.h b/drivers/staging/rtl8192e/ieee80211/ieee80211.h index 3ca388152616..dbe21ab0dbf7 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211.h @@ -1967,7 +1967,7 @@ struct ieee80211_device { u16 prev_seq_ctl; /* used to drop duplicate frames */ /* map of allowed channels. 0 is dummy */ - // FIXME: remeber to default to a basic channel plan depending of the PHY type + // FIXME: remember to default to a basic channel plan depending of the PHY type #ifdef ENABLE_DOT11D void* pDot11dInfo; bool bGlobalDomain; @@ -2121,7 +2121,7 @@ struct ieee80211_device { * not set. As some cards may have different HW queues that * one might want to use for data and management frames * the option to have two callbacks might be useful. - * This fucntion can't sleep. + * This function can't sleep. */ int (*softmac_hard_start_xmit)(struct sk_buff *skb, struct ieee80211_device *ieee80211); @@ -2160,9 +2160,9 @@ struct ieee80211_device { * it is called in a work_queue when swithcing to ad-hoc mode * or in behalf of iwlist scan when the card is associated * and root user ask for a scan. - * the fucntion stop_scan should stop both the syncro and + * the function stop_scan should stop both the syncro and * background scanning and can sleep. - * The fucntion start_scan should initiate the background + * The function start_scan should initiate the background * scanning and can't sleep. */ void (*scan_syncro)(struct ieee80211_device *ieee80211); diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c index add015ebba1c..ed5a38023094 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c @@ -1426,7 +1426,7 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 }; /* -* Make ther structure we read from the beacon packet has +* Make the structure we read from the beacon packet to have * the right values */ static int ieee80211_verify_qos_info(struct ieee80211_qos_information_element diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c index f6922d40a88a..7d4cba3a7c12 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c @@ -2023,7 +2023,7 @@ ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, return 1; } else - { //filling the PeerHTCap. //maybe not neccesary as we can get its info from current_network. + { //filling the PeerHTCap. //maybe not necessary as we can get its info from current_network. memcpy(ieee->pHTInfo->PeerHTCapBuf, network->bssht.bdHTCapBuf, network->bssht.bdHTCapLen); memcpy(ieee->pHTInfo->PeerHTInfoBuf, network->bssht.bdHTInfoBuf, network->bssht.bdHTInfoLen); } @@ -2163,7 +2163,7 @@ ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, return 0; } -/* following are for a simplier TX queue management. +/* following are for a simpler TX queue management. * Instead of using netif_[stop/wake]_queue the driver * will uses these two function (plus a reset one), that * will internally uses the kernel netif_* and takes diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_HT.h b/drivers/staging/rtl8192e/ieee80211/rtl819x_HT.h index f968817d073c..56a120cf6291 100644 --- a/drivers/staging/rtl8192e/ieee80211/rtl819x_HT.h +++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_HT.h @@ -64,7 +64,7 @@ typedef enum _HT_CHANNEL_WIDTH{ }HT_CHANNEL_WIDTH, *PHT_CHANNEL_WIDTH; // -// Represent Extention Channel Offset in HT Capabilities +// Represent Extension Channel Offset in HT Capabilities // This is available only in 40Mhz mode. // typedef enum _HT_EXTCHNL_OFFSET{ diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c b/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c index a2a4fe9dd9da..f7a9da3ec829 100644 --- a/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c +++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c @@ -459,7 +459,7 @@ u8 HTIOTActIsForcedCTS2Self(struct ieee80211_device *ieee, struct ieee80211_netw /** * Function: HTIOTActIsDisableMCS15 * -* Overview: Check whether driver should declare capability of receving MCS15 +* Overview: Check whether driver should declare capability of receiving MCS15 * * Input: * PADAPTER Adapter, @@ -496,7 +496,7 @@ bool HTIOTActIsDisableMCS15(struct ieee80211_device* ieee) /** * Function: HTIOTActIsDisableMCSTwoSpatialStream * -* Overview: Check whether driver should declare capability of receving All 2 ss packets +* Overview: Check whether driver should declare capability of receiving All 2 ss packets * * Input: * PADAPTER Adapter, @@ -1681,7 +1681,7 @@ void HTSetConnectBwMode(struct ieee80211_device* ieee, HT_CHANNEL_WIDTH Bandwidt //if in half N mode, set to 20M bandwidth please 09.08.2008 WB. if (Bandwidth==HT_CHANNEL_WIDTH_20_40 && (!ieee->GetHalfNmodeSupportByAPsHandler(ieee))) { - // Handle Illegal extention channel offset!! + // Handle Illegal extension channel offset!! if(ieee->current_network.channel<2 && Offset==HT_EXTCHNL_OFFSET_LOWER) Offset = HT_EXTCHNL_OFFSET_NO_EXT; if(Offset==HT_EXTCHNL_OFFSET_UPPER || Offset==HT_EXTCHNL_OFFSET_LOWER) { @@ -1698,7 +1698,7 @@ void HTSetConnectBwMode(struct ieee80211_device* ieee, HT_CHANNEL_WIDTH Bandwidt pHTInfo->bSwBwInProgress = true; - // TODO: 2007.7.13 by Emily Wait 2000ms in order to garantee that switching + // TODO: 2007.7.13 by Emily Wait 2000ms in order to guarantee that switching // bandwidth is executed after scan is finished. It is a temporal solution // because software should ganrantee the last operation of switching bandwidth // is executed properlly. diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_TS.h b/drivers/staging/rtl8192e/ieee80211/rtl819x_TS.h index baaac2149de1..e7e26fd96395 100644 --- a/drivers/staging/rtl8192e/ieee80211/rtl819x_TS.h +++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_TS.h @@ -44,7 +44,7 @@ typedef struct _RX_TS_RECORD { u16 RxTimeoutIndicateSeq; struct list_head RxPendingPktList; struct timer_list RxPktPendingTimer; - BA_RECORD RxAdmittedBARecord; // For BA Recepient + BA_RECORD RxAdmittedBARecord; // For BA Recipient u16 RxLastSeqNum; u8 RxLastFragNum; u8 num; diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c b/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c index 29eecf0ab769..ad6872dcf1c2 100644 --- a/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c +++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c @@ -135,7 +135,7 @@ void ResetRxTsEntry(PRX_TS_RECORD pTS) ResetTsCommonInfo(&pTS->TsCommonInfo); pTS->RxIndicateSeq = 0xffff; // This indicate the RxIndicateSeq is not used now!! pTS->RxTimeoutIndicateSeq = 0xffff; // This indicate the RxTimeoutIndicateSeq is not used now!! - ResetBaEntry(&pTS->RxAdmittedBARecord); // For BA Recepient + ResetBaEntry(&pTS->RxAdmittedBARecord); // For BA Recipient } void TSInitialize(struct ieee80211_device *ieee) diff --git a/drivers/staging/rtl8192e/r819xE_phy.c b/drivers/staging/rtl8192e/r819xE_phy.c index dfa4e112ef46..9e7828ef1cbe 100644 --- a/drivers/staging/rtl8192e/r819xE_phy.c +++ b/drivers/staging/rtl8192e/r819xE_phy.c @@ -2032,13 +2032,13 @@ void rtl8192_SetBWModeWorkItem(struct r8192_priv *priv) { case HT_CHANNEL_WIDTH_20: regBwOpMode |= BW_OPMODE_20MHZ; - // 2007/02/07 Mark by Emily becasue we have not verify whether this register works + // 2007/02/07 Mark by Emily because we have not verify whether this register works write_nic_byte(priv, BW_OPMODE, regBwOpMode); break; case HT_CHANNEL_WIDTH_20_40: regBwOpMode &= ~BW_OPMODE_20MHZ; - // 2007/02/07 Mark by Emily becasue we have not verify whether this register works + // 2007/02/07 Mark by Emily because we have not verify whether this register works write_nic_byte(priv, BW_OPMODE, regBwOpMode); break; @@ -2116,7 +2116,7 @@ void rtl8192_SetBWModeWorkItem(struct r8192_priv *priv) } /****************************************************************************** - *function: This function schedules bandwith switch work. + *function: This function schedules bandwidth switch work. * input: struct net_device *dev * HT_CHANNEL_WIDTH Bandwidth //20M or 40M * HT_EXTCHNL_OFFSET Offset //Upper, Lower, or Don't care diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211.h b/drivers/staging/rtl8192u/ieee80211/ieee80211.h index c0b844d75c0d..e716f7b1144f 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211.h @@ -1965,7 +1965,7 @@ struct ieee80211_device { u16 prev_seq_ctl; /* used to drop duplicate frames */ /* map of allowed channels. 0 is dummy */ - // FIXME: remeber to default to a basic channel plan depending of the PHY type + // FIXME: remember to default to a basic channel plan depending of the PHY type void* pDot11dInfo; bool bGlobalDomain; int rate; /* current rate */ @@ -2119,7 +2119,7 @@ struct ieee80211_device { * not set. As some cards may have different HW queues that * one might want to use for data and management frames * the option to have two callbacks might be useful. - * This fucntion can't sleep. + * This function can't sleep. */ int (*softmac_hard_start_xmit)(struct sk_buff *skb, struct net_device *dev); @@ -2158,9 +2158,9 @@ struct ieee80211_device { * it is called in a work_queue when swithcing to ad-hoc mode * or in behalf of iwlist scan when the card is associated * and root user ask for a scan. - * the fucntion stop_scan should stop both the syncro and + * the function stop_scan should stop both the syncro and * background scanning and can sleep. - * The fucntion start_scan should initiate the background + * The function start_scan should initiate the background * scanning and can't sleep. */ void (*scan_syncro)(struct net_device *dev); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c index 498b520efcf4..a414303aef54 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c @@ -1399,7 +1399,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 }; /* -* Make ther structure we read from the beacon packet has +* Make the structure we read from the beacon packet to have * the right values */ static int ieee80211_verify_qos_info(struct ieee80211_qos_information_element diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c index 4992d630f984..4ec0a6520ddc 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c @@ -1973,7 +1973,7 @@ ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, return 1; } else - { //filling the PeerHTCap. //maybe not neccesary as we can get its info from current_network. + { //filling the PeerHTCap. //maybe not necessary as we can get its info from current_network. memcpy(ieee->pHTInfo->PeerHTCapBuf, network->bssht.bdHTCapBuf, network->bssht.bdHTCapLen); memcpy(ieee->pHTInfo->PeerHTInfoBuf, network->bssht.bdHTInfoBuf, network->bssht.bdHTInfoLen); } @@ -2113,7 +2113,7 @@ ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, return 0; } -/* following are for a simplier TX queue management. +/* following are for a simpler TX queue management. * Instead of using netif_[stop/wake]_queue the driver * will uses these two function (plus a reset one), that * will internally uses the kernel netif_* and takes diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_HT.h b/drivers/staging/rtl8192u/ieee80211/rtl819x_HT.h index cde603f67f43..0b1a1fc09391 100644 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_HT.h +++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_HT.h @@ -64,7 +64,7 @@ typedef enum _HT_CHANNEL_WIDTH{ }HT_CHANNEL_WIDTH, *PHT_CHANNEL_WIDTH; // -// Represent Extention Channel Offset in HT Capabilities +// Represent Extension Channel Offset in HT Capabilities // This is available only in 40Mhz mode. // typedef enum _HT_EXTCHNL_OFFSET{ diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c index 50f4f5943e75..e88a839b2a91 100644 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c +++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c @@ -423,7 +423,7 @@ u8 HTIOTActIsDisableMCS14(struct ieee80211_device* ieee, u8* PeerMacAddr) /** * Function: HTIOTActIsDisableMCS15 * -* Overview: Check whether driver should declare capability of receving MCS15 +* Overview: Check whether driver should declare capability of receiving MCS15 * * Input: * PADAPTER Adapter, @@ -460,7 +460,7 @@ bool HTIOTActIsDisableMCS15(struct ieee80211_device* ieee) /** * Function: HTIOTActIsDisableMCSTwoSpatialStream * -* Overview: Check whether driver should declare capability of receving All 2 ss packets +* Overview: Check whether driver should declare capability of receiving All 2 ss packets * * Input: * PADAPTER Adapter, @@ -1409,7 +1409,7 @@ void HTSetConnectBwMode(struct ieee80211_device* ieee, HT_CHANNEL_WIDTH Bandwidt //if in half N mode, set to 20M bandwidth please 09.08.2008 WB. if(Bandwidth==HT_CHANNEL_WIDTH_20_40 && (!ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))) { - // Handle Illegal extention channel offset!! + // Handle Illegal extension channel offset!! if(ieee->current_network.channel<2 && Offset==HT_EXTCHNL_OFFSET_LOWER) Offset = HT_EXTCHNL_OFFSET_NO_EXT; if(Offset==HT_EXTCHNL_OFFSET_UPPER || Offset==HT_EXTCHNL_OFFSET_LOWER) { @@ -1426,7 +1426,7 @@ void HTSetConnectBwMode(struct ieee80211_device* ieee, HT_CHANNEL_WIDTH Bandwidt pHTInfo->bSwBwInProgress = true; - // TODO: 2007.7.13 by Emily Wait 2000ms in order to garantee that switching + // TODO: 2007.7.13 by Emily Wait 2000ms in order to guarantee that switching // bandwidth is executed after scan is finished. It is a temporal solution // because software should ganrantee the last operation of switching bandwidth // is executed properlly. diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_TS.h b/drivers/staging/rtl8192u/ieee80211/rtl819x_TS.h index baaac2149de1..e7e26fd96395 100644 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_TS.h +++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_TS.h @@ -44,7 +44,7 @@ typedef struct _RX_TS_RECORD { u16 RxTimeoutIndicateSeq; struct list_head RxPendingPktList; struct timer_list RxPktPendingTimer; - BA_RECORD RxAdmittedBARecord; // For BA Recepient + BA_RECORD RxAdmittedBARecord; // For BA Recipient u16 RxLastSeqNum; u8 RxLastFragNum; u8 num; diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c index c3fcaae0750d..957ce4ef48b5 100644 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c +++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c @@ -135,7 +135,7 @@ void ResetRxTsEntry(PRX_TS_RECORD pTS) ResetTsCommonInfo(&pTS->TsCommonInfo); pTS->RxIndicateSeq = 0xffff; // This indicate the RxIndicateSeq is not used now!! pTS->RxTimeoutIndicateSeq = 0xffff; // This indicate the RxTimeoutIndicateSeq is not used now!! - ResetBaEntry(&pTS->RxAdmittedBARecord); // For BA Recepient + ResetBaEntry(&pTS->RxAdmittedBARecord); // For BA Recipient } void TSInitialize(struct ieee80211_device *ieee) diff --git a/drivers/staging/rtl8192u/ieee80211/scatterwalk.c b/drivers/staging/rtl8192u/ieee80211/scatterwalk.c index 49f401fbce88..3543a6145046 100644 --- a/drivers/staging/rtl8192u/ieee80211/scatterwalk.c +++ b/drivers/staging/rtl8192u/ieee80211/scatterwalk.c @@ -71,7 +71,7 @@ static void scatterwalk_pagedone(struct scatter_walk *walk, int out, unsigned int more) { /* walk->data may be pointing the first byte of the next page; - however, we know we transfered at least one byte. So, + however, we know we transferred at least one byte. So, walk->data - 1 will be a virtual address in the mapped page. */ if (out) diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index da612e6d994e..e81b8ab6aa9d 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -460,7 +460,7 @@ u32 read_nic_dword(struct net_device *dev, int indx) /* u8 read_phy_cck(struct net_device *dev, u8 adr); */ /* u8 read_phy_ofdm(struct net_device *dev, u8 adr); */ /* this might still called in what was the PHY rtl8185/rtl8192 common code - * plans are to possibilty turn it again in one common code... + * plans are to possibility turn it again in one common code... */ inline void force_pci_posting(struct net_device *dev) { @@ -1378,7 +1378,7 @@ struct sk_buff *DrvAggr_Aggregation(struct net_device *dev, struct ieee80211_drv //tx_agg_desc->LINIP = 0; //tx_agg_desc->CmdInit = 1; tx_agg_desc->Offset = sizeof(tx_fwinfo_819x_usb) + 8; - /* already raw data, need not to substract header length */ + /* already raw data, need not to subtract header length */ tx_agg_desc->PktSize = skb->len & 0xffff; /*DWORD 1*/ @@ -2888,7 +2888,7 @@ static void rtl8192_get_eeprom_size(struct net_device* dev) RT_TRACE(COMP_EPROM, "<===========%s(), epromtype:%d\n", __FUNCTION__, priv->epromtype); } -//used to swap endian. as ntohl & htonl are not neccessary to swap endian, so use this instead. +//used to swap endian. as ntohl & htonl are not necessary to swap endian, so use this instead. static inline u16 endian_swap(u16* data) { u16 tmp = *data; diff --git a/drivers/staging/rtl8192u/r819xU_HTType.h b/drivers/staging/rtl8192u/r819xU_HTType.h index 01f58b902028..2ac421626e7c 100644 --- a/drivers/staging/rtl8192u/r819xU_HTType.h +++ b/drivers/staging/rtl8192u/r819xU_HTType.h @@ -65,7 +65,7 @@ typedef enum _HT_CHANNEL_WIDTH{ }HT_CHANNEL_WIDTH, *PHT_CHANNEL_WIDTH; // -// Represent Extention Channel Offset in HT Capabilities +// Represent Extension Channel Offset in HT Capabilities // This is available only in 40Mhz mode. // typedef enum _HT_EXTCHNL_OFFSET{ diff --git a/drivers/staging/rtl8192u/r819xU_phy.c b/drivers/staging/rtl8192u/r819xU_phy.c index 41684e8fcf4c..c4586b0817d1 100644 --- a/drivers/staging/rtl8192u/r819xU_phy.c +++ b/drivers/staging/rtl8192u/r819xU_phy.c @@ -1531,13 +1531,13 @@ void rtl8192_SetBWModeWorkItem(struct net_device *dev) { case HT_CHANNEL_WIDTH_20: regBwOpMode |= BW_OPMODE_20MHZ; - // 2007/02/07 Mark by Emily becasue we have not verify whether this register works + // 2007/02/07 Mark by Emily because we have not verify whether this register works write_nic_byte(dev, BW_OPMODE, regBwOpMode); break; case HT_CHANNEL_WIDTH_20_40: regBwOpMode &= ~BW_OPMODE_20MHZ; - // 2007/02/07 Mark by Emily becasue we have not verify whether this register works + // 2007/02/07 Mark by Emily because we have not verify whether this register works write_nic_byte(dev, BW_OPMODE, regBwOpMode); break; @@ -1647,7 +1647,7 @@ void rtl8192_SetBWModeWorkItem(struct net_device *dev) } /****************************************************************************** - *function: This function schedules bandwith switch work. + *function: This function schedules bandwidth switch work. * input: struct net_device *dev * HT_CHANNEL_WIDTH Bandwidth //20M or 40M * HT_EXTCHNL_OFFSET Offset //Upper, Lower, or Don't care diff --git a/drivers/staging/rtl8712/rtl871x_cmd.h b/drivers/staging/rtl8712/rtl871x_cmd.h index 3a945b5f0e01..2dc78476b7d3 100644 --- a/drivers/staging/rtl8712/rtl871x_cmd.h +++ b/drivers/staging/rtl8712/rtl871x_cmd.h @@ -656,7 +656,7 @@ struct PT_param { /* * Result: * 0x00: success - * 0x01: sucess, and check Response. + * 0x01: success, and check Response. * 0x02: cmd ignored due to duplicated sequcne number * 0x03: cmd dropped due to invalid cmd code * 0x04: reserved. diff --git a/drivers/staging/rtl8712/rtl871x_led.h b/drivers/staging/rtl8712/rtl871x_led.h index 994ef82141ab..8085e5eb82b1 100644 --- a/drivers/staging/rtl8712/rtl871x_led.h +++ b/drivers/staging/rtl8712/rtl871x_led.h @@ -78,14 +78,14 @@ struct LED_871x { }; struct led_priv { - /* add for led controll */ + /* add for led control */ struct LED_871x SwLed0; struct LED_871x SwLed1; enum LED_STRATEGY_871x LedStrategy; u8 bRegUseLed; void (*LedControlHandler)(struct _adapter *padapter, enum LED_CTL_MODE LedAction); - /* add for led controll */ + /* add for led control */ }; /*=========================================================================== diff --git a/drivers/staging/rtl8712/rtl871x_mlme.c b/drivers/staging/rtl8712/rtl871x_mlme.c index 98ba7602e250..866554d48d86 100644 --- a/drivers/staging/rtl8712/rtl871x_mlme.c +++ b/drivers/staging/rtl8712/rtl871x_mlme.c @@ -1663,7 +1663,7 @@ void r8712_update_registrypriv_dev_network(struct _adapter *adapter) (struct ndis_wlan_bssid_ex *)pdev_network); } -/*the fucntion is at passive_level*/ +/*the function is at passive_level*/ void r8712_joinbss_reset(struct _adapter *padapter) { int i; @@ -1726,7 +1726,7 @@ unsigned int r8712_restructure_ht_ie(struct _adapter *padapter, u8 *in_ie, return phtpriv->ht_option; } -/* the fucntion is > passive_level (in critical_section) */ +/* the function is > passive_level (in critical_section) */ static void update_ht_cap(struct _adapter *padapter, u8 *pie, uint ie_len) { u8 *p, max_ampdu_sz; @@ -1803,7 +1803,7 @@ void r8712_issue_addbareq_cmd(struct _adapter *padapter, int priority) } } -/*the fucntion is >= passive_level*/ +/*the function is >= passive_level*/ unsigned int r8712_add_ht_addt_info(struct _adapter *padapter, u8 *in_ie, u8 *out_ie, uint in_len, uint *pout_len) diff --git a/drivers/staging/rtl8712/rtl871x_mlme.h b/drivers/staging/rtl8712/rtl871x_mlme.h index 2b35b740ab89..2794804d0822 100644 --- a/drivers/staging/rtl8712/rtl871x_mlme.h +++ b/drivers/staging/rtl8712/rtl871x_mlme.h @@ -29,7 +29,7 @@ * single-tone*/ #define WIFI_MP_CTX_BACKGROUND_PENDING 0x00080000 /* pending in cont, tx * background due to out of skb*/ -#define WIFI_MP_CTX_CCK_HW 0x00100000 /* in continous tx*/ +#define WIFI_MP_CTX_CCK_HW 0x00100000 /* in continuous tx*/ #define WIFI_MP_CTX_CCK_CS 0x00200000 /* in cont, tx with carrier * suppression*/ #define WIFI_MP_LPBK_STATE 0x00400000 diff --git a/drivers/staging/rtl8712/rtl871x_mp_phy_regdef.h b/drivers/staging/rtl8712/rtl871x_mp_phy_regdef.h index e386fb0aac3e..23532a793859 100644 --- a/drivers/staging/rtl8712/rtl871x_mp_phy_regdef.h +++ b/drivers/staging/rtl8712/rtl871x_mp_phy_regdef.h @@ -38,7 +38,7 @@ * 2. 0x800/0x900/0xA00/0xC00/0xD00/0xE00 * 3. RF register 0x00-2E * 4. Bit Mask for BB/RF register - * 5. Other defintion for BB/RF R/W + * 5. Other definition for BB/RF R/W * * 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF * 1. Page1(0x100) diff --git a/drivers/staging/rtl8712/usb_halinit.c b/drivers/staging/rtl8712/usb_halinit.c index 0e9483bbabe1..46287c17a417 100644 --- a/drivers/staging/rtl8712/usb_halinit.c +++ b/drivers/staging/rtl8712/usb_halinit.c @@ -112,7 +112,7 @@ u8 r8712_usb_hal_bus_init(struct _adapter *padapter) /* Initialization for power on sequence, */ r8712_write8(padapter, SPS0_CTRL + 1, 0x53); r8712_write8(padapter, SPS0_CTRL, 0x57); - /* Enable AFE Macro Block's Bandgap adn Enable AFE Macro + /* Enable AFE Macro Block's Bandgap and Enable AFE Macro * Block's Mbias */ val8 = r8712_read8(padapter, AFE_MISC); diff --git a/drivers/staging/rts_pstor/rtsx_chip.h b/drivers/staging/rts_pstor/rtsx_chip.h index 713c5eaadacd..9f7cd82a1541 100644 --- a/drivers/staging/rts_pstor/rtsx_chip.h +++ b/drivers/staging/rts_pstor/rtsx_chip.h @@ -180,8 +180,8 @@ #define CUR_ERR 0x70 /* current error */ #define DEF_ERR 0x71 /* specific command error */ -/*---- sense key Infomation ----*/ -#define SNSKEYINFO_LEN 3 /* length of sense key infomation */ +/*---- sense key Information ----*/ +#define SNSKEYINFO_LEN 3 /* length of sense key information */ #define SKSV 0x80 #define CDB_ILLEGAL 0x40 @@ -235,13 +235,13 @@ struct sense_data_t { unsigned char seg_no; /* segment No. */ unsigned char sense_key; /* byte5 : ILI */ /* bit3-0 : sense key */ - unsigned char info[4]; /* infomation */ + unsigned char info[4]; /* information */ unsigned char ad_sense_len; /* additional sense data length */ - unsigned char cmd_info[4]; /* command specific infomation */ + unsigned char cmd_info[4]; /* command specific information */ unsigned char asc; /* ASC */ unsigned char ascq; /* ASCQ */ unsigned char rfu; /* FRU */ - unsigned char sns_key_info[3]; /* sense key specific infomation */ + unsigned char sns_key_info[3]; /* sense key specific information */ }; /* PCI Operation Register Address */ diff --git a/drivers/staging/rts_pstor/rtsx_scsi.h b/drivers/staging/rts_pstor/rtsx_scsi.h index fac122c1eabd..64b84992fdb3 100644 --- a/drivers/staging/rts_pstor/rtsx_scsi.h +++ b/drivers/staging/rts_pstor/rtsx_scsi.h @@ -85,7 +85,7 @@ #define CHIP_NORMALMODE 0x00 #define CHIP_DEBUGMODE 0x01 -/* SD Pass Through Command Extention */ +/* SD Pass Through Command Extension */ #define SD_PASS_THRU_MODE 0xD0 #define SD_EXECUTE_NO_DATA 0xD1 #define SD_EXECUTE_READ 0xD2 diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 21bfa5755bec..8d066bd428c4 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -1719,7 +1719,7 @@ static u8 sd_search_final_phase(struct rtsx_chip *chip, u32 phase_map, u8 tune_d } Search_Finish: - RTSX_DEBUGP("Final choosen phase: %d\n", final_phase); + RTSX_DEBUGP("Final chosen phase: %d\n", final_phase); return final_phase; } diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c index 71a5fbc041e4..c2f2664b61ae 100644 --- a/drivers/staging/sep/sep_driver.c +++ b/drivers/staging/sep/sep_driver.c @@ -586,7 +586,7 @@ static unsigned int sep_poll(struct file *filp, poll_table *wait) dev_dbg(&sep->pdev->dev, "poll: send_ct is %lx reply ct is %lx\n", sep->send_ct, sep->reply_ct); - /* Check if error occured during poll */ + /* Check if error occurred during poll */ retval2 = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); if (retval2 != 0x0) { dev_warn(&sep->pdev->dev, "poll; poll error %x\n", retval2); @@ -1106,7 +1106,7 @@ static int sep_lock_user_pages(struct sep_device *sep, lli_array[count].block_size); } - /* Set output params acording to the in_out flag */ + /* Set output params according to the in_out flag */ if (in_out_flag == SEP_DRIVER_IN_FLAG) { *lli_array_ptr = lli_array; sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages = num_pages; @@ -1577,7 +1577,7 @@ static int sep_prepare_input_dma_table(struct sep_device *sep, /* * If this is not the last table - - * then allign it to the block size + * then align it to the block size */ if (!last_table_flag) table_data_size = @@ -1974,7 +1974,7 @@ static int sep_prepare_input_output_dma_table(struct sep_device *sep, dev_dbg(&sep->pdev->dev, "SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP is %x\n", SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP); - /* Call the fucntion that creates table from the lli arrays */ + /* Call the function that creates table from the lli arrays */ error = sep_construct_dma_tables_from_lli(sep, lli_in_array, sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages, lli_out_array, @@ -2416,7 +2416,7 @@ end_function: * @cmd: command * @arg: pointer to argument structure * - * Implement the ioctl methods availble on the SEP device. + * Implement the ioctl methods available on the SEP device. */ static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { diff --git a/drivers/staging/sep/sep_driver_config.h b/drivers/staging/sep/sep_driver_config.h index d3b9220f3963..1033425c9c30 100644 --- a/drivers/staging/sep/sep_driver_config.h +++ b/drivers/staging/sep/sep_driver_config.h @@ -65,11 +65,11 @@ #define SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE 16 /* flag that signifies tah the lock is -currently held by the proccess (struct file) */ +currently held by the process (struct file) */ #define SEP_DRIVER_OWN_LOCK_FLAG 1 /* flag that signifies tah the lock is currently NOT -held by the proccess (struct file) */ +held by the process (struct file) */ #define SEP_DRIVER_DISOWN_LOCK_FLAG 0 /* indicates whether driver has mapped/unmapped shared area */ diff --git a/drivers/staging/slicoss/README b/drivers/staging/slicoss/README index 70f49099c065..b83bba19b7f0 100644 --- a/drivers/staging/slicoss/README +++ b/drivers/staging/slicoss/README @@ -33,7 +33,7 @@ TODO: - NAPI? - wasted overhead of extra stats - state variables for things that are - easily availble and shouldn't be kept in card structure, cardnum, ... + easily available and shouldn't be kept in card structure, cardnum, ... slotnumber, events, ... - get rid of slic_spinlock wrapper - volatile == bad design => bad code diff --git a/drivers/staging/sm7xx/smtcfb.c b/drivers/staging/sm7xx/smtcfb.c index d007e4a12c14..78a16a768509 100644 --- a/drivers/staging/sm7xx/smtcfb.c +++ b/drivers/staging/sm7xx/smtcfb.c @@ -965,7 +965,7 @@ static int __devinit smtcfb_pci_probe(struct pci_dev *pdev, goto failed; smtcfb_setmode(sfb); - /* Primary display starting from 0 postion */ + /* Primary display starting from 0 position */ hw.BaseAddressInVRAM = 0; sfb->fb.par = &hw; @@ -1055,7 +1055,7 @@ static int __maybe_unused smtcfb_suspend(struct pci_dev *pdev, pm_message_t msg) pdev->dev.power.power_state = msg; - /* additionaly turn off all function blocks including internal PLLs */ + /* additionally turn off all function blocks including internal PLLs */ smtc_seqw(0x21, 0xff); return 0; diff --git a/drivers/staging/speakup/keyhelp.c b/drivers/staging/speakup/keyhelp.c index 23cf7f44f450..170f38815ffd 100644 --- a/drivers/staging/speakup/keyhelp.c +++ b/drivers/staging/speakup/keyhelp.c @@ -69,7 +69,7 @@ static void build_key_data(void) memset(key_offsets, 0, sizeof(key_offsets)); kp = state_tbl + nstates + 1; while (*kp++) { - /* count occurrances of each function */ + /* count occurrences of each function */ for (i = 0; i < nstates; i++, kp++) { if (!*kp) continue; diff --git a/drivers/staging/speakup/spkguide.txt b/drivers/staging/speakup/spkguide.txt index 24362eb7b8f1..f3210571e396 100644 --- a/drivers/staging/speakup/spkguide.txt +++ b/drivers/staging/speakup/spkguide.txt @@ -1091,7 +1091,7 @@ screen that is constantly changing, such as a clock or status line. There is no way to save these window settings, and you can only have one window defined for each virtual console. There is also no way to have -windows automaticly defined for specific applications. +windows automatically defined for specific applications. In order to define a window, use the review keys to move your reading cursor to the beginning of the area you want to define. Then press diff --git a/drivers/staging/spectra/ffsport.c b/drivers/staging/spectra/ffsport.c index 007b24b54e25..20dae73d3b78 100644 --- a/drivers/staging/spectra/ffsport.c +++ b/drivers/staging/spectra/ffsport.c @@ -38,7 +38,7 @@ * Outputs: Number of Used Bits * 0, if the argument is 0 * Description: Calculate the number of bits used by a given power of 2 number -* Number can be upto 32 bit +* Number can be up to 32 bit *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/ int GLOB_Calc_Used_Bits(u32 n) { @@ -653,7 +653,7 @@ static int SBD_setup_device(struct spectra_nand_dev *dev, int which) } dev->queue->queuedata = dev; - /* As Linux block layer doens't support >4KB hardware sector, */ + /* As Linux block layer does't support >4KB hardware sector, */ /* Here we force report 512 byte hardware sector size to Kernel */ blk_queue_logical_block_size(dev->queue, 512); diff --git a/drivers/staging/spectra/flash.c b/drivers/staging/spectra/flash.c index a2f820025ae4..aead358e5c2a 100644 --- a/drivers/staging/spectra/flash.c +++ b/drivers/staging/spectra/flash.c @@ -965,7 +965,7 @@ static void process_cmd_fail_abort(int *first_failed_cmd, if (0 == *first_failed_cmd) *first_failed_cmd = PendingCMD[idx].SBDCmdIndex; - nand_dbg_print(NAND_DBG_DEBUG, "Uncorrectable error has occured " + nand_dbg_print(NAND_DBG_DEBUG, "Uncorrectable error has occurred " "while executing %u Command %u accesing Block %u\n", (unsigned int)p_BTableChangesDelta->ftl_cmd_cnt, PendingCMD[idx].CMD, @@ -1879,7 +1879,7 @@ static int write_back_to_l2_cache(u8 *buf, u64 logical_addr) } /* - * Seach in the Level2 Cache table to find the cache item. + * Search in the Level2 Cache table to find the cache item. * If find, read the data from the NAND page of L2 Cache, * Otherwise, return FAIL. */ @@ -3989,7 +3989,7 @@ int GLOB_FTL_Block_Erase(u64 blk_addr) * Inputs: index to block that was just incremented and is at the max * Outputs: PASS=0 / FAIL=1 * Description: If any erase counts at MAX, adjusts erase count of every -* block by substracting least worn +* block by subtracting least worn * counter from counter value of every entry in wear table *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/ static int FTL_Adjust_Relative_Erase_Count(u32 Index_of_MAX) diff --git a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c index d55a8e40318b..3e68d58fdffd 100644 --- a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c +++ b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c @@ -71,7 +71,7 @@ #define SYNAPTICS_RMI4_DEVICE_CONTROL_FUNC_NUM (0x01) /** - * struct synaptics_rmi4_fn_desc - contains the funtion descriptor information + * struct synaptics_rmi4_fn_desc - contains the function descriptor information * @query_base_addr: base address for query * @cmd_base_addr: base address for command * @ctrl_base_addr: base address for control @@ -92,7 +92,7 @@ struct synaptics_rmi4_fn_desc { }; /** - * struct synaptics_rmi4_fn - contains the funtion information + * struct synaptics_rmi4_fn - contains the function information * @fn_number: function number * @num_of_data_sources: number of data sources * @num_of_data_points: number of fingers touched @@ -151,7 +151,7 @@ struct synaptics_rmi4_device_info { * @input_dev: pointer for input device * @i2c_client: pointer for i2c client * @board: constant pointer for touch platform data - * @fn_list_mutex: mutex for funtion list + * @fn_list_mutex: mutex for function list * @rmi4_page_mutex: mutex for rmi4 page * @current_page: variable for integer * @number_of_interrupt_register: interrupt registers count @@ -278,7 +278,7 @@ static int synaptics_rmi4_i2c_byte_write(struct synaptics_rmi4_data *pdata, txbuf[0] = address & MASK_8BIT; txbuf[1] = data; retval = i2c_master_send(pdata->i2c_client, txbuf, 2); - /* Add in retry on writes only in certian error return values */ + /* Add in retry on writes only in certain error return values */ if (retval != 2) { dev_err(&i2c->dev, "%s:failed:%d\n", __func__, retval); retval = -EIO; @@ -561,7 +561,7 @@ static int synpatics_rmi4_touchpad_detect(struct synaptics_rmi4_data *pdata, } /* * 2D data sources have only 3 bits for the number of fingers - * supported - so the encoding is a bit wierd. + * supported - so the encoding is a bit weird. */ if ((queries[1] & MASK_3BIT) <= 4) /* add 1 since zero based */ @@ -1027,7 +1027,7 @@ err_input: * synaptics_rmi4_remove() - Removes the i2c-client touchscreen driver * @client: i2c client structure pointer * - * This funtion uses to remove the i2c-client + * This function uses to remove the i2c-client * touchscreen driver and returns integer. */ static int __devexit synaptics_rmi4_remove(struct i2c_client *client) @@ -1053,7 +1053,7 @@ static int __devexit synaptics_rmi4_remove(struct i2c_client *client) * synaptics_rmi4_suspend() - suspend the touch screen controller * @dev: pointer to device structure * - * This funtion is used to suspend the + * This function is used to suspend the * touch panel controller and returns integer */ static int synaptics_rmi4_suspend(struct device *dev) @@ -1089,7 +1089,7 @@ static int synaptics_rmi4_suspend(struct device *dev) * synaptics_rmi4_resume() - resume the touch screen controller * @dev: pointer to device structure * - * This funtion is used to resume the touch panel + * This function is used to resume the touch panel * controller and returns integer. */ static int synaptics_rmi4_resume(struct device *dev) @@ -1148,7 +1148,7 @@ static struct i2c_driver synaptics_rmi4_driver = { /** * synaptics_rmi4_init() - Initialize the touchscreen driver * - * This funtion uses to initializes the synaptics + * This function uses to initializes the synaptics * touchscreen driver and returns integer. */ static int __init synaptics_rmi4_init(void) @@ -1158,7 +1158,7 @@ static int __init synaptics_rmi4_init(void) /** * synaptics_rmi4_exit() - De-initialize the touchscreen driver * - * This funtion uses to de-initialize the synaptics + * This function uses to de-initialize the synaptics * touchscreen driver and returns none. */ static void __exit synaptics_rmi4_exit(void) diff --git a/drivers/staging/tidspbridge/core/_tiomap.h b/drivers/staging/tidspbridge/core/_tiomap.h index 1e0273e50d2b..7cb587103975 100644 --- a/drivers/staging/tidspbridge/core/_tiomap.h +++ b/drivers/staging/tidspbridge/core/_tiomap.h @@ -366,7 +366,7 @@ extern s32 dsp_debug; * ======== sm_interrupt_dsp ======== * Purpose: * Set interrupt value & send an interrupt to the DSP processor(s). - * This is typicaly used when mailbox interrupt mechanisms allow data + * This is typically used when mailbox interrupt mechanisms allow data * to be associated with interrupt such as for OMAP's CMD/DATA regs. * Parameters: * dev_context: Handle to Bridge driver defined device info. diff --git a/drivers/staging/tidspbridge/core/chnl_sm.c b/drivers/staging/tidspbridge/core/chnl_sm.c index 8381130e1460..6d66e7d0fba8 100644 --- a/drivers/staging/tidspbridge/core/chnl_sm.c +++ b/drivers/staging/tidspbridge/core/chnl_sm.c @@ -578,7 +578,7 @@ int bridge_chnl_get_ioc(struct chnl_object *chnl_obj, u32 timeout, } else if (stat_sync == -EPERM) { /* This can occur when the user mode thread is * aborted (^C), or when _VWIN32_WaitSingleObject() - * fails due to unkown causes. */ + * fails due to unknown causes. */ /* Even though Wait failed, there may be something in * the Q: */ if (list_empty(&pchnl->io_completions)) { diff --git a/drivers/staging/tidspbridge/dynload/cload.c b/drivers/staging/tidspbridge/dynload/cload.c index 390040984e03..5cecd237e3f6 100644 --- a/drivers/staging/tidspbridge/dynload/cload.c +++ b/drivers/staging/tidspbridge/dynload/cload.c @@ -718,7 +718,7 @@ static void dload_symbols(struct dload_state *dlthis) * as a temporary for .dllview record construction. * Allocate storage for the whole table. Add 1 to the section count * in case a trampoline section is auto-generated as well as the - * size of the trampoline section name so DLLView doens't get lost. + * size of the trampoline section name so DLLView does't get lost. */ siz = sym_count * sizeof(struct local_symbol); diff --git a/drivers/staging/tidspbridge/hw/hw_mmu.c b/drivers/staging/tidspbridge/hw/hw_mmu.c index 014f5d5293ae..c214df9b205e 100644 --- a/drivers/staging/tidspbridge/hw/hw_mmu.c +++ b/drivers/staging/tidspbridge/hw/hw_mmu.c @@ -59,7 +59,7 @@ enum hw_mmu_page_size_t { * RETURNS: * * Type : hw_status - * Description : 0 -- No errors occured + * Description : 0 -- No errors occurred * RET_BAD_NULL_PARAM -- A Pointer * Paramater was set to NULL * @@ -102,7 +102,7 @@ static hw_status mmu_flush_entry(const void __iomem *base_address); * RETURNS: * * Type : hw_status - * Description : 0 -- No errors occured + * Description : 0 -- No errors occurred * RET_BAD_NULL_PARAM -- A Pointer Paramater * was set to NULL * RET_PARAM_OUT_OF_RANGE -- Input Parameter out @@ -147,7 +147,7 @@ static hw_status mmu_set_cam_entry(const void __iomem *base_address, * RETURNS: * * Type : hw_status - * Description : 0 -- No errors occured + * Description : 0 -- No errors occurred * RET_BAD_NULL_PARAM -- A Pointer Paramater * was set to NULL * RET_PARAM_OUT_OF_RANGE -- Input Parameter diff --git a/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h b/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h index d60e25258020..6e7ab4fd8c39 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h +++ b/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h @@ -144,7 +144,7 @@ struct chnl_object { s8 chnl_mode; /* Chnl mode and attributes */ /* Chnl I/O completion event (user mode) */ void *user_event; - /* Abstract syncronization object */ + /* Abstract synchronization object */ struct sync_object *sync_event; u32 process; /* Process which created this channel */ u32 cb_arg; /* Argument to use with callback */ @@ -156,7 +156,7 @@ struct chnl_object { struct list_head io_completions; struct list_head free_packets_list; /* List of free Irps */ struct ntfy_object *ntfy_obj; - u32 bytes_moved; /* Total number of bytes transfered */ + u32 bytes_moved; /* Total number of bytes transferred */ /* For DSP-DMA */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/clk.h b/drivers/staging/tidspbridge/include/dspbridge/clk.h index b23950323421..685341c50693 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/clk.h +++ b/drivers/staging/tidspbridge/include/dspbridge/clk.h @@ -55,7 +55,7 @@ extern void dsp_clk_exit(void); * Initializes private state of CLK module. * Parameters: * Returns: - * TRUE if initialized; FALSE if error occured. + * TRUE if initialized; FALSE if error occurred. * Requires: * Ensures: * CLK initialized. @@ -71,7 +71,7 @@ void dsp_gpt_wait_overflow(short int clk_id, unsigned int load); * Parameters: * Returns: * 0: Success. - * -EPERM: Error occured while enabling the clock. + * -EPERM: Error occurred while enabling the clock. * Requires: * Ensures: */ @@ -86,7 +86,7 @@ u32 dsp_clock_enable_all(u32 dsp_per_clocks); * Parameters: * Returns: * 0: Success. - * -EPERM: Error occured while disabling the clock. + * -EPERM: Error occurred while disabling the clock. * Requires: * Ensures: */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/cmm.h b/drivers/staging/tidspbridge/include/dspbridge/cmm.h index 27a21b5f3ff0..aff22051cf57 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/cmm.h +++ b/drivers/staging/tidspbridge/include/dspbridge/cmm.h @@ -190,7 +190,7 @@ extern int cmm_get_info(struct cmm_object *hcmm_mgr, * Initializes private state of CMM module. * Parameters: * Returns: - * TRUE if initialized; FALSE if error occured. + * TRUE if initialized; FALSE if error occurred. * Requires: * Ensures: * CMM initialized. diff --git a/drivers/staging/tidspbridge/include/dspbridge/cod.h b/drivers/staging/tidspbridge/include/dspbridge/cod.h index 53bd4bb8b0bb..cb684c11b302 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/cod.h +++ b/drivers/staging/tidspbridge/include/dspbridge/cod.h @@ -249,7 +249,7 @@ extern int cod_get_sym_value(struct cod_manager *cod_mgr_obj, * Parameters: * None. * Returns: - * TRUE if initialized; FALSE if error occured. + * TRUE if initialized; FALSE if error occurred. * Requires: * Ensures: * A requirement for each of the other public COD functions. diff --git a/drivers/staging/tidspbridge/include/dspbridge/dev.h b/drivers/staging/tidspbridge/include/dspbridge/dev.h index f41e4783157f..f92b4be0b413 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dev.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dev.h @@ -497,7 +497,7 @@ extern void dev_exit(void); * Initialize DEV's private state, keeping a reference count on each call. * Parameters: * Returns: - * TRUE if initialized; FALSE if error occured. + * TRUE if initialized; FALSE if error occurred. * Requires: * Ensures: * TRUE: A requirement for the other public DEV functions. diff --git a/drivers/staging/tidspbridge/include/dspbridge/drv.h b/drivers/staging/tidspbridge/include/dspbridge/drv.h index 25ef1a2c58eb..9cdbd955dce9 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/drv.h +++ b/drivers/staging/tidspbridge/include/dspbridge/drv.h @@ -154,7 +154,7 @@ struct process_context { * Parameters: * drv_obj: Location to store created DRV Object handle. * Returns: - * 0: Sucess + * 0: Success * -ENOMEM: Failed in Memory allocation * -EPERM: General Failure * Requires: @@ -170,7 +170,7 @@ struct process_context { * There is one Driver Object for the Driver representing * the driver itself. It contains the list of device * Objects and the list of Device Extensions in the system. - * Also it can hold other neccessary + * Also it can hold other necessary * information in its storage area. */ extern int drv_create(struct drv_object **drv_obj); @@ -180,7 +180,7 @@ extern int drv_create(struct drv_object **drv_obj); * Purpose: * destroys the Dev Object list, DrvExt list * and destroy the DRV object - * Called upon driver unLoading.or unsuccesful loading of the driver. + * Called upon driver unLoading.or unsuccessful loading of the driver. * Parameters: * driver_obj: Handle to Driver object . * Returns: diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h b/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h index c2ba26c09308..ed32bf383132 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h @@ -52,7 +52,7 @@ struct bridge_dev_context; * dev_ctxt: Handle to Bridge driver defined device context. * Returns: * 0: Success. - * -ETIMEDOUT: Timeout occured waiting for a response from hardware. + * -ETIMEDOUT: Timeout occurred waiting for a response from hardware. * -EPERM: Other, unspecified error. * Requires: * dev_ctxt != NULL @@ -91,7 +91,7 @@ typedef int(*fxn_brd_setstate) (struct bridge_dev_context * dsp_addr: DSP address at which to start execution. * Returns: * 0: Success. - * -ETIMEDOUT: Timeout occured waiting for a response from hardware. + * -ETIMEDOUT: Timeout occurred waiting for a response from hardware. * -EPERM: Other, unspecified error. * Requires: * dev_ctxt != NULL @@ -142,7 +142,7 @@ typedef int(*fxn_brd_memcopy) (struct bridge_dev_context * mem_type: Memory space on DSP to which to transfer. * Returns: * 0: Success. - * -ETIMEDOUT: Timeout occured waiting for a response from hardware. + * -ETIMEDOUT: Timeout occurred waiting for a response from hardware. * -EPERM: Other, unspecified error. * Requires: * dev_ctxt != NULL; @@ -205,7 +205,7 @@ typedef int(*fxn_brd_memunmap) (struct bridge_dev_context * dev_ctxt: Handle to Bridge driver defined device context. * Returns: * 0: Success. - * -ETIMEDOUT: Timeout occured waiting for a response from hardware. + * -ETIMEDOUT: Timeout occurred waiting for a response from hardware. * -EPERM: Other, unspecified error. * Requires: * dev_ctxt != NULL @@ -248,7 +248,7 @@ typedef int(*fxn_brd_status) (struct bridge_dev_context *dev_ctxt, * mem_type: Memory space on DSP from which to transfer. * Returns: * 0: Success. - * -ETIMEDOUT: Timeout occured waiting for a response from hardware. + * -ETIMEDOUT: Timeout occurred waiting for a response from hardware. * -EPERM: Other, unspecified error. * Requires: * dev_ctxt != NULL; @@ -274,7 +274,7 @@ typedef int(*fxn_brd_read) (struct bridge_dev_context *dev_ctxt, * mem_type: Memory space on DSP to which to transfer. * Returns: * 0: Success. - * -ETIMEDOUT: Timeout occured waiting for a response from hardware. + * -ETIMEDOUT: Timeout occurred waiting for a response from hardware. * -EPERM: Other, unspecified error. * Requires: * dev_ctxt != NULL; @@ -601,7 +601,7 @@ typedef int(*fxn_chnl_getmgrinfo) (struct chnl_mgr * Returns: * 0: Success; * -EFAULT: Invalid chnl_obj. - * -ETIMEDOUT: Timeout occured before channel could be idled. + * -ETIMEDOUT: Timeout occurred before channel could be idled. * Requires: * Ensures: */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/mgr.h b/drivers/staging/tidspbridge/include/dspbridge/mgr.h index e506c4d49472..47b0318430e1 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/mgr.h +++ b/drivers/staging/tidspbridge/include/dspbridge/mgr.h @@ -176,7 +176,7 @@ extern void mgr_exit(void); * mgr_handle: Handle to the Manager Object * dcd_handle: Ptr to receive the DCD Handle. * Returns: - * 0: Sucess + * 0: Success * -EPERM: Failure to get the Handle * Requires: * MGR is initialized. @@ -195,7 +195,7 @@ extern int mgr_get_dcd_handle(struct mgr_object * call. Initializes the DCD. * Parameters: * Returns: - * TRUE if initialized; FALSE if error occured. + * TRUE if initialized; FALSE if error occurred. * Requires: * Ensures: * TRUE: A requirement for the other public MGR functions. diff --git a/drivers/staging/tidspbridge/include/dspbridge/node.h b/drivers/staging/tidspbridge/include/dspbridge/node.h index 53da0ef483c8..16371d818e3d 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/node.h +++ b/drivers/staging/tidspbridge/include/dspbridge/node.h @@ -44,7 +44,7 @@ * -ESPIPE: iAlg functions not found for a DAIS node. * -EDOM: attr_in != NULL and attr_in->prio out of * range. - * -EPERM: A failure occured, unable to allocate node. + * -EPERM: A failure occurred, unable to allocate node. * -EBADR: Proccessor is not in the running state. * Requires: * node_init(void) called. diff --git a/drivers/staging/tidspbridge/include/dspbridge/proc.h b/drivers/staging/tidspbridge/include/dspbridge/proc.h index 5e09fd165d9d..f00dffd51989 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/proc.h +++ b/drivers/staging/tidspbridge/include/dspbridge/proc.h @@ -89,7 +89,7 @@ extern int proc_auto_start(struct cfg_devnode *dev_node_obj, * Returns: * 0 : SUCCESS * -EFAULT : Invalid processor handle. - * -ETIME: A Timeout Occured before the Control information + * -ETIME: A Timeout Occurred before the Control information * could be sent. * -EPERM : General Failure. * Requires: @@ -169,7 +169,7 @@ extern int proc_enum_nodes(void *hprocessor, * 0 : Success. * -EFAULT : Invalid processor handle. * -EBADR: The processor is not in the PROC_RUNNING state. - * -ETIME: A timeout occured before the DSP responded to the + * -ETIME: A timeout occurred before the DSP responded to the * querry. * -EPERM : Unable to get Resource Information * Requires: @@ -229,7 +229,7 @@ extern int proc_get_dev_object(void *hprocessor, * call. * Parameters: * Returns: - * TRUE if initialized; FALSE if error occured. + * TRUE if initialized; FALSE if error occurred. * Requires: * Ensures: * TRUE: A requirement for the other public PROC functions. diff --git a/drivers/staging/tidspbridge/include/dspbridge/pwr.h b/drivers/staging/tidspbridge/include/dspbridge/pwr.h index 5e3ab2123aaa..0fb066488da9 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/pwr.h +++ b/drivers/staging/tidspbridge/include/dspbridge/pwr.h @@ -46,7 +46,7 @@ * 0: Success. * 0: Success, but the DSP was already asleep. * -EINVAL: The specified sleep_code is not supported. - * -ETIME: A timeout occured while waiting for DSP sleep + * -ETIME: A timeout occurred while waiting for DSP sleep * confirmation. * -EPERM: General failure, unable to send sleep command to * the DSP. @@ -67,7 +67,7 @@ extern int pwr_sleep_dsp(const u32 sleep_code, const u32 timeout); * Returns: * 0: Success. * 0: Success, but the DSP was already awake. - * -ETIME: A timeout occured while waiting for wake + * -ETIME: A timeout occurred while waiting for wake * confirmation. * -EPERM: General failure, unable to send wake command to * the DSP. @@ -85,7 +85,7 @@ extern int pwr_wake_dsp(const u32 timeout); * Returns: * 0: Success. * 0: Success, but the DSP was already awake. - * -ETIME: A timeout occured while waiting for wake + * -ETIME: A timeout occurred while waiting for wake * confirmation. * -EPERM: General failure, unable to send wake command to * the DSP. @@ -103,7 +103,7 @@ extern int pwr_pm_pre_scale(u16 voltage_domain, u32 level); * Returns: * 0: Success. * 0: Success, but the DSP was already awake. - * -ETIME: A timeout occured while waiting for wake + * -ETIME: A timeout occurred while waiting for wake * confirmation. * -EPERM: General failure, unable to send wake command to * the DSP. diff --git a/drivers/staging/tidspbridge/pmgr/dev.c b/drivers/staging/tidspbridge/pmgr/dev.c index 9a38d86a84a0..522810bc7427 100644 --- a/drivers/staging/tidspbridge/pmgr/dev.c +++ b/drivers/staging/tidspbridge/pmgr/dev.c @@ -787,7 +787,7 @@ int dev_notify_clients(struct dev_object *dev_obj, u32 ret) /* * FIXME: this code needs struct proc_object to have a list_head - * at the begining. If not, this can go horribly wrong. + * at the beginning. If not, this can go horribly wrong. */ list_for_each(curr, &dev_obj->proc_list) proc_notify_clients((void *)curr, ret); @@ -810,7 +810,7 @@ int dev_remove_device(struct cfg_devnode *dev_node_obj) if (!dev_node_obj) status = -EFAULT; - /* Retrieve the device object handle originaly stored with + /* Retrieve the device object handle originally stored with * the dev_node: */ if (!status) { /* check the device string and then store dev object */ @@ -986,7 +986,7 @@ int dev_insert_proc_object(struct dev_object *hdev_obj, /* Add DevObject to tail. */ /* * FIXME: this code needs struct proc_object to have a list_head - * at the begining. If not, this can go horribly wrong. + * at the beginning. If not, this can go horribly wrong. */ list_add_tail((struct list_head *)proc_obj, &dev_obj->proc_list); diff --git a/drivers/staging/tidspbridge/rmgr/drv.c b/drivers/staging/tidspbridge/rmgr/drv.c index 8c88583364eb..db8215f540d8 100644 --- a/drivers/staging/tidspbridge/rmgr/drv.c +++ b/drivers/staging/tidspbridge/rmgr/drv.c @@ -609,7 +609,7 @@ int drv_request_resources(u32 dw_context, u32 *dev_node_strg) DBC_REQUIRE(dev_node_strg != NULL); /* - * Allocate memory to hold the string. This will live untill + * Allocate memory to hold the string. This will live until * it is freed in the Release resources. Update the driver object * list. */ diff --git a/drivers/staging/tidspbridge/rmgr/nldr.c b/drivers/staging/tidspbridge/rmgr/nldr.c index fb5c2ba01d47..0e70cba15ebc 100644 --- a/drivers/staging/tidspbridge/rmgr/nldr.c +++ b/drivers/staging/tidspbridge/rmgr/nldr.c @@ -57,9 +57,9 @@ * uuuuuuuu|fueeeeee|fudddddd|fucccccc| * where * u = unused - * cccccc = prefered/required dynamic mem segid for create phase data/code - * dddddd = prefered/required dynamic mem segid for delete phase data/code - * eeeeee = prefered/req. dynamic mem segid for execute phase data/code + * cccccc = preferred/required dynamic mem segid for create phase data/code + * dddddd = preferred/required dynamic mem segid for delete phase data/code + * eeeeee = preferred/req. dynamic mem segid for execute phase data/code * f = flag indicating if memory is preferred or required: * f = 1 if required, f = 0 if preferred. * diff --git a/drivers/staging/tidspbridge/rmgr/proc.c b/drivers/staging/tidspbridge/rmgr/proc.c index c4e5c4e0d71c..242dd1399996 100644 --- a/drivers/staging/tidspbridge/rmgr/proc.c +++ b/drivers/staging/tidspbridge/rmgr/proc.c @@ -1670,7 +1670,7 @@ int proc_stop(void *hprocessor) if (!status) { dev_dbg(bridge, "%s: processor in standby mode\n", __func__); p_proc_object->proc_state = PROC_STOPPED; - /* Destory the Node Manager, msg_ctrl Manager */ + /* Destroy the Node Manager, msg_ctrl Manager */ if (!(dev_destroy2(p_proc_object->dev_obj))) { /* Destroy the msg_ctrl by calling msg_delete */ dev_get_msg_mgr(p_proc_object->dev_obj, &hmsg_mgr); @@ -1827,7 +1827,7 @@ static int proc_monitor(struct proc_object *proc_obj) /* This is needed only when Device is loaded when it is * already 'ACTIVE' */ - /* Destory the Node Manager, msg_ctrl Manager */ + /* Destroy the Node Manager, msg_ctrl Manager */ if (!dev_destroy2(proc_obj->dev_obj)) { /* Destroy the msg_ctrl by calling msg_delete */ dev_get_msg_mgr(proc_obj->dev_obj, &hmsg_mgr); diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c index c80a316d9d8f..17db6684abbe 100644 --- a/drivers/staging/tm6000/tm6000-video.c +++ b/drivers/staging/tm6000/tm6000-video.c @@ -182,7 +182,7 @@ static inline void get_next_buf(struct tm6000_dmaqueue *dma_q, if (!buf) return; - /* Cleans up buffer - Usefull for testing for frame/URB loss */ + /* Cleans up buffer - Useful for testing for frame/URB loss */ outp = videobuf_to_vmalloc(&(*buf)->vb); return; diff --git a/drivers/staging/tty/cd1865.h b/drivers/staging/tty/cd1865.h index 9940966e7a1d..8c2ad654b79d 100644 --- a/drivers/staging/tty/cd1865.h +++ b/drivers/staging/tty/cd1865.h @@ -9,7 +9,7 @@ * Please DO contact io8-linux@specialix.co.uk if you require * support. * - * This driver was developped in the BitWizard linux device + * This driver was developed in the BitWizard linux device * driver service. If you require a linux device driver for your * product, please contact devices@BitWizard.nl for a quote. * diff --git a/drivers/staging/tty/epca.c b/drivers/staging/tty/epca.c index 7ad3638967ae..7f1369e5b418 100644 --- a/drivers/staging/tty/epca.c +++ b/drivers/staging/tty/epca.c @@ -7,7 +7,7 @@ ** This driver is no longer supported by Digi ** Much of this design and code came from epca.c which was - copyright (C) 1994, 1995 Troy De Jongh, and subsquently + copyright (C) 1994, 1995 Troy De Jongh, and subsequently modified by David Nugent, Christoph Lameter, Mike McLagan. This program is free software; you can redistribute it and/or modify @@ -471,7 +471,7 @@ static void shutdown(struct channel *ch, struct tty_struct *tty) memoff(ch); /* - * The channel has officialy been closed. The next time it is opened it + * The channel has officially been closed. The next time it is opened it * will have to reinitialized. Set a flag to indicate this. */ /* Prevent future Digi programmed interrupts from coming active */ @@ -975,7 +975,7 @@ static int __init pc_init(void) /* * Note : If lilo was used to configure the driver and the ignore - * epcaconfig option was choosen (digiepca=2) then nbdevs and num_cards + * epcaconfig option was chosen (digiepca=2) then nbdevs and num_cards * will equal 0 at this point. This is okay; PCI cards will still be * picked up if detected. */ @@ -1230,14 +1230,14 @@ static void post_fep_init(unsigned int crd) memaddr = bd->re_map_membase; /* - * The below assignment will set bc to point at the BEGINING of the + * The below assignment will set bc to point at the BEGINNING of the * cards channel structures. For 1 card there will be between 8 and 64 * of these structures. */ bc = memaddr + CHANSTRUCT; /* - * The below assignment will set gd to point at the BEGINING of global + * The below assignment will set gd to point at the BEGINNING of global * memory address 0xc00. The first data in that global memory actually * starts at address 0xc1a. The command in pointer begins at 0xd10. */ @@ -1492,7 +1492,7 @@ static void doevent(int crd) /* * The two assignments below get the current modem status * (mstat) and the previous modem status (lstat). These are - * useful becuase an event could signal a change in modem + * useful because an event could signal a change in modem * signals itself. */ mstat = readb(eventbuf + 2); @@ -1897,7 +1897,7 @@ static void receive_data(struct channel *ch, struct tty_struct *tty) /* * Even if head has wrapped around only report the amount of * data to be equal to the size - tail. Remember memcpy can't - * automaticly wrap around the receive buffer. + * automatically wrap around the receive buffer. */ dataToRead = (wrapgap < bytesAvailable) ? wrapgap : bytesAvailable; @@ -2543,7 +2543,7 @@ static void __init epca_setup(char *str, int *ints) break; /* * If the index incremented above refers to a - * legitamate board type set it here. + * legitimate board type set it here. */ if (index < EPCA_NUM_TYPES) board.type = loop; diff --git a/drivers/staging/tty/ip2/i2hw.h b/drivers/staging/tty/ip2/i2hw.h index c0ba6c05f0cd..8df2f487217a 100644 --- a/drivers/staging/tty/ip2/i2hw.h +++ b/drivers/staging/tty/ip2/i2hw.h @@ -335,7 +335,7 @@ be off by a factor of five. The important point is that the first command reset in fact generates a reset pulse on the board. This pulse is guaranteed to last less than 10 milliseconds. The additional delay ensures the 1400 has had the chance to respond sufficiently to the first reset. Why not a longer delay? Much -more than 50 milliseconds gets to be noticable, but the board would still work. +more than 50 milliseconds gets to be noticeable, but the board would still work. Once all 16 bytes of the Power-on Reset Message have been read, the bootstrap firmware is ready to receive loadware. @@ -399,7 +399,7 @@ typedef union _porStr // "por" stands for Power On Reset // expandable products must report a MAP of available channels. Since // each UART supports four ports, we represent each UART found by a // single bit. Using two bytes to supply the mapping information we - // report the presense or absense of up to 16 UARTS, or 64 ports in + // report the presence or absence of up to 16 UARTS, or 64 ports in // steps of 4 ports. For -IIEX products, the ports are numbered // starting at the box closest to the controller in the "chain". diff --git a/drivers/staging/tty/ip2/i2lib.c b/drivers/staging/tty/ip2/i2lib.c index 0d10b89218ed..13a3caba85f2 100644 --- a/drivers/staging/tty/ip2/i2lib.c +++ b/drivers/staging/tty/ip2/i2lib.c @@ -821,7 +821,7 @@ i2GetStatus(i2ChanStrPtr pCh, int resetBits) // // Description: // Strips data from the input buffer and writes it to pDest. If there is a -// collosal blunder, (invalid structure pointers or the like), returns -1. +// colossal blunder, (invalid structure pointers or the like), returns -1. // Otherwise, returns the number of bytes read. //****************************************************************************** static int @@ -909,7 +909,7 @@ i2Input_exit: // Returns: Number of bytes stripped, or -1 for error // // Description: -// Strips any data from the input buffer. If there is a collosal blunder, +// Strips any data from the input buffer. If there is a colossal blunder, // (invalid structure pointers or the like), returns -1. Otherwise, returns the // number of bytes stripped. //****************************************************************************** @@ -963,7 +963,7 @@ i2InputFlush(i2ChanStrPtr pCh) // Returns: Number of bytes available, or -1 for error // // Description: -// If there is a collosal blunder, (invalid structure pointers or the like), +// If there is a colossal blunder, (invalid structure pointers or the like), // returns -1. Otherwise, returns the number of bytes stripped. Otherwise, // returns the number of bytes available in the buffer. //****************************************************************************** @@ -1001,7 +1001,7 @@ i2InputAvailable(i2ChanStrPtr pCh) // // Description: // Queues the data at pSource to be sent as data packets to the board. If there -// is a collosal blunder, (invalid structure pointers or the like), returns -1. +// is a colossal blunder, (invalid structure pointers or the like), returns -1. // Otherwise, returns the number of bytes written. What if there is not enough // room for all the data? If pCh->channelOptions & CO_NBLOCK_WRITE is set, then // we transfer as many characters as we can now, then return. If this bit is diff --git a/drivers/staging/tty/ip2/ip2main.c b/drivers/staging/tty/ip2/ip2main.c index ea7a8fb08283..ba074fbb4ce2 100644 --- a/drivers/staging/tty/ip2/ip2main.c +++ b/drivers/staging/tty/ip2/ip2main.c @@ -1824,7 +1824,7 @@ ip2_flush_chars( PTTY tty ) // ip2trace (CHANN, ITRC_PUTC, 10, 1, strip ); // - // We may need to restart i2Output if it does not fullfill this request + // We may need to restart i2Output if it does not fulfill this request // strip = i2Output( pCh, pCh->Pbuf, pCh->Pbuf_stuff); if ( strip != pCh->Pbuf_stuff ) { diff --git a/drivers/staging/tty/specialix.c b/drivers/staging/tty/specialix.c index 17a1be536a46..cb24c6d999db 100644 --- a/drivers/staging/tty/specialix.c +++ b/drivers/staging/tty/specialix.c @@ -9,7 +9,7 @@ * support. But please read the documentation (specialix.txt) * first. * - * This driver was developped in the BitWizard linux device + * This driver was developed in the BitWizard linux device * driver service. If you require a linux device driver for your * product, please contact devices@BitWizard.nl for a quote. * @@ -978,7 +978,7 @@ static void sx_change_speed(struct specialix_board *bp, spin_lock_irqsave(&bp->lock, flags); sx_out(bp, CD186x_CAR, port_No(port)); - /* The Specialix board doens't implement the RTS lines. + /* The Specialix board does't implement the RTS lines. They are used to set the IRQ level. Don't touch them. */ if (sx_crtscts(tty)) port->MSVR = MSVR_DTR | (sx_in(bp, CD186x_MSVR) & MSVR_RTS); diff --git a/drivers/staging/tty/specialix_io8.h b/drivers/staging/tty/specialix_io8.h index c63005274d9b..1215d7e2cb37 100644 --- a/drivers/staging/tty/specialix_io8.h +++ b/drivers/staging/tty/specialix_io8.h @@ -10,7 +10,7 @@ * Please DO contact io8-linux@specialix.co.uk if you require * support. * - * This driver was developped in the BitWizard linux device + * This driver was developed in the BitWizard linux device * driver service. If you require a linux device driver for your * product, please contact devices@BitWizard.nl for a quote. * @@ -79,7 +79,7 @@ more than a few PCI versions of the card. */ #define SPECIALIX_MAGIC 0x0907 -#define SX_CCR_TIMEOUT 10000 /* CCR timeout. You may need to wait upto +#define SX_CCR_TIMEOUT 10000 /* CCR timeout. You may need to wait up to 10 milliseconds before the internal processor is available again after you give it a command */ diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c index e23484998598..0f02a4b12ae4 100644 --- a/drivers/staging/usbip/vhci_hcd.c +++ b/drivers/staging/usbip/vhci_hcd.c @@ -194,7 +194,7 @@ void rh_port_disconnect(int rhport) * * So, the maximum number of ports is 31 ( port 0 to port 30) ? * - * The return value is the actual transfered length in byte. If nothing has + * The return value is the actual transferred length in byte. If nothing has * been changed, return 0. In the case that the number of ports is less than or * equal to 6 (VHCI_NPORTS==7), return 1. * diff --git a/drivers/staging/vme/bridges/vme_ca91cx42.c b/drivers/staging/vme/bridges/vme_ca91cx42.c index d4a48c4e59c2..a4007287ef47 100644 --- a/drivers/staging/vme/bridges/vme_ca91cx42.c +++ b/drivers/staging/vme/bridges/vme_ca91cx42.c @@ -621,7 +621,7 @@ static int ca91cx42_master_set(struct vme_master_resource *image, int enabled, /* * Let's allocate the resource here rather than further up the stack as - * it avoids pushing loads of bus dependant stuff up the stack + * it avoids pushing loads of bus dependent stuff up the stack */ retval = ca91cx42_alloc_resource(image, size); if (retval) { @@ -1052,7 +1052,7 @@ static int ca91cx42_dma_list_add(struct vme_dma_list *list, pci_attr = dest->private; } - /* Check we can do fullfill required attributes */ + /* Check we can do fulfill required attributes */ if ((vme_attr->aspace & ~(VME_A16 | VME_A24 | VME_A32 | VME_USER1 | VME_USER2)) != 0) { @@ -1069,7 +1069,7 @@ static int ca91cx42_dma_list_add(struct vme_dma_list *list, goto err_cycle; } - /* Check to see if we can fullfill source and destination */ + /* Check to see if we can fulfill source and destination */ if (!(((src->type == VME_DMA_PCI) && (dest->type == VME_DMA_VME)) || ((src->type == VME_DMA_VME) && (dest->type == VME_DMA_PCI)))) { diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c index b00a53e793e7..106aa9daff48 100644 --- a/drivers/staging/vme/bridges/vme_tsi148.c +++ b/drivers/staging/vme/bridges/vme_tsi148.c @@ -928,7 +928,7 @@ static int tsi148_master_set(struct vme_master_resource *image, int enabled, spin_lock(&image->lock); /* Let's allocate the resource here rather than further up the stack as - * it avoids pushing loads of bus dependant stuff up the stack. If size + * it avoids pushing loads of bus dependent stuff up the stack. If size * is zero, any existing resource will be freed. */ retval = tsi148_alloc_resource(image, size); @@ -1320,7 +1320,7 @@ static ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf, /* * Writes are posted. We need to do a read on the VME bus to flush out - * all of the writes before we check for errors. We can't guarentee + * all of the writes before we check for errors. We can't guarantee * that reading the data we have just written is safe. It is believed * that there isn't any read, write re-ordering, so we can read any * location in VME space, so lets read the Device ID from the tsi148's diff --git a/drivers/staging/vme/bridges/vme_tsi148.h b/drivers/staging/vme/bridges/vme_tsi148.h index 9f97fa8084e8..a3ac2fe98816 100644 --- a/drivers/staging/vme/bridges/vme_tsi148.h +++ b/drivers/staging/vme/bridges/vme_tsi148.h @@ -212,7 +212,7 @@ static const int TSI148_LCSR_OT[8] = { TSI148_LCSR_OT0, TSI148_LCSR_OT1, #define TSI148_LCSR_OFFSET_OTAT 0x1C /* - * VMEbus interupt ack + * VMEbus interrupt ack * offset 200 */ #define TSI148_LCSR_VIACK1 0x204 @@ -613,7 +613,7 @@ static const int TSI148_GCSR_MBOX[4] = { TSI148_GCSR_MBOX0, /* * PCI-X Status Register (CRG +$054) */ -#define TSI148_PCFS_PCIXSTAT_RSCEM (1<<29) /* Recieved Split Comp Error */ +#define TSI148_PCFS_PCIXSTAT_RSCEM (1<<29) /* Received Split Comp Error */ #define TSI148_PCFS_PCIXSTAT_DMCRS_M (7<<26) /* max Cumulative Read Size */ #define TSI148_PCFS_PCIXSTAT_DMOST_M (7<<23) /* max outstanding Split Trans */ @@ -982,8 +982,8 @@ static const int TSI148_GCSR_MBOX[4] = { TSI148_GCSR_MBOX0, #define TSI148_LCSR_VICR_CNTS_IRQ1 (2<<22) /* IRQ1 to Cntr */ #define TSI148_LCSR_VICR_CNTS_IRQ2 (3<<22) /* IRQ2 to Cntr */ -#define TSI148_LCSR_VICR_EDGIS_M (3<<20) /* Edge interupt MASK */ -#define TSI148_LCSR_VICR_EDGIS_DIS (1<<20) /* Edge interupt Disable */ +#define TSI148_LCSR_VICR_EDGIS_M (3<<20) /* Edge interrupt MASK */ +#define TSI148_LCSR_VICR_EDGIS_DIS (1<<20) /* Edge interrupt Disable */ #define TSI148_LCSR_VICR_EDGIS_IRQ1 (2<<20) /* IRQ1 to Edge */ #define TSI148_LCSR_VICR_EDGIS_IRQ2 (3<<20) /* IRQ2 to Edge */ diff --git a/drivers/staging/vme/vme_api.txt b/drivers/staging/vme/vme_api.txt index a910a0c4388b..4910e92c52af 100644 --- a/drivers/staging/vme/vme_api.txt +++ b/drivers/staging/vme/vme_api.txt @@ -6,7 +6,7 @@ Driver registration As with other subsystems within the Linux kernel, VME device drivers register with the VME subsystem, typically called from the devices init routine. This is -achieved via a call to the follwoing function: +achieved via a call to the following function: int vme_register_driver (struct vme_driver *driver); @@ -108,7 +108,7 @@ Master windows ============== Master windows provide access from the local processor[s] out onto the VME bus. -The number of windows available and the available access modes is dependant on +The number of windows available and the available access modes is dependent on the underlying chipset. A window must be configured before it can be used. @@ -163,7 +163,7 @@ Slave windows Slave windows provide devices on the VME bus access into mapped portions of the local memory. The number of windows available and the access modes that can be -used is dependant on the underlying chipset. A window must be configured before +used is dependent on the underlying chipset. A window must be configured before it can be used. diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index 951a3a8ddcb2..2721e0798496 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -1186,7 +1186,7 @@ CARDbStartMeasure ( wDuration += 1; // 1 TU for channel switching if ((LODWORD(qwStartTSF) == 0) && (HIDWORD(qwStartTSF) == 0)) { - // start imediately by setting start TSF == current TSF + 2 TU + // start immediately by setting start TSF == current TSF + 2 TU LODWORD(qwStartTSF) = LODWORD(qwCurrTSF) + 2048; HIDWORD(qwStartTSF) = HIDWORD(qwCurrTSF); if (LODWORD(qwCurrTSF) > LODWORD(qwStartTSF)) { diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index efaf19bc07b7..ad39c8727e9b 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -137,7 +137,7 @@ DEVICE_PARAM(TxDescriptors1,"Number of transmit descriptors1"); /* IP_byte_align[] is used for IP header unsigned long byte aligned 0: indicate the IP header won't be unsigned long byte aligned.(Default) . 1: indicate the IP header will be unsigned long byte aligned. - In some enviroment, the IP header should be unsigned long byte aligned, + In some environment, the IP header should be unsigned long byte aligned, or the packet will be droped when we receive it. (eg: IPVS) */ DEVICE_PARAM(IP_byte_align,"Enable IP header dword aligned"); diff --git a/drivers/staging/vt6655/wcmd.c b/drivers/staging/vt6655/wcmd.c index abd6745bc3fe..c30170a2bc44 100644 --- a/drivers/staging/vt6655/wcmd.c +++ b/drivers/staging/vt6655/wcmd.c @@ -587,7 +587,7 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED)) { // Call mgr to begin the deauthentication - // reason = (3) beacuse sta has left ESS + // reason = (3) because sta has left ESS if (pMgmt->eCurrState>= WMAC_STATE_AUTH) { vMgrDeAuthenBeginSta((void *)pDevice, pMgmt, pMgmt->abyCurrBSSID, (3), &Status); } diff --git a/drivers/staging/vt6655/wmgr.h b/drivers/staging/vt6655/wmgr.h index 141e80b843af..e3ae562f521a 100644 --- a/drivers/staging/vt6655/wmgr.h +++ b/drivers/staging/vt6655/wmgr.h @@ -220,7 +220,7 @@ typedef enum tagWMAC_POWER_MODE { */ -// Tx Managment Packet descriptor +// Tx Management Packet descriptor typedef struct tagSTxMgmtPacket { PUWLAN_80211HDR p80211Header; @@ -230,7 +230,7 @@ typedef struct tagSTxMgmtPacket { } STxMgmtPacket, *PSTxMgmtPacket; -// Rx Managment Packet descriptor +// Rx Management Packet descriptor typedef struct tagSRxMgmtPacket { PUWLAN_80211HDR p80211Header; diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index 8f18578a5903..5185d61564d7 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -1938,7 +1938,7 @@ s_vGenerateMACHeader ( * Out: * none * - * Return Value: CMD_STATUS_PENDING if MAC Tx resource avaliable; otherwise FALSE + * Return Value: CMD_STATUS_PENDING if MAC Tx resource available; otherwise FALSE * -*/ diff --git a/drivers/staging/vt6656/wcmd.c b/drivers/staging/vt6656/wcmd.c index b83b660b1f0f..019fb52de366 100644 --- a/drivers/staging/vt6656/wcmd.c +++ b/drivers/staging/vt6656/wcmd.c @@ -421,7 +421,7 @@ void vRunCommand(void *hDeviceContext) pMgmt->eScanState = WMAC_IS_SCANNING; pDevice->byScanBBType = pDevice->byBBType; //lucas pDevice->bStopDataPkt = TRUE; - // Turn off RCR_BSSID filter everytime + // Turn off RCR_BSSID filter every time MACvRegBitsOff(pDevice, MAC_REG_RCR, RCR_BSSID); pDevice->byRxMode &= ~RCR_BSSID; @@ -604,7 +604,7 @@ void vRunCommand(void *hDeviceContext) // if Infra mode if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED)) { // Call mgr to begin the deauthentication - // reason = (3) beacuse sta has left ESS + // reason = (3) because sta has left ESS if (pMgmt->eCurrState >= WMAC_STATE_AUTH) { vMgrDeAuthenBeginSta((void *)pDevice, pMgmt, diff --git a/drivers/staging/vt6656/wmgr.h b/drivers/staging/vt6656/wmgr.h index 594f3a89d8a7..13dfb3bf8328 100644 --- a/drivers/staging/vt6656/wmgr.h +++ b/drivers/staging/vt6656/wmgr.h @@ -218,7 +218,7 @@ typedef enum tagWMAC_POWER_MODE { -// Tx Managment Packet descriptor +// Tx Management Packet descriptor typedef struct tagSTxMgmtPacket { PUWLAN_80211HDR p80211Header; @@ -228,7 +228,7 @@ typedef struct tagSTxMgmtPacket { } STxMgmtPacket, *PSTxMgmtPacket; -// Rx Managment Packet descriptor +// Rx Management Packet descriptor typedef struct tagSRxMgmtPacket { PUWLAN_80211HDR p80211Header; diff --git a/drivers/staging/westbridge/astoria/api/src/cyasdma.c b/drivers/staging/westbridge/astoria/api/src/cyasdma.c index 16b8ec124510..c461d4f60bfb 100644 --- a/drivers/staging/westbridge/astoria/api/src/cyasdma.c +++ b/drivers/staging/westbridge/astoria/api/src/cyasdma.c @@ -1082,7 +1082,7 @@ cy_as_dma_received_data(cy_as_device *dev_p, /* * if the data received exceeds the size of the DMA buffer, * clip the data to the size of the buffer. this can lead - * to loosing some data, but is not different than doing + * to losing some data, but is not different than doing * non-packet reads on the other endpoints. */ if (dsize > dma_p->size - dma_p->offset) diff --git a/drivers/staging/westbridge/astoria/api/src/cyaslep2pep.c b/drivers/staging/westbridge/astoria/api/src/cyaslep2pep.c index 60b6f3525332..76821e51b817 100644 --- a/drivers/staging/westbridge/astoria/api/src/cyaslep2pep.c +++ b/drivers/staging/westbridge/astoria/api/src/cyaslep2pep.c @@ -126,7 +126,7 @@ find_endpoint_directions(cy_as_device *dev_p, cy_as_physical_endpoint_state desired; /* - * note, there is no error checking here becuase + * note, there is no error checking here because * ISO error checking happens when the API is called. */ for (i = 0; i < 10; i++) { diff --git a/drivers/staging/westbridge/astoria/api/src/cyaslowlevel.c b/drivers/staging/westbridge/astoria/api/src/cyaslowlevel.c index d43dd858de58..96a86d088305 100644 --- a/drivers/staging/westbridge/astoria/api/src/cyaslowlevel.c +++ b/drivers/staging/westbridge/astoria/api/src/cyaslowlevel.c @@ -432,7 +432,7 @@ cy_as_mail_box_queued_data_handler(cy_as_device *dev_p) * is received. When a complete request is received, the callback * associated with requests on that context is called. When a complete * response is recevied, the callback associated with the request that -* generated the reponse is called. +* generated the response is called. */ void cy_as_mail_box_interrupt_handler(cy_as_device *dev_p) diff --git a/drivers/staging/westbridge/astoria/api/src/cyasmisc.c b/drivers/staging/westbridge/astoria/api/src/cyasmisc.c index 7852410b0a4c..4564fc11df22 100644 --- a/drivers/staging/westbridge/astoria/api/src/cyasmisc.c +++ b/drivers/staging/westbridge/astoria/api/src/cyasmisc.c @@ -428,7 +428,7 @@ my_misc_callback(cy_as_device *dev_p, uint8_t context, if (v & CY_AS_MEM_P0_VM_SET_CFGMODE) cy_as_hal_print_message( "initialization message " - "recieved, but config bit " + "received, but config bit " "still set\n"); v = cy_as_hal_read_register(dev_p->tag, @@ -436,7 +436,7 @@ my_misc_callback(cy_as_device *dev_p, uint8_t context, if ((v & CY_AS_MEM_RST_RSTCMPT) == 0) cy_as_hal_print_message( "initialization message " - "recieved, but reset complete " + "received, but reset complete " "bit still not set\n"); } break; @@ -2381,7 +2381,7 @@ try_wakeup_again: /* * release the west bridge micro-_controller from reset, * so that firmware initialization can complete. the attempt - * to release antioch reset is made upto 8 times. + * to release antioch reset is made up to 8 times. */ v = 0x03; count = 0x08; diff --git a/drivers/staging/westbridge/astoria/api/src/cyasmtp.c b/drivers/staging/westbridge/astoria/api/src/cyasmtp.c index 368984633874..8598364f7ab7 100644 --- a/drivers/staging/westbridge/astoria/api/src/cyasmtp.c +++ b/drivers/staging/westbridge/astoria/api/src/cyasmtp.c @@ -346,7 +346,7 @@ cy_as_mtp_start(cy_as_device_handle handle, dev_p->mtp_event_cb = event_c_b; /* - * we register here becuase the start request may cause + * we register here because the start request may cause * events to occur before the response to the start request. */ cy_as_ll_register_request_callback(dev_p, @@ -424,7 +424,7 @@ my_handle_response_mtp_stop(cy_as_device *dev_p, goto destroy; /* - * we sucessfully shutdown the stack, so decrement + * we successfully shutdown the stack, so decrement * to make the count zero. */ dev_p->mtp_count--; diff --git a/drivers/staging/westbridge/astoria/api/src/cyasstorage.c b/drivers/staging/westbridge/astoria/api/src/cyasstorage.c index 2451404b88d4..7abd6a35e828 100644 --- a/drivers/staging/westbridge/astoria/api/src/cyasstorage.c +++ b/drivers/staging/westbridge/astoria/api/src/cyasstorage.c @@ -1773,7 +1773,7 @@ cy_as_storage_async_oper(cy_as_device *dev_p, cy_as_end_point_number_t ep, if (unit > 255) return CY_AS_ERROR_NO_SUCH_UNIT; - /* We are supposed to return sucess if the number of + /* We are supposed to return success if the number of * blocks is zero */ if (num_blocks == 0) { @@ -1969,7 +1969,7 @@ cy_as_storage_sync_oper(cy_as_device *dev_p, if (cy_as_device_is_usb_async_pending(dev_p, 6)) return CY_AS_ERROR_ASYNC_PENDING; - /* We are supposed to return sucess if the number of + /* We are supposed to return success if the number of * blocks is zero */ if (num_blocks == 0) @@ -3285,7 +3285,7 @@ cy_as_sdio_extended_i_o_async( if (callback == 0) return CY_AS_ERROR_NULL_CALLBACK; - /* We are supposed to return sucess if the number of + /* We are supposed to return success if the number of * blocks is zero */ if (((misc_buf&CY_SDIO_BLOCKMODE) != 0) && (argument == 0)) { diff --git a/drivers/staging/westbridge/astoria/api/src/cyasusb.c b/drivers/staging/westbridge/astoria/api/src/cyasusb.c index 92ea42503bf3..1b55e611191e 100644 --- a/drivers/staging/westbridge/astoria/api/src/cyasusb.c +++ b/drivers/staging/westbridge/astoria/api/src/cyasusb.c @@ -739,7 +739,7 @@ cy_as_usb_start(cy_as_device_handle handle, cy_as_usb_reset_e_p0_state(dev_p); /* - * we register here becuase the start request may cause + * we register here because the start request may cause * events to occur before the response to the start request. */ cy_as_ll_register_request_callback(dev_p, @@ -867,7 +867,7 @@ my_handle_response_usb_stop(cy_as_device *dev_p, goto destroy; /* - * we sucessfully shutdown the stack, so + * we successfully shutdown the stack, so * decrement to make the count zero. */ cy_as_usb_cleanup(dev_p); diff --git a/drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c b/drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c index 21cdb0637beb..3bcedce13f4a 100644 --- a/drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c +++ b/drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c @@ -87,7 +87,7 @@ /* - * For performance reasons, we handle storage endpoint transfers upto 4 KB + * For performance reasons, we handle storage endpoint transfers up to 4 KB * within the HAL itself. */ #define CYASSTORAGE_WRITE_EP_NUM (4) @@ -108,12 +108,12 @@ ((ep) == 6) || ((ep) == 8)) /* - * persistant, stores current GPMC interface cfg mode + * persistent, stores current GPMC interface cfg mode */ static uint8_t pnand_16bit; /* - * keep processing new WB DRQ in ISR untill all handled (performance feature) + * keep processing new WB DRQ in ISR until all handled (performance feature) */ #define PROCESS_MULTIPLE_DRQ_IN_ISR (1) @@ -157,7 +157,7 @@ typedef struct cy_as_hal_endpoint_dma { * dma_xfer_sz - size of the next dma xfer on P port * seg_xfer_cnt - counts xfered bytes for in current sg_list * memory segment - * req_xfer_cnt - total number of bytes transfered so far in + * req_xfer_cnt - total number of bytes transferred so far in * current request * req_length - total request length */ @@ -2160,7 +2160,7 @@ void cy_as_hal_mem_set(void *ptr, uint8_t value, uint32_t cnt) /* * This function is expected to create a sleep channel. * The data structure that represents the sleep channel object - * sleep channel (which is Linux "wait_queue_head_t wq" for this paticular HAL) + * sleep channel (which is Linux "wait_queue_head_t wq" for this particular HAL) * passed as a pointer, and allpocated by the caller * (typically as a local var on the stack) "Create" word should read as * "SleepOn", this func doesn't actually create anything @@ -2364,7 +2364,7 @@ int start_o_m_a_p_kernel(const char *pgm, */ cy_as_hal_gpmc_enable_16bit_bus(cy_true); #else - /* Astoria and GPMC are already in 8 bit mode, jsut initialize PNAND_CFG */ + /* Astoria and GPMC are already in 8 bit mode, just initialize PNAND_CFG */ ast_p_nand_casdi_write(CY_AS_MEM_PNAND_CFG, 0x0000); #endif diff --git a/drivers/staging/westbridge/astoria/arch/arm/plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyashalomap_kernel.h b/drivers/staging/westbridge/astoria/arch/arm/plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyashalomap_kernel.h index 80dd530bc4fd..6426ea61f3d4 100644 --- a/drivers/staging/westbridge/astoria/arch/arm/plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyashalomap_kernel.h +++ b/drivers/staging/westbridge/astoria/arch/arm/plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyashalomap_kernel.h @@ -20,7 +20,7 @@ */ /* - * This file contains the defintion of the hardware abstraction + * This file contains the definition of the hardware abstraction * layer on OMAP3430 talking to the West Bridge Astoria device */ diff --git a/drivers/staging/westbridge/astoria/arch/arm/plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyasmemmap.h b/drivers/staging/westbridge/astoria/arch/arm/plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyasmemmap.h index 3eee192ffe89..46f06ee29357 100644 --- a/drivers/staging/westbridge/astoria/arch/arm/plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyasmemmap.h +++ b/drivers/staging/westbridge/astoria/arch/arm/plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyasmemmap.h @@ -51,7 +51,7 @@ * GPMC_ADDR * [A8:A1]->upD[7:0] * INT# -GPMC_nWP_GPIO_62 - * DACK -N/C not conected + * DACK -N/C not connected * WAKEUP-GPIO_167 * RESET-GPIO_126 * R/B -GPMC_WAIT2_GPIO_64 @@ -108,7 +108,7 @@ * will be monitored * PF_EN_ENGINE - 1- ENABLES ENGINE, but it needs to be started after * that C ctrl reg bit 0 - * PF_FIFO_THRESHOLD - FIFO threshhold in number of BUS(8 or 16) words + * PF_FIFO_THRESHOLD - FIFO threshold in number of BUS(8 or 16) words * PF_WEIGHTED_PRIO - NUM of cycles granted to PFE if RND_ROBIN * prioritization is enabled * PF_ROUND_ROBIN - if enabled, gives priority to other CS, but diff --git a/drivers/staging/westbridge/astoria/block/cyasblkdev_queue.c b/drivers/staging/westbridge/astoria/block/cyasblkdev_queue.c index 0bbb8a3e191d..d1996a27515e 100644 --- a/drivers/staging/westbridge/astoria/block/cyasblkdev_queue.c +++ b/drivers/staging/westbridge/astoria/block/cyasblkdev_queue.c @@ -222,7 +222,7 @@ static int cyasblkdev_queue_thread(void *d) continue; } - /* new req recieved, issue it to the driver */ + /* new req received, issue it to the driver */ set_current_state(TASK_RUNNING); #ifndef WESTBRIDGE_NDEBUG diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasdevice.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasdevice.h index 0c0726b678ad..6452a9070091 100644 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasdevice.h +++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasdevice.h @@ -119,7 +119,7 @@ #define CY_AS_REQUEST_LIST_STATE_QUEUED (0x00) /* The request is sent, waiting for response */ #define CY_AS_REQUEST_LIST_STATE_WAITING (0x01) -/* The response has been received, processing reponse */ +/* The response has been received, processing response */ #define CY_AS_REQUEST_LIST_STATE_RECEIVED (0x02) /* The request/response is being canceled */ #define CY_AS_REQUEST_LIST_STATE_CANCELING (0x03) @@ -517,7 +517,7 @@ typedef struct cy_as_context { cy_as_ll_request_list_node *request_queue_p; /* The list node in the request queue */ cy_as_ll_request_list_node *last_node_p; - /* Index upto which data is stored. */ + /* Index up to which data is stored. */ uint16_t queue_index; /* Index to the next request in the queue. */ uint16_t rqt_index; @@ -768,7 +768,7 @@ struct cy_as_device { uint32_t mtp_count; /* The MTP event callback supplied by the client */ cy_as_mtp_event_callback mtp_event_cb; - /* The current block table to be transfered */ + /* The current block table to be transferred */ cy_as_mtp_block_table *tp_blk_tbl; cy_as_c_b_queue *func_cbs_mtp; diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasdma.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasdma.h index 8dab5e900149..16dc9f96018c 100644 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasdma.h +++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasdma.h @@ -108,7 +108,7 @@ typedef enum cy_as_dma_direction { completes a requested DMA operation. Returns - CY_AS_ERROR_SUCCESS - the module initialized sucessfully + CY_AS_ERROR_SUCCESS - the module initialized successfully CY_AS_ERROR_OUT_OF_MEMORY - memory allocation failed during initialization CY_AS_ERROR_ALREADY_RUNNING - the DMA module was already running @@ -131,7 +131,7 @@ cy_as_dma_start( then freeing the resources associated with each DMA endpoint. Returns - CY_AS_ERROR_SUCCESS - the module shutdown sucessfully + CY_AS_ERROR_SUCCESS - the module shutdown successfully CY_AS_ERROR_NOT_RUNNING - the DMA module was not running See Also @@ -161,7 +161,7 @@ cy_as_dma_stop( Returns CY_AS_ERROR_SUCCESS - the traffic on the endpoint is canceled - sucessfully + successfully See Also */ @@ -266,7 +266,7 @@ cy_as_dma_queue_request( will have to maintain a list of sleep channels to wake. Returns - * CY_AS_ERROR_SUCCESS - the queue has drained sucessfully + * CY_AS_ERROR_SUCCESS - the queue has drained successfully * CY_AS_ERROR_INVALID_ENDPOINT - the endpoint given is not valid * CY_AS_ERROR_NESTED_SLEEP - CyAsDmaQueueRequest() was requested * on an endpoint where CyAsDmaQueueRequest was already called @@ -295,7 +295,7 @@ cy_as_dma_drain_queue( CyAsHalDmaSetupRead() functoins. Returns - * CY_AS_ERROR_SUCCESS - the value was set sucessfully + * CY_AS_ERROR_SUCCESS - the value was set successfully * CY_AS_ERROR_INVALID_SIZE - the size value was not valid */ extern cy_as_return_status_t diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyaserr.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyaserr.h index f78d60270d45..2cd0af1ed781 100644 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyaserr.h +++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyaserr.h @@ -29,7 +29,7 @@ */ /* Summary - The function completed sucessfully + The function completed successfully */ #define CY_AS_ERROR_SUCCESS (0) @@ -796,7 +796,7 @@ Description This error is returned when an operation is attempted that cannot be completed while the USB stack is connected to a USB host. In order - to sucessfully complete the desired operation, CyAsUsbDisconnect() + to successfully complete the desired operation, CyAsUsbDisconnect() must be called to disconnect from the host. */ #define CY_AS_ERROR_USB_CONNECTED (53) diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyashaldoc.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyashaldoc.h index 28136ad75115..5bcbe9bf2f5d 100644 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyashaldoc.h +++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyashaldoc.h @@ -597,7 +597,7 @@ cy_as_mem_set( CyAsHalSleepChannel. Returns - CyTrue is the initialization was sucessful, and CyFalse otherwise + CyTrue is the initialization was successful, and CyFalse otherwise See Also * CyAsHalSleepChannel diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasintr.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasintr.h index 3d7063ea3093..60a6fffb5d53 100644 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasintr.h +++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasintr.h @@ -69,7 +69,7 @@ cy_as_intr_start( Returns * CY_AS_ERROR_SUCCESS - the interrupt module was stopped - * sucessfully + * successfully * CY_AS_ERROR_NOT_RUNNING - the interrupt module was not * running diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmisc.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmisc.h index 2f0701850561..df7c2b66cf27 100644 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmisc.h +++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmisc.h @@ -620,7 +620,7 @@ cy_as_misc_in_standby( * Nestable: YES Returns - * CY_AS_ERROR_SUCCESS - the firmware was sucessfully downloaded + * CY_AS_ERROR_SUCCESS - the firmware was successfully downloaded * CY_AS_ERROR_INVALID_HANDLE * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device * was not configured @@ -836,7 +836,7 @@ cy_as_misc_reset( ownership. Returns - * CY_AS_ERROR_SUCCESS - the p port sucessfully acquired the + * CY_AS_ERROR_SUCCESS - the p port successfully acquired the * resource of interest * CY_AS_ERROR_INVALID_HANDLE * CY_AS_ERROR_NOT_CONFIGURED @@ -879,7 +879,7 @@ cy_as_misc_acquire_resource( * Valid In Asynchronous Callback: NO Returns - * CY_AS_ERROR_SUCCESS - the p port sucessfully released + * CY_AS_ERROR_SUCCESS - the p port successfully released * the resource of interest * CY_AS_ERROR_INVALID_HANDLE * CY_AS_ERROR_NOT_CONFIGURED @@ -929,7 +929,7 @@ cy_as_misc_release_resource( Returns * CY_AS_ERROR_SUCCESS - the trace configuration has been - * sucessfully changed + * successfully changed * CY_AS_ERROR_NO_SUCH_BUS - the bus specified does not exist * CY_AS_ERROR_NO_SUCH_DEVICE - the specified media/device * pair does not exist diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasprotocol.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasprotocol.h index 317805fc4ff4..773b645ea7eb 100644 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasprotocol.h +++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasprotocol.h @@ -756,7 +756,7 @@ * 1 : Debug mode Description - This reponse is sent to return the firmware version + This response is sent to return the firmware version number to the requestor. */ #define CY_RESP_FIRMWARE_VERSION (16) @@ -3655,7 +3655,7 @@ This request is sent to the West Bridge when the P port needs to send data to the Host in a Turbo Endpoint. Upon receiving this event, Firmware will make the end point - avilable for the P port. If the length is zero, then + available for the P port. If the length is zero, then firmware will send a zero length packet. Direction diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasstorage.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasstorage.h index 64f078cf202c..52b93c3e4813 100644 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasstorage.h +++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasstorage.h @@ -832,7 +832,7 @@ typedef struct cy_as_sdio_func { * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been * loaded into West Bridge * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was passed in - * CY_AS_ERROR_SUCCESS - the module started sucessfully + * CY_AS_ERROR_SUCCESS - the module started successfully * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating * with the West Bridge device * CY_AS_ERROR_OUT_OF_MEMORY @@ -882,7 +882,7 @@ cy_as_storage_start( * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was * passed in * CY_AS_ERROR_SUCCESS - this module was shut - * down sucessfully + * down successfully * CY_AS_ERROR_TIMEOUT - a timeout occurred * communicating with the West Bridge device * CY_AS_ERROR_NOT_RUNNING @@ -934,7 +934,7 @@ cy_as_storage_stop( * CY_AS_ERROR_INVALID_HANDLE - an invalid handle * was passed in * CY_AS_ERROR_SUCCESS - the function was registered - * sucessfully + * successfully * CY_AS_ERROR_NOT_RUNNING - the stack is not running See Also @@ -981,7 +981,7 @@ cy_as_storage_register_callback( * been started * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was * passed in - * CY_AS_ERROR_SUCCESS - this request was sucessfully + * CY_AS_ERROR_SUCCESS - this request was successfully * transmitted to the West Bridge device * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating * with the West Bridge device @@ -1034,7 +1034,7 @@ cy_as_storage_claim( * been started * CY_AS_ERROR_INVALID_HANDLE - an invalid handle * was passed in - * CY_AS_ERROR_SUCCESS - the media was sucessfully + * CY_AS_ERROR_SUCCESS - the media was successfully * released * CY_AS_ERROR_MEDIA_NOT_CLAIMED - the media was not * claimed by the P port @@ -1905,7 +1905,7 @@ cy_as_storage_get_transfer_amount( differ between SD cards. A large erase can take a while to complete depending on the SD - card. In such a case it is reccomended that an async call is made. + card. In such a case it is recommended that an async call is made. Returns * CY_AS_ERROR_SUCCESS - API call completed successfully @@ -1926,7 +1926,7 @@ cy_as_storage_get_transfer_amount( * required before erase is allowed * CY_AS_ERROR_NO_SUCH_BUS * CY_AS_ERROR_NO_SUCH_DEVICE - * CY_AS_ERROR_NOT_SUPPORTED - Erase is currenly only supported + * CY_AS_ERROR_NOT_SUPPORTED - Erase is currently only supported * on SD and using SD only firmware * CY_AS_ERROR_OUT_OF_MEMORY @@ -1985,7 +1985,7 @@ cy_as_storage_erase( * type was made * CY_AS_ERROR_OUT_OF_MEMORY - insufficient memory available * CY_AS_ERROR_INVALID_RESPONSE - an error message was - * recieved from the firmware + * received from the firmware * CY_AS_ERROR_MEDIA_ACCESS_FAILURE - there was error in * reading from the media * CY_AS_ERROR_INVALID_FUNCTION - An IO attempt was made to @@ -2047,7 +2047,7 @@ cy_as_sdio_get_c_i_s_info( * pair does not exist * CY_AS_ERROR_OUT_OF_MEMORY - insufficient memory available * CY_AS_ERROR_INVALID_RESPONSE - an error message was - * recieved from the firmware + * received from the firmware */ cy_as_return_status_t @@ -2095,7 +2095,7 @@ cy_as_sdio_query_card( * pair does not exist * CY_AS_ERROR_OUT_OF_MEMORY - insufficient memory available * CY_AS_ERROR_INVALID_RESPONSE - an error message was - * recieved from the firmware + * received from the firmware */ cy_as_return_status_t cy_as_sdio_reset_card( @@ -2139,7 +2139,7 @@ cy_as_sdio_reset_card( * CY_AS_ERROR_NO_SUCH_DEVICE - the specified media/device pair * does not exist * CY_AS_ERROR_OUT_OF_MEMORY - insufficient memory available - * CY_AS_ERROR_INVALID_RESPONSE - an error message was recieved + * CY_AS_ERROR_INVALID_RESPONSE - an error message was received * from the firmware * CY_AS_ERROR_MEDIA_ACCESS_FAILURE - there was error in reading * from the media @@ -2198,7 +2198,7 @@ cy_as_sdio_direct_read( * CY_AS_ERROR_NO_SUCH_DEVICE - the specified media/device * pair does not exist * CY_AS_ERROR_OUT_OF_MEMORY - insufficient memory available - * CY_AS_ERROR_INVALID_RESPONSE - an error message was recieved + * CY_AS_ERROR_INVALID_RESPONSE - an error message was received * from the firmware * CY_AS_ERROR_MEDIA_ACCESS_FAILURE - there was error in * reading from the media @@ -2262,7 +2262,7 @@ cy_as_sdio_direct_write( * CY_AS_ERROR_OUT_OF_MEMORY - insufficient memory * available * CY_AS_ERROR_INVALID_RESPONSE - an error message was - * recieved from the firmware + * received from the firmware * CY_AS_ERROR_MEDIA_ACCESS_FAILURE - there was error in * reading from the media * CY_AS_ERROR_INVALID_FUNCTION - An IO attempt was made @@ -2319,7 +2319,7 @@ cy_as_sdio_set_blocksize( * pair does not exist * CY_AS_ERROR_ASYNC_PENDING - an async operation is pending * CY_AS_ERROR_OUT_OF_MEMORY - insufficient memory available - * CY_AS_ERROR_INVALID_RESPONSE - an error message was recieved + * CY_AS_ERROR_INVALID_RESPONSE - an error message was received * from the firmware * CY_AS_ERROR_MEDIA_ACCESS_FAILURE - there was error in * reading from the media @@ -2396,7 +2396,7 @@ cy_as_sdio_extended_read( * CY_AS_ERROR_ASYNC_PENDING - an async operation is pending * CY_AS_ERROR_OUT_OF_MEMORY - insufficient memory available * CY_AS_ERROR_INVALID_RESPONSE - an error message was - * recieved from the firmware + * received from the firmware * CY_AS_ERROR_MEDIA_ACCESS_FAILURE - there was error in * reading from the media * CY_AS_ERROR_INVALID_FUNCTION - An IO attempt was made @@ -2471,7 +2471,7 @@ cy_as_sdio_extended_write( * pair does not exist * CY_AS_ERROR_OUT_OF_MEMORY - insufficient memory available * CY_AS_ERROR_INVALID_RESPONSE - an error message was - * recieved from the firmware + * received from the firmware * CY_AS_ERROR_MEDIA_ACCESS_FAILURE - there was error in * reading from the media * CY_AS_ERROR_INVALID_FUNCTION - An IO attempt was made @@ -2714,7 +2714,7 @@ cy_as_sdio_suspend( * CY_AS_ERROR_OUT_OF_MEMORY - insufficient memory * available * CY_AS_ERROR_INVALID_RESPONSE - an error message was - * recieved from the firmware + * received from the firmware * CY_AS_ERROR_MEDIA_ACCESS_FAILURE - there was error * in reading from the media * CY_AS_ERROR_INVALID_FUNCTION - An IO attempt was diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasusb.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasusb.h index 4a549e146812..e3ba9ca4c75f 100644 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasusb.h +++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasusb.h @@ -464,7 +464,7 @@ typedef struct cy_as_usb_end_point_config { be selected on a partitioned storage device. Description - West Bridge firmware supports creating upto two + West Bridge firmware supports creating up to two partitions on mass storage devices connected to West Bridge. When there are two partitions on a device, the user can choose which of these partitions should be @@ -698,7 +698,7 @@ cy_as_usb_start( * been configured * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded * into West Bridge - * CY_AS_ERROR_SUCCESS - this module was shut down sucessfully + * CY_AS_ERROR_SUCCESS - this module was shut down successfully * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with * the West Bridge device @@ -752,7 +752,7 @@ cy_as_usb_register_callback( * Nestable: YES Returns - * CY_AS_ERROR_SUCCESS - this module was shut down sucessfully + * CY_AS_ERROR_SUCCESS - this module was shut down successfully * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not * been configured * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded @@ -791,7 +791,7 @@ cy_as_usb_connect( * Nestable: YES Returns - * CY_AS_ERROR_SUCCESS - this module was shut down sucessfully + * CY_AS_ERROR_SUCCESS - this module was shut down successfully * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not * been configured * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded @@ -825,7 +825,7 @@ cy_as_usb_disconnect( * Valid In Asynchronous Callback: Yes (if cb supplied) Returns - * CY_AS_ERROR_SUCCESS - this module was shut down sucessfully + * CY_AS_ERROR_SUCCESS - this module was shut down successfully * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not * been configured * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded @@ -855,13 +855,13 @@ cy_as_usb_set_enum_config( the USB stack Description - This function sends a request to West Bridge to retreive + This function sends a request to West Bridge to retrieve the current configuration * Valid In Asynchronous Callback: Yes (if cb supplied) Returns - * CY_AS_ERROR_SUCCESS - this module was shut down sucessfully + * CY_AS_ERROR_SUCCESS - this module was shut down successfully * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not * been configured * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded @@ -906,7 +906,7 @@ cy_as_usb_get_enum_config( Chapter 9. Returns - * CY_AS_ERROR_SUCCESS - this module was shut down sucessfully + * CY_AS_ERROR_SUCCESS - this module was shut down successfully * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not * been configured * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded @@ -993,7 +993,7 @@ cy_as_usb_clear_descriptors( Description This data structure the buffer to hold the descriptor data, and an in/out parameter ti indicate the - lenght of the buffer and descriptor data in bytes. + length of the buffer and descriptor data in bytes. See Also * CyAsUsbGetDescriptor @@ -1027,7 +1027,7 @@ typedef struct cy_as_get_descriptor_data { Chapter 9. Returns - * CY_AS_ERROR_SUCCESS - this module was shut down sucessfully + * CY_AS_ERROR_SUCCESS - this module was shut down successfully * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not * been configured * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded @@ -1106,7 +1106,7 @@ cy_as_usb_get_descriptor( * Valid In Asynchronous Callback: NO Returns - * CY_AS_ERROR_SUCCESS - this module was shut down sucessfully + * CY_AS_ERROR_SUCCESS - this module was shut down successfully * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not * been configured * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded @@ -1140,7 +1140,7 @@ cy_as_usb_set_physical_configuration( Add documentation about endpoint configuration limitations Returns - * CY_AS_ERROR_SUCCESS - this module was shut down sucessfully + * CY_AS_ERROR_SUCCESS - this module was shut down successfully * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not * been configured * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded @@ -1181,7 +1181,7 @@ cy_as_usb_set_end_point_config( * Valid In Asynchronous Callback: NO Returns - * CY_AS_ERROR_SUCCESS - this module was shut down sucessfully + * CY_AS_ERROR_SUCCESS - this module was shut down successfully * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not * been configured * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded @@ -1219,7 +1219,7 @@ cy_as_usb_get_end_point_config( functions store away the configuration information and this CyAsUsbCommitConfig() actually finds the best hardware configuration based on the requested endpoint - configuration and sends thsi optimal + configuration and sends this optimal confiuration down to the West Bridge device. * Valid In Asynchronous Callback: YES (if cb supplied) @@ -1268,7 +1268,7 @@ cy_as_usb_commit_config( * Valid In Asynchronous Callback: NO Returns - * CY_AS_ERROR_SUCCESS - this module was shut down sucessfully + * CY_AS_ERROR_SUCCESS - this module was shut down successfully * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with * the West Bridge device * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running @@ -1311,7 +1311,7 @@ cy_as_usb_read_data( * Valid In Asynchronous Callback: YES Returns - * CY_AS_ERROR_SUCCESS - this module was shut down sucessfully + * CY_AS_ERROR_SUCCESS - this module was shut down successfully * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with * the West Bridge device * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running @@ -1355,7 +1355,7 @@ cy_as_usb_read_data_async( a zero length packet transmitted to the USB host. Returns - * CY_AS_ERROR_SUCCESS - this module was shut down sucessfully + * CY_AS_ERROR_SUCCESS - this module was shut down successfully * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with * the West Bridge device * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running @@ -1395,7 +1395,7 @@ cy_as_usb_write_data( in a zero length packet transmitted to the USB host. Returns - * CY_AS_ERROR_SUCCESS - this module was shut down sucessfully + * CY_AS_ERROR_SUCCESS - this module was shut down successfully * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with * the West Bridge device * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running @@ -1435,7 +1435,7 @@ cy_as_usb_write_data_async( Returns * CY_AS_ERROR_SUCCESS - this module was shut down - * sucessfully + * successfully * CY_AS_ERROR_NOT_RUNNING - the USB stack is not * running * CY_AS_ERROR_ASYNC_NOT_PENDING - no asynchronous USB @@ -1791,7 +1791,7 @@ cy_as_usb_set_m_s_report_threshold( device should be made visible to USB. Description - West Bridge firmware supports the creation of upto two + West Bridge firmware supports the creation of up to two partitions on mass storage devices connected to the West Bridge device. When there are two partitions on a device, the user can choose which of these partitions should be made visible to the diff --git a/drivers/staging/winbond/mds.c b/drivers/staging/winbond/mds.c index 9cfea94bcea5..c9f0e8f856a0 100644 --- a/drivers/staging/winbond/mds.c +++ b/drivers/staging/winbond/mds.c @@ -492,7 +492,7 @@ Mds_Tx(struct wbsoft_priv *adapter) TxDesIndex = pMds->TxDesIndex; /* Get the current ID */ pTxDes->Descriptor_ID = TxDesIndex; - pMds->TxDesFrom[TxDesIndex] = 2; /* Storing the information of source comming from */ + pMds->TxDesFrom[TxDesIndex] = 2; /* Storing the information of source coming from */ pMds->TxDesIndex++; pMds->TxDesIndex %= MAX_USB_TX_DESCRIPTOR; diff --git a/drivers/staging/wlags49_h2/README.ubuntu b/drivers/staging/wlags49_h2/README.ubuntu index 47beaec86e4a..edee8b9385be 100644 --- a/drivers/staging/wlags49_h2/README.ubuntu +++ b/drivers/staging/wlags49_h2/README.ubuntu @@ -116,7 +116,7 @@ LICENSE The Agere Systems license applies. This is why I include the original README.wlags49. The instructions in that file are bogus now. I also -include the man page. Eventhough setting parameters on the module +include the man page. Even though setting parameters on the module does not work anymore but it provides some information about all the settings. diff --git a/drivers/staging/wlags49_h2/TODO b/drivers/staging/wlags49_h2/TODO index 14aa415b1a82..94032b6ac2b5 100644 --- a/drivers/staging/wlags49_h2/TODO +++ b/drivers/staging/wlags49_h2/TODO @@ -1,7 +1,7 @@ First of all, the best thing would be that this driver becomes obsolte by adding support for Hermes II and Hermes II.5 cards to the existing orinoco driver. The orinoco driver currently only supports Hermes I based cards. -Since this will not happen by magic and has not happend until now this +Since this will not happen by magic and has not happened until now this driver provides a stop-gap solution for these type of cards. Having said that, the following wishlist comes to mind to make the driver @@ -18,7 +18,7 @@ TODO: - the driver is split into a Hermes II and a Hermes II.5 part, it would be nice to handle both with one module instead of two - review by the wireless developer community - - verify the code against the coding standards for a propper linux + - verify the code against the coding standards for a proper linux driver - resolve license issues (?) diff --git a/drivers/staging/wlags49_h2/hcf.c b/drivers/staging/wlags49_h2/hcf.c index d4bdd3ee8be1..a73317ef9350 100644 --- a/drivers/staging/wlags49_h2/hcf.c +++ b/drivers/staging/wlags49_h2/hcf.c @@ -540,7 +540,7 @@ HCF_STATIC hcf_16* BASED xxxx[ ] = { * *.CONDITIONS * Except for hcf_action with HCF_ACT_INT_FORCE_ON or HCF_ACT_INT_OFF as parameter or hcf_connect with an I/O -* address (i.e. not HCF_DISCONNECT), all hcf-function calls MUST be preceeded by a call of hcf_action with +* address (i.e. not HCF_DISCONNECT), all hcf-function calls MUST be preceded by a call of hcf_action with * HCF_ACT_INT_OFF as parameter. * Note that hcf_connect defaults to NIC interrupt disabled mode, i.e. as if hcf_action( HCF_ACT_INT_OFF ) * was called. @@ -843,7 +843,7 @@ hcf_16 i; *.MODULE int hcf_cntl( IFBP ifbp, hcf_16 cmd ) *.PURPOSE Connect or disconnect a specific port to a specific network. *!! ;???????????????? continue needs more explanation -* recovers by means of "continue" when the connect proces in CCX mode fails +* recovers by means of "continue" when the connect process in CCX mode fails * Enables or disables data transmission and reception for the NIC. * Activates static NIC configuration for a specific port at connect. * Activates static configuration for all ports at enable. @@ -1170,12 +1170,12 @@ LTV_STRCT x; io_addr = io_base; } -#if 0 //;? if a subsequent hcf_connect is preceeded by an hcf_disconnect the wakeup is not needed !! +#if 0 //;? if a subsequent hcf_connect is preceded by an hcf_disconnect the wakeup is not needed !! #if HCF_SLEEP OUT_PORT_WORD( .....+HREG_IO, HREG_IO_WAKEUP_ASYNC ); //OPW not yet useable MSF_WAIT(800); // MSF-defined function to wait n microseconds. note that MSF_WAIT uses not yet defined!!!! IFB_IOBase and IFB_TickIni (via PROT_CNT_INI) - so be carefull if this code is restored + so be careful if this code is restored #endif // HCF_SLEEP #endif // 0 @@ -1563,7 +1563,7 @@ DESC_STRCT *p = descp->next_desc_addr; //pointer to 2nd descriptor of frame * This function is called by the MSF to supply the HCF with new/more buffers for receive purposes. * The HCF can be used in 2 fashions: with and without encapsulation for data transfer. * This is controlled at compile time by the HCF_ENC bit of the HCF_ENCAP system constant. -* As a consequence, some additional constaints apply to the number of descriptor and the buffers associated +* As a consequence, some additional constraints apply to the number of descriptor and the buffers associated * with the first 2 descriptors. Independent of the encapsulation feature, the COUNT fields are ignored. * A special case is the supplying of the DELWA descriptor, which must be supplied as the first descriptor. * @@ -1735,7 +1735,7 @@ DESC_STRCT *descp; // pointer to start of FrameList * - in case encapsulation by the HCF is selected: * - The FrameList does not consists of at least 2 Descriptors. * - The first databuffer does not contain exactly the (space for) the 802.11 header (== 28 words) -* - The first databuffer does not have a size to additionally accomodate the 802.3 header and the +* - The first databuffer does not have a size to additionally accommodate the 802.3 header and the * SNAP header of the frame after encapsulation (== 39 words). * - The second databuffer does not contain at least DA, SA and 'type/length' (==14 bytes or 7 words) *!! The 2nd part of the list of asserts should be kept in sync with put_frame_lst, in order to get @@ -1762,14 +1762,14 @@ DESC_STRCT *descp; // pointer to start of FrameList * - Copy DA/SA fields from the 2nd buffer * - Calculate total length of the message (snap-header + type-field + the length of all buffer fragments * associated with the 802.3 frame (i.e all descriptors except the first), but not the DestinationAddress, -* SourceAddress and lenght-field) +* SourceAddress and length-field) * Assert the message length * Write length. Note that the message is in BE format, hence on LE platforms the length must be converted * ;? THIS IS NOT WHAT CURRENTLY IS IMPLEMENTED * - Write snap header. Note that the last byte of the snap header is NOT copied, that byte is already in * place as result of the call to hcf_encap. * Note that there are many ways to skin a cat. To express the offsets in the 1st buffer while writing -* the snap header, HFS_TYPE is choosen as a reference point to make it easier to grasp that the snap header +* the snap header, HFS_TYPE is chosen as a reference point to make it easier to grasp that the snap header * and encapsualtion type are at least relative in the right. *8: modify 1st descriptor to reflect moved part of the 802.3 header + Snap-header * modify 2nd descriptor to skip the moved part of the 802.3 header (DA/SA @@ -1933,7 +1933,7 @@ hcf_16 t = (hcf_16)(*type<<8) + *(type+1); /* 2 */ * HCF_SUCCESS Success *!! via cmd_exe ( type >= CFG_RID_FW_MIN ) * HCF_ERR_NO_NIC NIC removed during retrieval -* HCF_ERR_TIME_OUT Expected Hermes event did not occure in expected time +* HCF_ERR_TIME_OUT Expected Hermes event did not occur in expected time *!! via cmd_exe and setup_bap (type >= CFG_RID_FW_MIN ) * HCF_ERR_DEFUNCT_... HCF is in defunct mode (bits 0x7F reflect cause) * @@ -2958,7 +2958,7 @@ or * hcf_service_nic is also skipped in those cases. * To prevent that hcf_service_nic reports bogus information to the MSF with all - possibly difficult to * debug - undesirable side effects, it is paramount to check the NIC presence. In former days the presence -* test was based on the Hermes register HREG_SW_0. Since in HCF_ACT_INT_OFF is choosen for strategy based on +* test was based on the Hermes register HREG_SW_0. Since in HCF_ACT_INT_OFF is chosen for strategy based on * HREG_EV_STAT, this is now also used in hcf_service_nic. The motivation to change strategy is partly * due to inconsistent F/W implementations with respect to HREG_SW_0 manipulation around reset and download. * Note that in polled environments Card Removal is not detected by INT_OFF which makes the check in @@ -4048,7 +4048,7 @@ hcf_32 FAR *p4; //prevent side effects from macro HCFASSERT( word_len == 0 || word_len == 2 || word_len == 4, word_len ) HCFASSERT( word_len == 0 || ((hcf_32)bufp & 1 ) == 0, (hcf_32)bufp ) HCFASSERT( word_len <= len, MERGE2( word_len, len ) ) - //see put_frag for an alternative implementation, but be carefull about what are int's and what are + //see put_frag for an alternative implementation, but be careful about what are int's and what are //hcf_16's if ( word_len ) { //. if there is anything to convert hcf_8 c; @@ -4712,7 +4712,7 @@ int rc = HCF_SUCCESS; * Note that len is unsigned, so even MSF I/F violation works out O.K. * The '2' in the expression "len+2" is used because 1 word is needed for L itself and 1 word is needed * for the zero-sentinel -*8: update MailBox Info length report to MSF with "oldest" MB Info Block size. Be carefull here, if you get +*8: update MailBox Info length report to MSF with "oldest" MB Info Block size. Be careful here, if you get * here before the MailBox is registered, you can't read from the buffer addressed by IFB_MBp (it is the * Null buffer) so don't move this code till the end of this routine but keep it where there is garuanteed * a buffer. diff --git a/drivers/staging/wlags49_h2/hcfdef.h b/drivers/staging/wlags49_h2/hcfdef.h index 4e20171b7829..cb1966d8473f 100644 --- a/drivers/staging/wlags49_h2/hcfdef.h +++ b/drivers/staging/wlags49_h2/hcfdef.h @@ -315,7 +315,7 @@ err: these values should match; #if HCF_DMA //************************* DMA (bus mastering) - // Be carefull to use these registers only at a genuine 32 bits NIC + // Be careful to use these registers only at a genuine 32 bits NIC // On 16 bits NICs, these addresses are mapped into the range 0x00 through 0x3F with all consequences // thereof, e.g. HREG_DMA_CTRL register maps to HREG_CMD. #define HREG_DMA_CTRL 0x0040 diff --git a/drivers/staging/wlags49_h2/wl_wext.c b/drivers/staging/wlags49_h2/wl_wext.c index 9e5da0815371..522a31090c58 100644 --- a/drivers/staging/wlags49_h2/wl_wext.c +++ b/drivers/staging/wlags49_h2/wl_wext.c @@ -2575,7 +2575,7 @@ static int wireless_set_scan(struct net_device *dev, struct iw_request_info *inf * This looks like a nice place to test if the HCF is still * communicating with the card. It seems that sometimes BAP_1 * gets corrupted. By looking at the comments in HCF the - * cause is still a mistery. Okay, the communication to the + * cause is still a mystery. Okay, the communication to the * card is dead, reset the card to revive. */ if((lp->hcfCtx.IFB_CardStat & CARD_STAT_DEFUNCT) != 0) @@ -3924,7 +3924,7 @@ void wl_wext_event_mic_failed( struct net_device *dev ) memset( msg, 0, sizeof( msg )); - /* Becuase MIC failures are not part of the Wireless Extensions yet, they + /* Because MIC failures are not part of the Wireless Extensions yet, they must be passed as a string using an IWEVCUSTOM event. In order for the event to be effective, the string format must be known by both the driver and the supplicant. The following is the string format used by the @@ -3999,7 +3999,7 @@ void wl_wext_event_assoc_ie( struct net_device *dev ) memcpy( &data.rawData, &( lp->ltvRecord.u.u8[1] ), 88 ); wpa_ie = wl_parse_wpa_ie( &data, &length ); - /* Becuase this event (Association WPA-IE) is not part of the Wireless + /* Because this event (Association WPA-IE) is not part of the Wireless Extensions yet, it must be passed as a string using an IWEVCUSTOM event. In order for the event to be effective, the string format must be known by both the driver and the supplicant. The following is the string format diff --git a/drivers/staging/wlags49_h25/TODO b/drivers/staging/wlags49_h25/TODO index 14aa415b1a82..94032b6ac2b5 100644 --- a/drivers/staging/wlags49_h25/TODO +++ b/drivers/staging/wlags49_h25/TODO @@ -1,7 +1,7 @@ First of all, the best thing would be that this driver becomes obsolte by adding support for Hermes II and Hermes II.5 cards to the existing orinoco driver. The orinoco driver currently only supports Hermes I based cards. -Since this will not happen by magic and has not happend until now this +Since this will not happen by magic and has not happened until now this driver provides a stop-gap solution for these type of cards. Having said that, the following wishlist comes to mind to make the driver @@ -18,7 +18,7 @@ TODO: - the driver is split into a Hermes II and a Hermes II.5 part, it would be nice to handle both with one module instead of two - review by the wireless developer community - - verify the code against the coding standards for a propper linux + - verify the code against the coding standards for a proper linux driver - resolve license issues (?) diff --git a/drivers/staging/wlan-ng/prism2sta.c b/drivers/staging/wlan-ng/prism2sta.c index ed751f418db9..21f25a21c291 100644 --- a/drivers/staging/wlan-ng/prism2sta.c +++ b/drivers/staging/wlan-ng/prism2sta.c @@ -1976,7 +1976,7 @@ static wlandevice_t *create_wlan(void) wlandev->nsdcaps = P80211_NSDCAP_HWFRAGMENT | P80211_NSDCAP_AUTOJOIN; - /* Initialize the device private data stucture. */ + /* Initialize the device private data structure. */ hw->dot11_desired_bss_type = 1; return wlandev; diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 8762a5327693..9669c22cc82c 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -7834,7 +7834,7 @@ unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE, == 600)) { index++; } - /* Alan 10/19/2007; do the similiar adjustment like XGISearchCRT1Rate() */ + /* Alan 10/19/2007; do the similar adjustment like XGISearchCRT1Rate() */ if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 1024) && (pVBInfo->RefIndex[RefreshRateTableIndex].YRes == 768)) { diff --git a/drivers/staging/xgifb/vgatypes.h b/drivers/staging/xgifb/vgatypes.h index 4b87951f4322..d613e84aab62 100644 --- a/drivers/staging/xgifb/vgatypes.h +++ b/drivers/staging/xgifb/vgatypes.h @@ -85,7 +85,7 @@ struct xgi_hw_device_info unsigned long *); }; -/* Addtional IOCTL for communication xgifb <> X driver */ +/* Additional IOCTL for communication xgifb <> X driver */ /* If changing this, xgifb.h must also be changed (for xgifb) */ diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index 2c5fcfed5934..30cbb743d9ba 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c @@ -496,8 +496,8 @@ static int core_alua_state_check( nonop_delay_msecs = tg_pt_gp->tg_pt_gp_nonop_delay_msecs; spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); /* - * Process ALUA_ACCESS_STATE_ACTIVE_OPTMIZED in a seperate conditional - * statement so the complier knows explictly to check this case first. + * Process ALUA_ACCESS_STATE_ACTIVE_OPTMIZED in a separate conditional + * statement so the compiler knows explicitly to check this case first. * For the Optimized ALUA access state case, we want to process the * incoming fabric cmd ASAP.. */ @@ -1157,7 +1157,7 @@ void core_alua_free_lu_gp(struct t10_alua_lu_gp *lu_gp) spin_unlock(&lu_gp->lu_gp_lock); /* * - * lu_gp_mem is assoicated with a single + * lu_gp_mem is associated with a single * struct se_device->dev_alua_lu_gp_mem, and is released when * struct se_device is released via core_alua_free_lu_gp_mem(). * @@ -1429,7 +1429,7 @@ void core_alua_free_tg_pt_gp( } spin_unlock(&tg_pt_gp->tg_pt_gp_lock); /* - * tg_pt_gp_mem is assoicated with a single + * tg_pt_gp_mem is associated with a single * se_port->sep_alua_tg_pt_gp_mem, and is released via * core_alua_free_tg_pt_gp_mem(). * @@ -1963,7 +1963,7 @@ int core_setup_alua(struct se_device *dev, int force_pt) printk(KERN_INFO "%s: Enabling ALUA Emulation for SPC-3" " device\n", TRANSPORT(dev)->name); /* - * Assoicate this struct se_device with the default ALUA + * Associate this struct se_device with the default ALUA * LUN Group. */ lu_gp_mem = core_alua_allocate_lu_gp_mem(dev); diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 3fb8e32506ed..d25e20829012 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -371,7 +371,7 @@ int core_update_device_list_for_node( if (!(enable)) { /* * deve->se_lun_acl will be NULL for demo-mode created LUNs - * that have not been explictly concerted to MappedLUNs -> + * that have not been explicitly concerted to MappedLUNs -> * struct se_lun_acl, but we remove deve->alua_port_list from * port->sep_alua_list. This also means that active UAs and * NodeACL context specific PR metadata for demo-mode diff --git a/drivers/target/target_core_fabric_lib.c b/drivers/target/target_core_fabric_lib.c index d57ad672677f..1e193f324895 100644 --- a/drivers/target/target_core_fabric_lib.c +++ b/drivers/target/target_core_fabric_lib.c @@ -433,7 +433,7 @@ char *iscsi_parse_pr_out_transport_id( /* * Go ahead and do the lower case conversion of the received * 12 ASCII characters representing the ISID in the TransportID - * for comparision against the running iSCSI session's ISID from + * for comparison against the running iSCSI session's ISID from * iscsi_target.c:lio_sess_get_initiator_sid() */ for (i = 0; i < 12; i++) { diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index 02f553aef43d..150c4305f385 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c @@ -159,7 +159,7 @@ static struct se_device *fd_create_virtdevice( #endif /* flags |= O_DIRECT; */ /* - * If fd_buffered_io=1 has not been set explictly (the default), + * If fd_buffered_io=1 has not been set explicitly (the default), * use O_SYNC to force FILEIO writes to disk. */ if (!(fd_dev->fbd_flags & FDBD_USE_BUFFERED_IO)) diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 2521f75362c3..a79f518ca6e2 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c @@ -478,7 +478,7 @@ static int core_scsi3_pr_seq_non_holder( break; } /* - * Case where the CDB is explictly allowed in the above switch + * Case where the CDB is explicitly allowed in the above switch * statement. */ if (!(ret) && !(other_cdb)) { @@ -3735,7 +3735,7 @@ static int core_scsi3_emulate_pr_out(struct se_cmd *cmd, unsigned char *cdb) return PYX_TRANSPORT_LU_COMM_FAILURE; if (cmd->data_length < 24) { - printk(KERN_WARNING "SPC-PR: Recieved PR OUT parameter list" + printk(KERN_WARNING "SPC-PR: Received PR OUT parameter list" " length too small: %u\n", cmd->data_length); return PYX_TRANSPORT_INVALID_PARAMETER_LIST; } @@ -3778,7 +3778,7 @@ static int core_scsi3_emulate_pr_out(struct se_cmd *cmd, unsigned char *cdb) */ if (!(spec_i_pt) && ((cdb[1] & 0x1f) != PRO_REGISTER_AND_MOVE) && (cmd->data_length != 24)) { - printk(KERN_WARNING "SPC-PR: Recieved PR OUT illegal parameter" + printk(KERN_WARNING "SPC-PR: Received PR OUT illegal parameter" " list length: %u\n", cmd->data_length); return PYX_TRANSPORT_INVALID_PARAMETER_LIST; } diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index bf6aa8a9f1d8..9583b23c9c84 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -719,7 +719,7 @@ static int transport_cmd_check_stop( cmd->se_lun = NULL; /* * Some fabric modules like tcm_loop can release - * their internally allocated I/O refrence now and + * their internally allocated I/O reference now and * struct se_cmd now. */ if (CMD_TFO(cmd)->check_stop_free != NULL) { @@ -2029,7 +2029,7 @@ int transport_generic_handle_data( * If the received CDB has aleady been ABORTED by the generic * target engine, we now call transport_check_aborted_status() * to queue any delated TASK_ABORTED status for the received CDB to the - * fabric module as we are expecting no futher incoming DATA OUT + * fabric module as we are expecting no further incoming DATA OUT * sequences at this point. */ if (transport_check_aborted_status(cmd, 1) != 0) @@ -2501,7 +2501,7 @@ static inline int transport_execute_task_attr(struct se_cmd *cmd) if (SE_DEV(cmd)->dev_task_attr_type != SAM_TASK_ATTR_EMULATED) return 1; /* - * Check for the existance of HEAD_OF_QUEUE, and if true return 1 + * Check for the existence of HEAD_OF_QUEUE, and if true return 1 * to allow the passed struct se_cmd list of tasks to the front of the list. */ if (cmd->sam_task_attr == TASK_ATTR_HOQ) { @@ -2547,7 +2547,7 @@ static inline int transport_execute_task_attr(struct se_cmd *cmd) if (atomic_read(&SE_DEV(cmd)->dev_ordered_sync) != 0) { /* * Otherwise, add cmd w/ tasks to delayed cmd queue that - * will be drained upon competion of HEAD_OF_QUEUE task. + * will be drained upon completion of HEAD_OF_QUEUE task. */ spin_lock(&SE_DEV(cmd)->delayed_cmd_lock); cmd->se_cmd_flags |= SCF_DELAYED_CMD_FROM_SAM_ATTR; @@ -2589,7 +2589,7 @@ static int transport_execute_tasks(struct se_cmd *cmd) } /* * Call transport_cmd_check_stop() to see if a fabric exception - * has occured that prevents execution. + * has occurred that prevents execution. */ if (!(transport_cmd_check_stop(cmd, 0, TRANSPORT_PROCESSING))) { /* @@ -3109,7 +3109,7 @@ static int transport_generic_cmd_sequencer( if (ret != 0) { cmd->transport_wait_for_tasks = &transport_nop_wait_for_tasks; /* - * Set SCSI additional sense code (ASC) to 'LUN Not Accessable'; + * Set SCSI additional sense code (ASC) to 'LUN Not Accessible'; * The ALUA additional sense code qualifier (ASCQ) is determined * by the ALUA primary or secondary access state.. */ @@ -3867,7 +3867,7 @@ static void transport_generic_complete_ok(struct se_cmd *cmd) } } /* - * Check for a callback, used by amoungst other things + * Check for a callback, used by amongst other things * XDWRITE_READ_10 emulation. */ if (cmd->transport_complete_callback) diff --git a/drivers/target/target_core_ua.c b/drivers/target/target_core_ua.c index a2ef346087e8..df355176a377 100644 --- a/drivers/target/target_core_ua.c +++ b/drivers/target/target_core_ua.c @@ -247,7 +247,7 @@ void core_scsi3_ua_for_check_condition( } /* * Otherwise for the default 00b, release the UNIT ATTENTION - * condition. Return the ASC/ASCQ of the higest priority UA + * condition. Return the ASC/ASCQ of the highest priority UA * (head of the list) in the outgoing CHECK_CONDITION + sense. */ if (head) { @@ -304,7 +304,7 @@ int core_scsi3_ua_clear_for_request_sense( * matching struct se_lun. * * Once the returning ASC/ASCQ values are set, we go ahead and - * release all of the Unit Attention conditions for the assoicated + * release all of the Unit Attention conditions for the associated * struct se_lun. */ spin_lock(&deve->ua_lock); diff --git a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c index b00101972f20..d5f923bcdffe 100644 --- a/drivers/telephony/ixj.c +++ b/drivers/telephony/ixj.c @@ -169,7 +169,7 @@ * Added support for Linux 2.4.x kernels. * * Revision 3.77 2001/01/09 04:00:52 eokerson - * Linetest will now test the line, even if it has previously succeded. + * Linetest will now test the line, even if it has previously succeeded. * * Revision 3.76 2001/01/08 19:27:00 eokerson * Fixed problem with standard cable on Internet PhoneCARD. @@ -352,7 +352,7 @@ static void ixj_fsk_alloc(IXJ *j) } else { j->fsksize = 8000; if(ixjdebug & 0x0200) { - printk("IXJ phone%d - allocate succeded\n", j->board); + printk("IXJ phone%d - allocate succeeded\n", j->board); } } } @@ -487,7 +487,7 @@ DSPbase + 8-9 Hardware Status Register Read Only A-B Hardware Control Register Read Write C-D Host Transmit (Write) Data Buffer Access Port (buffer input)Write Only -E-F Host Recieve (Read) Data Buffer Access Port (buffer input) Read Only +E-F Host Receive (Read) Data Buffer Access Port (buffer input) Read Only ************************************************************************/ static inline void ixj_read_HSR(IXJ *j) @@ -4195,7 +4195,7 @@ static void ixj_aec_start(IXJ *j, int level) ixj_WriteDSPCommand(0xE338, j); /* Set Echo Suppresser Attenuation to 0dB */ /* Now we can set the AGC initial parameters and turn it on */ - ixj_WriteDSPCommand(0xCF90, j); /* Set AGC Minumum gain */ + ixj_WriteDSPCommand(0xCF90, j); /* Set AGC Minimum gain */ ixj_WriteDSPCommand(0x0020, j); /* to 0.125 (-18dB) */ ixj_WriteDSPCommand(0xCF91, j); /* Set AGC Maximum gain */ diff --git a/drivers/telephony/ixj.h b/drivers/telephony/ixj.h index 4c32a43b7914..2c841134f61c 100644 --- a/drivers/telephony/ixj.h +++ b/drivers/telephony/ixj.h @@ -1149,7 +1149,7 @@ typedef struct { unsigned int firstring:1; /* First ring cadence is complete */ unsigned int pstncheck:1; /* Currently checking the PSTN Line */ unsigned int pstn_rmr:1; - unsigned int x:3; /* unsed bits */ + unsigned int x:3; /* unused bits */ } IXJ_FLAGS; diff --git a/drivers/tty/hvc/hvc_iucv.c b/drivers/tty/hvc/hvc_iucv.c index c3425bb3a1f6..b6f7d52f7c35 100644 --- a/drivers/tty/hvc/hvc_iucv.c +++ b/drivers/tty/hvc/hvc_iucv.c @@ -255,7 +255,7 @@ static int hvc_iucv_write(struct hvc_iucv_private *priv, default: written = -EIO; } - /* remove buffer if an error has occured or received data + /* remove buffer if an error has occurred or received data * is not correct */ if (rc || (rb->mbuf->version != MSG_VERSION) || (rb->msg.length != MSG_SIZE(rb->mbuf->datalen))) @@ -620,7 +620,7 @@ static void hvc_iucv_hangup(struct hvc_iucv_private *priv) * the index of an struct hvc_iucv_private instance. * * This routine notifies the HVC back-end that a tty hangup (carrier loss, - * virtual or otherwise) has occured. + * virtual or otherwise) has occurred. * The z/VM IUCV HVC device driver ignores virtual hangups (vhangup()) * to keep an existing IUCV communication path established. * (Background: vhangup() is called from user space (by getty or login) to diff --git a/drivers/tty/hvc/hvc_vio.c b/drivers/tty/hvc/hvc_vio.c index 5e2f52b33327..e6eea1485244 100644 --- a/drivers/tty/hvc/hvc_vio.c +++ b/drivers/tty/hvc/hvc_vio.c @@ -1,7 +1,7 @@ /* * vio driver interface to hvc_console.c * - * This code was moved here to allow the remaing code to be reused as a + * This code was moved here to allow the remaining code to be reused as a * generic polling mode with semi-reliable transport driver core to the * console and tty subsystems. * diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c index bef238f9ffd7..4c8b66546930 100644 --- a/drivers/tty/hvc/hvcs.c +++ b/drivers/tty/hvc/hvcs.c @@ -118,7 +118,7 @@ * arch/powerepc/include/asm/hvcserver.h * * 1.3.2 -> 1.3.3 Replaced yield() in hvcs_close() with tty_wait_until_sent() to - * prevent possible lockup with realtime scheduling as similarily pointed out by + * prevent possible lockup with realtime scheduling as similarly pointed out by * akpm in hvc_console. Changed resulted in the removal of hvcs_final_close() * to reorder cleanup operations and prevent discarding of pending data during * an hvcs_close(). Removed spinlock protection of hvcs_struct data members in @@ -581,7 +581,7 @@ static void hvcs_try_write(struct hvcs_struct *hvcsd) /* * We are still obligated to deliver the data to the * hypervisor even if the tty has been closed because - * we commited to delivering it. But don't try to wake + * we committed to delivering it. But don't try to wake * a non-existent tty. */ if (tty) { @@ -1349,7 +1349,7 @@ static int hvcs_write(struct tty_struct *tty, spin_lock_irqsave(&hvcsd->lock, flags); /* - * Somehow an open succedded but the device was removed or the + * Somehow an open succeeded but the device was removed or the * connection terminated between the vty-server and partner vty during * the middle of a write operation? This is a crummy place to do this * but we want to keep it all in the spinlock. @@ -1420,7 +1420,7 @@ static int hvcs_write(struct tty_struct *tty, } /* - * This is really asking how much can we guarentee that we can send or that we + * This is really asking how much can we guarantee that we can send or that we * absolutely WILL BUFFER if we can't send it. This driver MUST honor the * return value, hence the reason for hvcs_struct buffering. */ diff --git a/drivers/tty/mxser.h b/drivers/tty/mxser.h index 41878a69203d..0bf794313ffd 100644 --- a/drivers/tty/mxser.h +++ b/drivers/tty/mxser.h @@ -113,7 +113,7 @@ #define MOXA_MUST_IIR_RTO 0x0C #define MOXA_MUST_IIR_LSR 0x06 -/* recieved Xon/Xoff or specical interrupt pending */ +/* received Xon/Xoff or specical interrupt pending */ #define MOXA_MUST_IIR_XSC 0x10 /* RTS/CTS change state interrupt pending */ diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 176f63256b37..47f8cdb207f1 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -74,7 +74,7 @@ module_param(debug, int, 0600); #endif /* - * Semi-arbitary buffer size limits. 0710 is normally run with 32-64 byte + * Semi-arbitrary buffer size limits. 0710 is normally run with 32-64 byte * limits so this is plenty */ #define MAX_MRU 512 @@ -82,7 +82,7 @@ module_param(debug, int, 0600); /* * Each block of data we have queued to go out is in the form of - * a gsm_msg which holds everything we need in a link layer independant + * a gsm_msg which holds everything we need in a link layer independent * format */ @@ -1193,8 +1193,8 @@ static void gsm_control_message(struct gsm_mux *gsm, unsigned int command, break; /* Optional unsupported commands */ case CMD_PN: /* Parameter negotiation */ - case CMD_RPN: /* Remote port negotation */ - case CMD_SNC: /* Service negotation command */ + case CMD_RPN: /* Remote port negotiation */ + case CMD_SNC: /* Service negotiation command */ default: /* Reply to bad commands with an NSC */ buf[0] = command; @@ -2026,7 +2026,7 @@ EXPORT_SYMBOL_GPL(gsm_activate_mux); * @mux: mux to free * * Dispose of allocated resources for a dead mux. No refcounting - * at present so the mux must be truely dead. + * at present so the mux must be truly dead. */ void gsm_free_mux(struct gsm_mux *gsm) { diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c index f4f11164efe5..fd0a98524d51 100644 --- a/drivers/tty/nozomi.c +++ b/drivers/tty/nozomi.c @@ -1673,7 +1673,7 @@ static void ntty_hangup(struct tty_struct *tty) /* * called when the userspace process writes to the tty (/dev/noz*). - * Data is inserted into a fifo, which is then read and transfered to the modem. + * Data is inserted into a fifo, which is then read and transferred to the modem. */ static int ntty_write(struct tty_struct *tty, const unsigned char *buffer, int count) diff --git a/drivers/tty/rocket.c b/drivers/tty/rocket.c index 3780da8ad12d..036feeb5e3f6 100644 --- a/drivers/tty/rocket.c +++ b/drivers/tty/rocket.c @@ -2060,7 +2060,7 @@ static __init int register_PCI(int i, struct pci_dev *dev) sClockPrescale = 0x19; rp_baud_base[i] = 230400; } else { - /* mod 4 (devide by 5) prescale */ + /* mod 4 (divide by 5) prescale */ sClockPrescale = 0x14; rp_baud_base[i] = 460800; } @@ -2183,7 +2183,7 @@ static int __init init_ISA(int i) sClockPrescale = 0x19; /* mod 9 (divide by 10) prescale */ rp_baud_base[i] = 230400; } else { - sClockPrescale = 0x14; /* mod 4 (devide by 5) prescale */ + sClockPrescale = 0x14; /* mod 4 (divide by 5) prescale */ rp_baud_base[i] = 460800; } diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c index b3b881bc4712..6611535f4440 100644 --- a/drivers/tty/serial/8250.c +++ b/drivers/tty/serial/8250.c @@ -1629,7 +1629,7 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id) up->port.iotype == UPIO_DWAPB32) && (iir & UART_IIR_BUSY) == UART_IIR_BUSY) { /* The DesignWare APB UART has an Busy Detect (0x07) - * interrupt meaning an LCR write attempt occured while the + * interrupt meaning an LCR write attempt occurred while the * UART was busy. The interrupt must be cleared by reading * the UART status register (USR) and the LCR re-written. */ unsigned int status; diff --git a/drivers/tty/serial/8250_pci.c b/drivers/tty/serial/8250_pci.c index 8b8930f700b5..738cec9807d3 100644 --- a/drivers/tty/serial/8250_pci.c +++ b/drivers/tty/serial/8250_pci.c @@ -433,7 +433,7 @@ static void __devexit sbs_exit(struct pci_dev *dev) /* * SIIG serial cards have an PCI interface chip which also controls * the UART clocking frequency. Each UART can be clocked independently - * (except cards equiped with 4 UARTs) and initial clocking settings + * (except cards equipped with 4 UARTs) and initial clocking settings * are stored in the EEPROM chip. It can cause problems because this * version of serial driver doesn't support differently clocked UART's * on single PCI card. To prevent this, initialization functions set diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 57731e870085..6deee4e546be 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -520,7 +520,7 @@ static bool pl011_dma_tx_irq(struct uart_amba_port *uap) /* * We don't have a TX buffer queued, so try to queue one. - * If we succesfully queued a buffer, mask the TX IRQ. + * If we successfully queued a buffer, mask the TX IRQ. */ if (pl011_dma_tx_refill(uap) > 0) { uap->im &= ~UART011_TXIM; diff --git a/drivers/tty/serial/icom.c b/drivers/tty/serial/icom.c index 53a468227056..8a869e58f6d7 100644 --- a/drivers/tty/serial/icom.c +++ b/drivers/tty/serial/icom.c @@ -1248,7 +1248,7 @@ static void icom_set_termios(struct uart_port *port, } } - /* Enable Transmitter and Reciever */ + /* Enable Transmitter and Receiver */ offset = (unsigned long) &ICOM_PORT->statStg->rcv[0] - (unsigned long) ICOM_PORT->statStg; diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index dfcf4b1878aa..cb36b0d4ef3c 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -78,7 +78,7 @@ #define URXD_FRMERR (1<<12) #define URXD_BRK (1<<11) #define URXD_PRERR (1<<10) -#define UCR1_ADEN (1<<15) /* Auto dectect interrupt */ +#define UCR1_ADEN (1<<15) /* Auto detect interrupt */ #define UCR1_ADBR (1<<14) /* Auto detect baud rate */ #define UCR1_TRDYEN (1<<13) /* Transmitter ready interrupt enable */ #define UCR1_IDEN (1<<12) /* Idle condition interrupt */ diff --git a/drivers/tty/serial/ip22zilog.c b/drivers/tty/serial/ip22zilog.c index ebff4a1d4bcc..7b1cda59ebb5 100644 --- a/drivers/tty/serial/ip22zilog.c +++ b/drivers/tty/serial/ip22zilog.c @@ -375,7 +375,7 @@ static void ip22zilog_transmit_chars(struct uart_ip22zilog_port *up, * be nice to transmit console writes just like we normally would for * a TTY line. (ie. buffered and TX interrupt driven). That is not * easy because console writes cannot sleep. One solution might be - * to poll on enough port->xmit space becomming free. -DaveM + * to poll on enough port->xmit space becoming free. -DaveM */ if (!(status & Tx_BUF_EMP)) return; diff --git a/drivers/tty/serial/jsm/jsm.h b/drivers/tty/serial/jsm/jsm.h index 38a509c684cd..b704c8ce0d71 100644 --- a/drivers/tty/serial/jsm/jsm.h +++ b/drivers/tty/serial/jsm/jsm.h @@ -273,7 +273,7 @@ struct neo_uart_struct { u8 fctr; /* WR FCTR - Feature Control Reg */ u8 efr; /* WR EFR - Enhanced Function Reg */ u8 tfifo; /* WR TXCNT/TXTRG - Transmit FIFO Reg */ - u8 rfifo; /* WR RXCNT/RXTRG - Recieve FIFO Reg */ + u8 rfifo; /* WR RXCNT/RXTRG - Receive FIFO Reg */ u8 xoffchar1; /* WR XOFF 1 - XOff Character 1 Reg */ u8 xoffchar2; /* WR XOFF 2 - XOff Character 2 Reg */ u8 xonchar1; /* WR XON 1 - Xon Character 1 Reg */ diff --git a/drivers/tty/serial/jsm/jsm_neo.c b/drivers/tty/serial/jsm/jsm_neo.c index 7960d9633c15..4538c3e3646e 100644 --- a/drivers/tty/serial/jsm/jsm_neo.c +++ b/drivers/tty/serial/jsm/jsm_neo.c @@ -381,7 +381,7 @@ static void neo_copy_data_from_uart_to_queue(struct jsm_channel *ch) /* Copy data from uart to the queue */ memcpy_fromio(ch->ch_rqueue + head, &ch->ch_neo_uart->txrxburst, n); /* - * Since RX_FIFO_DATA_ERROR was 0, we are guarenteed + * Since RX_FIFO_DATA_ERROR was 0, we are guaranteed * that all the data currently in the FIFO is free of * breaks and parity/frame/orun errors. */ @@ -1210,7 +1210,7 @@ static irqreturn_t neo_intr(int irq, void *voidbrd) * Why would I check EVERY possibility of type of * interrupt, when we know its TXRDY??? * Becuz for some reason, even tho we got triggered for TXRDY, - * it seems to be occassionally wrong. Instead of TX, which + * it seems to be occasionally wrong. Instead of TX, which * it should be, I was getting things like RXDY too. Weird. */ neo_parse_isr(brd, port); diff --git a/drivers/tty/serial/max3107.h b/drivers/tty/serial/max3107.h index 7ab632392502..8415fc723b96 100644 --- a/drivers/tty/serial/max3107.h +++ b/drivers/tty/serial/max3107.h @@ -369,7 +369,7 @@ struct max3107_port { struct spi_device *spi; #if defined(CONFIG_GPIOLIB) - /* GPIO chip stucture */ + /* GPIO chip structure */ struct gpio_chip chip; #endif diff --git a/drivers/tty/serial/mrst_max3110.c b/drivers/tty/serial/mrst_max3110.c index 37e13c3d91d9..2f548af4e98a 100644 --- a/drivers/tty/serial/mrst_max3110.c +++ b/drivers/tty/serial/mrst_max3110.c @@ -23,7 +23,7 @@ * 1 word. If SPI master controller doesn't support sclk frequency change, * then the char need be sent out one by one with some delay * - * 2. Currently only RX availabe interrrupt is used, no need for waiting TXE + * 2. Currently only RX available interrrupt is used, no need for waiting TXE * interrupt for a low speed UART device */ diff --git a/drivers/tty/serial/mrst_max3110.h b/drivers/tty/serial/mrst_max3110.h index d1ef43af397c..c37ea48c825a 100644 --- a/drivers/tty/serial/mrst_max3110.h +++ b/drivers/tty/serial/mrst_max3110.h @@ -21,7 +21,7 @@ #define WC_IRQ_MASK (0xF << 8) #define WC_TXE_IRQ_ENABLE (1 << 11) /* TX empty irq */ -#define WC_RXA_IRQ_ENABLE (1 << 10) /* RX availabe irq */ +#define WC_RXA_IRQ_ENABLE (1 << 10) /* RX available irq */ #define WC_PAR_HIGH_IRQ_ENABLE (1 << 9) #define WC_REC_ACT_IRQ_ENABLE (1 << 8) diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c index b906f11f7c1a..624701f8138a 100644 --- a/drivers/tty/serial/msm_serial_hs.c +++ b/drivers/tty/serial/msm_serial_hs.c @@ -495,7 +495,7 @@ static void msm_hs_pm(struct uart_port *uport, unsigned int state, * * Interrupts should be disabled before we are called, as * we modify Set Baud rate - * Set receive stale interrupt level, dependant on Bit Rate + * Set receive stale interrupt level, dependent on Bit Rate * Goal is to have around 8 ms before indicate stale. * roundup (((Bit Rate * .008) / 10) + 1 */ @@ -1350,7 +1350,7 @@ static irqreturn_t msm_hs_rx_wakeup_isr(int irq, void *dev) spin_lock_irqsave(&uport->lock, flags); if (msm_uport->clk_state == MSM_HS_CLK_OFF) { - /* ignore the first irq - it is a pending irq that occured + /* ignore the first irq - it is a pending irq that occurred * before enable_irq() */ if (msm_uport->rx_wakeup.ignore) msm_uport->rx_wakeup.ignore = 0; diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 763537943a53..47cadf474149 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -13,7 +13,7 @@ * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * - * Note: This driver is made seperate from 8250 driver as we cannot + * Note: This driver is made separate from 8250 driver as we cannot * over load 8250 driver with omap platform specific configuration for * features like DMA, it makes easier to implement features like DMA and * hardware flow control and software flow control configuration with diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c index 5b9cde79e4ea..e1c8d4f1ce58 100644 --- a/drivers/tty/serial/pmac_zilog.c +++ b/drivers/tty/serial/pmac_zilog.c @@ -330,7 +330,7 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap) * When that happens, I disable the receive side of the driver. * Note that what I've been experiencing is a real irq loop where * I'm getting flooded regardless of the actual port speed. - * Something stange is going on with the HW + * Something strange is going on with the HW */ if ((++loops) > 1000) goto flood; @@ -396,7 +396,7 @@ static void pmz_transmit_chars(struct uart_pmac_port *uap) * be nice to transmit console writes just like we normally would for * a TTY line. (ie. buffered and TX interrupt driven). That is not * easy because console writes cannot sleep. One solution might be - * to poll on enough port->xmit space becomming free. -DaveM + * to poll on enough port->xmit space becoming free. -DaveM */ if (!(status & Tx_BUF_EMP)) return; @@ -809,7 +809,7 @@ static int pmz_set_scc_power(struct uart_pmac_port *uap, int state) #endif /* !CONFIG_PPC_PMAC */ /* - * FixZeroBug....Works around a bug in the SCC receving channel. + * FixZeroBug....Works around a bug in the SCC receiving channel. * Inspired from Darwin code, 15 Sept. 2000 -DanM * * The following sequence prevents a problem that is seen with O'Hare ASICs diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index 2335edafe903..9e2fa8d784e2 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -64,7 +64,7 @@ #define tx_enabled(port) ((port)->unused[0]) #define rx_enabled(port) ((port)->unused[1]) -/* flag to ignore all characters comming in */ +/* flag to ignore all characters coming in */ #define RXSTAT_DUMMY_READ (0x10000000) static inline struct s3c24xx_uart_port *to_ourport(struct uart_port *port) @@ -291,7 +291,7 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id) goto out; } - /* if there isnt anything more to transmit, or the uart is now + /* if there isn't anything more to transmit, or the uart is now * stopped, disable the uart and exit */ diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index eb7958c675a8..a7b083f4ea78 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -812,7 +812,7 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) } /* - * Here we define a transistion notifier so that we can update all of our + * Here we define a transition notifier so that we can update all of our * ports' baud rate when the peripheral clock changes. */ static int sci_notifier(struct notifier_block *self, diff --git a/drivers/tty/serial/sn_console.c b/drivers/tty/serial/sn_console.c index cff9a306660f..377ae74e7154 100644 --- a/drivers/tty/serial/sn_console.c +++ b/drivers/tty/serial/sn_console.c @@ -146,7 +146,7 @@ static struct sn_sal_ops intr_ops = { }; /* the console does output in two distinctly different ways: - * synchronous (raw) and asynchronous (buffered). initally, early_printk + * synchronous (raw) and asynchronous (buffered). initially, early_printk * does synchronous output. any data written goes directly to the SAL * to be output (incidentally, it is internally buffered by the SAL) * after interrupts and timers are initialized and available for use, @@ -481,7 +481,7 @@ sn_receive_chars(struct sn_cons_port *port, unsigned long flags) while (port->sc_ops->sal_input_pending()) { ch = port->sc_ops->sal_getc(); if (ch < 0) { - printk(KERN_ERR "sn_console: An error occured while " + printk(KERN_ERR "sn_console: An error occurred while " "obtaining data from the console (0x%0x)\n", ch); break; } diff --git a/drivers/tty/serial/sunzilog.c b/drivers/tty/serial/sunzilog.c index 99ff9abf57ce..8e916e76b7b5 100644 --- a/drivers/tty/serial/sunzilog.c +++ b/drivers/tty/serial/sunzilog.c @@ -474,7 +474,7 @@ static void sunzilog_transmit_chars(struct uart_sunzilog_port *up, * be nice to transmit console writes just like we normally would for * a TTY line. (ie. buffered and TX interrupt driven). That is not * easy because console writes cannot sleep. One solution might be - * to poll on enough port->xmit space becomming free. -DaveM + * to poll on enough port->xmit space becoming free. -DaveM */ if (!(status & Tx_BUF_EMP)) return; diff --git a/drivers/tty/synclink.c b/drivers/tty/synclink.c index 18888d005a0a..27da23d98e3f 100644 --- a/drivers/tty/synclink.c +++ b/drivers/tty/synclink.c @@ -4072,7 +4072,7 @@ static int mgsl_claim_resources(struct mgsl_struct *info) if ( request_irq(info->irq_level,mgsl_interrupt,info->irq_flags, info->device_name, info ) < 0 ) { - printk( "%s(%d):Cant request interrupt on device %s IRQ=%d\n", + printk( "%s(%d):Can't request interrupt on device %s IRQ=%d\n", __FILE__,__LINE__,info->device_name, info->irq_level ); goto errout; } @@ -4095,7 +4095,7 @@ static int mgsl_claim_resources(struct mgsl_struct *info) info->memory_base = ioremap_nocache(info->phys_memory_base, 0x40000); if (!info->memory_base) { - printk( "%s(%d):Cant map shared memory on device %s MemAddr=%08X\n", + printk( "%s(%d):Can't map shared memory on device %s MemAddr=%08X\n", __FILE__,__LINE__,info->device_name, info->phys_memory_base ); goto errout; } @@ -4109,7 +4109,7 @@ static int mgsl_claim_resources(struct mgsl_struct *info) info->lcr_base = ioremap_nocache(info->phys_lcr_base, PAGE_SIZE); if (!info->lcr_base) { - printk( "%s(%d):Cant map LCR memory on device %s MemAddr=%08X\n", + printk( "%s(%d):Can't map LCR memory on device %s MemAddr=%08X\n", __FILE__,__LINE__,info->device_name, info->phys_lcr_base ); goto errout; } @@ -4119,7 +4119,7 @@ static int mgsl_claim_resources(struct mgsl_struct *info) /* claim DMA channel */ if (request_dma(info->dma_level,info->device_name) < 0){ - printk( "%s(%d):Cant request DMA channel on device %s DMA=%d\n", + printk( "%s(%d):Can't request DMA channel on device %s DMA=%d\n", __FILE__,__LINE__,info->device_name, info->dma_level ); mgsl_release_resources( info ); return -ENODEV; @@ -4132,7 +4132,7 @@ static int mgsl_claim_resources(struct mgsl_struct *info) } if ( mgsl_allocate_dma_buffers(info) < 0 ) { - printk( "%s(%d):Cant allocate DMA buffers on device %s DMA=%d\n", + printk( "%s(%d):Can't allocate DMA buffers on device %s DMA=%d\n", __FILE__,__LINE__,info->device_name, info->dma_level ); goto errout; } diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index a35dd549a008..18b48cd3b41d 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c @@ -3491,7 +3491,7 @@ static int claim_resources(struct slgt_info *info) info->reg_addr = ioremap_nocache(info->phys_reg_addr, SLGT_REG_SIZE); if (!info->reg_addr) { - DBGERR(("%s cant map device registers, addr=%08X\n", + DBGERR(("%s can't map device registers, addr=%08X\n", info->device_name, info->phys_reg_addr)); info->init_error = DiagStatus_CantAssignPciResources; goto errout; diff --git a/drivers/tty/synclinkmp.c b/drivers/tty/synclinkmp.c index 327343694473..c77831c7675a 100644 --- a/drivers/tty/synclinkmp.c +++ b/drivers/tty/synclinkmp.c @@ -3595,7 +3595,7 @@ static int claim_resources(SLMP_INFO *info) info->memory_base = ioremap_nocache(info->phys_memory_base, SCA_MEM_SIZE); if (!info->memory_base) { - printk( "%s(%d):%s Cant map shared memory, MemAddr=%08X\n", + printk( "%s(%d):%s Can't map shared memory, MemAddr=%08X\n", __FILE__,__LINE__,info->device_name, info->phys_memory_base ); info->init_error = DiagStatus_CantAssignPciResources; goto errout; @@ -3603,7 +3603,7 @@ static int claim_resources(SLMP_INFO *info) info->lcr_base = ioremap_nocache(info->phys_lcr_base, PAGE_SIZE); if (!info->lcr_base) { - printk( "%s(%d):%s Cant map LCR memory, MemAddr=%08X\n", + printk( "%s(%d):%s Can't map LCR memory, MemAddr=%08X\n", __FILE__,__LINE__,info->device_name, info->phys_lcr_base ); info->init_error = DiagStatus_CantAssignPciResources; goto errout; @@ -3612,7 +3612,7 @@ static int claim_resources(SLMP_INFO *info) info->sca_base = ioremap_nocache(info->phys_sca_base, PAGE_SIZE); if (!info->sca_base) { - printk( "%s(%d):%s Cant map SCA memory, MemAddr=%08X\n", + printk( "%s(%d):%s Can't map SCA memory, MemAddr=%08X\n", __FILE__,__LINE__,info->device_name, info->phys_sca_base ); info->init_error = DiagStatus_CantAssignPciResources; goto errout; @@ -3622,7 +3622,7 @@ static int claim_resources(SLMP_INFO *info) info->statctrl_base = ioremap_nocache(info->phys_statctrl_base, PAGE_SIZE); if (!info->statctrl_base) { - printk( "%s(%d):%s Cant map SCA Status/Control memory, MemAddr=%08X\n", + printk( "%s(%d):%s Can't map SCA Status/Control memory, MemAddr=%08X\n", __FILE__,__LINE__,info->device_name, info->phys_statctrl_base ); info->init_error = DiagStatus_CantAssignPciResources; goto errout; @@ -3869,7 +3869,7 @@ static void device_init(int adapter_num, struct pci_dev *pdev) port_array[0]->irq_flags, port_array[0]->device_name, port_array[0]) < 0 ) { - printk( "%s(%d):%s Cant request interrupt, IRQ=%d\n", + printk( "%s(%d):%s Can't request interrupt, IRQ=%d\n", __FILE__,__LINE__, port_array[0]->device_name, port_array[0]->irq_level ); diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 936a4ead6c21..d7d50b48287e 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -2134,7 +2134,7 @@ done: * actually has driver level meaning and triggers a VC resize. * * Locking: - * Driver dependant. The default do_resize method takes the + * Driver dependent. The default do_resize method takes the * tty termios mutex and ctrl_lock. The console takes its own lock * then calls into the default method. */ @@ -2155,7 +2155,7 @@ static int tiocswinsz(struct tty_struct *tty, struct winsize __user *arg) * tioccons - allow admin to move logical console * @file: the file to become console * - * Allow the adminstrator to move the redirected console device + * Allow the administrator to move the redirected console device * * Locking: uses redirect_lock to guard the redirect information */ @@ -2290,7 +2290,7 @@ EXPORT_SYMBOL_GPL(tty_get_pgrp); /** * tiocgpgrp - get process group * @tty: tty passed by user - * @real_tty: tty side of the tty pased by the user if a pty else the tty + * @real_tty: tty side of the tty passed by the user if a pty else the tty * @p: returned pid * * Obtain the process group of the tty. If there is no process group @@ -2367,7 +2367,7 @@ out_unlock: /** * tiocgsid - get session id * @tty: tty passed by user - * @real_tty: tty side of the tty pased by the user if a pty else the tty + * @real_tty: tty side of the tty passed by the user if a pty else the tty * @p: pointer to returned session id * * Obtain the session id of the tty. If there is no session diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index 1a1135d580a2..21574cb32343 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c @@ -247,7 +247,7 @@ speed_t tty_termios_baud_rate(struct ktermios *termios) cbaud = termios->c_cflag & CBAUD; #ifdef BOTHER - /* Magic token for arbitary speed via c_ispeed/c_ospeed */ + /* Magic token for arbitrary speed via c_ispeed/c_ospeed */ if (cbaud == BOTHER) return termios->c_ospeed; #endif @@ -283,7 +283,7 @@ speed_t tty_termios_input_baud_rate(struct ktermios *termios) if (cbaud == B0) return tty_termios_baud_rate(termios); - /* Magic token for arbitary speed via c_ispeed*/ + /* Magic token for arbitrary speed via c_ispeed*/ if (cbaud == BOTHER) return termios->c_ispeed; @@ -449,7 +449,7 @@ EXPORT_SYMBOL(tty_get_baud_rate); * @new: New termios * @old: Old termios * - * Propogate the hardware specific terminal setting bits from + * Propagate the hardware specific terminal setting bits from * the old termios structure to the new one. This is used in cases * where the hardware does not support reconfiguration or as a helper * in some cases where only minimal reconfiguration is supported diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index c83cdfb56fcc..4bea1efaec98 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -3963,7 +3963,7 @@ void reset_palette(struct vc_data *vc) * of 32 pixels. Userspace fontdata is stored with 32 bytes (shorts/ints, * depending on width) reserved for each character which is kinda wasty, but * this is done in order to maintain compatibility with the EGA/VGA fonts. It - * is upto the actual low-level console-driver convert data into its favorite + * is up to the actual low-level console-driver convert data into its favorite * format (maybe we should add a `fontoffset' field to the `display' * structure so we won't have to convert the fontdata all the time. * /Jes diff --git a/drivers/uio/uio_pruss.c b/drivers/uio/uio_pruss.c index daf6e77de2b1..e67b566e7aa3 100644 --- a/drivers/uio/uio_pruss.c +++ b/drivers/uio/uio_pruss.c @@ -39,7 +39,7 @@ module_param(extram_pool_sz, int, 0); MODULE_PARM_DESC(extram_pool_sz, "external ram pool size to allocate"); /* - * Host event IRQ numbers from PRUSS - PRUSS can generate upto 8 interrupt + * Host event IRQ numbers from PRUSS - PRUSS can generate up to 8 interrupt * events to AINTC of ARM host processor - which can be used for IPC b/w PRUSS * firmware and user space application, async notification from PRU firmware * to user space application diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index b268e9fccb47..e71521ce3010 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c @@ -1283,7 +1283,7 @@ static void uea_set_bulk_timeout(struct uea_softc *sc, u32 dsrate) /* in bulk mode the modem have problem with high rate * changing internal timing could improve things, but the - * value is misterious. + * value is mysterious. * ADI930 don't support it (-EPIPE error). */ @@ -1743,7 +1743,7 @@ static int uea_send_cmvs_e1(struct uea_softc *sc) goto out; } } else { - /* This realy should not happen */ + /* This really should not happen */ uea_err(INS_TO_USBDEV(sc), "bad cmvs version %d\n", ver); goto out; } @@ -1798,7 +1798,7 @@ static int uea_send_cmvs_e4(struct uea_softc *sc) goto out; } } else { - /* This realy should not happen */ + /* This really should not happen */ uea_err(INS_TO_USBDEV(sc), "bad cmvs version %d\n", ver); goto out; } @@ -1829,7 +1829,7 @@ static int uea_start_reset(struct uea_softc *sc) /* mask interrupt */ sc->booting = 1; - /* We need to set this here because, a ack timeout could have occured, + /* We need to set this here because, a ack timeout could have occurred, * but before we start the reboot, the ack occurs and set this to 1. * So we will failed to wait Ready CMV. */ diff --git a/drivers/usb/c67x00/c67x00-drv.c b/drivers/usb/c67x00/c67x00-drv.c index b6d49234e521..62050f7a4f97 100644 --- a/drivers/usb/c67x00/c67x00-drv.c +++ b/drivers/usb/c67x00/c67x00-drv.c @@ -27,7 +27,7 @@ * the link between the common hardware parts and the subdrivers (e.g. * interrupt handling). * - * The c67x00 has 2 SIE's (serial interface engine) wich can be configured + * The c67x00 has 2 SIE's (serial interface engine) which can be configured * to be host, device or OTG (with some limitations, E.G. only SIE1 can be OTG). * * Depending on the platform configuration, the SIE's are created and diff --git a/drivers/usb/c67x00/c67x00-hcd.h b/drivers/usb/c67x00/c67x00-hcd.h index 74e44621e313..e3d493d4d61a 100644 --- a/drivers/usb/c67x00/c67x00-hcd.h +++ b/drivers/usb/c67x00/c67x00-hcd.h @@ -34,7 +34,7 @@ /* * The following parameters depend on the CPU speed, bus speed, ... * These can be tuned for specific use cases, e.g. if isochronous transfers - * are very important, bandwith can be sacrificed to guarantee that the + * are very important, bandwidth can be sacrificed to guarantee that the * 1ms deadline will be met. * If bulk transfers are important, the MAX_FRAME_BW can be increased, * but some (or many) isochronous deadlines might not be met. diff --git a/drivers/usb/c67x00/c67x00-sched.c b/drivers/usb/c67x00/c67x00-sched.c index f6b3c253f3fa..a03fbc15fa9c 100644 --- a/drivers/usb/c67x00/c67x00-sched.c +++ b/drivers/usb/c67x00/c67x00-sched.c @@ -907,7 +907,7 @@ static inline int c67x00_end_of_data(struct c67x00_td *td) /* Remove all td's from the list which come * after last_td and are meant for the same pipe. - * This is used when a short packet has occured */ + * This is used when a short packet has occurred */ static inline void c67x00_clear_pipe(struct c67x00_hcd *c67x00, struct c67x00_td *last_td) { diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h index 5eeb570b9a61..b4ea54dbf323 100644 --- a/drivers/usb/class/cdc-acm.h +++ b/drivers/usb/class/cdc-acm.h @@ -52,7 +52,7 @@ */ /* - * The only reason to have several buffers is to accomodate assumptions + * The only reason to have several buffers is to accommodate assumptions * in line disciplines. They ask for empty space amount, receive our URB size, * and proceed to issue several 1-character writes, assuming they will fit. * The very first write takes a complete URB. Fortunately, this only happens diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index 6a54634ab823..385acb895ab3 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c @@ -483,7 +483,7 @@ static ssize_t usbtmc_read(struct file *filp, char __user *buf, } done += n_characters; - /* Terminate if end-of-message bit recieved from device */ + /* Terminate if end-of-message bit received from device */ if ((buffer[8] & 0x01) && (actual >= n_characters + 12)) remaining = 0; else diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 02b4dbfa488a..8eed05d23838 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -700,7 +700,7 @@ void usb_hcd_poll_rh_status(struct usb_hcd *hcd) /* The USB 2.0 spec says 256 ms. This is close enough and won't * exceed that limit if HZ is 100. The math is more clunky than * maybe expected, this is to make sure that all timers for USB devices - * fire at the same time to give the CPU a break inbetween */ + * fire at the same time to give the CPU a break in between */ if (hcd->uses_new_polling ? HCD_POLL_RH(hcd) : (length == 0 && hcd->status_urb != NULL)) mod_timer (&hcd->rh_timer, (jiffies/(HZ/4) + 1) * (HZ/4)); diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 564eaa5525d7..8fb754916c67 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1649,7 +1649,7 @@ void usb_disconnect(struct usb_device **pdev) /* mark the device as inactive, so any further urb submissions for * this device (and any of its children) will fail immediately. - * this quiesces everyting except pending urbs. + * this quiesces everything except pending urbs. */ usb_set_device_state(udev, USB_STATE_NOTATTACHED); dev_info(&udev->dev, "USB disconnect, device number %d\n", diff --git a/drivers/usb/early/ehci-dbgp.c b/drivers/usb/early/ehci-dbgp.c index 0bc06e2bcfcb..a6a350f5827b 100644 --- a/drivers/usb/early/ehci-dbgp.c +++ b/drivers/usb/early/ehci-dbgp.c @@ -648,7 +648,7 @@ static int ehci_reset_port(int port) if (!(portsc & PORT_CONNECT)) return -ENOTCONN; - /* bomb out completely if something weird happend */ + /* bomb out completely if something weird happened */ if ((portsc & PORT_CSC)) return -EINVAL; diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c index f8dd7269d79c..6e42aab75806 100644 --- a/drivers/usb/gadget/amd5536udc.c +++ b/drivers/usb/gadget/amd5536udc.c @@ -278,7 +278,7 @@ static int udc_enable_dev_setup_interrupts(struct udc *dev) return 0; } -/* Calculates fifo start of endpoint based on preceeding endpoints */ +/* Calculates fifo start of endpoint based on preceding endpoints */ static int udc_set_txfifo_addr(struct udc_ep *ep) { struct udc *dev; @@ -2137,7 +2137,7 @@ static irqreturn_t udc_data_out_isr(struct udc *dev, int ep_ix) if (use_dma) { /* BNA event ? */ if (tmp & AMD_BIT(UDC_EPSTS_BNA)) { - DBG(dev, "BNA ep%dout occured - DESPTR = %x \n", + DBG(dev, "BNA ep%dout occurred - DESPTR = %x \n", ep->num, readl(&ep->regs->desptr)); /* clear BNA */ writel(tmp | AMD_BIT(UDC_EPSTS_BNA), &ep->regs->sts); @@ -2151,7 +2151,7 @@ static irqreturn_t udc_data_out_isr(struct udc *dev, int ep_ix) } /* HE event ? */ if (tmp & AMD_BIT(UDC_EPSTS_HE)) { - dev_err(&dev->pdev->dev, "HE ep%dout occured\n", ep->num); + dev_err(&dev->pdev->dev, "HE ep%dout occurred\n", ep->num); /* clear HE */ writel(tmp | AMD_BIT(UDC_EPSTS_HE), &ep->regs->sts); @@ -2354,7 +2354,7 @@ static irqreturn_t udc_data_in_isr(struct udc *dev, int ep_ix) /* BNA ? */ if (epsts & AMD_BIT(UDC_EPSTS_BNA)) { dev_err(&dev->pdev->dev, - "BNA ep%din occured - DESPTR = %08lx \n", + "BNA ep%din occurred - DESPTR = %08lx \n", ep->num, (unsigned long) readl(&ep->regs->desptr)); @@ -2367,7 +2367,7 @@ static irqreturn_t udc_data_in_isr(struct udc *dev, int ep_ix) /* HE event ? */ if (epsts & AMD_BIT(UDC_EPSTS_HE)) { dev_err(&dev->pdev->dev, - "HE ep%dn occured - DESPTR = %08lx \n", + "HE ep%dn occurred - DESPTR = %08lx \n", ep->num, (unsigned long) readl(&ep->regs->desptr)); /* clear HE */ @@ -2384,7 +2384,7 @@ static irqreturn_t udc_data_in_isr(struct udc *dev, int ep_ix) req = list_entry(ep->queue.next, struct udc_request, queue); /* - * length bytes transfered + * length bytes transferred * check dma done of last desc. in PPBDU mode */ if (use_dma_ppb_du) { @@ -2784,7 +2784,7 @@ static irqreturn_t udc_control_in_isr(struct udc *dev) /* write fifo */ udc_txfifo_write(ep, &req->req); - /* lengh bytes transfered */ + /* lengh bytes transferred */ len = req->req.length - req->req.actual; if (len > ep->ep.maxpacket) len = ep->ep.maxpacket; diff --git a/drivers/usb/gadget/amd5536udc.h b/drivers/usb/gadget/amd5536udc.h index 4bbabbbfc93f..1d1c7543468e 100644 --- a/drivers/usb/gadget/amd5536udc.h +++ b/drivers/usb/gadget/amd5536udc.h @@ -584,7 +584,7 @@ union udc_setup_data { * SET and GET bitfields in u32 values * via constants for mask/offset: * is the text between - * UDC_ and _MASK|_OFS of appropiate + * UDC_ and _MASK|_OFS of appropriate * constant * * set bitfield value in u32 u32Val diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index bb8ddf0469f9..9b7cdb16f26b 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c @@ -826,7 +826,7 @@ done: return status; } -/* reinit == restore inital software state */ +/* reinit == restore initial software state */ static void udc_reinit(struct at91_udc *udc) { u32 i; diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index c2251c40a205..82314ed22506 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -42,7 +42,7 @@ static struct usb_composite_driver *composite; static int (*composite_gadget_bind)(struct usb_composite_dev *cdev); -/* Some systems will need runtime overrides for the product identifers +/* Some systems will need runtime overrides for the product identifiers * published in the device descriptor, either numbers or strings or both. * String parameters are in UTF-8 (superset of ASCII's 7 bit characters). */ @@ -205,14 +205,14 @@ int usb_function_activate(struct usb_function *function) * usb_interface_id() is called from usb_function.bind() callbacks to * allocate new interface IDs. The function driver will then store that * ID in interface, association, CDC union, and other descriptors. It - * will also handle any control requests targetted at that interface, + * will also handle any control requests targeted at that interface, * particularly changing its altsetting via set_alt(). There may * also be class-specific or vendor-specific requests to handle. * * All interface identifier should be allocated using this routine, to * ensure that for example different functions don't wrongly assign * different meanings to the same identifier. Note that since interface - * identifers are configuration-specific, functions used in more than + * identifiers are configuration-specific, functions used in more than * one configuration (or more than once in a given configuration) need * multiple versions of the relevant descriptors. * diff --git a/drivers/usb/gadget/f_audio.c b/drivers/usb/gadget/f_audio.c index 00975ed903d1..9abecfddb27d 100644 --- a/drivers/usb/gadget/f_audio.c +++ b/drivers/usb/gadget/f_audio.c @@ -742,7 +742,7 @@ int __init control_selector_init(struct f_audio *audio) } /** - * audio_bind_config - add USB audio fucntion to a configuration + * audio_bind_config - add USB audio function to a configuration * @c: the configuration to supcard the USB audio function * Context: single threaded during gadget setup * diff --git a/drivers/usb/gadget/f_ncm.c b/drivers/usb/gadget/f_ncm.c index 130eee678c8b..86902a60bcdb 100644 --- a/drivers/usb/gadget/f_ncm.c +++ b/drivers/usb/gadget/f_ncm.c @@ -111,7 +111,7 @@ static inline unsigned ncm_bitrate(struct usb_gadget *g) #define NTB_OUT_SIZE 16384 /* - * skbs of size less than that will not be alligned + * skbs of size less than that will not be aligned * to NCM's dwNtbInMaxSize to save bus bandwidth */ diff --git a/drivers/usb/gadget/fsl_qe_udc.h b/drivers/usb/gadget/fsl_qe_udc.h index bea5b827bebe..e35e24fd64bb 100644 --- a/drivers/usb/gadget/fsl_qe_udc.h +++ b/drivers/usb/gadget/fsl_qe_udc.h @@ -208,14 +208,14 @@ struct qe_frame{ /* Frame status field */ /* Receive side */ #define FRAME_OK 0x00000000 /* Frame tranmitted or received OK */ -#define FRAME_ERROR 0x80000000 /* Error occured on frame */ +#define FRAME_ERROR 0x80000000 /* Error occurred on frame */ #define START_FRAME_LOST 0x40000000 /* START_FRAME_LOST */ #define END_FRAME_LOST 0x20000000 /* END_FRAME_LOST */ #define RX_ER_NONOCT 0x10000000 /* Rx Non Octet Aligned Packet */ #define RX_ER_BITSTUFF 0x08000000 /* Frame Aborted --Received packet with bit stuff error */ #define RX_ER_CRC 0x04000000 /* Received packet with CRC error */ -#define RX_ER_OVERUN 0x02000000 /* Over-run occured on reception */ +#define RX_ER_OVERUN 0x02000000 /* Over-run occurred on reception */ #define RX_ER_PID 0x01000000 /* Wrong PID received */ /* Tranmit side */ #define TX_ER_NAK 0x00800000 /* Received NAK handshake */ @@ -379,7 +379,7 @@ struct qe_udc { #define T_LSP 0x01000000 /* Low-speed transaction */ #define T_PID 0x00c00000 /* packet id */ #define T_NAK 0x00100000 /* No ack. */ -#define T_STAL 0x00080000 /* Stall recieved */ +#define T_STAL 0x00080000 /* Stall received */ #define T_TO 0x00040000 /* time out */ #define T_UN 0x00020000 /* underrun */ diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index 912cb8e63fe3..07499c1cdcc4 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -464,7 +464,7 @@ static int fsl_ep_enable(struct usb_ep *_ep, max = le16_to_cpu(desc->wMaxPacketSize); - /* Disable automatic zlp generation. Driver is reponsible to indicate + /* Disable automatic zlp generation. Driver is responsible to indicate * explicitly through req->req.zero. This is needed to enable multi-td * request. */ zlt = 1; @@ -648,7 +648,7 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req) | EP_QUEUE_HEAD_STATUS_HALT)); dQH->size_ioc_int_sts &= temp; - /* Ensure that updates to the QH will occure before priming. */ + /* Ensure that updates to the QH will occur before priming. */ wmb(); /* Prime endpoint by writing 1 to ENDPTPRIME */ @@ -1459,7 +1459,7 @@ static int process_ep_req(struct fsl_udc *udc, int pipe, status = -EILSEQ; break; } else - ERR("Unknown error has occured (0x%x)!\n", + ERR("Unknown error has occurred (0x%x)!\n", errors); } else if (le32_to_cpu(curr_td->size_ioc_sts) diff --git a/drivers/usb/gadget/fsl_usb2_udc.h b/drivers/usb/gadget/fsl_usb2_udc.h index 20aeceed48c7..e88cce5c2c0d 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.h +++ b/drivers/usb/gadget/fsl_usb2_udc.h @@ -15,7 +15,7 @@ struct usb_dr_device { u8 res1[256]; u16 caplength; /* Capability Register Length */ u16 hciversion; /* Host Controller Interface Version */ - u32 hcsparams; /* Host Controller Structual Parameters */ + u32 hcsparams; /* Host Controller Structural Parameters */ u32 hccparams; /* Host Controller Capability Parameters */ u8 res2[20]; u32 dciversion; /* Device Controller Interface Version */ @@ -52,7 +52,7 @@ struct usb_dr_host { u8 res1[256]; u16 caplength; /* Capability Register Length */ u16 hciversion; /* Host Controller Interface Version */ - u32 hcsparams; /* Host Controller Structual Parameters */ + u32 hcsparams; /* Host Controller Structural Parameters */ u32 hccparams; /* Host Controller Capability Parameters */ u8 res2[20]; u32 dciversion; /* Device Controller Interface Version */ diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c index 0ab7e141d494..47b86b99d449 100644 --- a/drivers/usb/gadget/gmidi.c +++ b/drivers/usb/gadget/gmidi.c @@ -67,7 +67,7 @@ MODULE_PARM_DESC(index, "Index value for the USB MIDI Gadget adapter."); module_param(id, charp, 0444); MODULE_PARM_DESC(id, "ID string for the USB MIDI Gadget adapter."); -/* Some systems will want different product identifers published in the +/* Some systems will want different product identifiers published in the * device descriptor, either numbers or strings or both. These string * parameters are in UTF-8 (superset of ASCII's 7 bit characters). */ diff --git a/drivers/usb/gadget/langwell_udc.c b/drivers/usb/gadget/langwell_udc.c index 1eca8b47ce3c..9cee88a43a73 100644 --- a/drivers/usb/gadget/langwell_udc.c +++ b/drivers/usb/gadget/langwell_udc.c @@ -642,7 +642,7 @@ static int queue_dtd(struct langwell_ep *ep, struct langwell_request *req) dqh->dtd_status &= dtd_status; dev_vdbg(&dev->pdev->dev, "dqh->dtd_status = 0x%x\n", dqh->dtd_status); - /* ensure that updates to the dQH will occure before priming */ + /* ensure that updates to the dQH will occur before priming */ wmb(); /* write 1 to endptprime register to PRIME endpoint */ diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c index d5468a7f38e0..b62b2640deb0 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/mv_udc_core.c @@ -325,7 +325,7 @@ static int queue_dtd(struct mv_ep *ep, struct mv_req *req) /* * Ensure that updates to the QH will - * occure before priming. + * occur before priming. */ wmb(); @@ -338,7 +338,7 @@ static int queue_dtd(struct mv_ep *ep, struct mv_req *req) & EP_QUEUE_HEAD_NEXT_POINTER_MASK;; dqh->size_ioc_int_sts = 0; - /* Ensure that updates to the QH will occure before priming. */ + /* Ensure that updates to the QH will occur before priming. */ wmb(); /* Prime the Endpoint */ @@ -1845,7 +1845,7 @@ static irqreturn_t mv_udc_irq(int irq, void *dev) return IRQ_NONE; } - /* Clear all the interrupts occured */ + /* Clear all the interrupts occurred */ writel(status, &udc->op_regs->usbsts); if (status & USBSTS_ERR) diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index d09155b25d73..24696f7fa6a9 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c @@ -117,7 +117,7 @@ module_param (fifo_mode, ushort, 0644); /* enable_suspend -- When enabled, the driver will respond to * USB suspend requests by powering down the NET2280. Otherwise, - * USB suspend requests will be ignored. This is acceptible for + * USB suspend requests will be ignored. This is acceptable for * self-powered devices */ static int enable_suspend = 0; diff --git a/drivers/usb/gadget/nokia.c b/drivers/usb/gadget/nokia.c index b5364f9d7cd2..55ca63ad3506 100644 --- a/drivers/usb/gadget/nokia.c +++ b/drivers/usb/gadget/nokia.c @@ -203,7 +203,7 @@ static int __init nokia_bind(struct usb_composite_dev *cdev) goto err_usb; } - /* finaly register the configuration */ + /* finally register the configuration */ status = usb_add_config(cdev, &nokia_config_500ma_driver, nokia_bind_config); if (status < 0) diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index 12ff6cffedc9..c3f2bd42bd5a 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c @@ -126,7 +126,7 @@ static struct printer_dev usb_printer_gadget; #define PRINTER_VENDOR_NUM 0x0525 /* NetChip */ #define PRINTER_PRODUCT_NUM 0xa4a8 /* Linux-USB Printer Gadget */ -/* Some systems will want different product identifers published in the +/* Some systems will want different product identifiers published in the * device descriptor, either numbers or strings or both. These string * parameters are in UTF-8 (superset of ASCII's 7 bit characters). */ diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c index 2efd6732d130..78a39a41547d 100644 --- a/drivers/usb/gadget/pxa27x_udc.c +++ b/drivers/usb/gadget/pxa27x_udc.c @@ -602,7 +602,7 @@ static void inc_ep_stats_reqs(struct pxa_ep *ep, int is_in) /** * inc_ep_stats_bytes - Update ep stats counts * @ep: physical endpoint - * @count: bytes transfered on endpoint + * @count: bytes transferred on endpoint * @is_in: ep direction (USB_DIR_IN or 0) */ static void inc_ep_stats_bytes(struct pxa_ep *ep, int count, int is_in) @@ -877,7 +877,7 @@ static void nuke(struct pxa_ep *ep, int status) * If there is less space in request than bytes received in OUT endpoint, * bytes are left in the OUT endpoint. * - * Returns how many bytes were actually transfered + * Returns how many bytes were actually transferred */ static int read_packet(struct pxa_ep *ep, struct pxa27x_request *req) { @@ -914,7 +914,7 @@ static int read_packet(struct pxa_ep *ep, struct pxa27x_request *req) * endpoint. If there are no bytes to transfer, doesn't write anything * to physical endpoint. * - * Returns how many bytes were actually transfered. + * Returns how many bytes were actually transferred. */ static int write_packet(struct pxa_ep *ep, struct pxa27x_request *req, unsigned int max) @@ -991,7 +991,7 @@ static int read_fifo(struct pxa_ep *ep, struct pxa27x_request *req) * caller guarantees at least one packet buffer is ready (or a zlp). * Doesn't complete the request, that's the caller's job * - * Returns 1 if request fully transfered, 0 if partial transfer + * Returns 1 if request fully transferred, 0 if partial transfer */ static int write_fifo(struct pxa_ep *ep, struct pxa27x_request *req) { @@ -1094,7 +1094,7 @@ static int read_ep0_fifo(struct pxa_ep *ep, struct pxa27x_request *req) * Sends a request (or a part of the request) to the control endpoint (ep0 in). * If the request doesn't fit, the remaining part will be sent from irq. * The request is considered fully written only if either : - * - last write transfered all remaining bytes, but fifo was not fully filled + * - last write transferred all remaining bytes, but fifo was not fully filled * - last write was a 0 length write * * Returns 1 if request fully written, 0 if request only partially sent @@ -1548,7 +1548,7 @@ static int pxa_udc_get_frame(struct usb_gadget *_gadget) * pxa_udc_wakeup - Force udc device out of suspend * @_gadget: usb gadget * - * Returns 0 if successfull, error code otherwise + * Returns 0 if successful, error code otherwise */ static int pxa_udc_wakeup(struct usb_gadget *_gadget) { diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index ef825c3baed9..0912679de99a 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -41,8 +41,8 @@ /* EP0_MPS_LIMIT * * Unfortunately there seems to be a limit of the amount of data that can - * be transfered by IN transactions on EP0. This is either 127 bytes or 3 - * packets (which practially means 1 packet and 63 bytes of data) when the + * be transferred by IN transactions on EP0. This is either 127 bytes or 3 + * packets (which practically means 1 packet and 63 bytes of data) when the * MPS is set to 64. * * This means if we are wanting to move >127 bytes of data, we need to @@ -783,7 +783,7 @@ static void s3c_hsotg_start_req(struct s3c_hsotg *hsotg, hsotg->regs + S3C_DIEPINT(index)); /* Note, trying to clear the NAK here causes problems with transmit - * on the S3C6400 ending up with the TXFIFO becomming full. */ + * on the S3C6400 ending up with the TXFIFO becoming full. */ /* check ep is enabled */ if (!(readl(hsotg->regs + epctrl_reg) & S3C_DxEPCTL_EPEna)) @@ -1176,10 +1176,10 @@ static void s3c_hsotg_process_control(struct s3c_hsotg *hsotg, writel(ctrl, hsotg->regs + reg); dev_dbg(hsotg->dev, - "writen DxEPCTL=0x%08x to %08x (DxEPCTL=0x%08x)\n", + "written DxEPCTL=0x%08x to %08x (DxEPCTL=0x%08x)\n", ctrl, reg, readl(hsotg->regs + reg)); - /* don't belive we need to anything more to get the EP + /* don't believe we need to anything more to get the EP * to reply with a STALL packet */ } } @@ -1416,7 +1416,7 @@ static void s3c_hsotg_rx_data(struct s3c_hsotg *hsotg, int ep_idx, int size) * transaction. * * Note, since we don't write any data to the TxFIFO, then it is - * currently belived that we do not need to wait for any space in + * currently believed that we do not need to wait for any space in * the TxFIFO. */ static void s3c_hsotg_send_zlp(struct s3c_hsotg *hsotg, @@ -1540,7 +1540,7 @@ static u32 s3c_hsotg_read_frameno(struct s3c_hsotg *hsotg) * that requires processing, so find out what is in there and do the * appropriate read. * - * The RXFIFO is a true FIFO, the packets comming out are still in packet + * The RXFIFO is a true FIFO, the packets coming out are still in packet * chunks, so if you have x packets received on an endpoint you'll get x * FIFO events delivered, each with a packet's worth of data in it. * @@ -2188,7 +2188,7 @@ irq_retry: /* these next two seem to crop-up occasionally causing the core * to shutdown the USB transfer, so try clearing them and logging - * the occurence. */ + * the occurrence. */ if (gintsts & S3C_GINTSTS_GOUTNakEff) { dev_info(hsotg->dev, "GOUTNakEff triggered\n"); @@ -2469,7 +2469,7 @@ static struct usb_ep_ops s3c_hsotg_ep_ops = { .queue = s3c_hsotg_ep_queue, .dequeue = s3c_hsotg_ep_dequeue, .set_halt = s3c_hsotg_ep_sethalt, - /* note, don't belive we have any call for the fifo routines */ + /* note, don't believe we have any call for the fifo routines */ }; /** diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 9483acdf2e9e..e0e0787b724b 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -402,7 +402,7 @@ config FHCI_DEBUG depends on USB_FHCI_HCD && DEBUG_FS help Say "y" to see some FHCI debug information and statistics - throught debugfs. + through debugfs. config USB_U132_HCD tristate "Elan U132 Adapter Host Controller" diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index f86d3fa20214..333ddc156919 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -644,7 +644,7 @@ static inline void ehci_writel(const struct ehci_hcd *ehci, /* * On certain ppc-44x SoC there is a HW issue, that could only worked around with * explicit suspend/operate of OHCI. This function hereby makes sense only on that arch. - * Other common bits are dependant on has_amcc_usb23 quirk flag. + * Other common bits are dependent on has_amcc_usb23 quirk flag. */ #ifdef CONFIG_44x static inline void set_ohci_hcfs(struct ehci_hcd *ehci, int operational) diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c index b84ff7e51896..19223c7449e1 100644 --- a/drivers/usb/host/fhci-hcd.c +++ b/drivers/usb/host/fhci-hcd.c @@ -401,7 +401,7 @@ static int fhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, /* 1 td fro setup,1 for ack */ size = 2; case PIPE_BULK: - /* one td for every 4096 bytes(can be upto 8k) */ + /* one td for every 4096 bytes(can be up to 8k) */ size += urb->transfer_buffer_length / 4096; /* ...add for any remaining bytes... */ if ((urb->transfer_buffer_length % 4096) != 0) diff --git a/drivers/usb/host/fhci-tds.c b/drivers/usb/host/fhci-tds.c index 38fe058fbe61..0ea577bfca2a 100644 --- a/drivers/usb/host/fhci-tds.c +++ b/drivers/usb/host/fhci-tds.c @@ -40,7 +40,7 @@ #define TD_RXER 0x0020 /* Rx error or not */ #define TD_NAK 0x0010 /* No ack. */ -#define TD_STAL 0x0008 /* Stall recieved */ +#define TD_STAL 0x0008 /* Stall received */ #define TD_TO 0x0004 /* time out */ #define TD_UN 0x0002 /* underrun */ #define TD_NO 0x0010 /* Rx Non Octet Aligned Packet */ @@ -274,7 +274,7 @@ void fhci_init_ep_registers(struct fhci_usb *usb, struct endpoint *ep, * It is also preparing the TDs for new frames. If the Tx interrupts * are disabled, the application should call that routine to get * confirmation about the submitted frames. Otherwise, the routine is - * called frome the interrupt service routine during the Tx interrupt. + * called from the interrupt service routine during the Tx interrupt. * In that case the application is informed by calling the application * specific 'fhci_transaction_confirm' routine */ @@ -337,7 +337,7 @@ static void fhci_td_transaction_confirm(struct fhci_usb *usb) pkt->status = USB_TD_RX_ER_NONOCT; else fhci_err(usb->fhci, "illegal error " - "occured\n"); + "occurred\n"); } else if (td_status & TD_NAK) pkt->status = USB_TD_TX_ER_NAK; else if (td_status & TD_TO) @@ -347,7 +347,7 @@ static void fhci_td_transaction_confirm(struct fhci_usb *usb) else if (td_status & TD_STAL) pkt->status = USB_TD_TX_ER_STALL; else - fhci_err(usb->fhci, "illegal error occured\n"); + fhci_err(usb->fhci, "illegal error occurred\n"); } else if ((extra_data & TD_TOK_IN) && pkt->len > td_length - CRC_SIZE) { pkt->status = USB_TD_RX_DATA_UNDERUN; diff --git a/drivers/usb/host/fhci.h b/drivers/usb/host/fhci.h index 71c3caaea4c1..dc6939a44a1a 100644 --- a/drivers/usb/host/fhci.h +++ b/drivers/usb/host/fhci.h @@ -82,7 +82,7 @@ #define USB_TD_RX_ER_NONOCT 0x40000000 /* Tx Non Octet Aligned Packet */ #define USB_TD_RX_ER_BITSTUFF 0x20000000 /* Frame Aborted-Received pkt */ #define USB_TD_RX_ER_CRC 0x10000000 /* CRC error */ -#define USB_TD_RX_ER_OVERUN 0x08000000 /* Over - run occured */ +#define USB_TD_RX_ER_OVERUN 0x08000000 /* Over - run occurred */ #define USB_TD_RX_ER_PID 0x04000000 /* wrong PID received */ #define USB_TD_RX_DATA_UNDERUN 0x02000000 /* shorter than expected */ #define USB_TD_RX_DATA_OVERUN 0x01000000 /* longer than expected */ @@ -363,7 +363,7 @@ struct ed { struct td { void *data; /* a pointer to the data buffer */ unsigned int len; /* length of the data to be submitted */ - unsigned int actual_len; /* actual bytes transfered on this td */ + unsigned int actual_len; /* actual bytes transferred on this td */ enum fhci_ta_type type; /* transaction type */ u8 toggle; /* toggle for next trans. within this TD */ u16 iso_index; /* ISO transaction index */ diff --git a/drivers/usb/host/imx21-hcd.c b/drivers/usb/host/imx21-hcd.c index 2562e92e3178..af05718bdc73 100644 --- a/drivers/usb/host/imx21-hcd.c +++ b/drivers/usb/host/imx21-hcd.c @@ -1323,7 +1323,7 @@ static void process_etds(struct usb_hcd *hcd, struct imx21 *imx21, int sof) * (and hence no interrupt occurs). * This causes the transfer in question to hang. * The kludge below checks for this condition at each SOF and processes any - * blocked ETDs (after an arbitary 10 frame wait) + * blocked ETDs (after an arbitrary 10 frame wait) * * With a single active transfer the usbtest test suite will run for days * without the kludge. diff --git a/drivers/usb/host/isp116x.h b/drivers/usb/host/isp116x.h index 12db961acdfb..9a2c400e6090 100644 --- a/drivers/usb/host/isp116x.h +++ b/drivers/usb/host/isp116x.h @@ -13,7 +13,7 @@ /* Full speed: max # of bytes to transfer for a single urb at a time must be < 1024 && must be multiple of 64. - 832 allows transfering 4kiB within 5 frames. */ + 832 allows transferring 4kiB within 5 frames. */ #define MAX_TRANSFER_SIZE_FULLSPEED 832 /* Low speed: there is no reason to schedule in very big diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c index 662cd002adfc..f97570a847ca 100644 --- a/drivers/usb/host/isp1362-hcd.c +++ b/drivers/usb/host/isp1362-hcd.c @@ -546,7 +546,7 @@ static void postproc_ep(struct isp1362_hcd *isp1362_hcd, struct isp1362_ep *ep) if (usb_pipecontrol(urb->pipe)) { ep->nextpid = USB_PID_ACK; /* save the data underrun error code for later and - * procede with the status stage + * proceed with the status stage */ urb->actual_length += PTD_GET_COUNT(ptd); BUG_ON(urb->actual_length > urb->transfer_buffer_length); diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index e7288639edb0..d55723514860 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -162,7 +162,7 @@ static int ohci_urb_enqueue ( // case PIPE_INTERRUPT: // case PIPE_BULK: default: - /* one TD for every 4096 Bytes (can be upto 8K) */ + /* one TD for every 4096 Bytes (can be up to 8K) */ size += urb->transfer_buffer_length / 4096; /* ... and for any remaining bytes ... */ if ((urb->transfer_buffer_length % 4096) != 0) diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c index 44e4deb362e1..4a771f6cc822 100644 --- a/drivers/usb/host/oxu210hp-hcd.c +++ b/drivers/usb/host/oxu210hp-hcd.c @@ -2879,7 +2879,7 @@ static int oxu_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, /* Ok, we have more job to do! :) */ for (i = 0; i < num - 1; i++) { - /* Get free micro URB poll till a free urb is recieved */ + /* Get free micro URB poll till a free urb is received */ do { murb = (struct urb *) oxu_murb_alloc(oxu); @@ -2911,7 +2911,7 @@ static int oxu_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, /* Last urb requires special handling */ - /* Get free micro URB poll till a free urb is recieved */ + /* Get free micro URB poll till a free urb is received */ do { murb = (struct urb *) oxu_murb_alloc(oxu); if (!murb) diff --git a/drivers/usb/host/whci/qset.c b/drivers/usb/host/whci/qset.c index dc0ab8382f5d..d6e175428618 100644 --- a/drivers/usb/host/whci/qset.c +++ b/drivers/usb/host/whci/qset.c @@ -739,7 +739,7 @@ static int get_urb_status_from_qtd(struct urb *urb, u32 status) * process_inactive_qtd - process an inactive (but not halted) qTD. * * Update the urb with the transfer bytes from the qTD, if the urb is - * completely transfered or (in the case of an IN only) the LPF is + * completely transferred or (in the case of an IN only) the LPF is * set, then the transfer is complete and the urb should be returned * to the system. */ diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 9a3645fd759b..196e0181b2ed 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -741,7 +741,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) int retval; /* Wait a bit if either of the roothubs need to settle from the - * transistion into bus suspend. + * transition into bus suspend. */ if (time_before(jiffies, xhci->bus_state[0].next_statechange) || time_before(jiffies, @@ -2072,7 +2072,7 @@ int xhci_alloc_streams(struct usb_hcd *hcd, struct usb_device *udev, return -EINVAL; } vdev = xhci->devs[udev->slot_id]; - /* Mark each endpoint as being in transistion, so + /* Mark each endpoint as being in transition, so * xhci_urb_enqueue() will reject all URBs. */ for (i = 0; i < num_eps; i++) { diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 711de253bc0f..07e263063e37 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -873,7 +873,7 @@ struct xhci_transfer_event { #define COMP_CMD_ABORT 25 /* Stopped - transfer was terminated by a stop endpoint command */ #define COMP_STOP 26 -/* Same as COMP_EP_STOPPED, but the transfered length in the event is invalid */ +/* Same as COMP_EP_STOPPED, but the transferred length in the event is invalid */ #define COMP_STOP_INVAL 27 /* Control Abort Error - Debug Capability - control pipe aborted */ #define COMP_DBG_ABORT 28 diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c index c90c89dc0003..a0037961e5bd 100644 --- a/drivers/usb/image/microtek.c +++ b/drivers/usb/image/microtek.c @@ -69,7 +69,7 @@ * 20000513 added IDs for all products supported by Windows driver (john) * 20000514 Rewrote mts_scsi_queuecommand to use URBs (john) * 20000514 Version 0.0.8j - * 20000514 Fix reporting of non-existant devices to SCSI layer (john) + * 20000514 Fix reporting of non-existent devices to SCSI layer (john) * 20000514 Added MTS_DEBUG_INT (john) * 20000514 Changed "usb-microtek" to "microtek" for consistency (john) * 20000514 Stupid bug fixes (john) @@ -557,14 +557,14 @@ mts_build_transfer_context(struct scsi_cmnd *srb, struct mts_desc* desc) if ( !memcmp( srb->cmnd, mts_read_image_sig, mts_read_image_sig_len ) ) { pipe = usb_rcvbulkpipe(desc->usb_dev,desc->ep_image); - MTS_DEBUG( "transfering from desc->ep_image == %d\n", + MTS_DEBUG( "transferring from desc->ep_image == %d\n", (int)desc->ep_image ); } else if ( MTS_DIRECTION_IS_IN(srb->cmnd[0]) ) { pipe = usb_rcvbulkpipe(desc->usb_dev,desc->ep_response); - MTS_DEBUG( "transfering from desc->ep_response == %d\n", + MTS_DEBUG( "transferring from desc->ep_response == %d\n", (int)desc->ep_response); } else { - MTS_DEBUG("transfering to desc->ep_out == %d\n", + MTS_DEBUG("transferring to desc->ep_out == %d\n", (int)desc->ep_out); pipe = usb_sndbulkpipe(desc->usb_dev,desc->ep_out); } diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c index e573e4704015..a2190b983f52 100644 --- a/drivers/usb/misc/iowarrior.c +++ b/drivers/usb/misc/iowarrior.c @@ -40,7 +40,7 @@ #ifdef CONFIG_USB_DYNAMIC_MINORS #define IOWARRIOR_MINOR_BASE 0 #else -#define IOWARRIOR_MINOR_BASE 208 // SKELETON_MINOR_BASE 192 + 16, not offical yet +#define IOWARRIOR_MINOR_BASE 208 // SKELETON_MINOR_BASE 192 + 16, not official yet #endif /* interrupt input queue size */ diff --git a/drivers/usb/otg/isp1301_omap.c b/drivers/usb/otg/isp1301_omap.c index 8c6fdef61d1c..e25700f44b6f 100644 --- a/drivers/usb/otg/isp1301_omap.c +++ b/drivers/usb/otg/isp1301_omap.c @@ -1531,7 +1531,7 @@ isp1301_probe(struct i2c_client *i2c, const struct i2c_device_id *id) i2c_set_clientdata(i2c, isp); isp->client = i2c; - /* verify the chip (shouldn't be necesary) */ + /* verify the chip (shouldn't be necessary) */ status = isp1301_get_u16(isp, ISP1301_VENDOR_ID); if (status != I2C_VENDOR_ID_PHILIPS) { dev_dbg(&i2c->dev, "not philips id: %d\n", status); diff --git a/drivers/usb/otg/langwell_otg.c b/drivers/usb/otg/langwell_otg.c index 7f9b8cd4514b..e973ff19c55a 100644 --- a/drivers/usb/otg/langwell_otg.c +++ b/drivers/usb/otg/langwell_otg.c @@ -580,7 +580,7 @@ static void langwell_otg_add_ktimer(enum langwell_otg_timer_type timers) time = TB_BUS_SUSPEND; break; default: - dev_dbg(lnw->dev, "unkown timer, cannot enable it\n"); + dev_dbg(lnw->dev, "unknown timer, cannot enable it\n"); return; } @@ -1381,7 +1381,7 @@ static void langwell_otg_work(struct work_struct *work) } else if (!iotg->hsm.a_bus_req && iotg->otg.host && iotg->otg.host->b_hnp_enable) { /* It is not safe enough to do a fast - * transistion from A_WAIT_BCON to + * transition from A_WAIT_BCON to * A_SUSPEND */ msleep(10000); if (iotg->hsm.a_bus_req) diff --git a/drivers/usb/serial/aircable.c b/drivers/usb/serial/aircable.c index 0db6ace16f7b..aba201cb872c 100644 --- a/drivers/usb/serial/aircable.c +++ b/drivers/usb/serial/aircable.c @@ -16,7 +16,7 @@ * When reading the process is almost equal except that the header starts with * 0x00 0x20. * - * The device simply need some stuff to understand data comming from the usb + * The device simply need some stuff to understand data coming from the usb * buffer: The First and Second byte is used for a Header, the Third and Fourth * tells the device the amount of information the package holds. * Packages are 60 bytes long Header Stuff. @@ -30,7 +30,7 @@ * one. * * The driver registers himself with the USB-serial core and the USB Core. I had - * to implement a probe function agains USB-serial, because other way, the + * to implement a probe function against USB-serial, because other way, the * driver was attaching himself to both interfaces. I have tryed with different * configurations of usb_serial_driver with out exit, only the probe function * could handle this correctly. diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 4df3e0cecbae..0f11afdda134 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -101,7 +101,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x10C4, 0x81F2) }, /* C1007 HF band RFID controller */ { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */ { USB_DEVICE(0x10C4, 0x822B) }, /* Modem EDGE(GSM) Comander 2 */ - { USB_DEVICE(0x10C4, 0x826B) }, /* Cygnal Integrated Products, Inc., Fasttrax GPS demostration module */ + { USB_DEVICE(0x10C4, 0x826B) }, /* Cygnal Integrated Products, Inc., Fasttrax GPS demonstration module */ { USB_DEVICE(0x10C4, 0x8293) }, /* Telegesys ETRX2USB */ { USB_DEVICE(0x10C4, 0x82F9) }, /* Procyon AVS */ { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */ diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index 987e9bf7bd02..d9906eb9d16a 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -35,7 +35,7 @@ * * Lonnie Mendez * 04-10-2004 - * Driver modified to support dynamic line settings. Various improvments + * Driver modified to support dynamic line settings. Various improvements * and features. * * Neil Whelchel diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 65967b36365f..a973c7a29d6e 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -17,7 +17,7 @@ * See Documentation/usb/usb-serial.txt for more information on using this * driver * - * See http://ftdi-usb-sio.sourceforge.net for upto date testing info + * See http://ftdi-usb-sio.sourceforge.net for up to date testing info * and extra documentation * * Change entries from 2004 and earlier can be found in versions of this diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index f1aedfa7c420..abf095be5753 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -1981,7 +1981,7 @@ static void process_rcvd_status(struct edgeport_serial *edge_serial, if (code == IOSP_STATUS_OPEN_RSP) { edge_port->txCredits = GET_TX_BUFFER_SIZE(byte3); edge_port->maxTxCredits = edge_port->txCredits; - dbg("%s - Port %u Open Response Inital MSR = %02x TxBufferSize = %d", __func__, edge_serial->rxPort, byte2, edge_port->txCredits); + dbg("%s - Port %u Open Response Initial MSR = %02x TxBufferSize = %d", __func__, edge_serial->rxPort, byte2, edge_port->txCredits); handle_new_msr(edge_port, byte2); /* send the current line settings to the port so we are diff --git a/drivers/usb/serial/io_edgeport.h b/drivers/usb/serial/io_edgeport.h index dced7ec65470..ad9c1d47a619 100644 --- a/drivers/usb/serial/io_edgeport.h +++ b/drivers/usb/serial/io_edgeport.h @@ -68,7 +68,7 @@ struct comMapper { #define PROC_SET_COM_ENTRY 2 -/* The following sturcture is passed to the write */ +/* The following structure is passed to the write */ struct procWrite { int Command; union { diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index d8434910fa7b..0aac00afb5c8 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -433,7 +433,7 @@ static int write_i2c_mem(struct edgeport_serial *serial, /* We can only send a maximum of 1 aligned byte page at a time */ - /* calulate the number of bytes left in the first page */ + /* calculate the number of bytes left in the first page */ write_length = EPROM_PAGE_SIZE - (start_address & (EPROM_PAGE_SIZE - 1)); diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index 201f6096844b..a6f63cc8c130 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c @@ -116,7 +116,7 @@ static void opticon_read_bulk_callback(struct urb *urb) } else { if ((data[0] == 0x00) && (data[1] == 0x01)) { spin_lock_irqsave(&priv->lock, flags); - /* CTS status infomation package */ + /* CTS status information package */ if (data[2] == 0x00) priv->cts = false; else diff --git a/drivers/usb/storage/ene_ub6250.c b/drivers/usb/storage/ene_ub6250.c index 08e03745e251..0e5aafda4537 100644 --- a/drivers/usb/storage/ene_ub6250.c +++ b/drivers/usb/storage/ene_ub6250.c @@ -562,7 +562,7 @@ static int ene_sd_init(struct us_data *us) result = ene_send_scsi_cmd(us, FDIR_READ, NULL, 0); if (result != USB_STOR_XFER_GOOD) { - US_DEBUGP("Exection SD Init Code Fail !!\n"); + US_DEBUGP("Execution SD Init Code Fail !!\n"); return USB_STOR_TRANSPORT_ERROR; } @@ -581,7 +581,7 @@ static int ene_sd_init(struct us_data *us) result = ene_send_scsi_cmd(us, FDIR_READ, &buf, 0); if (result != USB_STOR_XFER_GOOD) { - US_DEBUGP("Exection SD Init Code Fail !!\n"); + US_DEBUGP("Execution SD Init Code Fail !!\n"); return USB_STOR_TRANSPORT_ERROR; } diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c index 6b9982cd5423..09e52ba47ddf 100644 --- a/drivers/usb/storage/isd200.c +++ b/drivers/usb/storage/isd200.c @@ -1510,7 +1510,7 @@ static int isd200_Initialization(struct us_data *us) * Protocol and Transport for the ISD200 ASIC * * This protocol and transport are for ATA devices connected to an ISD200 - * ASIC. An ATAPI device that is conected as a slave device will be + * ASIC. An ATAPI device that is connected as a slave device will be * detected in the driver initialization function and the protocol will * be changed to an ATAPI protocol (Transparent SCSI). * diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 689ee1fb702a..13b8bcdf3dba 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -123,7 +123,7 @@ static int slave_configure(struct scsi_device *sdev) { struct us_data *us = host_to_us(sdev->host); - /* Many devices have trouble transfering more than 32KB at a time, + /* Many devices have trouble transferring more than 32KB at a time, * while others have trouble with more than 64K. At this time we * are limiting both to 32K (64 sectores). */ diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c index bd3f415893d8..0b00091d2ae9 100644 --- a/drivers/usb/storage/shuttle_usbat.c +++ b/drivers/usb/storage/shuttle_usbat.c @@ -340,7 +340,7 @@ static int usbat_check_status(struct us_data *us) } /* - * Stores critical information in internal registers in prepartion for the execution + * Stores critical information in internal registers in preparation for the execution * of a conditional usbat_read_blocks or usbat_write_blocks call. */ static int usbat_set_shuttle_features(struct us_data *us, diff --git a/drivers/usb/wusbcore/crypto.c b/drivers/usb/wusbcore/crypto.c index 827c87f10cc5..7e4bf95f8f7b 100644 --- a/drivers/usb/wusbcore/crypto.c +++ b/drivers/usb/wusbcore/crypto.c @@ -180,7 +180,7 @@ static void bytewise_xor(void *_bo, const void *_bi1, const void *_bi2, * using the 14 bytes of @a to fill up * b1.{mac_header,e0,security_reserved,padding}. * - * NOTE: The definiton of l(a) in WUSB1.0[6.5] vs the definition of + * NOTE: The definition of l(a) in WUSB1.0[6.5] vs the definition of * l(m) is orthogonal, they bear no relationship, so it is not * in conflict with the parameter's relation that * WUSB1.0[6.4.2]) defines. @@ -272,7 +272,7 @@ static int wusb_ccm_mac(struct crypto_blkcipher *tfm_cbc, /* Now we crypt the MIC Tag (*iv) with Ax -- values per WUSB1.0[6.5] * The procedure is to AES crypt the A0 block and XOR the MIC - * Tag agains it; we only do the first 8 bytes and place it + * Tag against it; we only do the first 8 bytes and place it * directly in the destination buffer. * * POS Crypto API: size is assumed to be AES's block size. diff --git a/drivers/usb/wusbcore/reservation.c b/drivers/usb/wusbcore/reservation.c index 4ed97360c046..6f4fafdc2401 100644 --- a/drivers/usb/wusbcore/reservation.c +++ b/drivers/usb/wusbcore/reservation.c @@ -71,7 +71,7 @@ static void wusbhc_rsv_complete_cb(struct uwb_rsv *rsv) /** * wusbhc_rsv_establish - establish a reservation for the cluster - * @wusbhc: the WUSB HC requesting a bandwith reservation + * @wusbhc: the WUSB HC requesting a bandwidth reservation */ int wusbhc_rsv_establish(struct wusbhc *wusbhc) { diff --git a/drivers/usb/wusbcore/rh.c b/drivers/usb/wusbcore/rh.c index c175b7300c73..39de3900ad20 100644 --- a/drivers/usb/wusbcore/rh.c +++ b/drivers/usb/wusbcore/rh.c @@ -133,7 +133,7 @@ static int wusbhc_rh_port_reset(struct wusbhc *wusbhc, u8 port_idx) * big of a problem [and we can't make it an spinlock * because other parts need to take it and sleep] . * - * @usb_hcd is refcounted, so it won't dissapear under us + * @usb_hcd is refcounted, so it won't disappear under us * and before killing a host, the polling of the root hub * would be stopped anyway. */ diff --git a/drivers/usb/wusbcore/wa-rpipe.c b/drivers/usb/wusbcore/wa-rpipe.c index 8cb9d80207fa..ca80171f42c6 100644 --- a/drivers/usb/wusbcore/wa-rpipe.c +++ b/drivers/usb/wusbcore/wa-rpipe.c @@ -24,7 +24,7 @@ * * RPIPE * - * Targetted at different downstream endpoints + * Targeted at different downstream endpoints * * Descriptor: use to config the remote pipe. * diff --git a/drivers/usb/wusbcore/wa-xfer.c b/drivers/usb/wusbcore/wa-xfer.c index 84b744c428a4..6ccd93a9b909 100644 --- a/drivers/usb/wusbcore/wa-xfer.c +++ b/drivers/usb/wusbcore/wa-xfer.c @@ -61,7 +61,7 @@ * * Two methods it could be done: * - * (a) set up a timer everytime an rpipe's use count drops to 1 + * (a) set up a timer every time an rpipe's use count drops to 1 * (which means unused) or when a transfer ends. Reset the * timer when a xfer is queued. If the timer expires, release * the rpipe [see rpipe_ep_disable()]. @@ -140,7 +140,7 @@ struct wa_xfer { struct wahc *wa; /* Wire adapter we are plugged to */ struct usb_host_endpoint *ep; - struct urb *urb; /* URB we are transfering for */ + struct urb *urb; /* URB we are transferring for */ struct wa_seg **seg; /* transfer segments */ u8 segs, segs_submitted, segs_done; unsigned is_inbound:1; @@ -161,7 +161,7 @@ static inline void wa_xfer_init(struct wa_xfer *xfer) } /* - * Destory a transfer structure + * Destroy a transfer structure * * Note that the xfer->seg[index] thingies follow the URB life cycle, * so we need to put them, not free them. @@ -494,7 +494,7 @@ static void __wa_xfer_setup_hdr0(struct wa_xfer *xfer, * function does almost the same thing and they work closely * together. * - * If the seg request has failed but this DTO phase has suceeded, + * If the seg request has failed but this DTO phase has succeeded, * wa_seg_cb() has already failed the segment and moved the * status to WA_SEG_ERROR, so this will go through 'case 0' and * effectively do nothing. diff --git a/drivers/usb/wusbcore/wusbhc.h b/drivers/usb/wusbcore/wusbhc.h index 6bd426b7ec07..3a2d09162e70 100644 --- a/drivers/usb/wusbcore/wusbhc.h +++ b/drivers/usb/wusbcore/wusbhc.h @@ -231,7 +231,7 @@ struct wusb_port { * * Most of the times when you need to use it, it will be non-NULL, * so there is no real need to check for it (wusb_dev will - * dissapear before usb_dev). + * disappear before usb_dev). * * - The following fields need to be filled out before calling * wusbhc_create(): ports_max, mmcies_max, mmcie_{add,rm}. diff --git a/drivers/uwb/driver.c b/drivers/uwb/driver.c index 08bd6dbfd4a6..3e5454aba5d4 100644 --- a/drivers/uwb/driver.c +++ b/drivers/uwb/driver.c @@ -61,7 +61,7 @@ /** - * If a beacon dissapears for longer than this, then we consider the + * If a beacon disappears for longer than this, then we consider the * device who was represented by that beacon to be gone. * * ECMA-368[17.2.3, last para] establishes that a device must not diff --git a/drivers/uwb/drp.c b/drivers/uwb/drp.c index a8d83e25e3b6..3fbcf789dfaa 100644 --- a/drivers/uwb/drp.c +++ b/drivers/uwb/drp.c @@ -27,7 +27,7 @@ /* DRP Conflict Actions ([ECMA-368 2nd Edition] 17.4.6) */ enum uwb_drp_conflict_action { - /* Reservation is mantained, no action needed */ + /* Reservation is maintained, no action needed */ UWB_DRP_CONFLICT_MANTAIN = 0, /* the device shall not transmit frames in conflicting MASs in @@ -741,12 +741,12 @@ void uwb_drp_process_all(struct uwb_rc *rc, struct uwb_rc_evt_drp *drp_evt, * DRP notifications can occur for three different reasons: * * - UWB_DRP_NOTIF_DRP_IE_RECVD: one or more DRP IEs with the RC as - * the target or source have been recieved. + * the target or source have been received. * * These DRP IEs could be new or for an existing reservation. * * If the DRP IE for an existing reservation ceases to be to - * recieved for at least mMaxLostBeacons, the reservation should be + * received for at least mMaxLostBeacons, the reservation should be * considered to be terminated. Note that the TERMINATE reason (see * below) may not always be signalled (e.g., the remote device has * two or more reservations established with the RC). diff --git a/drivers/uwb/lc-rc.c b/drivers/uwb/lc-rc.c index b0091c771b9a..b4395f41a007 100644 --- a/drivers/uwb/lc-rc.c +++ b/drivers/uwb/lc-rc.c @@ -168,7 +168,7 @@ int uwb_rc_mac_addr_setup(struct uwb_rc *rc) } if (uwb_mac_addr_unset(&addr) || uwb_mac_addr_bcast(&addr)) { - addr.data[0] = 0x02; /* locally adminstered and unicast */ + addr.data[0] = 0x02; /* locally administered and unicast */ get_random_bytes(&addr.data[1], sizeof(addr.data)-1); result = uwb_rc_mac_addr_set(rc, &addr); diff --git a/drivers/uwb/reset.c b/drivers/uwb/reset.c index 27849292b552..3de630b0f691 100644 --- a/drivers/uwb/reset.c +++ b/drivers/uwb/reset.c @@ -52,7 +52,7 @@ const char *__strerror[] = { "cancelled", "invalid state", "invalid size", - "ack not recieved", + "ack not received", "no more asie notification", }; diff --git a/drivers/uwb/umc-dev.c b/drivers/uwb/umc-dev.c index ccd2184e05d2..b2948ec57878 100644 --- a/drivers/uwb/umc-dev.c +++ b/drivers/uwb/umc-dev.c @@ -78,7 +78,7 @@ EXPORT_SYMBOL_GPL(umc_device_register); * First we unregister the device, make sure the driver can do it's * resource release thing and then we try to release any left over * resources. We take a ref to the device, to make sure it doesn't - * dissapear under our feet. + * disappear under our feet. */ void umc_device_unregister(struct umc_dev *umc) { diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index ccecf9974587..4484c721f0f9 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c @@ -637,7 +637,7 @@ static inline unsigned int chan_to_field(unsigned int chan, const struct fb_bitf * magnitude which needs to be scaled in this function for the hardware. * Things to take into consideration are how many color registers, if * any, are supported with the current color visual. With truecolor mode - * no color palettes are supported. Here a psuedo palette is created + * no color palettes are supported. Here a pseudo palette is created * which we store the value in pseudo_palette in struct fb_info. For * pseudocolor mode we have a limited color palette. To deal with this * we can program what color is displayed for a particular pixel value. diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index d437b3daf1f5..ebb893c49e90 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c @@ -3124,12 +3124,12 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev, M = pll_regs[2]; /* - * PLL Feedback Divider N (Dependant on CLOCK_CNTL): + * PLL Feedback Divider N (Dependent on CLOCK_CNTL): */ N = pll_regs[7 + (clock_cntl & 3)]; /* - * PLL Post Divider P (Dependant on CLOCK_CNTL): + * PLL Post Divider P (Dependent on CLOCK_CNTL): */ P = 1 << (pll_regs[6] >> ((clock_cntl & 3) << 1)); diff --git a/drivers/video/aty/mach64_cursor.c b/drivers/video/aty/mach64_cursor.c index 2ba8b3c421a1..46f72ed53510 100644 --- a/drivers/video/aty/mach64_cursor.c +++ b/drivers/video/aty/mach64_cursor.c @@ -51,7 +51,7 @@ * to a larger number and saturate CUR_HORZ_POSN to zero. * * if Y becomes negative, CUR_VERT_OFFSET must be adjusted to a larger number, - * CUR_OFFSET must be adjusted to a point to the appropraite line in the cursor + * CUR_OFFSET must be adjusted to a point to the appropriate line in the cursor * definitation and CUR_VERT_POSN must be saturated to zero. */ diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c index 4ea187d93768..5dff32ac8044 100644 --- a/drivers/video/au1200fb.c +++ b/drivers/video/au1200fb.c @@ -1572,7 +1572,7 @@ static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev) /* Copy monitor specs from panel data */ /* fixme: we're setting up LCD controller windows, so these dont give a damn as to what the monitor specs are (the panel itself does, but that - isnt done here...so maybe need a generic catchall monitor setting??? */ + isn't done here...so maybe need a generic catchall monitor setting??? */ memcpy(&fbi->monspecs, &panel->monspecs, sizeof(struct fb_monspecs)); /* We first try the user mode passed in argument. If that failed, diff --git a/drivers/video/backlight/corgi_lcd.c b/drivers/video/backlight/corgi_lcd.c index af6098396fe6..c6533bad26f8 100644 --- a/drivers/video/backlight/corgi_lcd.c +++ b/drivers/video/backlight/corgi_lcd.c @@ -109,7 +109,7 @@ static unsigned long corgibl_flags; #define CORGIBL_BATTLOW 0x02 /* - * This is only a psuedo I2C interface. We can't use the standard kernel + * This is only a pseudo I2C interface. We can't use the standard kernel * routines as the interface is write only. We just assume the data is acked... */ static void lcdtg_ssp_i2c_send(struct corgi_lcd *lcd, uint8_t data) diff --git a/drivers/video/backlight/locomolcd.c b/drivers/video/backlight/locomolcd.c index bbca3127071e..be20b5cbe26c 100644 --- a/drivers/video/backlight/locomolcd.c +++ b/drivers/video/backlight/locomolcd.c @@ -6,7 +6,7 @@ * GPL v2 * * This driver assumes single CPU. That's okay, because collie is - * slightly old hardware, and noone is going to retrofit second CPU to + * slightly old hardware, and no one is going to retrofit second CPU to * old PDA. */ diff --git a/drivers/video/bfin_adv7393fb.h b/drivers/video/bfin_adv7393fb.h index 8c7f9e4fc6eb..cd591b5152a5 100644 --- a/drivers/video/bfin_adv7393fb.h +++ b/drivers/video/bfin_adv7393fb.h @@ -87,12 +87,12 @@ static const u8 init_NTSC_TESTPATTERN[] = { static const u8 init_NTSC[] = { 0x00, 0x1E, /* Power up all DACs and PLL */ - 0xC3, 0x26, /* Program RGB->YCrCb Color Space convertion matrix */ - 0xC5, 0x12, /* Program RGB->YCrCb Color Space convertion matrix */ - 0xC2, 0x4A, /* Program RGB->YCrCb Color Space convertion matrix */ - 0xC6, 0x5E, /* Program RGB->YCrCb Color Space convertion matrix */ - 0xBD, 0x19, /* Program RGB->YCrCb Color Space convertion matrix */ - 0xBF, 0x42, /* Program RGB->YCrCb Color Space convertion matrix */ + 0xC3, 0x26, /* Program RGB->YCrCb Color Space conversion matrix */ + 0xC5, 0x12, /* Program RGB->YCrCb Color Space conversion matrix */ + 0xC2, 0x4A, /* Program RGB->YCrCb Color Space conversion matrix */ + 0xC6, 0x5E, /* Program RGB->YCrCb Color Space conversion matrix */ + 0xBD, 0x19, /* Program RGB->YCrCb Color Space conversion matrix */ + 0xBF, 0x42, /* Program RGB->YCrCb Color Space conversion matrix */ 0x8C, 0x1F, /* NTSC Subcarrier Frequency */ 0x8D, 0x7C, /* NTSC Subcarrier Frequency */ 0x8E, 0xF0, /* NTSC Subcarrier Frequency */ @@ -109,12 +109,12 @@ static const u8 init_NTSC[] = { static const u8 init_PAL[] = { 0x00, 0x1E, /* Power up all DACs and PLL */ - 0xC3, 0x26, /* Program RGB->YCrCb Color Space convertion matrix */ - 0xC5, 0x12, /* Program RGB->YCrCb Color Space convertion matrix */ - 0xC2, 0x4A, /* Program RGB->YCrCb Color Space convertion matrix */ - 0xC6, 0x5E, /* Program RGB->YCrCb Color Space convertion matrix */ - 0xBD, 0x19, /* Program RGB->YCrCb Color Space convertion matrix */ - 0xBF, 0x42, /* Program RGB->YCrCb Color Space convertion matrix */ + 0xC3, 0x26, /* Program RGB->YCrCb Color Space conversion matrix */ + 0xC5, 0x12, /* Program RGB->YCrCb Color Space conversion matrix */ + 0xC2, 0x4A, /* Program RGB->YCrCb Color Space conversion matrix */ + 0xC6, 0x5E, /* Program RGB->YCrCb Color Space conversion matrix */ + 0xBD, 0x19, /* Program RGB->YCrCb Color Space conversion matrix */ + 0xBF, 0x42, /* Program RGB->YCrCb Color Space conversion matrix */ 0x8C, 0xCB, /* PAL Subcarrier Frequency */ 0x8D, 0x8A, /* PAL Subcarrier Frequency */ 0x8E, 0x09, /* PAL Subcarrier Frequency */ diff --git a/drivers/video/console/font_mini_4x6.c b/drivers/video/console/font_mini_4x6.c index a19a7f33133e..fa6e698e63c4 100644 --- a/drivers/video/console/font_mini_4x6.c +++ b/drivers/video/console/font_mini_4x6.c @@ -1,5 +1,5 @@ -/* Hand composed "Miniscule" 4x6 font, with binary data generated using +/* Hand composed "Minuscule" 4x6 font, with binary data generated using * Perl stub. * * Use 'perl -x mini_4x6.c < mini_4x6.c > new_version.c' to regenerate diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index 8d61ef96eedd..8b7d47386f39 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c @@ -763,7 +763,7 @@ static int fb_wait_for_vsync(struct fb_info *info) /* * Set flag to 0 and wait for isr to set to 1. It would seem there is a - * race condition here where the ISR could have occured just before or + * race condition here where the ISR could have occurred just before or * just after this set. But since we are just coarsely waiting for * a frame to complete then that's OK. i.e. if the frame completed * just before this code executed then we have to wait another full diff --git a/drivers/video/display/display-sysfs.c b/drivers/video/display/display-sysfs.c index f6a09ab0dac6..0c647d7af0ee 100644 --- a/drivers/video/display/display-sysfs.c +++ b/drivers/video/display/display-sysfs.c @@ -182,7 +182,7 @@ void display_device_unregister(struct display_device *ddev) mutex_lock(&ddev->lock); device_unregister(ddev->dev); mutex_unlock(&ddev->lock); - // Mark device index as avaliable + // Mark device index as available mutex_lock(&allocated_dsp_lock); idr_remove(&allocated_dsp, ddev->idx); mutex_unlock(&allocated_dsp_lock); diff --git a/drivers/video/ep93xx-fb.c b/drivers/video/ep93xx-fb.c index b358d045f130..cbdb1bd77c21 100644 --- a/drivers/video/ep93xx-fb.c +++ b/drivers/video/ep93xx-fb.c @@ -456,7 +456,7 @@ static int __init ep93xxfb_alloc_videomem(struct fb_info *info) * There is a bug in the ep93xx framebuffer which causes problems * if bit 27 of the physical address is set. * See: http://marc.info/?l=linux-arm-kernel&m=110061245502000&w=2 - * There does not seem to be any offical errata for this, but I + * There does not seem to be any official errata for this, but I * have confirmed the problem exists on my hardware (ep9315) at * least. */ diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c index f4a32779168b..04251ce89184 100644 --- a/drivers/video/fbsysfs.c +++ b/drivers/video/fbsysfs.c @@ -33,7 +33,7 @@ * for driver private data (info->par). info->par (if any) will be * aligned to sizeof(long). * - * Returns the new structure, or NULL if an error occured. + * Returns the new structure, or NULL if an error occurred. * */ struct fb_info *framebuffer_alloc(size_t size, struct device *dev) diff --git a/drivers/video/fm2fb.c b/drivers/video/fm2fb.c index 1b0feb8e7244..d0533b7aad79 100644 --- a/drivers/video/fm2fb.c +++ b/drivers/video/fm2fb.c @@ -45,7 +45,7 @@ * buffer needs an amount of memory of 1.769.472 bytes which * is near to 2 MByte (the allocated address space of Zorro2). * The memory is channel interleaved. That means every channel - * owns four VRAMs. Unfortunatly most FrameMasters II are + * owns four VRAMs. Unfortunately most FrameMasters II are * not assembled with memory for the alpha channel. In this * case it could be possible to add the frame buffer into the * normal memory pool. diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c index 9048f87fa8c1..bedf5be27f05 100644 --- a/drivers/video/fsl-diu-fb.c +++ b/drivers/video/fsl-diu-fb.c @@ -882,7 +882,7 @@ static inline __u32 CNVT_TOHW(__u32 val, __u32 width) * which needs to be scaled in this function for the hardware. Things to take * into consideration are how many color registers, if any, are supported with * the current color visual. With truecolor mode no color palettes are - * supported. Here a psuedo palette is created which we store the value in + * supported. Here a pseudo palette is created which we store the value in * pseudo_palette in struct fb_info. For pseudocolor mode we have a limited * color palette. */ diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c index 933899dca33a..7e7b7a9ba274 100644 --- a/drivers/video/gbefb.c +++ b/drivers/video/gbefb.c @@ -721,7 +721,7 @@ static int gbefb_set_par(struct fb_info *info) Tiles have the advantage that they can be allocated individually in memory. However, this mapping is not linear at all, which is not - really convienient. In order to support linear addressing, the GBE + really convenient. In order to support linear addressing, the GBE DMA hardware is fooled into thinking the screen is only one tile large and but has a greater height, so that the DMA transfer covers the same region. diff --git a/drivers/video/geode/lxfb.h b/drivers/video/geode/lxfb.h index be8ccb47ebe0..cfcd8090f313 100644 --- a/drivers/video/geode/lxfb.h +++ b/drivers/video/geode/lxfb.h @@ -117,7 +117,7 @@ enum gp_registers { }; #define GP_BLT_STATUS_CE (1 << 4) /* cmd buf empty */ -#define GP_BLT_STATUS_PB (1 << 0) /* primative busy */ +#define GP_BLT_STATUS_PB (1 << 0) /* primitive busy */ /* Display Controller registers (table 6-47 from the data book) */ diff --git a/drivers/video/i810/i810_accel.c b/drivers/video/i810/i810_accel.c index f5bedee4310a..7672d2ea9b35 100644 --- a/drivers/video/i810/i810_accel.c +++ b/drivers/video/i810/i810_accel.c @@ -112,7 +112,7 @@ static inline int wait_for_engine_idle(struct fb_info *info) * @par: pointer to i810fb_par structure * * DESCRIPTION: - * Checks/waits for sufficent space in ringbuffer of size + * Checks/waits for sufficient space in ringbuffer of size * space. Returns the tail of the buffer */ static inline u32 begin_iring(struct fb_info *info, u32 space) diff --git a/drivers/video/kyro/STG4000OverlayDevice.c b/drivers/video/kyro/STG4000OverlayDevice.c index a8c9713413e6..0aeeaa10708b 100644 --- a/drivers/video/kyro/STG4000OverlayDevice.c +++ b/drivers/video/kyro/STG4000OverlayDevice.c @@ -417,7 +417,7 @@ int SetOverlayViewPort(volatile STG4000REG __iomem *pSTGReg, /***************** Horizontal decimation/scaling ***************************/ /* - * Now we handle the horizontal case, this is a simplified verison of + * Now we handle the horizontal case, this is a simplified version of * the vertical case in that we decimate by factors of 2. as we are * working in words we should always be able to decimate by these * factors. as we always have to have a buffer which is aligned to a diff --git a/drivers/video/kyro/STG4000Reg.h b/drivers/video/kyro/STG4000Reg.h index 244549e61368..5d6269882589 100644 --- a/drivers/video/kyro/STG4000Reg.h +++ b/drivers/video/kyro/STG4000Reg.h @@ -16,7 +16,7 @@ /* * Macros that access memory mapped card registers in PCI space - * Add an appropraite section for your OS or processor architecture. + * Add an appropriate section for your OS or processor architecture. */ #if defined(__KERNEL__) #include diff --git a/drivers/video/matrox/matroxfb_DAC1064.h b/drivers/video/matrox/matroxfb_DAC1064.h index c6ed7801efe2..1e6e45b57b78 100644 --- a/drivers/video/matrox/matroxfb_DAC1064.h +++ b/drivers/video/matrox/matroxfb_DAC1064.h @@ -46,7 +46,7 @@ void DAC1064_global_restore(struct matrox_fb_info *minfo); #define M1064_XDVICLKCTRL_DVILOOPCTL 0x30 /* CRTC2 pixel clock allowed to(0)/blocked from(1) driving CRTC2 */ #define M1064_XDVICLKCTRL_C2DVICLKEN 0x40 - /* P1PLL loop filter bandwith selection */ + /* P1PLL loop filter bandwidth selection */ #define M1064_XDVICLKCTRL_P1LOOPBWDTCTL 0x80 #define M1064_XCURCOL0RED 0x08 #define M1064_XCURCOL0GREEN 0x09 diff --git a/drivers/video/matrox/matroxfb_Ti3026.c b/drivers/video/matrox/matroxfb_Ti3026.c index 835aaaae6b96..9a44cec394b5 100644 --- a/drivers/video/matrox/matroxfb_Ti3026.c +++ b/drivers/video/matrox/matroxfb_Ti3026.c @@ -387,7 +387,7 @@ static int Ti3026_init(struct matrox_fb_info *minfo, struct my_timming *m) hw->DACreg[POS3026_XMISCCTRL] = TVP3026_XMISCCTRL_DAC_PUP | TVP3026_XMISCCTRL_DAC_8BIT | TVP3026_XMISCCTRL_PSEL_DIS | TVP3026_XMISCCTRL_PSEL_LOW; break; case 16: - /* XLATCHCTRL should be _4_1 / _2_1... Why is not? (_2_1 is used everytime) */ + /* XLATCHCTRL should be _4_1 / _2_1... Why is not? (_2_1 is used every time) */ hw->DACreg[POS3026_XTRUECOLORCTRL] = (minfo->fbcon.var.green.length == 5) ? (TVP3026_XTRUECOLORCTRL_DIRECTCOLOR | TVP3026_XTRUECOLORCTRL_ORGB_1555) : (TVP3026_XTRUECOLORCTRL_DIRECTCOLOR | TVP3026_XTRUECOLORCTRL_RGB_565); hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_16BIT; hw->DACreg[POS3026_XCLKCTRL] = TVP3026_XCLKCTRL_SRC_PLL | TVP3026_XCLKCTRL_DIV2; @@ -399,7 +399,7 @@ static int Ti3026_init(struct matrox_fb_info *minfo, struct my_timming *m) hw->DACreg[POS3026_XCLKCTRL] = TVP3026_XCLKCTRL_SRC_PLL | TVP3026_XCLKCTRL_DIV4; break; case 32: - /* XLATCHCTRL should be _2_1 / _1_1... Why is not? (_2_1 is used everytime) */ + /* XLATCHCTRL should be _2_1 / _1_1... Why is not? (_2_1 is used every time) */ hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_32BIT; break; default: diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c index 5ce6fa6e59f0..44bf8d4a216b 100644 --- a/drivers/video/matrox/matroxfb_base.c +++ b/drivers/video/matrox/matroxfb_base.c @@ -621,7 +621,7 @@ static int matroxfb_decode_var(const struct matrox_fb_info *minfo, var->yoffset = var->yres_virtual - var->yres; if (bpp == 16 && var->green.length == 5) { - bpp--; /* an artifical value - 15 */ + bpp--; /* an artificial value - 15 */ } for (rgbt = table; rgbt->bpp < bpp; rgbt++); diff --git a/drivers/video/matrox/matroxfb_base.h b/drivers/video/matrox/matroxfb_base.h index f96a471cb1a8..11ed57bb704e 100644 --- a/drivers/video/matrox/matroxfb_base.h +++ b/drivers/video/matrox/matroxfb_base.h @@ -12,7 +12,7 @@ #undef MATROXFB_DEBUG /* heavy debugging: */ -/* -- logs putc[s], so everytime a char is displayed, it's logged */ +/* -- logs putc[s], so every time a char is displayed, it's logged */ #undef MATROXFB_DEBUG_HEAVY /* This one _could_ cause infinite loops */ diff --git a/drivers/video/nuc900fb.h b/drivers/video/nuc900fb.h index 6c23aa3d3b89..bc7c9300f276 100644 --- a/drivers/video/nuc900fb.h +++ b/drivers/video/nuc900fb.h @@ -8,7 +8,7 @@ * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * - * Auther: + * Author: * Wang Qiang(rurality.linux@gmail.com) 2009/12/16 */ diff --git a/drivers/video/omap/Kconfig b/drivers/video/omap/Kconfig index 15e7f1912af9..196fa2e7f438 100644 --- a/drivers/video/omap/Kconfig +++ b/drivers/video/omap/Kconfig @@ -64,7 +64,7 @@ config FB_OMAP_MANUAL_UPDATE depends on FB_OMAP && FB_OMAP_LCDC_EXTERNAL help Say Y here, if your user-space applications are capable of - notifying the frame buffer driver when a change has occured in + notifying the frame buffer driver when a change has occurred in the frame buffer content and thus a reload of the image data to the external frame buffer is required. If unsure, say N. diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index 0d44f070ef36..a981def8099a 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c @@ -587,7 +587,7 @@ static void get_edid_timing_data(u8 *edid) struct hdmi_cm cm; struct omap_video_timings edid_timings; - /* seach block 0, there are 4 DTDs arranged in priority order */ + /* search block 0, there are 4 DTDs arranged in priority order */ for (count = 0; count < EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR; count++) { current_descriptor_addrs = EDID_DESCRIPTOR_BLOCK0_ADDRESS + diff --git a/drivers/video/pxa3xx-gcu.c b/drivers/video/pxa3xx-gcu.c index cf4beb9dc9bb..0283c7021090 100644 --- a/drivers/video/pxa3xx-gcu.c +++ b/drivers/video/pxa3xx-gcu.c @@ -25,7 +25,7 @@ /* * WARNING: This controller is attached to System Bus 2 of the PXA which - * needs its arbiter to be enabled explictly (CKENB & 1<<9). + * needs its arbiter to be enabled explicitly (CKENB & 1<<9). * There is currently no way to do this from Linux, so you need to teach * your bootloader for now. */ diff --git a/drivers/video/savage/savagefb.h b/drivers/video/savage/savagefb.h index e4c3f214eb8e..4e9490c19d7d 100644 --- a/drivers/video/savage/savagefb.h +++ b/drivers/video/savage/savagefb.h @@ -153,7 +153,7 @@ struct savage_reg { unsigned char CRTC[25]; /* Crtc Controller */ unsigned char Sequencer[5]; /* Video Sequencer */ unsigned char Graphics[9]; /* Video Graphics */ - unsigned char Attribute[21]; /* Video Atribute */ + unsigned char Attribute[21]; /* Video Attribute */ unsigned int mode, refresh; unsigned char SR08, SR0E, SR0F; diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c index 487911e2926c..a2dc1a7ec758 100644 --- a/drivers/video/savage/savagefb_driver.c +++ b/drivers/video/savage/savagefb_driver.c @@ -385,7 +385,7 @@ SavageSetup2DEngine(struct savagefb_par *par) BCI_SEND(GlobalBitmapDescriptor); /* - * I don't know why, sending this twice fixes the intial black screen, + * I don't know why, sending this twice fixes the initial black screen, * prevents X from crashing at least in Toshiba laptops with SavageIX. * --Tony */ @@ -2211,7 +2211,7 @@ static int __devinit savagefb_probe(struct pci_dev* dev, goto failed_mmio; video_len = savage_init_hw(par); - /* FIXME: cant be negative */ + /* FIXME: can't be negative */ if (video_len < 0) { err = video_len; goto failed_mmio; diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c index 46d1a64fe80d..56ef6b3a9851 100644 --- a/drivers/video/sm501fb.c +++ b/drivers/video/sm501fb.c @@ -265,7 +265,7 @@ static unsigned long sm501fb_ps_to_hz(unsigned long psvalue) return (unsigned long)numerator; } -/* sm501fb_hz_to_ps is identical to the oposite transform */ +/* sm501fb_hz_to_ps is identical to the opposite transform */ #define sm501fb_hz_to_ps(x) sm501fb_ps_to_hz(x) @@ -1719,7 +1719,7 @@ static int sm501fb_init_fb(struct fb_info *fb, (head == HEAD_CRT) ? &sm501fb_ops_crt : &sm501fb_ops_pnl, sizeof(struct fb_ops)); - /* update ops dependant on what we've been passed */ + /* update ops dependent on what we've been passed */ if ((pd->flags & SM501FB_FLAG_USE_HWCURSOR) == 0) par->ops.fb_cursor = NULL; diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c index 2ab704118c44..2301c275d63a 100644 --- a/drivers/video/sstfb.c +++ b/drivers/video/sstfb.c @@ -221,7 +221,7 @@ static int __sst_wait_idle(u8 __iomem *vbase) while(1) { if (__sst_read(vbase, STATUS) & STATUS_FBI_BUSY) { f_dddprintk("status: busy\n"); -/* FIXME basicaly, this is a busy wait. maybe not that good. oh well; +/* FIXME basically, this is a busy wait. maybe not that good. oh well; * this is a small loop after all. * Or maybe we should use mdelay() or udelay() here instead ? */ count = 0; @@ -501,7 +501,7 @@ static int sstfb_set_par(struct fb_info *info) } if (IS_VOODOO2(par)) { - /* voodoo2 has 32 pixel wide tiles , BUT stange things + /* voodoo2 has 32 pixel wide tiles , BUT strange things happen with odd number of tiles */ par->tiles_in_X = (info->var.xres + 63 ) / 64 * 2; } else { @@ -920,11 +920,11 @@ static int __devinit sst_detect_ti(struct fb_info *info) * we get the 1st byte (M value) of preset f1,f7 and fB * why those 3 ? mmmh... for now, i'll do it the glide way... * and ask questions later. anyway, it seems that all the freq registers are - * realy at their default state (cf specs) so i ask again, why those 3 regs ? + * really at their default state (cf specs) so i ask again, why those 3 regs ? * mmmmh.. it seems that's much more ugly than i thought. we use f0 and fA for * pll programming, so in fact, we *hope* that the f1, f7 & fB won't be * touched... - * is it realy safe ? how can i reset this ramdac ? geee... + * is it really safe ? how can i reset this ramdac ? geee... */ static int __devinit sst_detect_ics(struct fb_info *info) { diff --git a/drivers/video/sticore.h b/drivers/video/sticore.h index 7fe5be4bc70e..addf7b615ef8 100644 --- a/drivers/video/sticore.h +++ b/drivers/video/sticore.h @@ -79,7 +79,7 @@ struct sti_glob_cfg_ext { u8 curr_mon; /* current monitor configured */ u8 friendly_boot; /* in friendly boot mode */ s16 power; /* power calculation (in Watts) */ - s32 freq_ref; /* frequency refrence */ + s32 freq_ref; /* frequency reference */ u32 sti_mem_addr; /* pointer to global sti memory (size=sti_mem_request) */ u32 future_ptr; /* pointer to future data */ }; diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c index 3ee5e63cfa4f..a99b994c9b6b 100644 --- a/drivers/video/tdfxfb.c +++ b/drivers/video/tdfxfb.c @@ -877,12 +877,12 @@ static void tdfxfb_fillrect(struct fb_info *info, else tdfx_rop = TDFX_ROP_XOR; - /* asume always rect->height < 4096 */ + /* assume always rect->height < 4096 */ if (dy + rect->height > 4095) { dstbase = stride * dy; dy = 0; } - /* asume always rect->width < 4096 */ + /* assume always rect->width < 4096 */ if (dx + rect->width > 4095) { dstbase += dx * bpp >> 3; dx = 0; @@ -915,22 +915,22 @@ static void tdfxfb_copyarea(struct fb_info *info, u32 dstbase = 0; u32 srcbase = 0; - /* asume always area->height < 4096 */ + /* assume always area->height < 4096 */ if (sy + area->height > 4095) { srcbase = stride * sy; sy = 0; } - /* asume always area->width < 4096 */ + /* assume always area->width < 4096 */ if (sx + area->width > 4095) { srcbase += sx * bpp >> 3; sx = 0; } - /* asume always area->height < 4096 */ + /* assume always area->height < 4096 */ if (dy + area->height > 4095) { dstbase = stride * dy; dy = 0; } - /* asume always area->width < 4096 */ + /* assume always area->width < 4096 */ if (dx + area->width > 4095) { dstbase += dx * bpp >> 3; dx = 0; @@ -1003,12 +1003,12 @@ static void tdfxfb_imageblit(struct fb_info *info, const struct fb_image *image) #else srcfmt = 0x400000; #endif - /* asume always image->height < 4096 */ + /* assume always image->height < 4096 */ if (dy + image->height > 4095) { dstbase = stride * dy; dy = 0; } - /* asume always image->width < 4096 */ + /* assume always image->width < 4096 */ if (dx + image->width > 4095) { dstbase += dx * bpp >> 3; dx = 0; @@ -1124,7 +1124,7 @@ static int tdfxfb_cursor(struct fb_info *info, struct fb_cursor *cursor) * lower half (least significant 64 bits) of a 128 bit word * and pattern 1 the upper half. If you examine the data of * the cursor image the graphics card uses then from the - * begining you see line one of pattern 0, line one of + * beginning you see line one of pattern 0, line one of * pattern 1, line two of pattern 0, line two of pattern 1, * etc etc. The linear stride for the cursor is always 16 bytes * (128 bits) which is the maximum cursor width times two for diff --git a/drivers/video/tmiofb.c b/drivers/video/tmiofb.c index 9710bf8caeae..0c341d739604 100644 --- a/drivers/video/tmiofb.c +++ b/drivers/video/tmiofb.c @@ -359,7 +359,7 @@ tmiofb_acc_wait(struct fb_info *info, unsigned int ccs) { struct tmiofb_par *par = info->par; /* - * This code can be called whith interrupts disabled. + * This code can be called with interrupts disabled. * So instead of relaying on irq to trigger the event, * poll the state till the necessary command is executed. */ diff --git a/drivers/video/udlfb.c b/drivers/video/udlfb.c index 2c8364e9b632..68041d9dc260 100644 --- a/drivers/video/udlfb.c +++ b/drivers/video/udlfb.c @@ -769,7 +769,7 @@ static int dlfb_ops_ioctl(struct fb_info *info, unsigned int cmd, /* * If we have a damage-aware client, turn fb_defio "off" - * To avoid perf imact of unecessary page fault handling. + * To avoid perf imact of unnecessary page fault handling. * Done by resetting the delay for this fb_info to a very * long period. Pages will become writable and stay that way. * Reset to normal value when all clients have closed this fb. diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c index 28ccab44a391..53b2c5aae067 100644 --- a/drivers/video/vga16fb.c +++ b/drivers/video/vga16fb.c @@ -152,7 +152,7 @@ static inline int setop(int op) } /* Set the Enable Set/Reset Register and return its old value. - The code here always uses value 0xf for thsi register. */ + The code here always uses value 0xf for this register. */ static inline int setsr(int sr) { int oldsr; diff --git a/drivers/video/via/via_utility.c b/drivers/video/via/via_utility.c index d05ccb62b55f..35458a5eadc8 100644 --- a/drivers/video/via/via_utility.c +++ b/drivers/video/via/via_utility.c @@ -174,7 +174,7 @@ void viafb_set_gamma_table(int bpp, unsigned int *gamma_table) } /* If adjust Gamma value in SAMM, fill IGA1, - IGA2 Gamma table simultanous. */ + IGA2 Gamma table simultaneous. */ /* Switch to IGA2 Gamma Table */ if ((active_device_amount > 1) && !((viaparinfo->chip_info->gfx_chip_name == diff --git a/drivers/video/via/via_utility.h b/drivers/video/via/via_utility.h index 1670ba82143f..f23be1708c14 100644 --- a/drivers/video/via/via_utility.h +++ b/drivers/video/via/via_utility.h @@ -21,7 +21,7 @@ #ifndef __VIAUTILITY_H__ #define __VIAUTILITY_H__ -/* These functions are used to get infomation about device's state */ +/* These functions are used to get information about device's state */ void viafb_get_device_support_state(u32 *support_state); void viafb_get_device_connect_state(u32 *connect_state); bool viafb_lcd_get_support_expand_state(u32 xres, u32 yres); diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index f555b891cc72..b64818953aa7 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c @@ -2019,7 +2019,7 @@ int __init viafb_init(void) return -EINVAL; printk(KERN_INFO - "VIA Graphics Intergration Chipset framebuffer %d.%d initializing\n", + "VIA Graphics Integration Chipset framebuffer %d.%d initializing\n", VERSION_MAJOR, VERSION_MINOR); return 0; } diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c index d8b12c32e3ef..c8be8af0cc6d 100644 --- a/drivers/video/w100fb.c +++ b/drivers/video/w100fb.c @@ -1306,7 +1306,7 @@ static void w100_init_lcd(struct w100fb_par *par) union graphic_v_disp_u graphic_v_disp; union crtc_total_u crtc_total; - /* w3200 doesnt like undefined bits being set so zero register values first */ + /* w3200 doesn't like undefined bits being set so zero register values first */ active_h_disp.val = 0; active_h_disp.f.active_h_start=mode->left_margin; diff --git a/drivers/w1/masters/omap_hdq.c b/drivers/w1/masters/omap_hdq.c index 38e96ab90945..5ef385bfed18 100644 --- a/drivers/w1/masters/omap_hdq.c +++ b/drivers/w1/masters/omap_hdq.c @@ -545,7 +545,7 @@ static void omap_w1_write_byte(void *_hdq, u8 byte) return; } - /* Second write, data transfered. Release the module */ + /* Second write, data transferred. Release the module */ if (hdq_data->init_trans > 1) { omap_hdq_put(hdq_data); ret = mutex_lock_interruptible(&hdq_data->hdq_mutex); diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index b69d71482554..1b0f98bc51b5 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -933,7 +933,7 @@ config PNX833X_WDT depends on SOC_PNX8335 help Hardware driver for the PNX833x's watchdog. This is a - watchdog timer that will reboot the machine after a programable + watchdog timer that will reboot the machine after a programmable timer has expired and no process has written to /dev/watchdog during that time. diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index d520bf9c3355..3f8608b922a7 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -4,7 +4,7 @@ # Only one watchdog can succeed. We probe the ISA/PCI/USB based # watchdog-cards first, then the architecture specific watchdog -# drivers and then the architecture independant "softdog" driver. +# drivers and then the architecture independent "softdog" driver. # This means that if your ISA/PCI/USB card isn't detected that # you can fall back to an architecture specific driver and if # that also fails then you can fall back to the software watchdog @@ -153,7 +153,7 @@ obj-$(CONFIG_WATCHDOG_CP1XXX) += cpwd.o # Xen obj-$(CONFIG_XEN_WDT) += xen_wdt.o -# Architecture Independant +# Architecture Independent obj-$(CONFIG_WM831X_WATCHDOG) += wm831x_wdt.o obj-$(CONFIG_WM8350_WATCHDOG) += wm8350_wdt.o obj-$(CONFIG_MAX63XX_WATCHDOG) += max63xx_wdt.o diff --git a/drivers/watchdog/acquirewdt.c b/drivers/watchdog/acquirewdt.c index 2ffce4d75443..b6a2b58cbe64 100644 --- a/drivers/watchdog/acquirewdt.c +++ b/drivers/watchdog/acquirewdt.c @@ -26,7 +26,7 @@ * Theory of Operation: * The Watch-Dog Timer is provided to ensure that standalone * Systems can always recover from catastrophic conditions that - * caused the CPU to crash. This condition may have occured by + * caused the CPU to crash. This condition may have occurred by * external EMI or a software bug. When the CPU stops working * correctly, hardware on the board will either perform a hardware * reset (cold boot) or a non-maskable interrupt (NMI) to bring the diff --git a/drivers/watchdog/pc87413_wdt.c b/drivers/watchdog/pc87413_wdt.c index 139d773300c6..b7c139051575 100644 --- a/drivers/watchdog/pc87413_wdt.c +++ b/drivers/watchdog/pc87413_wdt.c @@ -49,7 +49,7 @@ #define WDT_DATA_IO_PORT (WDT_INDEX_IO_PORT+1) #define SWC_LDN 0x04 #define SIOCFG2 0x22 /* Serial IO register */ -#define WDCTL 0x10 /* Watchdog-Timer-Controll-Register */ +#define WDCTL 0x10 /* Watchdog-Timer-Control-Register */ #define WDTO 0x11 /* Watchdog timeout register */ #define WDCFG 0x12 /* Watchdog config register */ diff --git a/drivers/watchdog/sbc7240_wdt.c b/drivers/watchdog/sbc7240_wdt.c index 67ddeb1c830a..ff11504c376e 100644 --- a/drivers/watchdog/sbc7240_wdt.c +++ b/drivers/watchdog/sbc7240_wdt.c @@ -273,7 +273,7 @@ static int __init sbc7240_wdt_init(void) /* The IO port 0x043 used to disable the watchdog * is already claimed by the system timer, so we - * cant request_region() it ...*/ + * can't request_region() it ...*/ if (timeout < 1 || timeout > SBC7240_MAX_TIMEOUT) { timeout = SBC7240_TIMEOUT; diff --git a/drivers/watchdog/sch311x_wdt.c b/drivers/watchdog/sch311x_wdt.c index b61ab1c54293..c7cf4b01f58d 100644 --- a/drivers/watchdog/sch311x_wdt.c +++ b/drivers/watchdog/sch311x_wdt.c @@ -201,7 +201,7 @@ static void sch311x_wdt_get_status(int *status) spin_lock(&sch311x_wdt_data.io_lock); /* -- Watchdog timer control -- - * Bit 0 Status Bit: 0 = Timer counting, 1 = Timeout occured + * Bit 0 Status Bit: 0 = Timer counting, 1 = Timeout occurred * Bit 1 Reserved * Bit 2 Force Timeout: 1 = Forces WD timeout event (self-cleaning) * Bit 3 P20 Force Timeout enabled: diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c index 4e3e7eb5919c..db84f2322d1a 100644 --- a/drivers/watchdog/shwdt.c +++ b/drivers/watchdog/shwdt.c @@ -50,7 +50,7 @@ * necssary. * * As a result of this timing problem, the only modes that are particularly - * feasible are the 4096 and the 2048 divisors, which yeild 5.25 and 2.62ms + * feasible are the 4096 and the 2048 divisors, which yield 5.25 and 2.62ms * overflow periods respectively. * * Also, since we can't really expect userspace to be responsive enough diff --git a/drivers/watchdog/smsc37b787_wdt.c b/drivers/watchdog/smsc37b787_wdt.c index df88cfa05f35..e97b0499bd0d 100644 --- a/drivers/watchdog/smsc37b787_wdt.c +++ b/drivers/watchdog/smsc37b787_wdt.c @@ -191,7 +191,7 @@ static inline void wdt_timer_conf(unsigned char conf) static inline void wdt_timer_ctrl(unsigned char reg) { /* -- Watchdog timer control -- - * Bit 0 Status Bit: 0 = Timer counting, 1 = Timeout occured + * Bit 0 Status Bit: 0 = Timer counting, 1 = Timeout occurred * Bit 1 Power LED Toggle: 0 = Disable Toggle, 1 = Toggle at 1 Hz * Bit 2 Force Timeout: 1 = Forces WD timeout event (self-cleaning) * Bit 3 P20 Force Timeout enabled: diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c index 0a0efe713bc8..0d80e08b6439 100644 --- a/drivers/watchdog/sp805_wdt.c +++ b/drivers/watchdog/sp805_wdt.c @@ -90,7 +90,7 @@ static void wdt_setload(unsigned int timeout) /* * sp805 runs counter with given value twice, after the end of first * counter it gives an interrupt and then starts counter again. If - * interrupt already occured then it resets the system. This is why + * interrupt already occurred then it resets the system. This is why * load is half of what should be required. */ load = div_u64(rate, 2) * timeout - 1; diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 036343ba204e..42d6c930cc87 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -5,7 +5,7 @@ * domain gets 1024 event channels, but NR_IRQ is not that large, we * must dynamically map irqs<->event channels. The event channels * interface with the rest of the kernel by defining a xen interrupt - * chip. When an event is recieved, it is mapped to an irq and sent + * chip. When an event is received, it is mapped to an irq and sent * through the normal interrupt processing path. * * There are four kinds of events which can be mapped to an event @@ -416,7 +416,7 @@ static int __must_check xen_allocate_irq_dynamic(void) #ifdef CONFIG_X86_IO_APIC /* * For an HVM guest or domain 0 which see "real" (emulated or - * actual repectively) GSIs we allocate dynamic IRQs + * actual respectively) GSIs we allocate dynamic IRQs * e.g. those corresponding to event channels or MSIs * etc. from the range above those "real" GSIs to avoid * collisions. diff --git a/fs/adfs/map.c b/fs/adfs/map.c index d1a5932bb0f1..6935f05202ac 100644 --- a/fs/adfs/map.c +++ b/fs/adfs/map.c @@ -51,7 +51,7 @@ static DEFINE_RWLOCK(adfs_map_lock); /* * This is fun. We need to load up to 19 bits from the map at an - * arbitary bit alignment. (We're limited to 19 bits by F+ version 2). + * arbitrary bit alignment. (We're limited to 19 bits by F+ version 2). */ #define GET_FRAG_ID(_map,_start,_idmask) \ ({ \ diff --git a/fs/afs/cache.c b/fs/afs/cache.c index 0fb315dd4d2a..577763c3d88b 100644 --- a/fs/afs/cache.c +++ b/fs/afs/cache.c @@ -98,7 +98,7 @@ static uint16_t afs_cell_cache_get_key(const void *cookie_netfs_data, } /* - * provide new auxilliary cache data + * provide new auxiliary cache data */ static uint16_t afs_cell_cache_get_aux(const void *cookie_netfs_data, void *buffer, uint16_t bufmax) @@ -117,7 +117,7 @@ static uint16_t afs_cell_cache_get_aux(const void *cookie_netfs_data, } /* - * check that the auxilliary data indicates that the entry is still valid + * check that the auxiliary data indicates that the entry is still valid */ static enum fscache_checkaux afs_cell_cache_check_aux(void *cookie_netfs_data, const void *buffer, @@ -150,7 +150,7 @@ static uint16_t afs_vlocation_cache_get_key(const void *cookie_netfs_data, } /* - * provide new auxilliary cache data + * provide new auxiliary cache data */ static uint16_t afs_vlocation_cache_get_aux(const void *cookie_netfs_data, void *buffer, uint16_t bufmax) @@ -172,7 +172,7 @@ static uint16_t afs_vlocation_cache_get_aux(const void *cookie_netfs_data, } /* - * check that the auxilliary data indicates that the entry is still valid + * check that the auxiliary data indicates that the entry is still valid */ static enum fscache_checkaux afs_vlocation_cache_check_aux(void *cookie_netfs_data, @@ -283,7 +283,7 @@ static void afs_vnode_cache_get_attr(const void *cookie_netfs_data, } /* - * provide new auxilliary cache data + * provide new auxiliary cache data */ static uint16_t afs_vnode_cache_get_aux(const void *cookie_netfs_data, void *buffer, uint16_t bufmax) @@ -309,7 +309,7 @@ static uint16_t afs_vnode_cache_get_aux(const void *cookie_netfs_data, } /* - * check that the auxilliary data indicates that the entry is still valid + * check that the auxiliary data indicates that the entry is still valid */ static enum fscache_checkaux afs_vnode_cache_check_aux(void *cookie_netfs_data, const void *buffer, diff --git a/fs/afs/cell.c b/fs/afs/cell.c index 0d5eeadf6121..3c090b7555ea 100644 --- a/fs/afs/cell.c +++ b/fs/afs/cell.c @@ -293,7 +293,7 @@ struct afs_cell *afs_cell_lookup(const char *name, unsigned namesz, if (!cell) { /* this should not happen unless user tries to mount * when root cell is not set. Return an impossibly - * bizzare errno to alert the user. Things like + * bizarre errno to alert the user. Things like * ENOENT might be "more appropriate" but they happen * for other reasons. */ diff --git a/fs/attr.c b/fs/attr.c index 1007ed616314..91dbe2a107f2 100644 --- a/fs/attr.c +++ b/fs/attr.c @@ -128,7 +128,7 @@ EXPORT_SYMBOL(inode_newsize_ok); * setattr_copy must be called with i_mutex held. * * setattr_copy updates the inode's metadata with that specified - * in attr. Noticably missing is inode size update, which is more complex + * in attr. Noticeably missing is inode size update, which is more complex * as it requires pagecache updates. * * The inode is not marked as dirty after this operation. The rationale is diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index 96804a17bbd0..f55ae23b137e 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c @@ -612,7 +612,7 @@ static int autofs4_dir_unlink(struct inode *dir, struct dentry *dentry) * set the DMANAGED_AUTOMOUNT and DMANAGED_TRANSIT flags on the leaves * of the directory tree. There is no need to clear the automount flag * following a mount or restore it after an expire because these mounts - * are always covered. However, it is neccessary to ensure that these + * are always covered. However, it is necessary to ensure that these * flags are clear on non-empty directories to avoid unnecessary calls * during path walks. */ diff --git a/fs/befs/ChangeLog b/fs/befs/ChangeLog index ce8c787916be..75a461cfaca6 100644 --- a/fs/befs/ChangeLog +++ b/fs/befs/ChangeLog @@ -24,7 +24,7 @@ Version 0.9 (2002-03-14) Version 0.64 (2002-02-07) ========== -* Did the string comparision really right this time (btree.c) [WD] +* Did the string comparison really right this time (btree.c) [WD] * Fixed up some places where I assumed that a long int could hold a pointer value. (btree.c) [WD] @@ -114,7 +114,7 @@ Version 0.6 (2001-12-15) More flexible. Will soon be controllable at mount time (see TODO). [WD] -* Rewrote datastream positon lookups. +* Rewrote datastream position lookups. (datastream.c) [WD] * Moved the TODO list to its own file. @@ -150,7 +150,7 @@ Version 0.50 (2001-11-13) * Anton also told me that the blocksize is not allowed to be larger than the page size in linux, which is 4k i386. Oops. Added a test for (blocksize > PAGE_SIZE), and refuse to mount in that case. What this - practicaly means is that 8k blocksize volumes won't work without a major + practically means is that 8k blocksize volumes won't work without a major restructuring of the driver (or an alpha or other 64bit hardware). [WD] * Cleaned up the befs_count_blocks() function. Much smarter now. @@ -183,7 +183,7 @@ Version 0.45 (2001-10-29) structures into the generic pointer fields of the public structures with kmalloc(). put_super and put_inode free them. This allows us not to have to touch the definitions of the public structures in - include/linux/fs.h. Also, befs_inode_info is huge (becuase of the + include/linux/fs.h. Also, befs_inode_info is huge (because of the symlink string). (super.c, inode.c, befs_fs.h) [WD] * Fixed a thinko that was corrupting file reads after the first block_run @@ -404,7 +404,7 @@ Version 0.4 (2001-10-28) * Fixed compile errors on 2.4.1 kernel (WD) Resolve rejected patches - Accomodate changed NLS interface (util.h) + Accommodate changed NLS interface (util.h) Needed to include in most files Makefile changes fs/Config.in changes diff --git a/fs/befs/befs_fs_types.h b/fs/befs/befs_fs_types.h index 7893eaa1e58c..eb557d9dc8be 100644 --- a/fs/befs/befs_fs_types.h +++ b/fs/befs/befs_fs_types.h @@ -234,7 +234,7 @@ typedef struct { } PACKED befs_btree_super; /* - * Header stucture of each btree node + * Header structure of each btree node */ typedef struct { fs64 left; diff --git a/fs/befs/btree.c b/fs/befs/btree.c index 4202db7496cb..a66c9b1136e0 100644 --- a/fs/befs/btree.c +++ b/fs/befs/btree.c @@ -5,7 +5,7 @@ * * Licensed under the GNU GPL. See the file COPYING for details. * - * 2002-02-05: Sergey S. Kostyliov added binary search withing + * 2002-02-05: Sergey S. Kostyliov added binary search within * btree nodes. * * Many thanks to: diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c index 06457ed8f3e7..54b8c28bebc8 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c @@ -734,7 +734,7 @@ parse_options(char *options, befs_mount_options * opts) /* This function has the responsibiltiy of getting the * filesystem ready for unmounting. - * Basicly, we free everything that we allocated in + * Basically, we free everything that we allocated in * befs_read_inode */ static void diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index 811384bec8de..397d3057d336 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -717,7 +717,7 @@ static int load_flat_file(struct linux_binprm * bprm, * help simplify all this mumbo jumbo * * We've got two different sections of relocation entries. - * The first is the GOT which resides at the begining of the data segment + * The first is the GOT which resides at the beginning of the data segment * and is terminated with a -1. This one can be relocated in place. * The second is the extra relocation entries tacked after the image's * data segment. These require a little more processing as the entry is diff --git a/fs/bio.c b/fs/bio.c index 4d6d4b6c2bf1..840a0d755248 100644 --- a/fs/bio.c +++ b/fs/bio.c @@ -1436,7 +1436,7 @@ EXPORT_SYMBOL(bio_flush_dcache_pages); * preferred way to end I/O on a bio, it takes care of clearing * BIO_UPTODATE on error. @error is 0 on success, and and one of the * established -Exxxx (-EIO, for instance) error values in case - * something went wrong. Noone should call bi_end_io() directly on a + * something went wrong. No one should call bi_end_io() directly on a * bio unless they own it and thus know that it has an end_io * function. **/ diff --git a/fs/block_dev.c b/fs/block_dev.c index c1511c674f53..5147bdd3b8e1 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -653,7 +653,7 @@ void bd_forget(struct inode *inode) * @whole: whole block device containing @bdev, may equal @bdev * @holder: holder trying to claim @bdev * - * Test whther @bdev can be claimed by @holder. + * Test whether @bdev can be claimed by @holder. * * CONTEXT: * spin_lock(&bdev_lock). diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index 2b6c12e983b3..a24a3f2fa13e 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c @@ -243,7 +243,7 @@ out: * Insert @em into @tree or perform a simple forward/backward merge with * existing mappings. The extent_map struct passed in will be inserted * into the tree directly, with an additional reference taken, or a - * reference dropped if the merge attempt was successfull. + * reference dropped if the merge attempt was successful. */ int add_extent_mapping(struct extent_map_tree *tree, struct extent_map *em) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 93c28a1d6bdc..80920bce01ab 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -2324,7 +2324,7 @@ int btrfs_orphan_cleanup(struct btrfs_root *root) /* * if ret == 0 means we found what we were searching for, which - * is weird, but possible, so only screw with path if we didnt + * is weird, but possible, so only screw with path if we didn't * find the key and see if we have stuff that matches */ if (ret > 0) { diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 58250e09eb05..199a80134312 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -2346,7 +2346,7 @@ struct btrfs_root *select_one_root(struct btrfs_trans_handle *trans, root = next->root; BUG_ON(!root); - /* no other choice for non-refernce counted tree */ + /* no other choice for non-references counted tree */ if (!root->ref_cows) return root; diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c index 37fe101a4e0d..1064805e653b 100644 --- a/fs/cachefiles/interface.c +++ b/fs/cachefiles/interface.c @@ -197,7 +197,7 @@ struct fscache_object *cachefiles_grab_object(struct fscache_object *_object) } /* - * update the auxilliary data for an object object on disk + * update the auxiliary data for an object object on disk */ static void cachefiles_update_object(struct fscache_object *_object) { diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index 37368ba2e67c..e159c529fd2b 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c @@ -24,7 +24,7 @@ * context needs to be associated with the osd write during writeback. * * Similarly, struct ceph_inode_info maintains a set of counters to - * count dirty pages on the inode. In the absense of snapshots, + * count dirty pages on the inode. In the absence of snapshots, * i_wrbuffer_ref == i_wrbuffer_ref_head == the dirty page count. * * When a snapshot is taken (that is, when the client receives diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 6b61ded701e1..5323c330bbf3 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -765,7 +765,7 @@ int __ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, int touch) if (touch) { struct rb_node *q; - /* touch this + preceeding caps */ + /* touch this + preceding caps */ __touch_cap(cap); for (q = rb_first(&ci->i_caps); q != p; q = rb_next(q)) { diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c index 0aee66b92af3..e86ec1155f8f 100644 --- a/fs/ceph/snap.c +++ b/fs/ceph/snap.c @@ -342,7 +342,7 @@ static int build_snap_context(struct ceph_snap_realm *realm) num = 0; snapc->seq = realm->seq; if (parent) { - /* include any of parent's snaps occuring _after_ my + /* include any of parent's snaps occurring _after_ my parent became my parent */ for (i = 0; i < parent->cached_context->num_snaps; i++) if (parent->cached_context->snaps[i] >= diff --git a/fs/cifs/AUTHORS b/fs/cifs/AUTHORS index 7f7fa3c302af..ea940b1db77b 100644 --- a/fs/cifs/AUTHORS +++ b/fs/cifs/AUTHORS @@ -35,7 +35,7 @@ Adrian Bunk (kcalloc cleanups) Miklos Szeredi Kazeon team for various fixes especially for 2.4 version. Asser Ferno (Change Notify support) -Shaggy (Dave Kleikamp) for inumerable small fs suggestions and some good cleanup +Shaggy (Dave Kleikamp) for innumerable small fs suggestions and some good cleanup Gunter Kukkukk (testing and suggestions for support of old servers) Igor Mammedov (DFS support) Jeff Layton (many, many fixes, as well as great work on the cifs Kerberos code) diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c index 0a265ad9e426..2b68ac57d97d 100644 --- a/fs/cifs/cifs_dfs_ref.c +++ b/fs/cifs/cifs_dfs_ref.c @@ -53,7 +53,7 @@ void cifs_dfs_release_automount_timer(void) * * Extracts sharename form full UNC. * i.e. strips from UNC trailing path that is not part of share - * name and fixup missing '\' in the begining of DFS node refferal + * name and fixup missing '\' in the beginning of DFS node refferal * if necessary. * Returns pointer to share name on success or ERR_PTR on error. * Caller is responsible for freeing returned string. diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 904aa47e3515..2644a5d6cc67 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -5247,7 +5247,7 @@ cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset, * Samba server ignores set of file size to zero due to bugs in some * older clients, but we should be precise - we use SetFileSize to * set file size and do not want to truncate file size to zero - * accidently as happened on one Samba server beta by putting + * accidentally as happened on one Samba server beta by putting * zero instead of -1 here */ data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64); diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 8d6c17ab593d..6e2b2addfc78 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -1572,7 +1572,7 @@ match_security(struct TCP_Server_Info *server, struct smb_vol *vol) return false; } - /* now check if signing mode is acceptible */ + /* now check if signing mode is acceptable */ if ((secFlags & CIFSSEC_MAY_SIGN) == 0 && (server->secMode & SECMODE_SIGN_REQUIRED)) return false; @@ -2933,7 +2933,7 @@ mount_fail_check: if (mount_data != mount_data_global) kfree(mount_data); /* If find_unc succeeded then rc == 0 so we can not end */ - /* up accidently freeing someone elses tcon struct */ + /* up accidentally freeing someone elses tcon struct */ if (tcon) cifs_put_tcon(tcon); else if (pSesInfo) diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index dd5f22918c33..9ea65cf36714 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -189,7 +189,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, inode->i_sb, mode, oflags, &oplock, &fileHandle, xid); /* EIO could indicate that (posix open) operation is not supported, despite what server claimed in capability - negotation. EREMOTE indicates DFS junction, which is not + negotiation. EREMOTE indicates DFS junction, which is not handled in posix open */ if (rc == 0) { diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 90ff3cb10de3..3313dd19f543 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c @@ -990,7 +990,7 @@ static int configfs_dump(struct configfs_dirent *sd, int level) * This describes these functions and their helpers. * * Allow another kernel system to depend on a config_item. If this - * happens, the item cannot go away until the dependant can live without + * happens, the item cannot go away until the dependent can live without * it. The idea is to give client modules as simple an interface as * possible. When a system asks them to depend on an item, they just * call configfs_depend_item(). If the item is live and the client diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index 04b8c449303f..56d6bfcc1e48 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c @@ -519,7 +519,7 @@ static void toss_rsb(struct kref *kref) } } -/* When all references to the rsb are gone it's transfered to +/* When all references to the rsb are gone it's transferred to the tossed list for later disposal. */ static void put_rsb(struct dlm_rsb *r) diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c index bffa1e73b9a9..5e2c71f05e46 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms.c @@ -810,7 +810,7 @@ static int tcp_accept_from_sock(struct connection *con) /* * Add it to the active queue in case we got data - * beween processing the accept adding the socket + * between processing the accept adding the socket * to the read_sockets list */ if (!test_and_set_bit(CF_READ_PENDING, &addcon->flags)) diff --git a/fs/dlm/recover.c b/fs/dlm/recover.c index eda43f362616..14638235f7b2 100644 --- a/fs/dlm/recover.c +++ b/fs/dlm/recover.c @@ -304,7 +304,7 @@ static void set_master_lkbs(struct dlm_rsb *r) } /* - * Propogate the new master nodeid to locks + * Propagate the new master nodeid to locks * The NEW_MASTER flag tells dlm_recover_locks() which rsb's to consider. * The NEW_MASTER2 flag tells recover_lvb() and set_locks_purged() which * rsb's to consider. diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index c27c0ecf90bc..fdb2eb0ad09e 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c @@ -276,7 +276,7 @@ static void ecryptfs_init_mount_crypt_stat( /** * ecryptfs_parse_options * @sb: The ecryptfs super block - * @options: The options pased to the kernel + * @options: The options passed to the kernel * * Parse mount options: * debug=N - ecryptfs_verbosity level for debug output @@ -840,7 +840,7 @@ static int __init ecryptfs_init(void) } rc = ecryptfs_init_messaging(); if (rc) { - printk(KERN_ERR "Failure occured while attempting to " + printk(KERN_ERR "Failure occurred while attempting to " "initialize the communications channel to " "ecryptfsd\n"); goto out_destroy_kthread; diff --git a/fs/eventpoll.c b/fs/eventpoll.c index ed38801b57a7..f9cfd168fbe2 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c @@ -181,7 +181,7 @@ struct eventpoll { /* * This is a single linked list that chains all the "struct epitem" that - * happened while transfering ready events to userspace w/out + * happened while transferring ready events to userspace w/out * holding ->lock. */ struct epitem *ovflist; @@ -606,7 +606,7 @@ static void ep_free(struct eventpoll *ep) * We do not need to hold "ep->mtx" here because the epoll file * is on the way to be removed and no one has references to it * anymore. The only hit might come from eventpoll_release_file() but - * holding "epmutex" is sufficent here. + * holding "epmutex" is sufficient here. */ mutex_lock(&epmutex); @@ -720,7 +720,7 @@ void eventpoll_release_file(struct file *file) /* * We don't want to get "file->f_lock" because it is not * necessary. It is not necessary because we're in the "struct file" - * cleanup path, and this means that noone is using this file anymore. + * cleanup path, and this means that no one is using this file anymore. * So, for example, epoll_ctl() cannot hit here since if we reach this * point, the file counter already went to zero and fget() would fail. * The only hit might come from ep_free() but by holding the mutex @@ -1112,7 +1112,7 @@ static int ep_send_events_proc(struct eventpoll *ep, struct list_head *head, * Trigger mode, we need to insert back inside * the ready list, so that the next call to * epoll_wait() will check again the events - * availability. At this point, noone can insert + * availability. At this point, no one can insert * into ep->rdllist besides us. The epoll_ctl() * callers are locked out by * ep_scan_ready_list() holding "mtx" and the diff --git a/fs/exofs/common.h b/fs/exofs/common.h index 5e74ad3d4009..3bbd46956d77 100644 --- a/fs/exofs/common.h +++ b/fs/exofs/common.h @@ -115,7 +115,7 @@ struct exofs_sb_stats { * Describes the raid used in the FS. It is part of the device table. * This here is taken from the pNFS-objects definition. In exofs we * use one raid policy through-out the filesystem. (NOTE: the funny - * alignment at begining. We take care of it at exofs_device_table. + * alignment at beginning. We take care of it at exofs_device_table. */ struct exofs_dt_data_map { __le32 cb_num_comps; @@ -136,7 +136,7 @@ struct exofs_dt_device_info { u8 systemid[OSD_SYSTEMID_LEN]; __le64 long_name_offset; /* If !0 then offset-in-file */ __le32 osdname_len; /* */ - u8 osdname[44]; /* Embbeded, Ususally an asci uuid */ + u8 osdname[44]; /* Embbeded, Usually an asci uuid */ } __packed; /* diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c index 0d06f4e75699..8f44cef1b3ef 100644 --- a/fs/ext2/balloc.c +++ b/fs/ext2/balloc.c @@ -850,7 +850,7 @@ static int find_next_reservable_window( rsv_window_remove(sb, my_rsv); /* - * Let's book the whole avaliable window for now. We will check the + * Let's book the whole available window for now. We will check the * disk bitmap later and then, if there are free blocks then we adjust * the window size if it's larger than requested. * Otherwise, we will remove this node from the tree next time @@ -1357,9 +1357,9 @@ retry_alloc: goto allocated; } /* - * We may end up a bogus ealier ENOSPC error due to + * We may end up a bogus earlier ENOSPC error due to * filesystem is "full" of reservations, but - * there maybe indeed free blocks avaliable on disk + * there maybe indeed free blocks available on disk * In this case, we just forget about the reservations * just do block allocation as without reservations. */ diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index c47f706878b5..788e09a07f7e 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c @@ -305,7 +305,7 @@ static ext2_fsblk_t ext2_find_near(struct inode *inode, Indirect *ind) return ind->bh->b_blocknr; /* - * It is going to be refered from inode itself? OK, just put it into + * It is going to be referred from inode itself? OK, just put it into * the same cylinder group then. */ bg_start = ext2_group_first_block_no(inode->i_sb, ei->i_block_group); @@ -913,7 +913,7 @@ static inline int all_zeroes(__le32 *p, __le32 *q) * * When we do truncate() we may have to clean the ends of several indirect * blocks but leave the blocks themselves alive. Block is partially - * truncated if some data below the new i_size is refered from it (and + * truncated if some data below the new i_size is referred from it (and * it is on the path to the first completely truncated data block, indeed). * We have to free the top of that path along with everything to the right * of the path. Since no allocation past the truncation point is possible @@ -990,7 +990,7 @@ no_top: * @p: array of block numbers * @q: points immediately past the end of array * - * We are freeing all blocks refered from that array (numbers are + * We are freeing all blocks referred from that array (numbers are * stored as little-endian 32-bit) and updating @inode->i_blocks * appropriately. */ @@ -1030,7 +1030,7 @@ static inline void ext2_free_data(struct inode *inode, __le32 *p, __le32 *q) * @q: pointer immediately past the end of array * @depth: depth of the branches to free * - * We are freeing all blocks refered from these branches (numbers are + * We are freeing all blocks referred from these branches (numbers are * stored as little-endian 32-bit) and updating @inode->i_blocks * appropriately. */ diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 7731695e65d9..0a78dae7e2cb 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -1382,7 +1382,7 @@ static struct dentry *ext2_mount(struct file_system_type *fs_type, /* Read data from quotafile - avoid pagecache and such because we cannot afford * acquiring the locks... As quota files are never truncated and quota code - * itself serializes the operations (and noone else should touch the files) + * itself serializes the operations (and no one else should touch the files) * we don't have to be afraid of races */ static ssize_t ext2_quota_read(struct super_block *sb, int type, char *data, size_t len, loff_t off) diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c index c2e4dce984d2..529970617a21 100644 --- a/fs/ext2/xattr.c +++ b/fs/ext2/xattr.c @@ -35,7 +35,7 @@ * +------------------+ * * The block header is followed by multiple entry descriptors. These entry - * descriptors are variable in size, and alligned to EXT2_XATTR_PAD + * descriptors are variable in size, and aligned to EXT2_XATTR_PAD * byte boundaries. The entry descriptors are sorted by attribute name, * so that two extended attribute blocks can be compared efficiently. * diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c index 153242187fce..fe52297e31ad 100644 --- a/fs/ext3/balloc.c +++ b/fs/ext3/balloc.c @@ -590,7 +590,7 @@ do_more: BUFFER_TRACE(debug_bh, "Deleted!"); if (!bh2jh(bitmap_bh)->b_committed_data) BUFFER_TRACE(debug_bh, - "No commited data in bitmap"); + "No committed data in bitmap"); BUFFER_TRACE2(debug_bh, bitmap_bh, "bitmap"); __brelse(debug_bh); } @@ -1063,7 +1063,7 @@ static int find_next_reservable_window( rsv_window_remove(sb, my_rsv); /* - * Let's book the whole avaliable window for now. We will check the + * Let's book the whole available window for now. We will check the * disk bitmap later and then, if there are free blocks then we adjust * the window size if it's larger than requested. * Otherwise, we will remove this node from the tree next time @@ -1456,7 +1456,7 @@ static int ext3_has_free_blocks(struct ext3_sb_info *sbi) * * ext3_should_retry_alloc() is called when ENOSPC is returned, and if * it is profitable to retry the operation, this function will wait - * for the current or commiting transaction to complete, and then + * for the current or committing transaction to complete, and then * return TRUE. * * if the total number of retries exceed three times, return FALSE. @@ -1632,9 +1632,9 @@ retry_alloc: goto allocated; } /* - * We may end up a bogus ealier ENOSPC error due to + * We may end up a bogus earlier ENOSPC error due to * filesystem is "full" of reservations, but - * there maybe indeed free blocks avaliable on disk + * there maybe indeed free blocks available on disk * In this case, we just forget about the reservations * just do block allocation as without reservations. */ diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index fe2541d250e4..b5c2f3c97d71 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c @@ -2055,7 +2055,7 @@ static inline int all_zeroes(__le32 *p, __le32 *q) * * When we do truncate() we may have to clean the ends of several * indirect blocks but leave the blocks themselves alive. Block is - * partially truncated if some data below the new i_size is refered + * partially truncated if some data below the new i_size is referred * from it (and it is on the path to the first completely truncated * data block, indeed). We have to free the top of that path along * with everything to the right of the path. Since no allocation @@ -2184,7 +2184,7 @@ static void ext3_clear_blocks(handle_t *handle, struct inode *inode, * @first: array of block numbers * @last: points immediately past the end of array * - * We are freeing all blocks refered from that array (numbers are stored as + * We are freeing all blocks referred from that array (numbers are stored as * little-endian 32-bit) and updating @inode->i_blocks appropriately. * * We accumulate contiguous runs of blocks to free. Conveniently, if these @@ -2272,7 +2272,7 @@ static void ext3_free_data(handle_t *handle, struct inode *inode, * @last: pointer immediately past the end of array * @depth: depth of the branches to free * - * We are freeing all blocks refered from these branches (numbers are + * We are freeing all blocks referred from these branches (numbers are * stored as little-endian 32-bit) and updating @inode->i_blocks * appropriately. */ diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c index 108b142e11ed..7916e4ce166a 100644 --- a/fs/ext3/resize.c +++ b/fs/ext3/resize.c @@ -1009,7 +1009,7 @@ int ext3_group_extend(struct super_block *sb, struct ext3_super_block *es, if (test_opt(sb, DEBUG)) printk(KERN_DEBUG "EXT3-fs: extending last group from "E3FSBLK - " upto "E3FSBLK" blocks\n", + " up to "E3FSBLK" blocks\n", o_blocks_count, n_blocks_count); if (n_blocks_count == 0 || n_blocks_count == o_blocks_count) diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 071689f86e18..3c6a9e0eadc1 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -2925,7 +2925,7 @@ static int ext3_quota_on(struct super_block *sb, int type, int format_id, /* Read data from quotafile - avoid pagecache and such because we cannot afford * acquiring the locks... As quota files are never truncated and quota code - * itself serializes the operations (and noone else should touch the files) + * itself serializes the operations (and no one else should touch the files) * we don't have to be afraid of races */ static ssize_t ext3_quota_read(struct super_block *sb, int type, char *data, size_t len, loff_t off) diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 97b970e7dd13..1c67139ad4b4 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c @@ -547,7 +547,7 @@ int ext4_claim_free_blocks(struct ext4_sb_info *sbi, * * ext4_should_retry_alloc() is called when ENOSPC is returned, and if * it is profitable to retry the operation, this function will wait - * for the current or commiting transaction to complete, and then + * for the current or committing transaction to complete, and then * return TRUE. * * if the total number of retries exceed three times, return FALSE. diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index dd2cb5076ff9..4890d6f3ad15 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -1729,7 +1729,7 @@ repeat: BUG_ON(npath->p_depth != path->p_depth); eh = npath[depth].p_hdr; if (le16_to_cpu(eh->eh_entries) < le16_to_cpu(eh->eh_max)) { - ext_debug("next leaf isnt full(%d)\n", + ext_debug("next leaf isn't full(%d)\n", le16_to_cpu(eh->eh_entries)); path = npath; goto repeat; @@ -2533,7 +2533,7 @@ static int ext4_ext_zeroout(struct inode *inode, struct ext4_extent *ex) /* * This function is called by ext4_ext_map_blocks() if someone tries to write * to an uninitialized extent. It may result in splitting the uninitialized - * extent into multiple extents (upto three - one initialized and two + * extent into multiple extents (up to three - one initialized and two * uninitialized). * There are three possibilities: * a> There is no split required: Entire extent should be initialized @@ -3174,7 +3174,7 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode, path, flags); /* * Flag the inode(non aio case) or end_io struct (aio case) - * that this IO needs to convertion to written when IO is + * that this IO needs to conversion to written when IO is * completed */ if (io && !(io->flag & EXT4_IO_END_UNWRITTEN)) { @@ -3460,10 +3460,10 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode, ext4_ext_mark_uninitialized(&newex); /* * io_end structure was created for every IO write to an - * uninitialized extent. To avoid unecessary conversion, + * uninitialized extent. To avoid unnecessary conversion, * here we flag the IO that really needs the conversion. * For non asycn direct IO case, flag the inode state - * that we need to perform convertion when IO is done. + * that we need to perform conversion when IO is done. */ if ((flags & EXT4_GET_BLOCKS_PRE_IO)) { if (io && !(io->flag & EXT4_IO_END_UNWRITTEN)) { diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c index 7f74019d6d77..4673bc05274f 100644 --- a/fs/ext4/fsync.c +++ b/fs/ext4/fsync.c @@ -101,7 +101,7 @@ extern int ext4_flush_completed_IO(struct inode *inode) * to the work-to-be schedule is freed. * * Thus we need to keep the io structure still valid here after - * convertion finished. The io structure has a flag to + * conversion finished. The io structure has a flag to * avoid double converting from both fsync and background work * queue work. */ diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 1a86282b9024..ad8e303c0d29 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -2588,7 +2588,7 @@ static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate); * because we should have holes filled from ext4_page_mkwrite(). We even don't * need to file the inode to the transaction's list in ordered mode because if * we are writing back data added by write(), the inode is already there and if - * we are writing back data modified via mmap(), noone guarantees in which + * we are writing back data modified via mmap(), no one guarantees in which * transaction the data will hit the disk. In case we are journaling data, we * cannot start transaction directly because transaction start ranks above page * lock so we have to do some magic. @@ -2690,7 +2690,7 @@ static int ext4_writepage(struct page *page, /* * This is called via ext4_da_writepages() to - * calulate the total number of credits to reserve to fit + * calculate the total number of credits to reserve to fit * a single extent allocation into a single transaction, * ext4_da_writpeages() will loop calling this before * the block allocation. @@ -3304,7 +3304,7 @@ int ext4_alloc_da_blocks(struct inode *inode) * the pages by calling redirty_page_for_writepage() but that * would be ugly in the extreme. So instead we would need to * replicate parts of the code in the above functions, - * simplifying them becuase we wouldn't actually intend to + * simplifying them because we wouldn't actually intend to * write out the pages, but rather only collect contiguous * logical block extents, call the multi-block allocator, and * then update the buffer heads with the block allocations. @@ -3694,7 +3694,7 @@ retry: * * The unwrritten extents will be converted to written when DIO is completed. * For async direct IO, since the IO may still pending when return, we - * set up an end_io call back function, which will do the convertion + * set up an end_io call back function, which will do the conversion * when async direct IO completed. * * If the O_DIRECT write will extend the file then add this inode to the @@ -3717,7 +3717,7 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb, * We could direct write to holes and fallocate. * * Allocated blocks to fill the hole are marked as uninitialized - * to prevent paralel buffered read to expose the stale data + * to prevent parallel buffered read to expose the stale data * before DIO complete the data IO. * * As to previously fallocated extents, ext4 get_block @@ -3778,7 +3778,7 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb, int err; /* * for non AIO case, since the IO is already - * completed, we could do the convertion right here + * completed, we could do the conversion right here */ err = ext4_convert_unwritten_extents(inode, offset, ret); @@ -4025,7 +4025,7 @@ static inline int all_zeroes(__le32 *p, __le32 *q) * * When we do truncate() we may have to clean the ends of several * indirect blocks but leave the blocks themselves alive. Block is - * partially truncated if some data below the new i_size is refered + * partially truncated if some data below the new i_size is referred * from it (and it is on the path to the first completely truncated * data block, indeed). We have to free the top of that path along * with everything to the right of the path. Since no allocation @@ -4169,7 +4169,7 @@ out_err: * @first: array of block numbers * @last: points immediately past the end of array * - * We are freeing all blocks refered from that array (numbers are stored as + * We are freeing all blocks referred from that array (numbers are stored as * little-endian 32-bit) and updating @inode->i_blocks appropriately. * * We accumulate contiguous runs of blocks to free. Conveniently, if these @@ -4261,7 +4261,7 @@ static void ext4_free_data(handle_t *handle, struct inode *inode, * @last: pointer immediately past the end of array * @depth: depth of the branches to free * - * We are freeing all blocks refered from these branches (numbers are + * We are freeing all blocks referred from these branches (numbers are * stored as little-endian 32-bit) and updating @inode->i_blocks * appropriately. */ @@ -5478,7 +5478,7 @@ static int ext4_meta_trans_blocks(struct inode *inode, int nrblocks, int chunk) } /* - * Calulate the total number of credits to reserve to fit + * Calculate the total number of credits to reserve to fit * the modification of a single pages into a single transaction, * which may include multiple chunks of block allocations. * diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index a5837a837a8b..d8a16eecf1d5 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -92,7 +92,7 @@ * between CPUs. It is possible to get scheduled at this point. * * The locality group prealloc space is used looking at whether we have - * enough free space (pa_free) withing the prealloc space. + * enough free space (pa_free) within the prealloc space. * * If we can't allocate blocks via inode prealloc or/and locality group * prealloc then we look at the buddy cache. The buddy cache is represented diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c index d1bafa57f483..92816b4e0f16 100644 --- a/fs/ext4/migrate.c +++ b/fs/ext4/migrate.c @@ -517,7 +517,7 @@ int ext4_ext_migrate(struct inode *inode) * start with one credit accounted for * superblock modification. * - * For the tmp_inode we already have commited the + * For the tmp_inode we already have committed the * trascation that created the inode. Later as and * when we add extents we extent the journal */ diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 22546ad7f0ae..056474b7b8e0 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -617,7 +617,7 @@ __acquires(bitlock) * filesystem will have already been marked read/only and the * journal has been aborted. We return 1 as a hint to callers * who might what to use the return value from - * ext4_grp_locked_error() to distinguish beween the + * ext4_grp_locked_error() to distinguish between the * ERRORS_CONT and ERRORS_RO case, and perhaps return more * aggressively from the ext4 function in question, with a * more appropriate error code. @@ -4624,7 +4624,7 @@ static int ext4_quota_off(struct super_block *sb, int type) /* Read data from quotafile - avoid pagecache and such because we cannot afford * acquiring the locks... As quota files are never truncated and quota code - * itself serializes the operations (and noone else should touch the files) + * itself serializes the operations (and no one else should touch the files) * we don't have to be afraid of races */ static ssize_t ext4_quota_read(struct super_block *sb, int type, char *data, size_t len, loff_t off) diff --git a/fs/freevxfs/vxfs_fshead.c b/fs/freevxfs/vxfs_fshead.c index 78948b4b1894..c9a6a94e58e9 100644 --- a/fs/freevxfs/vxfs_fshead.c +++ b/fs/freevxfs/vxfs_fshead.c @@ -164,7 +164,7 @@ vxfs_read_fshead(struct super_block *sbp) goto out_free_pfp; } if (!VXFS_ISILT(VXFS_INO(infp->vsi_stilist))) { - printk(KERN_ERR "vxfs: structual list inode is of wrong type (%x)\n", + printk(KERN_ERR "vxfs: structural list inode is of wrong type (%x)\n", VXFS_INO(infp->vsi_stilist)->vii_mode & VXFS_TYPE_MASK); goto out_iput_stilist; } diff --git a/fs/freevxfs/vxfs_lookup.c b/fs/freevxfs/vxfs_lookup.c index 6c5131d592f0..3360f1e678ad 100644 --- a/fs/freevxfs/vxfs_lookup.c +++ b/fs/freevxfs/vxfs_lookup.c @@ -162,7 +162,7 @@ vxfs_find_entry(struct inode *ip, struct dentry *dp, struct page **ppp) /** * vxfs_inode_by_name - find inode number for dentry * @dip: directory to search in - * @dp: dentry we seach for + * @dp: dentry we search for * * Description: * vxfs_inode_by_name finds out the inode number of diff --git a/fs/freevxfs/vxfs_olt.h b/fs/freevxfs/vxfs_olt.h index d8324296486f..b7b3af502615 100644 --- a/fs/freevxfs/vxfs_olt.h +++ b/fs/freevxfs/vxfs_olt.h @@ -60,7 +60,7 @@ enum { * * The Object Location Table header is placed at the beginning of each * OLT extent. It is used to fing certain filesystem-wide metadata, e.g. - * the inital inode list, the fileset header or the device configuration. + * the initial inode list, the fileset header or the device configuration. */ struct vxfs_olt { u_int32_t olt_magic; /* magic number */ diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index b5ed541fb137..34591ee804b5 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -144,7 +144,7 @@ __bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages, * * Description: * This does WB_SYNC_NONE opportunistic writeback. The IO is only - * started when this function returns, we make no guarentees on + * started when this function returns, we make no guarantees on * completion. Caller need not hold sb s_umount semaphore. * */ diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 6ea00734984e..82a66466a24c 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -523,7 +523,7 @@ static int fuse_readpage(struct file *file, struct page *page) goto out; /* - * Page writeback can extend beyond the liftime of the + * Page writeback can extend beyond the lifetime of the * page-cache page, so make sure we read a properly synced * page. */ diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index ef3dc4b9fae2..74add2ddcc3f 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c @@ -1136,7 +1136,7 @@ void gfs2_trim_blocks(struct inode *inode) * earlier versions of GFS2 have a bug in the stuffed file reading * code which will result in a buffer overrun if the size is larger * than the max stuffed file size. In order to prevent this from - * occuring, such files are unstuffed, but in other cases we can + * occurring, such files are unstuffed, but in other cases we can * just update the inode size directly. * * Returns: 0 on success, or -ve on error diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index e2431313491f..f07643e21bfa 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -1123,7 +1123,7 @@ void gfs2_glock_dq_uninit(struct gfs2_holder *gh) * @number: the lock number * @glops: the glock operations for the type of glock * @state: the state to acquire the glock in - * @flags: modifier flags for the aquisition + * @flags: modifier flags for the acquisition * @gh: the struct gfs2_holder * * Returns: errno diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index ec73ed70bae1..a4e23d68a398 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -657,7 +657,7 @@ out: * @sdp: the file system * * This function flushes data and meta data for all machines by - * aquiring the transaction log exclusively. All journals are + * acquiring the transaction log exclusively. All journals are * ensured to be in a clean state as well. * * Returns: errno diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c index da871ee084d3..69b180459463 100644 --- a/fs/jbd/commit.c +++ b/fs/jbd/commit.c @@ -362,7 +362,7 @@ void journal_commit_transaction(journal_t *journal) * we do not require it to remember exactly which old buffers it * has reserved. This is consistent with the existing behaviour * that multiple journal_get_write_access() calls to the same - * buffer are perfectly permissable. + * buffer are perfectly permissible. */ while (commit_transaction->t_reserved_list) { jh = commit_transaction->t_reserved_list; diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c index eb11601f2e00..b3713afaaa9e 100644 --- a/fs/jbd/journal.c +++ b/fs/jbd/journal.c @@ -770,7 +770,7 @@ journal_t * journal_init_dev(struct block_device *bdev, journal->j_wbufsize = n; journal->j_wbuf = kmalloc(n * sizeof(struct buffer_head*), GFP_KERNEL); if (!journal->j_wbuf) { - printk(KERN_ERR "%s: Cant allocate bhs for commit thread\n", + printk(KERN_ERR "%s: Can't allocate bhs for commit thread\n", __func__); goto out_err; } @@ -831,7 +831,7 @@ journal_t * journal_init_inode (struct inode *inode) journal->j_wbufsize = n; journal->j_wbuf = kmalloc(n * sizeof(struct buffer_head*), GFP_KERNEL); if (!journal->j_wbuf) { - printk(KERN_ERR "%s: Cant allocate bhs for commit thread\n", + printk(KERN_ERR "%s: Can't allocate bhs for commit thread\n", __func__); goto out_err; } diff --git a/fs/jbd/revoke.c b/fs/jbd/revoke.c index d29018307e2e..305a90763154 100644 --- a/fs/jbd/revoke.c +++ b/fs/jbd/revoke.c @@ -71,7 +71,7 @@ * switching hash tables under them. For operations on the lists of entries in * the hash table j_revoke_lock is used. * - * Finally, also replay code uses the hash tables but at this moment noone else + * Finally, also replay code uses the hash tables but at this moment no one else * can touch them (filesystem isn't mounted yet) and hence no locking is * needed. */ diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c index 5b2e4c30a2a1..60d2319651b2 100644 --- a/fs/jbd/transaction.c +++ b/fs/jbd/transaction.c @@ -1392,7 +1392,7 @@ int journal_stop(handle_t *handle) * by 30x or more... * * We try and optimize the sleep time against what the underlying disk - * can do, instead of having a static sleep time. This is usefull for + * can do, instead of having a static sleep time. This is useful for * the case where our storage is so fast that it is more optimal to go * ahead and force a flush and wait for the transaction to be committed * than it is to wait for an arbitrary amount of time for new writers to diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index fa36d7662b21..20af62f4304b 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c @@ -403,7 +403,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) * we do not require it to remember exactly which old buffers it * has reserved. This is consistent with the existing behaviour * that multiple jbd2_journal_get_write_access() calls to the same - * buffer are perfectly permissable. + * buffer are perfectly permissible. */ while (commit_transaction->t_reserved_list) { jh = commit_transaction->t_reserved_list; diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 90407b8fece7..aba8ebaec25c 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -917,7 +917,7 @@ journal_t * jbd2_journal_init_dev(struct block_device *bdev, journal->j_wbufsize = n; journal->j_wbuf = kmalloc(n * sizeof(struct buffer_head*), GFP_KERNEL); if (!journal->j_wbuf) { - printk(KERN_ERR "%s: Cant allocate bhs for commit thread\n", + printk(KERN_ERR "%s: Can't allocate bhs for commit thread\n", __func__); goto out_err; } @@ -983,7 +983,7 @@ journal_t * jbd2_journal_init_inode (struct inode *inode) journal->j_wbufsize = n; journal->j_wbuf = kmalloc(n * sizeof(struct buffer_head*), GFP_KERNEL); if (!journal->j_wbuf) { - printk(KERN_ERR "%s: Cant allocate bhs for commit thread\n", + printk(KERN_ERR "%s: Can't allocate bhs for commit thread\n", __func__); goto out_err; } diff --git a/fs/jbd2/revoke.c b/fs/jbd2/revoke.c index 9ad321fd63fd..69fd93588118 100644 --- a/fs/jbd2/revoke.c +++ b/fs/jbd2/revoke.c @@ -71,7 +71,7 @@ * switching hash tables under them. For operations on the lists of entries in * the hash table j_revoke_lock is used. * - * Finally, also replay code uses the hash tables but at this moment noone else + * Finally, also replay code uses the hash tables but at this moment no one else * can touch them (filesystem isn't mounted yet) and hence no locking is * needed. */ diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 1d1191050f99..05fa77a23711 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c @@ -1403,7 +1403,7 @@ int jbd2_journal_stop(handle_t *handle) /* * Once we drop t_updates, if it goes to zero the transaction - * could start commiting on us and eventually disappear. So + * could start committing on us and eventually disappear. So * once we do this, we must not dereference transaction * pointer again. */ diff --git a/fs/jffs2/TODO b/fs/jffs2/TODO index 5d3ea4070f01..ca28964abd4b 100644 --- a/fs/jffs2/TODO +++ b/fs/jffs2/TODO @@ -11,7 +11,7 @@ - checkpointing (do we need this? scan is quite fast) - make the scan code populate real inodes so read_inode just after mount doesn't have to read the flash twice for large files. - Make this a per-inode option, changable with chattr, so you can + Make this a per-inode option, changeable with chattr, so you can decide which inodes should be in-core immediately after mount. - test, test, test diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c index d32ee9412cb9..2ab1a0d91210 100644 --- a/fs/jffs2/readinode.c +++ b/fs/jffs2/readinode.c @@ -24,7 +24,7 @@ * * Returns: 0 if the data CRC is correct; * 1 - if incorrect; - * error code if an error occured. + * error code if an error occurred. */ static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info *tn) { diff --git a/fs/jffs2/summary.c b/fs/jffs2/summary.c index 800171dca53b..e537fb0e0184 100644 --- a/fs/jffs2/summary.c +++ b/fs/jffs2/summary.c @@ -121,7 +121,7 @@ int jffs2_sum_add_inode_mem(struct jffs2_summary *s, struct jffs2_raw_inode *ri, temp->nodetype = ri->nodetype; temp->inode = ri->ino; temp->version = ri->version; - temp->offset = cpu_to_je32(ofs); /* relative offset from the begining of the jeb */ + temp->offset = cpu_to_je32(ofs); /* relative offset from the beginning of the jeb */ temp->totlen = ri->totlen; temp->next = NULL; @@ -139,7 +139,7 @@ int jffs2_sum_add_dirent_mem(struct jffs2_summary *s, struct jffs2_raw_dirent *r temp->nodetype = rd->nodetype; temp->totlen = rd->totlen; - temp->offset = cpu_to_je32(ofs); /* relative from the begining of the jeb */ + temp->offset = cpu_to_je32(ofs); /* relative from the beginning of the jeb */ temp->pino = rd->pino; temp->version = rd->version; temp->ino = rd->ino; diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c index 07ee1546b2fa..4515bea0268f 100644 --- a/fs/jffs2/wbuf.c +++ b/fs/jffs2/wbuf.c @@ -1116,7 +1116,7 @@ int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c, /* * On NAND we try to mark this block bad. If the block was erased more - * than MAX_ERASE_FAILURES we mark it finaly bad. + * than MAX_ERASE_FAILURES we mark it finally bad. * Don't care about failures. This block remains on the erase-pending * or badblock list as long as nobody manipulates the flash with * a bootloader or something like that. diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c index c92ea3b3ea5e..4496872cf4e7 100644 --- a/fs/jfs/jfs_dmap.c +++ b/fs/jfs/jfs_dmap.c @@ -1649,7 +1649,7 @@ static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno) } /* search the tree within the dmap control page for - * sufficent free space. if sufficient free space is found, + * sufficient free space. if sufficient free space is found, * dbFindLeaf() returns the index of the leaf at which * free space was found. */ @@ -2744,7 +2744,7 @@ static int dbJoin(dmtree_t * tp, int leafno, int newval) /* check which (leafno or buddy) is the left buddy. * the left buddy gets to claim the blocks resulting * from the join while the right gets to claim none. - * the left buddy is also eligable to participate in + * the left buddy is also eligible to participate in * a join at the next higher level while the right * is not. * diff --git a/fs/jfs/jfs_extent.c b/fs/jfs/jfs_extent.c index 5d3bbd10f8db..e5fe8506ed16 100644 --- a/fs/jfs/jfs_extent.c +++ b/fs/jfs/jfs_extent.c @@ -126,7 +126,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, bool abnr) /* allocate the disk blocks for the extent. initially, extBalloc() * will try to allocate disk blocks for the requested size (xlen). - * if this fails (xlen contiguous free blocks not avaliable), it'll + * if this fails (xlen contiguous free blocks not available), it'll * try to allocate a smaller number of blocks (producing a smaller * extent), with this smaller number of blocks consisting of the * requested number of blocks rounded down to the next smaller @@ -481,7 +481,7 @@ int extFill(struct inode *ip, xad_t * xp) * * initially, we will try to allocate disk blocks for the * requested size (nblocks). if this fails (nblocks - * contiguous free blocks not avaliable), we'll try to allocate + * contiguous free blocks not available), we'll try to allocate * a smaller number of blocks (producing a smaller extent), with * this smaller number of blocks consisting of the requested * number of blocks rounded down to the next smaller power of 2 @@ -575,7 +575,7 @@ extBalloc(struct inode *ip, s64 hint, s64 * nblocks, s64 * blkno) * to a new set of blocks. If moving the extent, we initially * will try to allocate disk blocks for the requested size * (newnblks). if this fails (new contiguous free blocks not - * avaliable), we'll try to allocate a smaller number of + * available), we'll try to allocate a smaller number of * blocks (producing a smaller extent), with this smaller * number of blocks consisting of the requested number of * blocks rounded down to the next smaller power of 2 diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c index 3a09423b6c22..ed53a4740168 100644 --- a/fs/jfs/jfs_imap.c +++ b/fs/jfs/jfs_imap.c @@ -1069,7 +1069,7 @@ int diFree(struct inode *ip) */ if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG - 1)) { /* in preparation for removing the iag from the - * ag extent free list, read the iags preceeding + * ag extent free list, read the iags preceding * and following the iag on the ag extent free * list. */ @@ -1095,7 +1095,7 @@ int diFree(struct inode *ip) int inofreefwd = le32_to_cpu(iagp->inofreefwd); /* in preparation for removing the iag from the - * ag inode free list, read the iags preceeding + * ag inode free list, read the iags preceding * and following the iag on the ag inode free * list. before reading these iags, we must make * sure that we already don't have them in hand @@ -1681,7 +1681,7 @@ diAllocAG(struct inomap * imap, int agno, bool dir, struct inode *ip) * try to allocate a new extent of free inodes. */ if (addext) { - /* if free space is not avaliable for this new extent, try + /* if free space is not available for this new extent, try * below to allocate a free and existing (already backed) * inode from the ag. */ @@ -2036,7 +2036,7 @@ static int diAllocBit(struct inomap * imap, struct iag * iagp, int ino) /* check if this is the last free inode within the iag. * if so, it will have to be removed from the ag free - * inode list, so get the iags preceeding and following + * inode list, so get the iags preceding and following * it on the list. */ if (iagp->nfreeinos == cpu_to_le32(1)) { @@ -2208,7 +2208,7 @@ static int diNewExt(struct inomap * imap, struct iag * iagp, int extno) /* check if this is the last free extent within the * iag. if so, the iag must be removed from the ag - * free extent list, so get the iags preceeding and + * free extent list, so get the iags preceding and * following the iag on this list. */ if (iagp->nfreeexts == cpu_to_le32(1)) { @@ -2504,7 +2504,7 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp) } - /* get the next avaliable iag number */ + /* get the next available iag number */ iagno = imap->im_nextiag; /* make sure that we have not exceeded the maximum inode @@ -2615,7 +2615,7 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp) duplicateIXtree(sb, blkno, xlen, &xaddr); - /* update the next avaliable iag number */ + /* update the next available iag number */ imap->im_nextiag += 1; /* Add the iag to the iag free list so we don't lose the iag diff --git a/fs/jfs/jfs_logmgr.h b/fs/jfs/jfs_logmgr.h index 9236bc49ae7f..e38c21598850 100644 --- a/fs/jfs/jfs_logmgr.h +++ b/fs/jfs/jfs_logmgr.h @@ -288,7 +288,7 @@ struct lrd { /* * SYNCPT: log sync point * - * replay log upto syncpt address specified; + * replay log up to syncpt address specified; */ struct { __le32 sync; /* 4: syncpt address (0 = here) */ diff --git a/fs/jfs/jfs_metapage.h b/fs/jfs/jfs_metapage.h index d94f8d9e87d7..a78beda85f68 100644 --- a/fs/jfs/jfs_metapage.h +++ b/fs/jfs/jfs_metapage.h @@ -75,7 +75,7 @@ extern void grab_metapage(struct metapage *); extern void force_metapage(struct metapage *); /* - * hold_metapage and put_metapage are used in conjuction. The page lock + * hold_metapage and put_metapage are used in conjunction. The page lock * is not dropped between the two, so no other threads can get or release * the metapage */ diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c index 9466957ec841..f6cc0c09ec63 100644 --- a/fs/jfs/jfs_txnmgr.c +++ b/fs/jfs/jfs_txnmgr.c @@ -636,7 +636,7 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp, * the inode of the page and available to all anonymous * transactions until txCommit() time at which point * they are transferred to the transaction tlock list of - * the commiting transaction of the inode) + * the committing transaction of the inode) */ if (xtid == 0) { tlck->tid = tid; diff --git a/fs/jfs/resize.c b/fs/jfs/resize.c index 1aba0039f1c9..8ea5efb5a34e 100644 --- a/fs/jfs/resize.c +++ b/fs/jfs/resize.c @@ -57,7 +57,7 @@ * 2. compute new FSCKSize from new LVSize; * 3. set new FSSize as MIN(FSSize, LVSize-(LogSize+FSCKSize)) where * assert(new FSSize >= old FSSize), - * i.e., file system must not be shrinked; + * i.e., file system must not be shrunk; */ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize) { @@ -182,7 +182,7 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize) */ newFSSize = newLVSize - newLogSize - newFSCKSize; - /* file system cannot be shrinked */ + /* file system cannot be shrunk */ if (newFSSize < bmp->db_mapsize) { rc = -EINVAL; goto out; diff --git a/fs/jfs/super.c b/fs/jfs/super.c index eeca48a031ab..06c8a67cbe76 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c @@ -644,7 +644,7 @@ static int jfs_show_options(struct seq_file *seq, struct vfsmount *vfs) /* Read data from quotafile - avoid pagecache and such because we cannot afford * acquiring the locks... As quota files are never truncated and quota code - * itself serializes the operations (and noone else should touch the files) + * itself serializes the operations (and no one else should touch the files) * we don't have to be afraid of races */ static ssize_t jfs_quota_read(struct super_block *sb, int type, char *data, size_t len, loff_t off) diff --git a/fs/logfs/dev_mtd.c b/fs/logfs/dev_mtd.c index 7466e9dcc8c5..339e17e9133d 100644 --- a/fs/logfs/dev_mtd.c +++ b/fs/logfs/dev_mtd.c @@ -60,7 +60,7 @@ static int mtd_write(struct super_block *sb, loff_t ofs, size_t len, void *buf) * asynchronous properties. So just to prevent the first implementor of such * a thing from breaking logfs in 2350, we do the usual pointless dance to * declare a completion variable and wait for completion before returning - * from mtd_erase(). What an excercise in futility! + * from mtd_erase(). What an exercise in futility! */ static void logfs_erase_callback(struct erase_info *ei) { diff --git a/fs/logfs/dir.c b/fs/logfs/dir.c index f9ddf0c388c8..9ed89d1663f8 100644 --- a/fs/logfs/dir.c +++ b/fs/logfs/dir.c @@ -92,7 +92,7 @@ static int beyond_eof(struct inode *inode, loff_t bix) * so short names (len <= 9) don't even occupy the complete 32bit name * space. A prime >256 ensures short names quickly spread the 32bit * name space. Add about 26 for the estimated amount of information - * of each character and pick a prime nearby, preferrably a bit-sparse + * of each character and pick a prime nearby, preferably a bit-sparse * one. */ static u32 hash_32(const char *s, int len, u32 seed) diff --git a/fs/logfs/readwrite.c b/fs/logfs/readwrite.c index ee99a9f5dfd3..9e22085231b3 100644 --- a/fs/logfs/readwrite.c +++ b/fs/logfs/readwrite.c @@ -1616,7 +1616,7 @@ int logfs_rewrite_block(struct inode *inode, u64 bix, u64 ofs, err = logfs_write_buf(inode, page, flags); if (!err && shrink_level(gc_level) == 0) { /* Rewrite cannot mark the inode dirty but has to - * write it immediatly. + * write it immediately. * Q: Can't we just create an alias for the inode * instead? And if not, why not? */ diff --git a/fs/mbcache.c b/fs/mbcache.c index a25444ab2baf..2f174be06555 100644 --- a/fs/mbcache.c +++ b/fs/mbcache.c @@ -542,7 +542,7 @@ __mb_cache_entry_find(struct list_head *l, struct list_head *head, * mb_cache_entry_find_first() * * Find the first cache entry on a given device with a certain key in - * an additional index. Additonal matches can be found with + * an additional index. Additional matches can be found with * mb_cache_entry_find_next(). Returns NULL if no match was found. The * returned cache entry is locked for shared access ("multiple readers"). * diff --git a/fs/namei.c b/fs/namei.c index 3cb616d38d9c..e6cd6113872c 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -70,7 +70,7 @@ * name indicated by the symlink. The old code always complained that the * name already exists, due to not following the symlink even if its target * is nonexistent. The new semantics affects also mknod() and link() when - * the name is a symlink pointing to a non-existant name. + * the name is a symlink pointing to a non-existent name. * * I don't know which semantics is the right one, since I have no access * to standards. But I found by trial that HP-UX 9.0 has the full "new" diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c index 00a1d1c3d3a4..0250e4ce4893 100644 --- a/fs/ncpfs/inode.c +++ b/fs/ncpfs/inode.c @@ -596,7 +596,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent) /* server->priv.data = NULL; */ server->m = data; - /* Althought anything producing this is buggy, it happens + /* Although anything producing this is buggy, it happens now because of PATH_MAX changes.. */ if (server->m.time_out < 1) { server->m.time_out = 10; diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c index 14e0f9371d14..00ecf62ce7c1 100644 --- a/fs/nfs/callback_xdr.c +++ b/fs/nfs/callback_xdr.c @@ -241,7 +241,7 @@ static __be32 decode_layoutrecall_args(struct svc_rqst *rqstp, args->cbl_layout_type = ntohl(*p++); /* Depite the spec's xdr, iomode really belongs in the FILE switch, - * as it is unuseable and ignored with the other types. + * as it is unusable and ignored with the other types. */ iomode = ntohl(*p++); args->cbl_layoutchanged = ntohl(*p++); diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 3ac5bd695e5e..2f093ed16980 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -301,7 +301,7 @@ nfs_file_mmap(struct file * file, struct vm_area_struct * vma) * disk, but it retrieves and clears ctx->error after synching, despite * the two being set at the same time in nfs_context_set_write_error(). * This is because the former is used to notify the _next_ call to - * nfs_file_write() that a write error occured, and hence cause it to + * nfs_file_write() that a write error occurred, and hence cause it to * fall back to doing a synchronous write. */ static int diff --git a/fs/nfs/nfs4filelayout.h b/fs/nfs/nfs4filelayout.h index 085a354e0f08..7c44579f5832 100644 --- a/fs/nfs/nfs4filelayout.h +++ b/fs/nfs/nfs4filelayout.h @@ -33,7 +33,7 @@ #include "pnfs.h" /* - * Field testing shows we need to support upto 4096 stripe indices. + * Field testing shows we need to support up to 4096 stripe indices. * We store each index as a u8 (u32 on the wire) to keep the memory footprint * reasonable. This in turn means we support a maximum of 256 * RFC 5661 multipath_list4 structures. diff --git a/fs/nfs_common/nfsacl.c b/fs/nfs_common/nfsacl.c index ec0f277be7f5..6940439bd609 100644 --- a/fs/nfs_common/nfsacl.c +++ b/fs/nfs_common/nfsacl.c @@ -173,7 +173,7 @@ xdr_nfsace_decode(struct xdr_array2_desc *desc, void *elem) return -EINVAL; break; case ACL_MASK: - /* Solaris sometimes sets additonal bits in the mask */ + /* Solaris sometimes sets additional bits in the mask */ entry->e_perm &= S_IRWXO; break; default: diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index 7e84a852cdae..ad48faca20fc 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c @@ -702,7 +702,7 @@ nfs3svc_encode_readres(struct svc_rqst *rqstp, __be32 *p, *p++ = htonl(resp->eof); *p++ = htonl(resp->count); /* xdr opaque count */ xdr_ressize_check(rqstp, p); - /* now update rqstp->rq_res to reflect data aswell */ + /* now update rqstp->rq_res to reflect data as well */ rqstp->rq_res.page_len = resp->count; if (resp->count & 3) { /* need to pad the tail */ diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index fbde6f79922e..4b36ec3eb8ea 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -3055,7 +3055,7 @@ check_special_stateids(svc_fh *current_fh, stateid_t *stateid, int flags) if (ONE_STATEID(stateid) && (flags & RD_STATE)) return nfs_ok; else if (locks_in_grace()) { - /* Answer in remaining cases depends on existance of + /* Answer in remaining cases depends on existence of * conflicting state; so we must wait out the grace period. */ return nfserr_grace; } else if (flags & WR_STATE) @@ -3675,7 +3675,7 @@ find_lockstateowner_str(struct inode *inode, clientid_t *clid, /* * Alloc a lock owner structure. * Called in nfsd4_lock - therefore, OPEN and OPEN_CONFIRM (if needed) has - * occured. + * occurred. * * strhashval = lock_ownerstr_hashval */ diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c index 4ce005dbf3e6..65ec595e2226 100644 --- a/fs/nfsd/nfsxdr.c +++ b/fs/nfsd/nfsxdr.c @@ -451,7 +451,7 @@ nfssvc_encode_readres(struct svc_rqst *rqstp, __be32 *p, *p++ = htonl(resp->count); xdr_ressize_check(rqstp, p); - /* now update rqstp->rq_res to reflect data aswell */ + /* now update rqstp->rq_res to reflect data as well */ rqstp->rq_res.page_len = resp->count; if (resp->count & 3) { /* need to pad the tail */ diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 6b1305dc26c0..9fde1c00a296 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -164,7 +164,7 @@ static int process_access_response(struct fsnotify_group *group, fd, response); /* * make sure the response is valid, if invalid we do nothing and either - * userspace can send a valid responce or we will clean it up after the + * userspace can send a valid response or we will clean it up after the * timeout */ switch (response) { diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c index a91b69a6a291..7400898c0339 100644 --- a/fs/notify/inotify/inotify_fsnotify.c +++ b/fs/notify/inotify/inotify_fsnotify.c @@ -194,7 +194,7 @@ static int idr_callback(int id, void *p, void *data) static void inotify_free_group_priv(struct fsnotify_group *group) { - /* ideally the idr is empty and we won't hit the BUG in teh callback */ + /* ideally the idr is empty and we won't hit the BUG in the callback */ idr_for_each(&group->inotify_data.idr, idr_callback, group); idr_remove_all(&group->inotify_data.idr); idr_destroy(&group->inotify_data.idr); diff --git a/fs/notify/mark.c b/fs/notify/mark.c index 50c00856f730..252ab1f6452b 100644 --- a/fs/notify/mark.c +++ b/fs/notify/mark.c @@ -24,7 +24,7 @@ * referencing this object. The object typically will live inside the kernel * with a refcnt of 2, one for each list it is on (i_list, g_list). Any task * which can find this object holding the appropriete locks, can take a reference - * and the object itself is guarenteed to survive until the reference is dropped. + * and the object itself is guaranteed to survive until the reference is dropped. * * LOCKING: * There are 3 spinlocks involved with fsnotify inode marks and they MUST diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c index f5094ee224c1..f14fde2b03d6 100644 --- a/fs/ntfs/attrib.c +++ b/fs/ntfs/attrib.c @@ -197,7 +197,7 @@ err_out: } else if (ctx_needs_reset) { /* * If there is no attribute list, restoring the search context - * is acomplished simply by copying the saved context back over + * is accomplished simply by copying the saved context back over * the caller supplied context. If there is an attribute list, * things are more complicated as we need to deal with mapping * of mft records and resulting potential changes in pointers. @@ -1181,7 +1181,7 @@ not_found: * for, i.e. if one wants to add the attribute to the mft record this is the * correct place to insert its attribute list entry into. * - * When -errno != -ENOENT, an error occured during the lookup. @ctx->attr is + * When -errno != -ENOENT, an error occurred during the lookup. @ctx->attr is * then undefined and in particular you should not rely on it not changing. */ int ntfs_attr_lookup(const ATTR_TYPE type, const ntfschar *name, diff --git a/fs/ntfs/compress.c b/fs/ntfs/compress.c index ef9ed854255c..ee4144ce5d7c 100644 --- a/fs/ntfs/compress.c +++ b/fs/ntfs/compress.c @@ -501,7 +501,7 @@ int ntfs_read_compressed_block(struct page *page) VCN start_vcn = (((s64)index << PAGE_CACHE_SHIFT) & ~cb_size_mask) >> vol->cluster_size_bits; /* - * The first vcn after the last wanted vcn (minumum alignment is again + * The first vcn after the last wanted vcn (minimum alignment is again * PAGE_CACHE_SIZE. */ VCN end_vcn = ((((s64)(index + 1UL) << PAGE_CACHE_SHIFT) + cb_size - 1) diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c index 0b56c6b7ec01..c05d6dcf77a4 100644 --- a/fs/ntfs/inode.c +++ b/fs/ntfs/inode.c @@ -622,7 +622,7 @@ static int ntfs_read_locked_inode(struct inode *vi) */ /* Everyone gets all permissions. */ vi->i_mode |= S_IRWXUGO; - /* If read-only, noone gets write permissions. */ + /* If read-only, no one gets write permissions. */ if (IS_RDONLY(vi)) vi->i_mode &= ~S_IWUGO; if (m->flags & MFT_RECORD_IS_DIRECTORY) { @@ -2529,7 +2529,7 @@ retry_truncate: * specifies that the behaviour is unspecified thus we do not * have to do anything. This means that in our implementation * in the rare case that the file is mmap()ped and a write - * occured into the mmap()ped region just beyond the file size + * occurred into the mmap()ped region just beyond the file size * and writepage has not yet been called to write out the page * (which would clear the area beyond the file size) and we now * extend the file size to incorporate this dirty region diff --git a/fs/ntfs/layout.h b/fs/ntfs/layout.h index 8b2549f672bf..faece7190866 100644 --- a/fs/ntfs/layout.h +++ b/fs/ntfs/layout.h @@ -286,7 +286,7 @@ typedef le16 MFT_RECORD_FLAGS; * fragmented. Volume free space includes the empty part of the mft zone and * when the volume's free 88% are used up, the mft zone is shrunk by a factor * of 2, thus making more space available for more files/data. This process is - * repeated everytime there is no more free space except for the mft zone until + * repeated every time there is no more free space except for the mft zone until * there really is no more free space. */ @@ -1657,13 +1657,13 @@ typedef enum { * pointed to by the Owner field was provided by a defaulting mechanism * rather than explicitly provided by the original provider of the * security descriptor. This may affect the treatment of the SID with - * respect to inheritence of an owner. + * respect to inheritance of an owner. * * SE_GROUP_DEFAULTED - This boolean flag, when set, indicates that the SID in * the Group field was provided by a defaulting mechanism rather than * explicitly provided by the original provider of the security * descriptor. This may affect the treatment of the SID with respect to - * inheritence of a primary group. + * inheritance of a primary group. * * SE_DACL_PRESENT - This boolean flag, when set, indicates that the security * descriptor contains a discretionary ACL. If this flag is set and the @@ -1674,7 +1674,7 @@ typedef enum { * pointed to by the Dacl field was provided by a defaulting mechanism * rather than explicitly provided by the original provider of the * security descriptor. This may affect the treatment of the ACL with - * respect to inheritence of an ACL. This flag is ignored if the + * respect to inheritance of an ACL. This flag is ignored if the * DaclPresent flag is not set. * * SE_SACL_PRESENT - This boolean flag, when set, indicates that the security @@ -1686,7 +1686,7 @@ typedef enum { * pointed to by the Sacl field was provided by a defaulting mechanism * rather than explicitly provided by the original provider of the * security descriptor. This may affect the treatment of the ACL with - * respect to inheritence of an ACL. This flag is ignored if the + * respect to inheritance of an ACL. This flag is ignored if the * SaclPresent flag is not set. * * SE_SELF_RELATIVE - This boolean flag, when set, indicates that the security @@ -2283,7 +2283,7 @@ typedef struct { // the key_length is zero, then the vcn immediately // follows the INDEX_ENTRY_HEADER. Regardless of // key_length, the address of the 8-byte boundary - // alligned vcn of INDEX_ENTRY{_HEADER} *ie is given by + // aligned vcn of INDEX_ENTRY{_HEADER} *ie is given by // (char*)ie + le16_to_cpu(ie*)->length) - sizeof(VCN), // where sizeof(VCN) can be hardcoded as 8 if wanted. */ } __attribute__ ((__packed__)) INDEX_ENTRY; diff --git a/fs/ntfs/logfile.c b/fs/ntfs/logfile.c index 4dadcdf3d451..c71de292c5ad 100644 --- a/fs/ntfs/logfile.c +++ b/fs/ntfs/logfile.c @@ -669,7 +669,7 @@ err_out: * of cases where we think that a volume is dirty when in fact it is clean. * This should only affect volumes that have not been shutdown cleanly but did * not have any pending, non-check-pointed i/o, i.e. they were completely idle - * at least for the five seconds preceeding the unclean shutdown. + * at least for the five seconds preceding the unclean shutdown. * * This function assumes that the $LogFile journal has already been consistency * checked by a call to ntfs_check_logfile() and in particular if the $LogFile diff --git a/fs/ntfs/logfile.h b/fs/ntfs/logfile.h index b5a6f08bd35c..aa2b6ac3f0a4 100644 --- a/fs/ntfs/logfile.h +++ b/fs/ntfs/logfile.h @@ -222,7 +222,7 @@ typedef struct { /* 24*/ sle64 file_size; /* Usable byte size of the log file. If the restart_area_offset + the offset of the file_size are > 510 then corruption has - occured. This is the very first check when + occurred. This is the very first check when starting with the restart_area as if it fails it means that some of the above values will be corrupted by the multi sector diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c index 326e7475a22a..382857f9c7db 100644 --- a/fs/ntfs/mft.c +++ b/fs/ntfs/mft.c @@ -73,7 +73,7 @@ static inline MFT_RECORD *map_mft_record_page(ntfs_inode *ni) if (index > end_index || (i_size & ~PAGE_CACHE_MASK) < ofs + vol->mft_record_size) { page = ERR_PTR(-ENOENT); - ntfs_error(vol->sb, "Attemt to read mft record 0x%lx, " + ntfs_error(vol->sb, "Attempt to read mft record 0x%lx, " "which is beyond the end of the mft. " "This is probably a bug in the ntfs " "driver.", ni->mft_no); @@ -1442,7 +1442,7 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol) // Note: It will need to be a special mft record and if none of // those are available it gets rather complicated... ntfs_error(vol->sb, "Not enough space in this mft record to " - "accomodate extended mft bitmap attribute " + "accommodate extended mft bitmap attribute " "extent. Cannot handle this yet."); ret = -EOPNOTSUPP; goto undo_alloc; @@ -1879,7 +1879,7 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol) // and we would then need to update all references to this mft // record appropriately. This is rather complicated... ntfs_error(vol->sb, "Not enough space in this mft record to " - "accomodate extended mft data attribute " + "accommodate extended mft data attribute " "extent. Cannot handle this yet."); ret = -EOPNOTSUPP; goto undo_alloc; @@ -2357,7 +2357,7 @@ ntfs_inode *ntfs_mft_record_alloc(ntfs_volume *vol, const int mode, } #ifdef DEBUG read_lock_irqsave(&mftbmp_ni->size_lock, flags); - ntfs_debug("Status of mftbmp after initialized extention: " + ntfs_debug("Status of mftbmp after initialized extension: " "allocated_size 0x%llx, data_size 0x%llx, " "initialized_size 0x%llx.", (long long)mftbmp_ni->allocated_size, diff --git a/fs/ntfs/runlist.c b/fs/ntfs/runlist.c index 56a9a6d25a2a..eac7d6788a10 100644 --- a/fs/ntfs/runlist.c +++ b/fs/ntfs/runlist.c @@ -1243,7 +1243,7 @@ err_out: * write. * * This is used when building the mapping pairs array of a runlist to compress - * a given logical cluster number (lcn) or a specific run length to the minumum + * a given logical cluster number (lcn) or a specific run length to the minimum * size possible. * * Return the number of bytes written on success. On error, i.e. the diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c index 29099a07b9fe..b52706da4645 100644 --- a/fs/ntfs/super.c +++ b/fs/ntfs/super.c @@ -458,7 +458,7 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt) * the volume on boot and updates them. * * When remounting read-only, mark the volume clean if no volume errors - * have occured. + * have occurred. */ if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) { static const char *es = ". Cannot remount read-write."; @@ -1269,7 +1269,7 @@ static int check_windows_hibernation_status(ntfs_volume *vol) "hibernated on the volume."); return 0; } - /* A real error occured. */ + /* A real error occurred. */ ntfs_error(vol->sb, "Failed to find inode number for " "hiberfil.sys."); return ret; @@ -1370,7 +1370,7 @@ static bool load_and_init_quota(ntfs_volume *vol) NVolSetQuotaOutOfDate(vol); return true; } - /* A real error occured. */ + /* A real error occurred. */ ntfs_error(vol->sb, "Failed to find inode number for $Quota."); return false; } @@ -1454,7 +1454,7 @@ not_enabled: NVolSetUsnJrnlStamped(vol); return true; } - /* A real error occured. */ + /* A real error occurred. */ ntfs_error(vol->sb, "Failed to find inode number for " "$UsnJrnl."); return false; @@ -2292,7 +2292,7 @@ static void ntfs_put_super(struct super_block *sb) ntfs_commit_inode(vol->mft_ino); /* - * If a read-write mount and no volume errors have occured, mark the + * If a read-write mount and no volume errors have occurred, mark the * volume clean. Also, re-commit all affected inodes. */ if (!(sb->s_flags & MS_RDONLY)) { @@ -2496,7 +2496,7 @@ static s64 get_nr_free_clusters(ntfs_volume *vol) if (vol->nr_clusters & 63) nr_free += 64 - (vol->nr_clusters & 63); up_read(&vol->lcnbmp_lock); - /* If errors occured we may well have gone below zero, fix this. */ + /* If errors occurred we may well have gone below zero, fix this. */ if (nr_free < 0) nr_free = 0; ntfs_debug("Exiting."); @@ -2561,7 +2561,7 @@ static unsigned long __get_nr_free_mft_records(ntfs_volume *vol, } ntfs_debug("Finished reading $MFT/$BITMAP, last index = 0x%lx.", index - 1); - /* If errors occured we may well have gone below zero, fix this. */ + /* If errors occurred we may well have gone below zero, fix this. */ if (nr_free < 0) nr_free = 0; ntfs_debug("Exiting."); diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index b27a0d86f8c5..48aa9c7401c7 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c @@ -4519,7 +4519,7 @@ set_tail_append: } /* - * Helper function called at the begining of an insert. + * Helper function called at the beginning of an insert. * * This computes a few things that are commonly used in the process of * inserting into the btree: diff --git a/fs/ocfs2/aops.h b/fs/ocfs2/aops.h index eceb456037c1..75cf3ad987a6 100644 --- a/fs/ocfs2/aops.h +++ b/fs/ocfs2/aops.h @@ -71,7 +71,7 @@ static inline void ocfs2_iocb_set_rw_locked(struct kiocb *iocb, int level) /* * Using a named enum representing lock types in terms of #N bit stored in - * iocb->private, which is going to be used for communication bewteen + * iocb->private, which is going to be used for communication between * ocfs2_dio_end_io() and ocfs2_file_aio_write/read(). */ enum ocfs2_iocb_lock_bits { diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c index 2461eb3272ed..643720209a98 100644 --- a/fs/ocfs2/cluster/heartbeat.c +++ b/fs/ocfs2/cluster/heartbeat.c @@ -2275,7 +2275,7 @@ void o2hb_free_hb_set(struct config_group *group) kfree(hs); } -/* hb callback registration and issueing */ +/* hb callback registration and issuing */ static struct o2hb_callback *hbcall_from_type(enum o2hb_callback_type type) { diff --git a/fs/ocfs2/cluster/quorum.c b/fs/ocfs2/cluster/quorum.c index a87366750f23..8f9cea1597af 100644 --- a/fs/ocfs2/cluster/quorum.c +++ b/fs/ocfs2/cluster/quorum.c @@ -89,7 +89,7 @@ static void o2quo_fence_self(void) }; } -/* Indicate that a timeout occured on a hearbeat region write. The +/* Indicate that a timeout occurred on a hearbeat region write. The * other nodes in the cluster may consider us dead at that time so we * want to "fence" ourselves so that we don't scribble on the disk * after they think they've recovered us. This can't solve all @@ -261,7 +261,7 @@ void o2quo_hb_still_up(u8 node) spin_unlock(&qs->qs_lock); } -/* This is analagous to hb_up. as a node's connection comes up we delay the +/* This is analogous to hb_up. as a node's connection comes up we delay the * quorum decision until we see it heartbeating. the hold will be droped in * hb_up or hb_down. it might be perpetuated by con_err until hb_down. if * it's already heartbeating we we might be dropping a hold that conn_up got. diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c index ee04ff5ee603..db5ee4b4f47a 100644 --- a/fs/ocfs2/cluster/tcp.c +++ b/fs/ocfs2/cluster/tcp.c @@ -565,7 +565,7 @@ static void o2net_set_nn_state(struct o2net_node *nn, * the work queue actually being up. */ if (!valid && o2net_wq) { unsigned long delay; - /* delay if we're withing a RECONNECT_DELAY of the + /* delay if we're within a RECONNECT_DELAY of the * last attempt */ delay = (nn->nn_last_connect_attempt + msecs_to_jiffies(o2net_reconnect_delay())) diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index 9d67610dfc74..fede57ed005f 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c @@ -808,7 +808,7 @@ lookup: dlm_mle_detach_hb_events(dlm, mle); dlm_put_mle(mle); mle = NULL; - /* this is lame, but we cant wait on either + /* this is lame, but we can't wait on either * the mle or lockres waitqueue here */ if (mig) msleep(100); @@ -843,7 +843,7 @@ lookup: /* finally add the lockres to its hash bucket */ __dlm_insert_lockres(dlm, res); - /* since this lockres is new it doesnt not require the spinlock */ + /* since this lockres is new it doesn't not require the spinlock */ dlm_lockres_grab_inflight_ref_new(dlm, res); /* if this node does not become the master make sure to drop diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index 177d3a6c2a5f..b4c8bb6b8d28 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c @@ -835,7 +835,7 @@ static int ocfs2_inode_is_valid_to_delete(struct inode *inode) /* If we have allowd wipe of this inode for another node, it * will be marked here so we can safely skip it. Recovery will - * cleanup any inodes we might inadvertantly skip here. */ + * cleanup any inodes we might inadvertently skip here. */ if (oi->ip_flags & OCFS2_INODE_SKIP_DELETE) goto bail_unlock; @@ -917,7 +917,7 @@ static int ocfs2_query_inode_wipe(struct inode *inode, * the inode open lock in ocfs2_read_locked_inode(). When we * get to ->delete_inode(), each node tries to convert it's * lock to an exclusive. Trylocks are serialized by the inode - * meta data lock. If the upconvert suceeds, we know the inode + * meta data lock. If the upconvert succeeds, we know the inode * is no longer live and can be deleted. * * Though we call this with the meta data lock held, the diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c index dcc2d9327150..b141a44605ca 100644 --- a/fs/ocfs2/journal.c +++ b/fs/ocfs2/journal.c @@ -1368,7 +1368,7 @@ skip_recovery: mlog_errno(status); /* Now it is right time to recover quotas... We have to do this under - * superblock lock so that noone can start using the slot (and crash) + * superblock lock so that no one can start using the slot (and crash) * before we recover it */ for (i = 0; i < rm_quota_used; i++) { qrec = ocfs2_begin_quota_recovery(osb, rm_quota[i]); diff --git a/fs/ocfs2/journal.h b/fs/ocfs2/journal.h index 6180da1e37e6..68cf2f6d3c6a 100644 --- a/fs/ocfs2/journal.h +++ b/fs/ocfs2/journal.h @@ -215,7 +215,7 @@ static inline void ocfs2_checkpoint_inode(struct inode *inode) /* WARNING: This only kicks off a single * checkpoint. If someone races you and adds more * metadata to the journal, you won't know, and will - * wind up waiting *alot* longer than necessary. Right + * wind up waiting *a lot* longer than necessary. Right * now we only use this in clear_inode so that's * OK. */ ocfs2_start_checkpoint(osb); diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 28f2cc1080d8..e5d738cd9cc0 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c @@ -2128,7 +2128,7 @@ leave: } /** - * ocfs2_prep_new_orphaned_file() - Prepare the orphan dir to recieve a newly + * ocfs2_prep_new_orphaned_file() - Prepare the orphan dir to receive a newly * allocated file. This is different from the typical 'add to orphan dir' * operation in that the inode does not yet exist. This is a problem because * the orphan dir stringifies the inode block number to come up with it's diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h index bf2e7764920e..b68f87a83924 100644 --- a/fs/ocfs2/ocfs2_fs.h +++ b/fs/ocfs2/ocfs2_fs.h @@ -441,7 +441,7 @@ static unsigned char ocfs2_type_by_mode[S_IFMT >> S_SHIFT] = { struct ocfs2_block_check { /*00*/ __le32 bc_crc32e; /* 802.3 Ethernet II CRC32 */ __le16 bc_ecc; /* Single-error-correction parity vector. - This is a simple Hamming code dependant + This is a simple Hamming code dependent on the blocksize. OCFS2's maximum blocksize, 4K, requires 16 parity bits, so we fit in __le16. */ @@ -750,7 +750,7 @@ struct ocfs2_dinode { after an unclean shutdown */ } journal1; - } id1; /* Inode type dependant 1 */ + } id1; /* Inode type dependent 1 */ /*C0*/ union { struct ocfs2_super_block i_super; struct ocfs2_local_alloc i_lab; diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c index 279aef68025b..92fcd575775a 100644 --- a/fs/ocfs2/quota_global.c +++ b/fs/ocfs2/quota_global.c @@ -556,7 +556,7 @@ int __ocfs2_sync_dquot(struct dquot *dquot, int freeing) spin_unlock(&dq_data_lock); err = ocfs2_qinfo_lock(info, freeing); if (err < 0) { - mlog(ML_ERROR, "Failed to lock quota info, loosing quota write" + mlog(ML_ERROR, "Failed to lock quota info, losing quota write" " (type=%d, id=%u)\n", dquot->dq_type, (unsigned)dquot->dq_id); goto out; diff --git a/fs/ocfs2/reservations.h b/fs/ocfs2/reservations.h index 1e49cc29d06c..42c2b804f3fd 100644 --- a/fs/ocfs2/reservations.h +++ b/fs/ocfs2/reservations.h @@ -29,7 +29,7 @@ struct ocfs2_alloc_reservation { struct rb_node r_node; - unsigned int r_start; /* Begining of current window */ + unsigned int r_start; /* Beginning of current window */ unsigned int r_len; /* Length of the window */ unsigned int r_last_len; /* Length of most recent alloc */ diff --git a/fs/ocfs2/stackglue.h b/fs/ocfs2/stackglue.h index 8ce7398ae1d2..1ec56fdb8d0d 100644 --- a/fs/ocfs2/stackglue.h +++ b/fs/ocfs2/stackglue.h @@ -126,7 +126,7 @@ struct ocfs2_stack_operations { * * ->connect() must not return until it is guaranteed that * - * - Node down notifications for the filesystem will be recieved + * - Node down notifications for the filesystem will be received * and passed to conn->cc_recovery_handler(). * - Locking requests for the filesystem will be processed. */ diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c index ab6e2061074f..ba5d97e4a73e 100644 --- a/fs/ocfs2/suballoc.c +++ b/fs/ocfs2/suballoc.c @@ -1511,7 +1511,7 @@ static int ocfs2_cluster_group_search(struct inode *inode, max_bits = le16_to_cpu(gd->bg_bits); /* Tail groups in cluster bitmaps which aren't cpg - * aligned are prone to partial extention by a failed + * aligned are prone to partial extension by a failed * fs resize. If the file system resize never got to * update the dinode cluster count, then we don't want * to trust any clusters past it, regardless of what @@ -2459,7 +2459,7 @@ static int _ocfs2_free_suballoc_bits(handle_t *handle, /* The alloc_bh comes from ocfs2_free_dinode() or * ocfs2_free_clusters(). The callers have all locked the * allocator and gotten alloc_bh from the lock call. This - * validates the dinode buffer. Any corruption that has happended + * validates the dinode buffer. Any corruption that has happened * is a code bug. */ BUG_ON(!OCFS2_IS_VALID_DINODE(fe)); BUG_ON((count + start_bit) > ocfs2_bits_per_group(cl)); diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 69fa11b35aa4..5a521c748859 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c @@ -78,7 +78,7 @@ static struct kmem_cache *ocfs2_inode_cachep = NULL; struct kmem_cache *ocfs2_dquot_cachep; struct kmem_cache *ocfs2_qf_chunk_cachep; -/* OCFS2 needs to schedule several differnt types of work which +/* OCFS2 needs to schedule several different types of work which * require cluster locking, disk I/O, recovery waits, etc. Since these * types of work tend to be heavy we avoid using the kernel events * workqueue and schedule on our own. */ diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index 57a215dc2d9b..81ecf9c0bf0a 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c @@ -3554,7 +3554,7 @@ int ocfs2_xattr_set(struct inode *inode, down_write(&OCFS2_I(inode)->ip_xattr_sem); /* * Scan inode and external block to find the same name - * extended attribute and collect search infomation. + * extended attribute and collect search information. */ ret = ocfs2_xattr_ibody_find(inode, name_index, name, &xis); if (ret) @@ -3578,7 +3578,7 @@ int ocfs2_xattr_set(struct inode *inode, goto cleanup; } - /* Check whether the value is refcounted and do some prepartion. */ + /* Check whether the value is refcounted and do some preparation. */ if (OCFS2_I(inode)->ip_dyn_features & OCFS2_HAS_REFCOUNT_FL && (!xis.not_found || !xbs.not_found)) { ret = ocfs2_prepare_refcount_xattr(inode, di, &xi, diff --git a/fs/partitions/check.c b/fs/partitions/check.c index ac546975031f..d545e97d99c3 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c @@ -500,7 +500,7 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno, /* everything is up and running, commence */ rcu_assign_pointer(ptbl->part[partno], p); - /* suppress uevent if the disk supresses it */ + /* suppress uevent if the disk suppresses it */ if (!dev_get_uevent_suppress(ddev)) kobject_uevent(&pdev->kobj, KOBJ_ADD); @@ -585,7 +585,7 @@ rescan: /* * If any partition code tried to read beyond EOD, try * unlocking native capacity even if partition table is - * sucessfully read as we could be missing some partitions. + * successfully read as we could be missing some partitions. */ if (state->access_beyond_eod) { printk(KERN_WARNING diff --git a/fs/proc/base.c b/fs/proc/base.c index 5a670c11aeac..dd6628d3ba42 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -220,7 +220,7 @@ static struct mm_struct *__check_mem_permission(struct task_struct *task) } /* - * Noone else is allowed. + * No one else is allowed. */ mmput(mm); return ERR_PTR(-EPERM); diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig index 867d0ac026ce..8007ae7c0d8c 100644 --- a/fs/pstore/Kconfig +++ b/fs/pstore/Kconfig @@ -1,5 +1,5 @@ config PSTORE - bool "Persistant store support" + bool "Persistent store support" default n help This option enables generic access to platform level diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index fcc8ae75d874..a925bf205497 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -956,7 +956,7 @@ static inline int dqput_blocks(struct dquot *dquot) /* * Remove references to dquots from inode and add dquot to list for freeing - * if we have the last referece to dquot + * if we have the last reference to dquot * We can't race with anybody because we hold dqptr_sem for writing... */ static int remove_inode_dquot_ref(struct inode *inode, int type, diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index c77514bd5776..c5e82ece7c6c 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c @@ -1,7 +1,7 @@ /* ** Write ahead logging implementation copyright Chris Mason 2000 ** -** The background commits make this code very interelated, and +** The background commits make this code very interrelated, and ** overly complex. I need to rethink things a bit....The major players: ** ** journal_begin -- call with the number of blocks you expect to log. @@ -2725,7 +2725,7 @@ int journal_init(struct super_block *sb, const char *j_dev_name, REISERFS_DISK_OFFSET_IN_BYTES / sb->s_blocksize + 2); - /* Sanity check to see is the standard journal fitting withing first bitmap + /* Sanity check to see is the standard journal fitting within first bitmap (actual for small blocksizes) */ if (!SB_ONDISK_JOURNAL_DEVICE(sb) && (SB_JOURNAL_1st_RESERVED_BLOCK(sb) + diff --git a/fs/reiserfs/lock.c b/fs/reiserfs/lock.c index b87aa2c1afc1..7df1ce48203a 100644 --- a/fs/reiserfs/lock.c +++ b/fs/reiserfs/lock.c @@ -15,7 +15,7 @@ * for this mutex, no need for a system wide mutex facility. * * Also this lock is often released before a call that could block because - * reiserfs performances were partialy based on the release while schedule() + * reiserfs performances were partially based on the release while schedule() * property of the Bkl. */ void reiserfs_write_lock(struct super_block *s) diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 0aab04f46827..b216ff6be1c9 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -393,7 +393,7 @@ void add_save_link(struct reiserfs_transaction_handle *th, /* body of "save" link */ link = INODE_PKEY(inode)->k_dir_id; - /* put "save" link inot tree, don't charge quota to anyone */ + /* put "save" link into tree, don't charge quota to anyone */ retval = reiserfs_insert_item(th, &path, &key, &ih, NULL, (char *)&link); if (retval) { @@ -2104,7 +2104,7 @@ out: /* Read data from quotafile - avoid pagecache and such because we cannot afford * acquiring the locks... As quota files are never truncated and quota code - * itself serializes the operations (and noone else should touch the files) + * itself serializes the operations (and no one else should touch the files) * we don't have to be afraid of races */ static ssize_t reiserfs_quota_read(struct super_block *sb, int type, char *data, size_t len, loff_t off) diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 5c11ca82b782..47d2a4498b03 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -396,7 +396,7 @@ static struct page *reiserfs_get_page(struct inode *dir, size_t n) struct address_space *mapping = dir->i_mapping; struct page *page; /* We can deadlock if we try to free dentries, - and an unlink/rmdir has just occured - GFP_NOFS avoids this */ + and an unlink/rmdir has just occurred - GFP_NOFS avoids this */ mapping_set_gfp_mask(mapping, GFP_NOFS); page = read_mapping_page(mapping, n >> PAGE_CACHE_SHIFT, NULL); if (!IS_ERR(page)) { diff --git a/fs/squashfs/cache.c b/fs/squashfs/cache.c index 26b15ae34d6f..c37b520132ff 100644 --- a/fs/squashfs/cache.c +++ b/fs/squashfs/cache.c @@ -104,7 +104,7 @@ struct squashfs_cache_entry *squashfs_cache_get(struct super_block *sb, entry = &cache->entry[i]; /* - * Initialise choosen cache entry, and fill it in from + * Initialise chosen cache entry, and fill it in from * disk. */ cache->unused--; @@ -286,7 +286,7 @@ cleanup: /* - * Copy upto length bytes from cache entry to buffer starting at offset bytes + * Copy up to length bytes from cache entry to buffer starting at offset bytes * into the cache entry. If there's not length bytes then copy the number of * bytes available. In all cases return the number of bytes copied. */ diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c index c8ff0d1ae5d3..8b3a7da531eb 100644 --- a/fs/ubifs/budget.c +++ b/fs/ubifs/budget.c @@ -147,7 +147,7 @@ static int make_free_space(struct ubifs_info *c) if (liab2 < liab1) return -EAGAIN; - dbg_budg("new liability %lld (not shrinked)", liab2); + dbg_budg("new liability %lld (not shrunk)", liab2); /* Liability did not shrink again, try GC */ dbg_budg("Run GC"); diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index 27a4babe7df0..e765743cf9f3 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c @@ -78,7 +78,7 @@ static int ufs_block_to_path(struct inode *inode, sector_t i_block, sector_t off /* * Returns the location of the fragment from - * the begining of the filesystem. + * the beginning of the filesystem. */ static u64 ufs_frag_map(struct inode *inode, sector_t frag, bool needs_lock) diff --git a/fs/ufs/super.c b/fs/ufs/super.c index 7693d6293404..3915ade6f9a8 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c @@ -483,9 +483,9 @@ static int ufs_parse_options (char * options, unsigned * mount_options) } /* - * Diffrent types of UFS hold fs_cstotal in different - * places, and use diffrent data structure for it. - * To make things simplier we just copy fs_cstotal to ufs_sb_private_info + * Different types of UFS hold fs_cstotal in different + * places, and use different data structure for it. + * To make things simpler we just copy fs_cstotal to ufs_sb_private_info */ static void ufs_setup_cstotal(struct super_block *sb) { diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 52dbd14260ba..79ce38be15a1 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c @@ -1295,7 +1295,7 @@ xfs_get_blocks_direct( * If the private argument is non-NULL __xfs_get_blocks signals us that we * need to issue a transaction to convert the range from unwritten to written * extents. In case this is regular synchronous I/O we just call xfs_end_io - * to do this and we are done. But in case this was a successfull AIO + * to do this and we are done. But in case this was a successful AIO * request this handler is called from interrupt context, from which we * can't start transactions. In that case offload the I/O completion to * the workqueues we also use for buffered I/O completion. diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index 596bb2c9de42..5ea402023ebd 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c @@ -120,7 +120,7 @@ xfs_buf_lru_add( * The unlocked check is safe here because it only occurs when there are not * b_lru_ref counts left on the inode under the pag->pag_buf_lock. it is there * to optimise the shrinker removing the buffer from the LRU and calling - * xfs_buf_free(). i.e. it removes an unneccessary round trip on the + * xfs_buf_free(). i.e. it removes an unnecessary round trip on the * bt_lru_lock. */ STATIC void @@ -380,7 +380,7 @@ out_free_pages: } /* - * Map buffer into kernel address-space if nessecary. + * Map buffer into kernel address-space if necessary. */ STATIC int _xfs_buf_map_pages( diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index 52aadfbed132..f4213ba1ff85 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c @@ -381,7 +381,7 @@ xfs_aio_write_isize_update( /* * If this was a direct or synchronous I/O that failed (such as ENOSPC) then - * part of the I/O may have been written to disk before the error occured. In + * part of the I/O may have been written to disk before the error occurred. In * this case the on-disk file size may have been adjusted beyond the in-memory * file size and now needs to be truncated back. */ diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 9ff7fc603d2f..dd21784525a8 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c @@ -70,7 +70,7 @@ xfs_synchronize_times( /* * If the linux inode is valid, mark it dirty. - * Used when commiting a dirty inode into a transaction so that + * Used when committing a dirty inode into a transaction so that * the inode will get written back by the linux code */ void diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c index 594cd822d84d..9cf35a688f53 100644 --- a/fs/xfs/linux-2.6/xfs_sync.c +++ b/fs/xfs/linux-2.6/xfs_sync.c @@ -401,7 +401,7 @@ xfs_quiesce_fs( /* * Second stage of a quiesce. The data is already synced, now we have to take * care of the metadata. New transactions are already blocked, so we need to - * wait for any remaining transactions to drain out before proceding. + * wait for any remaining transactions to drain out before proceeding. */ void xfs_quiesce_attr( diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c index 7e2416478503..6fa214603819 100644 --- a/fs/xfs/quota/xfs_dquot.c +++ b/fs/xfs/quota/xfs_dquot.c @@ -600,7 +600,7 @@ xfs_qm_dqread( /* * Reservation counters are defined as reservation plus current usage - * to avoid having to add everytime. + * to avoid having to add every time. */ dqp->q_res_bcount = be64_to_cpu(ddqp->d_bcount); dqp->q_res_icount = be64_to_cpu(ddqp->d_icount); diff --git a/fs/xfs/quota/xfs_qm_bhv.c b/fs/xfs/quota/xfs_qm_bhv.c index 774d7ec6df8e..a0a829addca9 100644 --- a/fs/xfs/quota/xfs_qm_bhv.c +++ b/fs/xfs/quota/xfs_qm_bhv.c @@ -134,7 +134,7 @@ xfs_qm_newmount( */ if (quotaondisk && !XFS_QM_NEED_QUOTACHECK(mp)) { /* - * If an error occured, qm_mount_quotas code + * If an error occurred, qm_mount_quotas code * has already disabled quotas. So, just finish * mounting, and get on with the boring life * without disk quotas. diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c index c82f06778a27..0d62a07b7fd8 100644 --- a/fs/xfs/quota/xfs_qm_syscalls.c +++ b/fs/xfs/quota/xfs_qm_syscalls.c @@ -172,7 +172,7 @@ xfs_qm_scall_quotaoff( /* * Next we make the changes in the quota flag in the mount struct. * This isn't protected by a particular lock directly, because we - * don't want to take a mrlock everytime we depend on quotas being on. + * don't want to take a mrlock every time we depend on quotas being on. */ mp->m_qflags &= ~(flags); @@ -354,7 +354,7 @@ xfs_qm_scall_quotaon( return XFS_ERROR(EINVAL); } /* - * If everything's upto-date incore, then don't waste time. + * If everything's up to-date incore, then don't waste time. */ if ((mp->m_qflags & flags) == flags) return XFS_ERROR(EEXIST); diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index e5413d96f1af..7b7e005e3dcc 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c @@ -992,7 +992,7 @@ xfs_buf_iodone_callbacks( lasttarg = XFS_BUF_TARGET(bp); /* - * If the write was asynchronous then noone will be looking for the + * If the write was asynchronous then no one will be looking for the * error. Clear the error state and write the buffer out again. * * During sync or umount we'll write all pending buffers again diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 742c8330994a..a37480a6e023 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -2789,7 +2789,7 @@ xfs_iflush( /* * We can't flush the inode until it is unpinned, so wait for it if we - * are allowed to block. We know noone new can pin it, because we are + * are allowed to block. We know no one new can pin it, because we are * holding the inode lock shared and you need to hold it exclusively to * pin the inode. * diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index f753200cef8d..ff4e2a30227d 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -111,7 +111,7 @@ struct xfs_imap { * Generally, we do not want to hold the i_rlock while holding the * i_ilock. Hierarchy is i_iolock followed by i_rlock. * - * xfs_iptr_t contains all the inode fields upto and including the + * xfs_iptr_t contains all the inode fields up to and including the * i_mnext and i_mprev fields, it is used as a marker in the inode * chain off the mount structure by xfs_sync calls. */ @@ -336,7 +336,7 @@ xfs_iflags_test_and_clear(xfs_inode_t *ip, unsigned short flags) /* * Project quota id helpers (previously projid was 16bit only - * and using two 16bit values to hold new 32bit projid was choosen + * and using two 16bit values to hold new 32bit projid was chosen * to retain compatibility with "old" filesystems). */ static inline prid_t diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index 15dbf1f9c2be..ffae692c9832 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h @@ -570,7 +570,7 @@ int xlog_write(struct log *log, struct xfs_log_vec *log_vector, * When we crack an atomic LSN, we sample it first so that the value will not * change while we are cracking it into the component values. This means we * will always get consistent component values to work from. This should always - * be used to smaple and crack LSNs taht are stored and updated in atomic + * be used to sample and crack LSNs that are stored and updated in atomic * variables. */ static inline void diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 0c4a5618e7af..5cc464a17c93 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -101,7 +101,7 @@ xlog_get_bp( /* * We do log I/O in units of log sectors (a power-of-2 * multiple of the basic block size), so we round up the - * requested size to acommodate the basic blocks required + * requested size to accommodate the basic blocks required * for complete log sectors. * * In addition, the buffer may be used for a non-sector- @@ -112,7 +112,7 @@ xlog_get_bp( * an issue. Nor will this be a problem if the log I/O is * done in basic blocks (sector size 1). But otherwise we * extend the buffer by one extra log sector to ensure - * there's space to accomodate this possiblility. + * there's space to accommodate this possibility. */ if (nbblks > 1 && log->l_sectBBsize > 1) nbblks += log->l_sectBBsize; diff --git a/fs/xfs/xfs_trans_inode.c b/fs/xfs/xfs_trans_inode.c index 16084d8ea231..048b0c689d3e 100644 --- a/fs/xfs/xfs_trans_inode.c +++ b/fs/xfs/xfs_trans_inode.c @@ -81,7 +81,7 @@ xfs_trans_ijoin( * * * Grabs a reference to the inode which will be dropped when the transaction - * is commited. The inode will also be unlocked at that point. The inode + * is committed. The inode will also be unlocked at that point. The inode * must be locked, and it cannot be associated with any transaction. */ void diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index c48b4217ec47..b7a5fe7c52c8 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -953,7 +953,7 @@ xfs_release( * If we previously truncated this file and removed old data * in the process, we want to initiate "early" writeout on * the last close. This is an attempt to combat the notorious - * NULL files problem which is particularly noticable from a + * NULL files problem which is particularly noticeable from a * truncate down, buffered (re-)write (delalloc), followed by * a crash. What we are effectively doing here is * significantly reducing the time window where we'd otherwise @@ -982,7 +982,7 @@ xfs_release( * * Further, check if the inode is being opened, written and * closed frequently and we have delayed allocation blocks - * oustanding (e.g. streaming writes from the NFS server), + * outstanding (e.g. streaming writes from the NFS server), * truncating the blocks past EOF will cause fragmentation to * occur. * diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h index d41c94885211..f1380287ed4d 100644 --- a/include/acpi/actbl.h +++ b/include/acpi/actbl.h @@ -290,7 +290,7 @@ struct acpi_table_fadt { #define ACPI_FADT_APIC_CLUSTER (1<<18) /* 18: [V4] All local APICs must use cluster model (ACPI 3.0) */ #define ACPI_FADT_APIC_PHYSICAL (1<<19) /* 19: [V4] All local x_aPICs must use physical dest mode (ACPI 3.0) */ -/* Values for preferred_profile (Prefered Power Management Profiles) */ +/* Values for preferred_profile (Preferred Power Management Profiles) */ enum acpi_prefered_pm_profiles { PM_UNSPECIFIED = 0, diff --git a/include/asm-generic/siginfo.h b/include/asm-generic/siginfo.h index 942d30b5aab1..0dd4e87f6fba 100644 --- a/include/asm-generic/siginfo.h +++ b/include/asm-generic/siginfo.h @@ -192,7 +192,7 @@ typedef struct siginfo { * SIGBUS si_codes */ #define BUS_ADRALN (__SI_FAULT|1) /* invalid address alignment */ -#define BUS_ADRERR (__SI_FAULT|2) /* non-existant physical address */ +#define BUS_ADRERR (__SI_FAULT|2) /* non-existent physical address */ #define BUS_OBJERR (__SI_FAULT|3) /* object specific hardware error */ /* hardware memory error consumed on a machine check: action required */ #define BUS_MCEERR_AR (__SI_FAULT|4) diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 32c45e5fe0ab..bd297a20ab98 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -773,7 +773,7 @@ * the sections that has this restriction (or similar) * is located before the ones requiring PAGE_SIZE alignment. * NOSAVE_DATA starts and ends with a PAGE_SIZE alignment which - * matches the requirment of PAGE_ALIGNED_DATA. + * matches the requirement of PAGE_ALIGNED_DATA. * * use 0 as page_align if page_aligned data is not used */ #define RW_DATA_SECTION(cacheline, pagealigned, inittask) \ diff --git a/include/drm/drmP.h b/include/drm/drmP.h index ad5770f2315c..202424d17ed7 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -95,7 +95,7 @@ struct drm_device; * drm_core, drm_driver, drm_kms * drm_core level can be used in the generic drm code. For example: * drm_ioctl, drm_mm, drm_memory - * The macro definiton of DRM_DEBUG is used. + * The macro definition of DRM_DEBUG is used. * DRM_DEBUG(fmt, args...) * The debug info by using the DRM_DEBUG can be obtained by adding * the boot option of "drm.debug=1". @@ -808,7 +808,7 @@ struct drm_driver { * * \return Flags, or'ed together as follows: * - * DRM_SCANOUTPOS_VALID = Query successfull. + * DRM_SCANOUTPOS_VALID = Query successful. * DRM_SCANOUTPOS_INVBL = Inside vblank. * DRM_SCANOUTPOS_ACCURATE = Returned position is accurate. A lack of * this flag means that returned position may be offset by a constant diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 60edf9be31e5..e2ed98b175f6 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -65,7 +65,7 @@ enum drm_mode_status { MODE_H_ILLEGAL, /* mode has illegal horizontal timings */ MODE_V_ILLEGAL, /* mode has illegal horizontal timings */ MODE_BAD_WIDTH, /* requires an unsupported linepitch */ - MODE_NOMODE, /* no mode with a maching name */ + MODE_NOMODE, /* no mode with a matching name */ MODE_NO_INTERLACE, /* interlaced mode not supported */ MODE_NO_DBLESCAN, /* doublescan mode not supported */ MODE_NO_VSCAN, /* multiscan mode not supported */ @@ -321,7 +321,7 @@ struct drm_crtc_funcs { /* * Flip to the given framebuffer. This implements the page - * flip ioctl descibed in drm_mode.h, specifically, the + * flip ioctl described in drm_mode.h, specifically, the * implementation must return immediately and block all * rendering to the current fb until the flip has completed. * If userspace set the event flag in the ioctl, the event diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h index b1e7809e5e15..c2f93a8ae2e1 100644 --- a/include/drm/drm_mm.h +++ b/include/drm/drm_mm.h @@ -56,7 +56,7 @@ struct drm_mm_node { }; struct drm_mm { - /* List of all memory nodes that immediatly preceed a free hole. */ + /* List of all memory nodes that immediately precede a free hole. */ struct list_head hole_stack; /* head_node.node_list is the list of all memory nodes, ordered * according to the (increasing) start address of the memory node. */ diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h index ae6b7a3dbec7..c4961ea50a49 100644 --- a/include/drm/drm_mode.h +++ b/include/drm/drm_mode.h @@ -277,7 +277,7 @@ struct drm_mode_mode_cmd { #define DRM_MODE_CURSOR_MOVE (1<<1) /* - * depending on the value in flags diffrent members are used. + * depending on the value in flags different members are used. * * CURSOR_BO uses * crtc diff --git a/include/drm/mga_drm.h b/include/drm/mga_drm.h index c16097f99be0..fca817009e13 100644 --- a/include/drm/mga_drm.h +++ b/include/drm/mga_drm.h @@ -107,7 +107,7 @@ */ #define MGA_NR_SAREA_CLIPRECTS 8 -/* 2 heaps (1 for card, 1 for agp), each divided into upto 128 +/* 2 heaps (1 for card, 1 for agp), each divided into up to 128 * regions, subject to a minimum region size of (1<<16) == 64k. * * Clients may subdivide regions internally, but when sharing between diff --git a/include/drm/radeon_drm.h b/include/drm/radeon_drm.h index 3dec41cf8342..3bce1a4fc305 100644 --- a/include/drm/radeon_drm.h +++ b/include/drm/radeon_drm.h @@ -641,7 +641,7 @@ typedef struct drm_radeon_vertex2 { } drm_radeon_vertex2_t; /* v1.3 - obsoletes drm_radeon_vertex2 - * - allows arbitarily large cliprect list + * - allows arbitrarily large cliprect list * - allows updating of tcl packet, vector and scalar state * - allows memory-efficient description of state updates * - allows state to be emitted without a primitive diff --git a/include/drm/savage_drm.h b/include/drm/savage_drm.h index 4863cf6bf96f..818d49be2e6e 100644 --- a/include/drm/savage_drm.h +++ b/include/drm/savage_drm.h @@ -29,7 +29,7 @@ #ifndef __SAVAGE_SAREA_DEFINES__ #define __SAVAGE_SAREA_DEFINES__ -/* 2 heaps (1 for card, 1 for agp), each divided into upto 128 +/* 2 heaps (1 for card, 1 for agp), each divided into up to 128 * regions, subject to a minimum region size of (1<<16) == 64k. * * Clients may subdivide regions internally, but when sharing between diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index 50852aad260a..94e2ce43488d 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h @@ -50,10 +50,10 @@ struct drm_mm_node; * * @fpfn: first valid page frame number to put the object * @lpfn: last valid page frame number to put the object - * @num_placement: number of prefered placements - * @placement: prefered placements - * @num_busy_placement: number of prefered placements when need to evict buffer - * @busy_placement: prefered placements when need to evict buffer + * @num_placement: number of preferred placements + * @placement: preferred placements + * @num_busy_placement: number of preferred placements when need to evict buffer + * @busy_placement: preferred placements when need to evict buffer * * Structure indicating the placement you request for an object. */ @@ -160,7 +160,7 @@ struct ttm_tt; * @mem: structure describing current placement. * @persistant_swap_storage: Usually the swap storage is deleted for buffers * pinned in physical memory. If this behaviour is not desired, this member - * holds a pointer to a persistant shmem object. + * holds a pointer to a persistent shmem object. * @ttm: TTM structure holding system pages. * @evicted: Whether the object was evicted without user-space knowing. * @cpu_writes: For synchronization. Number of cpu writers. @@ -461,7 +461,7 @@ extern void ttm_bo_synccpu_write_release(struct ttm_buffer_object *bo); * sleep interruptible. * @persistant_swap_storage: Usually the swap storage is deleted for buffers * pinned in physical memory. If this behaviour is not desired, this member - * holds a pointer to a persistant shmem object. Typically, this would + * holds a pointer to a persistent shmem object. Typically, this would * point to the shmem object backing a GEM object if TTM is used to back a * GEM user interface. * @acc_size: Accounted size for this object. @@ -508,7 +508,7 @@ extern int ttm_bo_init(struct ttm_bo_device *bdev, * sleep interruptible. * @persistant_swap_storage: Usually the swap storage is deleted for buffers * pinned in physical memory. If this behaviour is not desired, this member - * holds a pointer to a persistant shmem object. Typically, this would + * holds a pointer to a persistent shmem object. Typically, this would * point to the shmem object backing a GEM object if TTM is used to back a * GEM user interface. * @p_bo: On successful completion *p_bo points to the created object. diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index efed0820d9fa..8b52c9ab350b 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h @@ -223,9 +223,9 @@ struct ttm_mem_type_manager_func { * @mem::mm_node should be set to a non-null value, and * @mem::start should be set to a value identifying the beginning * of the range allocated, and the function should return zero. - * If the memory region accomodate the buffer object, @mem::mm_node + * If the memory region accommodate the buffer object, @mem::mm_node * should be set to NULL, and the function should return 0. - * If a system error occured, preventing the request to be fulfilled, + * If a system error occurred, preventing the request to be fulfilled, * the function should return a negative error code. * * Note that @mem::mm_node will only be dereferenced by @@ -841,7 +841,7 @@ extern void ttm_mem_io_unlock(struct ttm_mem_type_manager *man); * different order, either by will or as a result of a buffer being evicted * to make room for a buffer already reserved. (Buffers are reserved before * they are evicted). The following algorithm prevents such deadlocks from - * occuring: + * occurring: * 1) Buffers are reserved with the lru spinlock held. Upon successful * reservation they are removed from the lru list. This stops a reserved buffer * from being evicted. However the lru spinlock is released between the time diff --git a/include/drm/vmwgfx_drm.h b/include/drm/vmwgfx_drm.h index 650e6bf6f69f..5c36432d9ce5 100644 --- a/include/drm/vmwgfx_drm.h +++ b/include/drm/vmwgfx_drm.h @@ -592,7 +592,7 @@ struct drm_vmw_stream_arg { /** * DRM_VMW_UPDATE_LAYOUT - Update layout * - * Updates the prefered modes and connection status for connectors. The + * Updates the preferred modes and connection status for connectors. The * command conisits of one drm_vmw_update_layout_arg pointing out a array * of num_outputs drm_vmw_rect's. */ diff --git a/include/linux/amba/clcd.h b/include/linux/amba/clcd.h index 24d26efd1432..e82e3ee2c54a 100644 --- a/include/linux/amba/clcd.h +++ b/include/linux/amba/clcd.h @@ -136,7 +136,7 @@ struct clcd_board { int (*check)(struct clcd_fb *fb, struct fb_var_screeninfo *var); /* - * Compulsary. Decode fb->fb.var into regs->*. In the case of + * Compulsory. Decode fb->fb.var into regs->*. In the case of * fixed timing, set regs->* to the register values required. */ void (*decode)(struct clcd_fb *fb, struct clcd_regs *regs); diff --git a/include/linux/amba/mmci.h b/include/linux/amba/mmci.h index f60227088b7b..21114810c7c0 100644 --- a/include/linux/amba/mmci.h +++ b/include/linux/amba/mmci.h @@ -30,15 +30,15 @@ struct dma_chan; * @cd_invert: true if the gpio_cd pin value is active low * @capabilities: the capabilities of the block as implemented in * this platform, signify anything MMC_CAP_* from mmc/host.h - * @dma_filter: function used to select an apropriate RX and TX + * @dma_filter: function used to select an appropriate RX and TX * DMA channel to be used for DMA, if and only if you're deploying the * generic DMA engine * @dma_rx_param: parameter passed to the DMA allocation - * filter in order to select an apropriate RX channel. If + * filter in order to select an appropriate RX channel. If * there is a bidirectional RX+TX channel, then just specify * this and leave dma_tx_param set to NULL * @dma_tx_param: parameter passed to the DMA allocation - * filter in order to select an apropriate TX channel. If this + * filter in order to select an appropriate TX channel. If this * is NULL the driver will attempt to use the RX channel as a * bidirectional channel */ diff --git a/include/linux/can/error.h b/include/linux/can/error.h index d4127fd9e681..5958074302a4 100644 --- a/include/linux/can/error.h +++ b/include/linux/can/error.h @@ -51,7 +51,7 @@ #define CAN_ERR_PROT_BIT1 0x10 /* unable to send recessive bit */ #define CAN_ERR_PROT_OVERLOAD 0x20 /* bus overload */ #define CAN_ERR_PROT_ACTIVE 0x40 /* active error announcement */ -#define CAN_ERR_PROT_TX 0x80 /* error occured on transmission */ +#define CAN_ERR_PROT_TX 0x80 /* error occurred on transmission */ /* error in CAN protocol (location) / data[3] */ #define CAN_ERR_PROT_LOC_UNSPEC 0x00 /* unspecified */ diff --git a/include/linux/can/netlink.h b/include/linux/can/netlink.h index 3250de935e1a..34542d374dd8 100644 --- a/include/linux/can/netlink.h +++ b/include/linux/can/netlink.h @@ -17,7 +17,7 @@ /* * CAN bit-timing parameters * - * For futher information, please read chapter "8 BIT TIMING + * For further information, please read chapter "8 BIT TIMING * REQUIREMENTS" of the "Bosch CAN Specification version 2.0" * at http://www.semiconductors.bosch.de/pdf/can2spec.pdf. */ diff --git a/include/linux/cdk.h b/include/linux/cdk.h index 0908daf7bf56..80093a8d4f64 100644 --- a/include/linux/cdk.h +++ b/include/linux/cdk.h @@ -149,7 +149,7 @@ typedef struct cdkhdr { /* * Define the memory mapping structure. This structure is pointed to by * the memp field in the stlcdkhdr struct. As many as these structures - * as required are layed out in shared memory to define how the rest of + * as required are laid out in shared memory to define how the rest of * shared memory is divided up. There will be one for each port. */ typedef struct cdkmem { diff --git a/include/linux/cfag12864b.h b/include/linux/cfag12864b.h index 6f9f19d66591..b454dfce60d9 100644 --- a/include/linux/cfag12864b.h +++ b/include/linux/cfag12864b.h @@ -44,7 +44,7 @@ extern unsigned char * cfag12864b_buffer; /* * Get the refresh rate of the LCD * - * Returns the refresh rate (hertzs). + * Returns the refresh rate (hertz). */ extern unsigned int cfag12864b_getrate(void); diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index e654fa239916..5ac7ebc36dbb 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -240,7 +240,7 @@ struct cgroup { /* For RCU-protected deletion */ struct rcu_head rcu_head; - /* List of events which userspace want to recieve */ + /* List of events which userspace want to receive */ struct list_head event_list; spinlock_t event_list_lock; }; diff --git a/include/linux/cm4000_cs.h b/include/linux/cm4000_cs.h index 72bfefdbd767..3c4aac406175 100644 --- a/include/linux/cm4000_cs.h +++ b/include/linux/cm4000_cs.h @@ -20,7 +20,7 @@ typedef struct atreq { } atreq_t; -/* what is particularly stupid in the original driver is the arch-dependant +/* what is particularly stupid in the original driver is the arch-dependent * member sizes. This leads to CONFIG_COMPAT breakage, since 32bit userspace * will lay out the structure members differently than the 64bit kernel. * diff --git a/include/linux/configfs.h b/include/linux/configfs.h index ddb7a97c78c2..645778ad899b 100644 --- a/include/linux/configfs.h +++ b/include/linux/configfs.h @@ -218,7 +218,7 @@ static ssize_t _item##_attr_store(struct config_item *item, \ * group children. default_groups may coexist alongsize make_group() or * make_item(), but if the group wishes to have only default_groups * children (disallowing mkdir(2)), it need not provide either function. - * If the group has commit(), it supports pending and commited (active) + * If the group has commit(), it supports pending and committed (active) * items. */ struct configfs_item_operations { diff --git a/include/linux/cper.h b/include/linux/cper.h index 372a25839fd1..c23049496531 100644 --- a/include/linux/cper.h +++ b/include/linux/cper.h @@ -310,7 +310,7 @@ struct cper_sec_proc_ia { __u8 cpuid[48]; }; -/* IA32/X64 Processor Error Infomation Structure */ +/* IA32/X64 Processor Error Information Structure */ struct cper_ia_err_info { uuid_le err_type; __u64 validation_bits; diff --git a/include/linux/decompress/mm.h b/include/linux/decompress/mm.h index 4cb72b920c74..7925bf0ee836 100644 --- a/include/linux/decompress/mm.h +++ b/include/linux/decompress/mm.h @@ -16,7 +16,7 @@ /* * Some architectures want to ensure there is no local data in their - * pre-boot environment, so that data can arbitarily relocated (via + * pre-boot environment, so that data can arbitrarily relocated (via * GOT references). This is achieved by defining STATIC_RW_DATA to * be null. */ diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 9bebd7f16ef1..eee7addec282 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -434,7 +434,7 @@ struct dma_tx_state { * zero or error code * @device_tx_status: poll for transaction completion, the optional * txstate parameter can be supplied with a pointer to get a - * struct with auxilary transfer status information, otherwise the call + * struct with auxiliary transfer status information, otherwise the call * will just return a simple status code * @device_issue_pending: push pending transactions to hardware */ diff --git a/include/linux/drbd.h b/include/linux/drbd.h index d18d673ebc78..cec467f5d676 100644 --- a/include/linux/drbd.h +++ b/include/linux/drbd.h @@ -36,7 +36,7 @@ #include #include -/* Altough the Linux source code makes a difference between +/* Although the Linux source code makes a difference between generic endianness and the bitfields' endianness, there is no architecture as of Linux-2.6.24-rc4 where the bitfileds' endianness does not match the generic endianness. */ @@ -184,7 +184,7 @@ enum drbd_conns { /* These temporal states are all used on the way * from >= C_CONNECTED to Unconnected. * The 'disconnect reason' states - * I do not allow to change beween them. */ + * I do not allow to change between them. */ C_TIMEOUT, C_BROKEN_PIPE, C_NETWORK_FAILURE, diff --git a/include/linux/drbd_limits.h b/include/linux/drbd_limits.h index bb264a5732de..246f576c981d 100644 --- a/include/linux/drbd_limits.h +++ b/include/linux/drbd_limits.h @@ -43,7 +43,7 @@ /* net { */ /* timeout, unit centi seconds - * more than one minute timeout is not usefull */ + * more than one minute timeout is not useful */ #define DRBD_TIMEOUT_MIN 1 #define DRBD_TIMEOUT_MAX 600 #define DRBD_TIMEOUT_DEF 60 /* 6 seconds */ @@ -68,7 +68,7 @@ #define DRBD_MAX_EPOCH_SIZE_MAX 20000 #define DRBD_MAX_EPOCH_SIZE_DEF 2048 - /* I don't think that a tcp send buffer of more than 10M is usefull */ + /* I don't think that a tcp send buffer of more than 10M is useful */ #define DRBD_SNDBUF_SIZE_MIN 0 #define DRBD_SNDBUF_SIZE_MAX (10<<20) #define DRBD_SNDBUF_SIZE_DEF 0 @@ -101,7 +101,7 @@ #define DRBD_RATE_MAX (4 << 20) #define DRBD_RATE_DEF 250 /* kb/second */ - /* less than 7 would hit performance unneccessarily. + /* less than 7 would hit performance unnecessarily. * 3833 is the largest prime that still does fit * into 64 sectors of activity log */ #define DRBD_AL_EXTENTS_MIN 7 diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index c8fcbdd2b0e7..dc80d8294247 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -614,7 +614,7 @@ struct ethtool_sfeatures { * values of corresponding bits in features[].requested. Bits in .requested * not set in .valid or not changeable are ignored. * - * Returns %EINVAL when .valid contains undefined or never-changable bits + * Returns %EINVAL when .valid contains undefined or never-changeable bits * or size is not equal to required number of features words (32-bit blocks). * Returns >= 0 if request was completed; bits set in the value mean: * %ETHTOOL_F_UNSUPPORTED - there were bits set in .valid that are not diff --git a/include/linux/eventpoll.h b/include/linux/eventpoll.h index f6856a5a1d4b..f362733186a5 100644 --- a/include/linux/eventpoll.h +++ b/include/linux/eventpoll.h @@ -1,5 +1,5 @@ /* - * include/linux/eventpoll.h ( Efficent event polling implementation ) + * include/linux/eventpoll.h ( Efficient event polling implementation ) * Copyright (C) 2001,...,2006 Davide Libenzi * * This program is free software; you can redistribute it and/or modify diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h index 33a42f24b275..3a4cef5322dc 100644 --- a/include/linux/exportfs.h +++ b/include/linux/exportfs.h @@ -120,7 +120,7 @@ struct fid { * encode_fh: * @encode_fh should store in the file handle fragment @fh (using at most * @max_len bytes) information that can be used by @decode_fh to recover the - * file refered to by the &struct dentry @de. If the @connectable flag is + * file referred to by the &struct dentry @de. If the @connectable flag is * set, the encode_fh() should store sufficient information so that a good * attempt can be made to find not only the file but also it's place in the * filesystem. This typically means storing a reference to de->d_parent in diff --git a/include/linux/fb.h b/include/linux/fb.h index b2a36391d2a1..df728c1c29ed 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -534,14 +534,14 @@ struct fb_cursor_user { #define FB_EVENT_GET_CONSOLE_MAP 0x07 /* CONSOLE-SPECIFIC: set console to framebuffer mapping */ #define FB_EVENT_SET_CONSOLE_MAP 0x08 -/* A hardware display blank change occured */ +/* A hardware display blank change occurred */ #define FB_EVENT_BLANK 0x09 /* Private modelist is to be replaced */ #define FB_EVENT_NEW_MODELIST 0x0A /* The resolution of the passed in fb_info about to change and all vc's should be changed */ #define FB_EVENT_MODE_CHANGE_ALL 0x0B -/* A software display blank change occured */ +/* A software display blank change occurred */ #define FB_EVENT_CONBLANK 0x0C /* Get drawing requirements */ #define FB_EVENT_GET_REQ 0x0D @@ -805,7 +805,7 @@ struct fb_tile_ops { /* A driver may set this flag to indicate that it does want a set_par to be * called every time when fbcon_switch is executed. The advantage is that with * this flag set you can really be sure that set_par is always called before - * any of the functions dependant on the correct hardware state or altering + * any of the functions dependent on the correct hardware state or altering * that state, even if you are using some broken X releases. The disadvantage * is that it introduces unwanted delays to every console switch if set_par * is slow. It is a good idea to try this flag in the drivers initialization @@ -877,7 +877,7 @@ struct fb_info { void *fbcon_par; /* fbcon use-only private area */ /* From here on everything is device dependent */ void *par; - /* we need the PCI or similiar aperture base/size not + /* we need the PCI or similar aperture base/size not smem_start/size as smem_start may just be an object allocated inside the aperture so may not actually overlap */ struct apertures_struct { diff --git a/include/linux/firewire-cdev.h b/include/linux/firewire-cdev.h index 59ea406be7f6..4ff09889c5c0 100644 --- a/include/linux/firewire-cdev.h +++ b/include/linux/firewire-cdev.h @@ -900,7 +900,7 @@ struct fw_cdev_get_cycle_timer2 { /** * struct fw_cdev_allocate_iso_resource - (De)allocate a channel or bandwidth - * @closure: Passed back to userspace in correponding iso resource events + * @closure: Passed back to userspace in corresponding iso resource events * @channels: Isochronous channels of which one is to be (de)allocated * @bandwidth: Isochronous bandwidth units to be (de)allocated * @handle: Handle to the allocation, written by the kernel (only valid in diff --git a/include/linux/fs.h b/include/linux/fs.h index 52f283c1edb2..f03632d2ac18 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -465,7 +465,7 @@ struct iattr { struct timespec ia_ctime; /* - * Not an attribute, but an auxilary info for filesystems wanting to + * Not an attribute, but an auxiliary info for filesystems wanting to * implement an ftruncate() like method. NOTE: filesystem should * check for (ia_valid & ATTR_FILE), and not for (ia_file != NULL). */ @@ -647,7 +647,7 @@ struct address_space { } __attribute__((aligned(sizeof(long)))); /* * On most architectures that alignment is already the case; but - * must be enforced here for CRIS, to let the least signficant bit + * must be enforced here for CRIS, to let the least significant bit * of struct page's "mapping" pointer be used for PAGE_MAPPING_ANON. */ diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h index b8581c09d19f..76427e688d15 100644 --- a/include/linux/fscache-cache.h +++ b/include/linux/fscache-cache.h @@ -236,7 +236,7 @@ struct fscache_cache_ops { /* unpin an object in the cache */ void (*unpin_object)(struct fscache_object *object); - /* store the updated auxilliary data on an object */ + /* store the updated auxiliary data on an object */ void (*update_object)(struct fscache_object *object); /* discard the resources pinned by an object and effect retirement if diff --git a/include/linux/fscache.h b/include/linux/fscache.h index ec0dad5ab90f..7c4d72f5581f 100644 --- a/include/linux/fscache.h +++ b/include/linux/fscache.h @@ -102,9 +102,9 @@ struct fscache_cookie_def { */ void (*get_attr)(const void *cookie_netfs_data, uint64_t *size); - /* get the auxilliary data from netfs data + /* get the auxiliary data from netfs data * - this function can be absent if the index carries no state data - * - should store the auxilliary data in the buffer + * - should store the auxiliary data in the buffer * - should return the amount of amount stored * - not permitted to return an error * - the netfs data from the cookie being used as the source is @@ -117,7 +117,7 @@ struct fscache_cookie_def { /* consult the netfs about the state of an object * - this function can be absent if the index carries no state data * - the netfs data from the cookie being used as the target is - * presented, as is the auxilliary data + * presented, as is the auxiliary data */ enum fscache_checkaux (*check_aux)(void *cookie_netfs_data, const void *data, diff --git a/include/linux/hid.h b/include/linux/hid.h index bb29bb1dbd2f..42f7e2fb501f 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -799,7 +799,7 @@ static inline int __must_check hid_parse(struct hid_device *hdev) * * Call this in probe function *after* hid_parse. This will setup HW buffers * and start the device (if not deffered to device open). hid_hw_stop must be - * called if this was successfull. + * called if this was successful. */ static inline int __must_check hid_hw_start(struct hid_device *hdev, unsigned int connect_mask) diff --git a/include/linux/hp_sdc.h b/include/linux/hp_sdc.h index 9db3d454887f..d392975d8887 100644 --- a/include/linux/hp_sdc.h +++ b/include/linux/hp_sdc.h @@ -101,7 +101,7 @@ int hp_sdc_dequeue_transaction(hp_sdc_transaction *this); #define HP_SDC_STATUS_REG 0x40 /* Data from an i8042 register */ #define HP_SDC_STATUS_HILCMD 0x50 /* Command from HIL MLC */ #define HP_SDC_STATUS_HILDATA 0x60 /* Data from HIL MLC */ -#define HP_SDC_STATUS_PUP 0x70 /* Sucessful power-up self test */ +#define HP_SDC_STATUS_PUP 0x70 /* Successful power-up self test */ #define HP_SDC_STATUS_KCOOKED 0x80 /* Key from cooked kbd */ #define HP_SDC_STATUS_KRPG 0xc0 /* Key from Repeat Gen */ #define HP_SDC_STATUS_KMOD_SUP 0x10 /* Shift key is up */ diff --git a/include/linux/i2o.h b/include/linux/i2o.h index 9e7a12d6385d..a6deef4f4f67 100644 --- a/include/linux/i2o.h +++ b/include/linux/i2o.h @@ -826,7 +826,7 @@ static inline struct i2o_message __iomem *i2o_msg_in_to_virt(struct * @c: I2O controller * * This function tries to get a message frame. If no message frame is - * available do not wait until one is availabe (see also i2o_msg_get_wait). + * available do not wait until one is available (see also i2o_msg_get_wait). * The returned pointer to the message frame is not in I/O memory, it is * allocated from a mempool. But because a MFA is allocated from the * controller too it is guaranteed that i2o_msg_post() will never fail. diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 943c9b53695c..bea0ac750712 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -98,7 +98,7 @@ typedef irqreturn_t (*irq_handler_t)(int, void *); * @next: pointer to the next irqaction for shared interrupts * @irq: interrupt number * @dir: pointer to the proc/irq/NN/name entry - * @thread_fn: interupt handler function for threaded interrupts + * @thread_fn: interrupt handler function for threaded interrupts * @thread: thread pointer for threaded interrupts * @thread_flags: flags related to @thread * @thread_mask: bitmask for keeping track of @thread activity @@ -484,7 +484,7 @@ extern void __send_remote_softirq(struct call_single_data *cp, int cpu, Properties: * If tasklet_schedule() is called, then tasklet is guaranteed to be executed on some cpu at least once after this. - * If the tasklet is already scheduled, but its excecution is still not + * If the tasklet is already scheduled, but its execution is still not started, it will be executed only once. * If this tasklet is already running on another CPU (or schedule is called from tasklet itself), it is rescheduled for later. diff --git a/include/linux/ipmi.h b/include/linux/ipmi.h index 045f2f275cd0..ca85cf894e33 100644 --- a/include/linux/ipmi.h +++ b/include/linux/ipmi.h @@ -111,7 +111,7 @@ struct ipmi_ipmb_addr { * A LAN Address. This is an address to/from a LAN interface bridged * by the BMC, not an address actually out on the LAN. * - * A concious decision was made here to deviate slightly from the IPMI + * A conscious decision was made here to deviate slightly from the IPMI * spec. We do not use rqSWID and rsSWID like it shows in the * message. Instead, we use remote_SWID and local_SWID. This means * that any message (a request or response) from another device will @@ -259,7 +259,7 @@ struct ipmi_recv_msg { void (*done)(struct ipmi_recv_msg *msg); /* Place-holder for the data, don't make any assumptions about - the size or existance of this, since it may change. */ + the size or existence of this, since it may change. */ unsigned char msg_data[IPMI_MAX_MSG_LENGTH]; }; diff --git a/include/linux/isdn/hdlc.h b/include/linux/isdn/hdlc.h index 4b3ecc40889a..96521370c782 100644 --- a/include/linux/isdn/hdlc.h +++ b/include/linux/isdn/hdlc.h @@ -2,7 +2,7 @@ * hdlc.h -- General purpose ISDN HDLC decoder. * * Implementation of a HDLC decoder/encoder in software. - * Neccessary because some ISDN devices don't have HDLC + * Necessary because some ISDN devices don't have HDLC * controllers. * * Copyright (C) diff --git a/include/linux/ixjuser.h b/include/linux/ixjuser.h index 88b45895746d..94ab5e942e53 100644 --- a/include/linux/ixjuser.h +++ b/include/linux/ixjuser.h @@ -50,7 +50,7 @@ * IOCTL's used for the Quicknet Telephony Cards * * If you use the IXJCTL_TESTRAM command, the card must be power cycled to -* reset the SRAM values before futher use. +* reset the SRAM values before further use. * ******************************************************************************/ diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h index 922aa313c9f9..f97672a36fa8 100644 --- a/include/linux/jiffies.h +++ b/include/linux/jiffies.h @@ -42,7 +42,7 @@ /* LATCH is used in the interval timer and ftape setup. */ #define LATCH ((CLOCK_TICK_RATE + HZ/2) / HZ) /* For divider */ -/* Suppose we want to devide two numbers NOM and DEN: NOM/DEN, then we can +/* Suppose we want to divide two numbers NOM and DEN: NOM/DEN, then we can * improve accuracy by shifting LSH bits, hence calculating: * (NOM << LSH) / DEN * This however means trouble for large NOM, because (NOM << LSH) may no diff --git a/include/linux/ktime.h b/include/linux/ktime.h index e1ceaa9b36bb..603bec2913b0 100644 --- a/include/linux/ktime.h +++ b/include/linux/ktime.h @@ -35,7 +35,7 @@ * * On 32-bit CPUs an optimized representation of the timespec structure * is used to avoid expensive conversions from and to timespecs. The - * endian-aware order of the tv struct members is choosen to allow + * endian-aware order of the tv struct members is chosen to allow * mathematical operations on the tv64 member of the union too, which * for certain operations produces better code. * @@ -158,7 +158,7 @@ static inline ktime_t ktime_set(const long secs, const unsigned long nsecs) * @lhs: minuend * @rhs: subtrahend * - * Returns the remainder of the substraction + * Returns the remainder of the subtraction */ static inline ktime_t ktime_sub(const ktime_t lhs, const ktime_t rhs) { diff --git a/include/linux/led-lm3530.h b/include/linux/led-lm3530.h index bb69d20da0dc..58592fa67d24 100644 --- a/include/linux/led-lm3530.h +++ b/include/linux/led-lm3530.h @@ -41,7 +41,7 @@ #define LM3530_RAMP_TIME_8s (7) /* ALS Resistor Select */ -#define LM3530_ALS_IMPD_Z (0x00) /* ALS Impedence */ +#define LM3530_ALS_IMPD_Z (0x00) /* ALS Impedance */ #define LM3530_ALS_IMPD_13_53kOhm (0x01) #define LM3530_ALS_IMPD_9_01kOhm (0x02) #define LM3530_ALS_IMPD_5_41kOhm (0x03) diff --git a/include/linux/libata.h b/include/linux/libata.h index c71f46960f39..7f675aa81d87 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -364,7 +364,7 @@ enum { ATA_EH_CMD_TIMEOUT_TABLE_SIZE = 6, /* Horkage types. May be set by libata or controller on drives - (some horkage may be drive/controller pair dependant */ + (some horkage may be drive/controller pair dependent */ ATA_HORKAGE_DIAGNOSTIC = (1 << 0), /* Failed boot diag */ ATA_HORKAGE_NODMA = (1 << 1), /* DMA problems */ diff --git a/include/linux/lru_cache.h b/include/linux/lru_cache.h index 78fbf24f357a..6a4fab7c6e09 100644 --- a/include/linux/lru_cache.h +++ b/include/linux/lru_cache.h @@ -148,7 +148,7 @@ write intent log information, three of which are mentioned here. * * DRBD currently (May 2009) only uses 61 elements on the resync lru_cache * (total memory usage 2 pages), and up to 3833 elements on the act_log - * lru_cache, totalling ~215 kB for 64bit architechture, ~53 pages. + * lru_cache, totalling ~215 kB for 64bit architecture, ~53 pages. * * We usually do not actually free these objects again, but only "recycle" * them, as the change "index: -old_label, +LC_FREE" would need a transaction diff --git a/include/linux/mfd/wm8350/pmic.h b/include/linux/mfd/wm8350/pmic.h index e786fe9841ef..579b50ca2e02 100644 --- a/include/linux/mfd/wm8350/pmic.h +++ b/include/linux/mfd/wm8350/pmic.h @@ -1,5 +1,5 @@ /* - * pmic.h -- Power Managment Driver for Wolfson WM8350 PMIC + * pmic.h -- Power Management Driver for Wolfson WM8350 PMIC * * Copyright 2007 Wolfson Microelectronics PLC * diff --git a/include/linux/mm.h b/include/linux/mm.h index 7606d7db96c9..692dbae6ffa7 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -608,7 +608,7 @@ static inline pte_t maybe_mkwrite(pte_t pte, struct vm_area_struct *vma) #endif /* - * Define the bit shifts to access each section. For non-existant + * Define the bit shifts to access each section. For non-existent * sections we define the shift as 0; that plus a 0 mask ensures * the compiler will optimise away reference to them. */ diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h index c0207a770476..bdd7ceeb99e4 100644 --- a/include/linux/mmc/dw_mmc.h +++ b/include/linux/mmc/dw_mmc.h @@ -98,7 +98,7 @@ struct mmc_data; * EVENT_DATA_COMPLETE is set in @pending_events, all data-related * interrupts must be disabled and @data_status updated with a * snapshot of SR. Similarly, before EVENT_CMD_COMPLETE is set, the - * CMDRDY interupt must be disabled and @cmd_status updated with a + * CMDRDY interrupt must be disabled and @cmd_status updated with a * snapshot of SR, and before EVENT_XFER_COMPLETE can be set, the * bytes_xfered field of @data must be written. This is ensured by * using barriers. @@ -172,7 +172,7 @@ struct dw_mci_dma_ops { #define DW_MCI_QUIRK_IDMAC_DTO BIT(0) /* delay needed between retries on some 2.11a implementations */ #define DW_MCI_QUIRK_RETRY_DELAY BIT(1) -/* High Speed Capable - Supports HS cards (upto 50MHz) */ +/* High Speed Capable - Supports HS cards (up to 50MHz) */ #define DW_MCI_QUIRK_HIGHSPEED BIT(2) /* Unreliable card detection */ #define DW_MCI_QUIRK_BROKEN_CARD_DETECTION BIT(3) diff --git a/include/linux/mroute6.h b/include/linux/mroute6.h index 9d2deb200f54..a3759cb0ac10 100644 --- a/include/linux/mroute6.h +++ b/include/linux/mroute6.h @@ -249,7 +249,7 @@ static inline int ip6mr_sk_done(struct sock *sk) * Structure used to communicate from kernel to multicast router. * We'll overlay the structure onto an MLD header (not an IPv6 heder like igmpmsg{} * used for IPv4 implementation). This is because this structure will be passed via an - * IPv6 raw socket, on wich an application will only receiver the payload i.e the data after + * IPv6 raw socket, on which an application will only receiver the payload i.e the data after * the IPv6 header and all the extension headers. (See section 3 of RFC 3542) */ diff --git a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h index 0d823f2dd667..d24925492972 100644 --- a/include/linux/mtd/cfi.h +++ b/include/linux/mtd/cfi.h @@ -308,7 +308,7 @@ static inline uint32_t cfi_build_cmd_addr(uint32_t cmd_ofs, addr = (cmd_ofs * type) * interleave; - /* Modify the unlock address if we are in compatiblity mode. + /* Modify the unlock address if we are in compatibility mode. * For 16bit devices on 8 bit busses * and 32bit devices on 16 bit busses * set the low bit of the alternating bit sequence of the address. diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index ae67ef56a8f5..d44192740f6f 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -416,9 +416,9 @@ struct nand_buffers { * @select_chip: [REPLACEABLE] select chip nr * @block_bad: [REPLACEABLE] check, if the block is bad * @block_markbad: [REPLACEABLE] mark the block bad - * @cmd_ctrl: [BOARDSPECIFIC] hardwarespecific funtion for controlling + * @cmd_ctrl: [BOARDSPECIFIC] hardwarespecific function for controlling * ALE/CLE/nCE. Also used to write command and address - * @init_size: [BOARDSPECIFIC] hardwarespecific funtion for setting + * @init_size: [BOARDSPECIFIC] hardwarespecific function for setting * mtd->oobsize, mtd->writesize and so on. * @id_data contains the 8 bytes values of NAND_CMD_READID. * Return with the bus width. @@ -437,7 +437,7 @@ struct nand_buffers { * @erase_cmd: [INTERN] erase command write function, selectable due * to AND support. * @scan_bbt: [REPLACEABLE] function to scan bad block table - * @chip_delay: [BOARDSPECIFIC] chip dependent delay for transfering + * @chip_delay: [BOARDSPECIFIC] chip dependent delay for transferring * data from array to read regs (tR). * @state: [INTERN] the current state of the NAND device * @oob_poi: poison value buffer diff --git a/include/linux/mtd/xip.h b/include/linux/mtd/xip.h index 36efcba15ecd..abed4dec5c2f 100644 --- a/include/linux/mtd/xip.h +++ b/include/linux/mtd/xip.h @@ -51,7 +51,7 @@ * return in usecs the elapsed timebetween now and the reference x as * returned by xip_currtime(). * - * note 1: convertion to usec can be approximated, as long as the + * note 1: conversion to usec can be approximated, as long as the * returned value is <= the real elapsed time. * note 2: this should be able to cope with a few seconds without * overflowing. diff --git a/include/linux/netfilter/nf_conntrack_proto_gre.h b/include/linux/netfilter/nf_conntrack_proto_gre.h index 2a10efda17fb..6a0664c0c451 100644 --- a/include/linux/netfilter/nf_conntrack_proto_gre.h +++ b/include/linux/netfilter/nf_conntrack_proto_gre.h @@ -60,7 +60,7 @@ struct gre_hdr_pptp { __be16 payload_len; /* size of ppp payload, not inc. gre header */ __be16 call_id; /* peer's call_id for this session */ __be32 seq; /* sequence number. Present if S==1 */ - __be32 ack; /* seq number of highest packet recieved by */ + __be32 ack; /* seq number of highest packet received by */ /* sender in this session */ }; diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h index 1c6f0c5f530e..8797ed16feb2 100644 --- a/include/linux/netfilter_bridge/ebtables.h +++ b/include/linux/netfilter_bridge/ebtables.h @@ -92,7 +92,7 @@ struct ebt_entries { /* This is a hack to make a difference between an ebt_entry struct and an * ebt_entries struct when traversing the entries from start to end. - * Using this simplifies the code alot, while still being able to use + * Using this simplifies the code a lot, while still being able to use * ebt_entries. * Contrary, iptables doesn't use something like ebt_entries and therefore uses * different techniques for naming the policy and such. So, iptables doesn't diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index b528f6d4b860..178fafe0ff93 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h @@ -359,7 +359,7 @@ enum nfsstat4 { /* Error 10073 is unused. */ NFS4ERR_CLIENTID_BUSY = 10074, /* clientid has state */ NFS4ERR_PNFS_IO_HOLE = 10075, /* IO to _SPARSE file hole */ - NFS4ERR_SEQ_FALSE_RETRY = 10076, /* retry not origional */ + NFS4ERR_SEQ_FALSE_RETRY = 10076, /* retry not original */ NFS4ERR_BAD_HIGH_SLOT = 10077, /* sequence arg bad */ NFS4ERR_DEADSESSION = 10078, /* persistent session dead */ NFS4ERR_ENCR_ALG_UNSUPP = 10079, /* SSV alg mismatch */ diff --git a/include/linux/nfsd/export.h b/include/linux/nfsd/export.h index bd316159278c..84058ec69390 100644 --- a/include/linux/nfsd/export.h +++ b/include/linux/nfsd/export.h @@ -80,7 +80,7 @@ struct nfsd4_fs_locations { /* * We keep an array of pseudoflavors with the export, in order from most - * to least preferred. For the forseeable future, we don't expect more + * to least preferred. For the foreseeable future, we don't expect more * than the eight pseudoflavors null, unix, krb5, krb5i, krb5p, skpm3, * spkm3i, and spkm3p (and using all 8 at once should be rare). */ diff --git a/include/linux/nfsd/nfsfh.h b/include/linux/nfsd/nfsfh.h index 80d55bbc5365..f76d80ccec10 100644 --- a/include/linux/nfsd/nfsfh.h +++ b/include/linux/nfsd/nfsfh.h @@ -49,7 +49,7 @@ struct nfs_fhbase_old { * * The auth_type field specifies how the filehandle can be authenticated * This might allow a file to be confirmed to be in a writable part of a - * filetree without checking the path from it upto the root. + * filetree without checking the path from it up to the root. * Current values: * 0 - No authentication. fb_auth is 0 bytes long * Possible future values: diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 30022189104d..bbfa1093f606 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -414,7 +414,7 @@ * @__NL80211_CMD_AFTER_LAST: internal use */ enum nl80211_commands { -/* don't change the order or add anything inbetween, this is ABI! */ +/* don't change the order or add anything between, this is ABI! */ NL80211_CMD_UNSPEC, NL80211_CMD_GET_WIPHY, /* can dump */ @@ -860,7 +860,7 @@ enum nl80211_commands { * This can be used to mask out antennas which are not attached or should * not be used for receiving. If an antenna is not selected in this bitmap * the hardware should not be configured to receive on this antenna. - * For a more detailed descripton see @NL80211_ATTR_WIPHY_ANTENNA_TX. + * For a more detailed description see @NL80211_ATTR_WIPHY_ANTENNA_TX. * * @NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX: Bitmap of antennas which are available * for configuration as TX antennas via the above parameters. @@ -891,7 +891,7 @@ enum nl80211_commands { * @__NL80211_ATTR_AFTER_LAST: internal use */ enum nl80211_attrs { -/* don't change the order or add anything inbetween, this is ABI! */ +/* don't change the order or add anything between, this is ABI! */ NL80211_ATTR_UNSPEC, NL80211_ATTR_WIPHY, @@ -1419,7 +1419,7 @@ enum nl80211_bitrate_attr { * 802.11 country information element with regulatory information it * thinks we should consider. cfg80211 only processes the country * code from the IE, and relies on the regulatory domain information - * structure pased by userspace (CRDA) from our wireless-regdb. + * structure passed by userspace (CRDA) from our wireless-regdb. * If a channel is enabled but the country code indicates it should * be disabled we disable the channel and re-enable it upon disassociation. */ @@ -1598,7 +1598,7 @@ enum nl80211_mntr_flags { * @NL80211_MESHCONF_RETRY_TIMEOUT: specifies the initial retry timeout in * millisecond units, used by the Peer Link Open message * - * @NL80211_MESHCONF_CONFIRM_TIMEOUT: specifies the inital confirm timeout, in + * @NL80211_MESHCONF_CONFIRM_TIMEOUT: specifies the initial confirm timeout, in * millisecond units, used by the peer link management to close a peer link * * @NL80211_MESHCONF_HOLDING_TIMEOUT: specifies the holding timeout, in diff --git a/include/linux/notifier.h b/include/linux/notifier.h index 2026f9e1ceb8..621dfa16acc0 100644 --- a/include/linux/notifier.h +++ b/include/linux/notifier.h @@ -237,7 +237,7 @@ static inline int notifier_to_errno(int ret) * enabling interrupts. Must not sleep, * must not fail */ -/* Used for CPU hotplug events occuring while tasks are frozen due to a suspend +/* Used for CPU hotplug events occurring while tasks are frozen due to a suspend * operation in progress */ #define CPU_TASKS_FROZEN 0x0010 diff --git a/include/linux/omap3isp.h b/include/linux/omap3isp.h index 150822b4dbff..b6111f8cd49a 100644 --- a/include/linux/omap3isp.h +++ b/include/linux/omap3isp.h @@ -250,7 +250,7 @@ enum omap3isp_h3a_af_rgbpos { /* Contains the information regarding the Horizontal Median Filter */ struct omap3isp_h3a_af_hmf { __u8 enable; /* Status of Horizontal Median Filter */ - __u8 threshold; /* Threshhold Value for Horizontal Median Filter */ + __u8 threshold; /* Threshold Value for Horizontal Median Filter */ }; /* Contains the information regarding the IIR Filters */ diff --git a/include/linux/page_cgroup.h b/include/linux/page_cgroup.h index f5de21de31dd..961ecc7d30bc 100644 --- a/include/linux/page_cgroup.h +++ b/include/linux/page_cgroup.h @@ -138,7 +138,7 @@ static inline void move_unlock_page_cgroup(struct page_cgroup *pc, #define PCG_ARRAYID_OFFSET (BITS_PER_LONG - PCG_ARRAYID_WIDTH) /* - * Zero the shift count for non-existant fields, to prevent compiler + * Zero the shift count for non-existent fields, to prevent compiler * warnings and ensure references are optimized away. */ #define PCG_ARRAYID_SHIFT (PCG_ARRAYID_OFFSET * (PCG_ARRAYID_WIDTH != 0)) diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h index 5b7e6b1ba54f..be01380f798a 100644 --- a/include/linux/pci_regs.h +++ b/include/linux/pci_regs.h @@ -223,7 +223,7 @@ #define PCI_PM_CAP_PME_CLOCK 0x0008 /* PME clock required */ #define PCI_PM_CAP_RESERVED 0x0010 /* Reserved field */ #define PCI_PM_CAP_DSI 0x0020 /* Device specific initialization */ -#define PCI_PM_CAP_AUX_POWER 0x01C0 /* Auxilliary power support mask */ +#define PCI_PM_CAP_AUX_POWER 0x01C0 /* Auxiliary power support mask */ #define PCI_PM_CAP_D1 0x0200 /* D1 power state support */ #define PCI_PM_CAP_D2 0x0400 /* D2 power state support */ #define PCI_PM_CAP_PME 0x0800 /* PME pin supported */ @@ -435,7 +435,7 @@ #define PCI_EXP_LNKCAP_L0SEL 0x00007000 /* L0s Exit Latency */ #define PCI_EXP_LNKCAP_L1EL 0x00038000 /* L1 Exit Latency */ #define PCI_EXP_LNKCAP_CLKPM 0x00040000 /* L1 Clock Power Management */ -#define PCI_EXP_LNKCAP_SDERC 0x00080000 /* Suprise Down Error Reporting Capable */ +#define PCI_EXP_LNKCAP_SDERC 0x00080000 /* Surprise Down Error Reporting Capable */ #define PCI_EXP_LNKCAP_DLLLARC 0x00100000 /* Data Link Layer Link Active Reporting Capable */ #define PCI_EXP_LNKCAP_LBNC 0x00200000 /* Link Bandwidth Notification Capability */ #define PCI_EXP_LNKCAP_PN 0xff000000 /* Port Number */ diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 311b4dc785a1..393b60c71732 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -662,7 +662,7 @@ struct pmu { int (*commit_txn) (struct pmu *pmu); /* optional */ /* * Will cancel the transaction, assumes ->del() is called - * for each successfull ->add() during the transaction. + * for each successful ->add() during the transaction. */ void (*cancel_txn) (struct pmu *pmu); /* optional */ }; diff --git a/include/linux/pid.h b/include/linux/pid.h index efceda0a51b1..31afb7ecbe1f 100644 --- a/include/linux/pid.h +++ b/include/linux/pid.h @@ -21,7 +21,7 @@ enum pid_type * quickly from the numeric pid value. The attached processes may be * quickly accessed by following pointers from struct pid. * - * Storing pid_t values in the kernel and refering to them later has a + * Storing pid_t values in the kernel and referring to them later has a * problem. The process originally with that pid may have exited and the * pid allocator wrapped, and another process could have come along * and been assigned that pid. diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h index b1032a3fafdc..3a02e0208575 100644 --- a/include/linux/pkt_sched.h +++ b/include/linux/pkt_sched.h @@ -223,7 +223,7 @@ struct tc_gred_qopt { __u32 limit; /* HARD maximal queue length (bytes) */ __u32 qth_min; /* Min average length threshold (bytes) */ __u32 qth_max; /* Max average length threshold (bytes) */ - __u32 DP; /* upto 2^32 DPs */ + __u32 DP; /* up to 2^32 DPs */ __u32 backlog; __u32 qave; __u32 forced; diff --git a/include/linux/poll.h b/include/linux/poll.h index 1a2ccd6f3823..cf40010ce0cd 100644 --- a/include/linux/poll.h +++ b/include/linux/poll.h @@ -82,7 +82,7 @@ static inline int poll_schedule(struct poll_wqueues *pwq, int state) } /* - * Scaleable version of the fd_set. + * Scalable version of the fd_set. */ typedef struct { diff --git a/include/linux/prefetch.h b/include/linux/prefetch.h index af7c36a5a521..a3bfbdf63d32 100644 --- a/include/linux/prefetch.h +++ b/include/linux/prefetch.h @@ -29,7 +29,7 @@ prefetchw(x) - prefetches the cacheline at "x" for write spin_lock_prefetch(x) - prefetches the spinlock *x for taking - there is also PREFETCH_STRIDE which is the architecure-prefered + there is also PREFETCH_STRIDE which is the architecure-preferred "lookahead" size for prefetching streamed operations. */ diff --git a/include/linux/pxa2xx_ssp.h b/include/linux/pxa2xx_ssp.h index 2f691e4e6222..44835fb39793 100644 --- a/include/linux/pxa2xx_ssp.h +++ b/include/linux/pxa2xx_ssp.h @@ -122,7 +122,7 @@ #define SSCR1_TSRE (1 << 21) /* Transmit Service Request Enable */ #define SSCR1_RSRE (1 << 20) /* Receive Service Request Enable */ #define SSCR1_TINTE (1 << 19) /* Receiver Time-out Interrupt enable */ -#define SSCR1_PINTE (1 << 18) /* Peripheral Trailing Byte Interupt Enable */ +#define SSCR1_PINTE (1 << 18) /* Peripheral Trailing Byte Interrupt Enable */ #define SSCR1_IFS (1 << 16) /* Invert Frame Signal */ #define SSCR1_STRF (1 << 15) /* Select FIFO or EFWR */ #define SSCR1_EFWR (1 << 14) /* Enable FIFO Write/Read */ diff --git a/include/linux/raid/md_p.h b/include/linux/raid/md_p.h index ffa2efbbe382..75cbf4f62fe8 100644 --- a/include/linux/raid/md_p.h +++ b/include/linux/raid/md_p.h @@ -251,7 +251,7 @@ struct mdp_superblock_1 { __le64 utime; /* 40 bits second, 24 btes microseconds */ __le64 events; /* incremented when superblock updated */ __le64 resync_offset; /* data before this offset (from data_offset) known to be in sync */ - __le32 sb_csum; /* checksum upto devs[max_dev] */ + __le32 sb_csum; /* checksum up to devs[max_dev] */ __le32 max_dev; /* size of devs[] array to consider */ __u8 pad3[64-32]; /* set to 0 when writing */ diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h index 0a3842aacba9..eca75df00fed 100644 --- a/include/linux/reiserfs_fs.h +++ b/include/linux/reiserfs_fs.h @@ -1557,7 +1557,7 @@ struct tree_balance { /* When inserting an item. */ #define M_INSERT 'i' /* When inserting into (directories only) or appending onto an already - existant item. */ + existent item. */ #define M_PASTE 'p' /* When deleting an item. */ #define M_DELETE 'd' diff --git a/include/linux/sched.h b/include/linux/sched.h index 83bd2e2982fc..4ec2c027e92c 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -854,7 +854,7 @@ extern int __weak arch_sd_sibiling_asym_packing(void); /* * Optimise SD flags for power savings: - * SD_BALANCE_NEWIDLE helps agressive task consolidation and power savings. + * SD_BALANCE_NEWIDLE helps aggressive task consolidation and power savings. * Keep default SD flags if sched_{smt,mc}_power_saving=0 */ diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 239083bfea13..b759896d9754 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -474,7 +474,7 @@ static inline void skb_dst_set(struct sk_buff *skb, struct dst_entry *dst) extern void skb_dst_set_noref(struct sk_buff *skb, struct dst_entry *dst); /** - * skb_dst_is_noref - Test if skb dst isnt refcounted + * skb_dst_is_noref - Test if skb dst isn't refcounted * @skb: buffer */ static inline bool skb_dst_is_noref(const struct sk_buff *skb) diff --git a/include/linux/smc91x.h b/include/linux/smc91x.h index bc21db598c06..76199b75d584 100644 --- a/include/linux/smc91x.h +++ b/include/linux/smc91x.h @@ -21,7 +21,7 @@ #define RPC_LED_10 (0x02) /* LED = 10Mbps link detect */ #define RPC_LED_FD (0x03) /* LED = Full Duplex Mode */ #define RPC_LED_TX_RX (0x04) /* LED = TX or RX packet occurred */ -#define RPC_LED_100 (0x05) /* LED = 100Mbps link dectect */ +#define RPC_LED_100 (0x05) /* LED = 100Mbps link detect */ #define RPC_LED_TX (0x06) /* LED = TX packet occurred */ #define RPC_LED_RX (0x07) /* LED = RX packet occurred */ diff --git a/include/linux/socket.h b/include/linux/socket.h index edbb1d07ddf4..d2b5e982f079 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -88,7 +88,7 @@ struct cmsghdr { }; /* - * Ancilliary data object information MACROS + * Ancillary data object information MACROS * Table 5-14 of POSIX 1003.1g */ diff --git a/include/linux/soundcard.h b/include/linux/soundcard.h index 1904afedb82f..fe204fe39f7c 100644 --- a/include/linux/soundcard.h +++ b/include/linux/soundcard.h @@ -1231,7 +1231,7 @@ void seqbuf_dump(void); /* This function must be provided by programs */ #define SEQ_PANNING(dev, voice, pos) SEQ_CONTROL(dev, voice, CTL_PAN, (pos+128) / 2) /* - * Timing and syncronization macros + * Timing and synchronization macros */ #define _TIMER_EVENT(ev, parm) {_SEQ_NEEDBUF(8);\ diff --git a/include/linux/spi/spidev.h b/include/linux/spi/spidev.h index bf0570a84f7a..52d9ed01855f 100644 --- a/include/linux/spi/spidev.h +++ b/include/linux/spi/spidev.h @@ -66,7 +66,7 @@ * are in a different address space (and may be of different sizes in some * cases, such as 32-bit i386 userspace over a 64-bit x86_64 kernel). * Zero-initialize the structure, including currently unused fields, to - * accomodate potential future updates. + * accommodate potential future updates. * * SPI_IOC_MESSAGE gives userspace the equivalent of kernel spi_sync(). * Pass it an array of related transfers, they'll execute together. diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h index 80e535897de6..0b22d51258e6 100644 --- a/include/linux/spinlock.h +++ b/include/linux/spinlock.h @@ -81,7 +81,7 @@ #include /* - * Pull the arch_spin*() functions/declarations (UP-nondebug doesnt need them): + * Pull the arch_spin*() functions/declarations (UP-nondebug doesn't need them): */ #ifdef CONFIG_SMP # include diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h index e10352915698..f29197a4b227 100644 --- a/include/linux/stmmac.h +++ b/include/linux/stmmac.h @@ -26,7 +26,7 @@ #ifndef __STMMAC_PLATFORM_DATA #define __STMMAC_PLATFORM_DATA -/* platfrom data for platfrom device structure's platfrom_data field */ +/* platform data for platform device structure's platform_data field */ /* Private data for the STM on-board ethernet driver */ struct plat_stmmacenet_data { diff --git a/include/linux/stop_machine.h b/include/linux/stop_machine.h index 1808960c5059..092dc9b1ce7d 100644 --- a/include/linux/stop_machine.h +++ b/include/linux/stop_machine.h @@ -105,7 +105,7 @@ static inline int try_stop_cpus(const struct cpumask *cpumask, * @cpus: the cpus to run the @fn() on (NULL = any online cpu) * * Description: This causes a thread to be scheduled on every cpu, - * each of which disables interrupts. The result is that noone is + * each of which disables interrupts. The result is that no one is * holding a spinlock or inside any other preempt-disabled region when * @fn() runs. * diff --git a/include/linux/sunrpc/cache.h b/include/linux/sunrpc/cache.h index 7898ea13de70..8d2eef1a8582 100644 --- a/include/linux/sunrpc/cache.h +++ b/include/linux/sunrpc/cache.h @@ -35,10 +35,10 @@ * Each cache must be registered so that it can be cleaned regularly. * When the cache is unregistered, it is flushed completely. * - * Entries have a ref count and a 'hashed' flag which counts the existance + * Entries have a ref count and a 'hashed' flag which counts the existence * in the hash table. * We only expire entries when refcount is zero. - * Existance in the cache is counted the refcount. + * Existence in the cache is counted the refcount. */ /* Every cache item has a common header that is used diff --git a/include/linux/sunrpc/svcauth_gss.h b/include/linux/sunrpc/svcauth_gss.h index ca7d725861fc..83bbee3f089c 100644 --- a/include/linux/sunrpc/svcauth_gss.h +++ b/include/linux/sunrpc/svcauth_gss.h @@ -2,7 +2,7 @@ * linux/include/linux/sunrpc/svcauth_gss.h * * Bruce Fields - * Copyright (c) 2002 The Regents of the Unviersity of Michigan + * Copyright (c) 2002 The Regents of the University of Michigan */ #ifndef _LINUX_SUNRPC_SVCAUTH_GSS_H diff --git a/include/linux/sysdev.h b/include/linux/sysdev.h index 8a75da551e4e..dfb078db8ebb 100644 --- a/include/linux/sysdev.h +++ b/include/linux/sysdev.h @@ -7,13 +7,13 @@ * We still have a notion of a driver for a system device, because we still * want to perform basic operations on these devices. * - * We also support auxillary drivers binding to devices of a certain class. + * We also support auxiliary drivers binding to devices of a certain class. * * This allows configurable drivers to register themselves for devices of * a certain type. And, it allows class definitions to reside in generic * code while arch-specific code can register specific drivers. * - * Auxillary drivers registered with a NULL cls are registered as drivers + * Auxiliary drivers registered with a NULL cls are registered as drivers * for all system devices, and get notification calls for each device. */ @@ -70,7 +70,7 @@ extern int sysdev_class_create_file(struct sysdev_class *, extern void sysdev_class_remove_file(struct sysdev_class *, struct sysdev_class_attribute *); /** - * Auxillary system device drivers. + * Auxiliary system device drivers. */ struct sysdev_driver { diff --git a/include/linux/timerqueue.h b/include/linux/timerqueue.h index d24aabaca474..a520fd70a59f 100644 --- a/include/linux/timerqueue.h +++ b/include/linux/timerqueue.h @@ -24,7 +24,7 @@ extern struct timerqueue_node *timerqueue_iterate_next( struct timerqueue_node *node); /** - * timerqueue_getnext - Returns the timer with the earlies expiration time + * timerqueue_getnext - Returns the timer with the earliest expiration time * * @head: head of timerqueue * diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h index 3a2e66d88a32..ebcfa4ebdbf8 100644 --- a/include/linux/tracehook.h +++ b/include/linux/tracehook.h @@ -169,7 +169,7 @@ static inline int tracehook_unsafe_exec(struct task_struct *task) * tracehook_tracer_task - return the task that is tracing the given task * @tsk: task to consider * - * Returns NULL if noone is tracing @task, or the &struct task_struct + * Returns NULL if no one is tracing @task, or the &struct task_struct * pointer to its tracer. * * Must called under rcu_read_lock(). The pointer returned might be kept @@ -448,7 +448,7 @@ static inline int tracehook_force_sigpending(void) * * Return zero to check for a real pending signal normally. * Return -1 after releasing the siglock to repeat the check. - * Return a signal number to induce an artifical signal delivery, + * Return a signal number to induce an artificial signal delivery, * setting *@info and *@return_ka to specify its details and behavior. * * The @return_ka->sa_handler value controls the disposition of the diff --git a/include/linux/ucb1400.h b/include/linux/ucb1400.h index 1b4790911052..5c75153f9441 100644 --- a/include/linux/ucb1400.h +++ b/include/linux/ucb1400.h @@ -8,7 +8,7 @@ * Copyright: MontaVista Software, Inc. * * Spliting done by: Marek Vasut - * If something doesnt work and it worked before spliting, e-mail me, + * If something doesn't work and it worked before spliting, e-mail me, * dont bother Nicolas please ;-) * * This program is free software; you can redistribute it and/or modify diff --git a/include/linux/usb.h b/include/linux/usb.h index e63efeb378e3..65f78ca5d88e 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -623,7 +623,7 @@ extern struct usb_host_interface *usb_find_alt_setting( * USB hubs. That makes it stay the same until systems are physically * reconfigured, by re-cabling a tree of USB devices or by moving USB host * controllers. Adding and removing devices, including virtual root hubs - * in host controller driver modules, does not change these path identifers; + * in host controller driver modules, does not change these path identifiers; * neither does rebooting or re-enumerating. These are more useful identifiers * than changeable ("unstable") ones like bus numbers or device addresses. * @@ -793,7 +793,7 @@ struct usbdrv_wrap { * usb_set_intfdata() to associate driver-specific data with the * interface. It may also use usb_set_interface() to specify the * appropriate altsetting. If unwilling to manage the interface, - * return -ENODEV, if genuine IO errors occured, an appropriate + * return -ENODEV, if genuine IO errors occurred, an appropriate * negative errno value. * @disconnect: Called when the interface is no longer accessible, usually * because its device has been (or is being) disconnected or the diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 3d29a7dcac2d..882a084a8411 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -188,7 +188,7 @@ ep_choose(struct usb_gadget *g, struct usb_endpoint_descriptor *hs, * @bind() method is then used to initialize all the functions and then * call @usb_add_function() for them. * - * Those functions would normally be independant of each other, but that's + * Those functions would normally be independent of each other, but that's * not mandatory. CDC WMC devices are an example where functions often * depend on other functions, with some functions subsidiary to others. * Such interdependency may be managed in any way, so long as all of the diff --git a/include/linux/usb/ehci_def.h b/include/linux/usb/ehci_def.h index 656380245198..e49dfd45baa4 100644 --- a/include/linux/usb/ehci_def.h +++ b/include/linux/usb/ehci_def.h @@ -159,7 +159,7 @@ struct ehci_regs { #define USBMODE_CM_IDLE (0<<0) /* idle state */ /* Moorestown has some non-standard registers, partially due to the fact that - * its EHCI controller has both TT and LPM support. HOSTPCx are extentions to + * its EHCI controller has both TT and LPM support. HOSTPCx are extensions to * PORTSCx */ #define HOSTPC0 0x84 /* HOSTPC extension */ diff --git a/include/linux/usb/functionfs.h b/include/linux/usb/functionfs.h index 6f649c13193b..7587ef934ba8 100644 --- a/include/linux/usb/functionfs.h +++ b/include/linux/usb/functionfs.h @@ -45,7 +45,7 @@ struct usb_functionfs_descs_head { * | off | name | type | description | * |-----+-----------+--------------+--------------------------------------| * | 0 | magic | LE32 | FUNCTIONFS_{FS,HS}_DESCRIPTORS_MAGIC | - * | 4 | lenght | LE32 | length of the whole data chunk | + * | 4 | length | LE32 | length of the whole data chunk | * | 8 | fs_count | LE32 | number of full-speed descriptors | * | 12 | hs_count | LE32 | number of high-speed descriptors | * | 16 | fs_descrs | Descriptor[] | list of full-speed descriptors | @@ -86,7 +86,7 @@ struct usb_functionfs_strings_head { * | 0 | lang | LE16 | language code | * | 2 | strings | String[str_count] | array of strings in given language | * - * For each string ther is one strings entry (ie. there are str_count + * For each string there is one strings entry (ie. there are str_count * string entries). Each String is a NUL terminated string encoded in * UTF-8. */ diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 006412ce2303..e538172c0f64 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -72,7 +72,7 @@ struct usb_ep; * Bulk endpoints can use any size buffers, and can also be used for interrupt * transfers. interrupt-only endpoints can be much less functional. * - * NOTE: this is analagous to 'struct urb' on the host side, except that + * NOTE: this is analogous to 'struct urb' on the host side, except that * it's thinner and promotes more pre-allocation. */ @@ -269,7 +269,7 @@ static inline void usb_ep_free_request(struct usb_ep *ep, * * Control endpoints ... after getting a setup() callback, the driver queues * one response (even if it would be zero length). That enables the - * status ack, after transfering data as specified in the response. Setup + * status ack, after transferring data as specified in the response. Setup * functions may return negative error codes to generate protocol stalls. * (Note that some USB device controllers disallow protocol stall responses * in some cases.) When control responses are deferred (the response is diff --git a/include/linux/usb/midi.h b/include/linux/usb/midi.h index 1d1040865661..c8c52e3c91de 100644 --- a/include/linux/usb/midi.h +++ b/include/linux/usb/midi.h @@ -70,7 +70,7 @@ struct usb_midi_out_jack_descriptor { __u8 bJackID; __u8 bNrInputPins; /* p */ struct usb_midi_source_pin pins[]; /* [p] */ - /*__u8 iJack; -- ommitted due to variable-sized pins[] */ + /*__u8 iJack; -- omitted due to variable-sized pins[] */ } __attribute__ ((packed)); #define USB_DT_MIDI_OUT_SIZE(p) (7 + 2 * (p)) diff --git a/include/linux/usb/wusb.h b/include/linux/usb/wusb.h index 63ebdcc5dda6..0c4d4ca370ec 100644 --- a/include/linux/usb/wusb.h +++ b/include/linux/usb/wusb.h @@ -126,7 +126,7 @@ enum { /** * WUSB IE: Channel Stop (WUSB1.0[7.5.8]) * - * Tells devices the host is going to stop sending MMCs and will dissapear. + * Tells devices the host is going to stop sending MMCs and will disappear. */ struct wuie_channel_stop { struct wuie_hdr hdr; diff --git a/include/linux/uwb.h b/include/linux/uwb.h index 7fc9746f22cd..b0c564ec2160 100644 --- a/include/linux/uwb.h +++ b/include/linux/uwb.h @@ -274,7 +274,7 @@ static inline void uwb_mas_bm_copy_le(void *dst, const struct uwb_mas_bm *mas) /** * struct uwb_drp_avail - a radio controller's view of MAS usage - * @global: MAS unused by neighbors (excluding reservations targetted + * @global: MAS unused by neighbors (excluding reservations targeted * or owned by the local radio controller) or the beaon period * @local: MAS unused by local established reservations * @pending: MAS unused by local pending reservations @@ -702,10 +702,10 @@ void edc_init(struct edc *edc) edc->timestart = jiffies; } -/* Called when an error occured. +/* Called when an error occurred. * This is way to determine if the number of acceptable errors per time * period has been exceeded. It is not accurate as there are cases in which - * this scheme will not work, for example if there are periodic occurences + * this scheme will not work, for example if there are periodic occurrences * of errors that straddle updates to the start time. This scheme is * sufficient for our usage. * diff --git a/include/linux/uwb/umc.h b/include/linux/uwb/umc.h index 4b4fc0f43855..7b4842028ca7 100644 --- a/include/linux/uwb/umc.h +++ b/include/linux/uwb/umc.h @@ -132,7 +132,7 @@ int umc_match_pci_id(struct umc_driver *umc_drv, struct umc_dev *umc); * * FIXME: This is as dirty as it gets, but we need some way to check * the correct type of umc_dev->parent (so that for example, we can - * cast to pci_dev). Casting to pci_dev is necesary because at some + * cast to pci_dev). Casting to pci_dev is necessary because at some * point we need to request resources from the device. Mapping is * easily over come (ioremap and stuff are bus agnostic), but hooking * up to some error handlers (such as pci error handlers) might need diff --git a/include/linux/vgaarb.h b/include/linux/vgaarb.h index e9e1524b582c..9c3120dca294 100644 --- a/include/linux/vgaarb.h +++ b/include/linux/vgaarb.h @@ -78,7 +78,7 @@ extern void vga_set_legacy_decoding(struct pci_dev *pdev, * wether the card is doing legacy decoding for that type of resource. If * yes, the lock is "converted" into a legacy resource lock. * The arbiter will first look for all VGA cards that might conflict - * and disable their IOs and/or Memory access, inlcuding VGA forwarding + * and disable their IOs and/or Memory access, including VGA forwarding * on P2P bridges if necessary, so that the requested resources can * be used. Then, the card is marked as locking these resources and * the IO and/or Memory accesse are enabled on the card (including @@ -187,7 +187,7 @@ extern struct pci_dev *vga_default_device(void); * vga_conflicts * * Architectures should define this if they have several - * independant PCI domains that can afford concurrent VGA + * independent PCI domains that can afford concurrent VGA * decoding */ diff --git a/include/linux/wimax.h b/include/linux/wimax.h index 4fdcc5635518..9f6b77af2f6d 100644 --- a/include/linux/wimax.h +++ b/include/linux/wimax.h @@ -114,7 +114,7 @@ enum { WIMAX_GNL_RESET_IFIDX = 1, }; -/* Atributes for wimax_state_get() */ +/* Attributes for wimax_state_get() */ enum { WIMAX_GNL_STGET_IFIDX = 1, }; diff --git a/include/linux/xilinxfb.h b/include/linux/xilinxfb.h index f2463f559fb9..5a155a968054 100644 --- a/include/linux/xilinxfb.h +++ b/include/linux/xilinxfb.h @@ -16,7 +16,7 @@ /* ML300/403 reference design framebuffer driver platform data struct */ struct xilinxfb_platform_data { u32 rotate_screen; /* Flag to rotate display 180 degrees */ - u32 screen_height_mm; /* Physical dimentions of screen in mm */ + u32 screen_height_mm; /* Physical dimensions of screen in mm */ u32 screen_width_mm; u32 xres, yres; /* resolution of screen in pixels */ u32 xvirt, yvirt; /* resolution of memory buffer */ diff --git a/include/media/davinci/dm355_ccdc.h b/include/media/davinci/dm355_ccdc.h index df8a7b107477..adf2fe4bf0bb 100644 --- a/include/media/davinci/dm355_ccdc.h +++ b/include/media/davinci/dm355_ccdc.h @@ -193,7 +193,7 @@ struct ccdc_dft_corr_mem_ctl { #define CCDC_DFT_TABLE_SIZE 16 /* * Main Structure for vertical defect correction. Vertical defect - * correction can correct upto 16 defects if defects less than 16 + * correction can correct up to 16 defects if defects less than 16 * then pad the rest with 0 */ struct ccdc_vertical_dft { diff --git a/include/media/davinci/isif.h b/include/media/davinci/isif.h index b0b74ad618cc..7f3d76a4b9e3 100644 --- a/include/media/davinci/isif.h +++ b/include/media/davinci/isif.h @@ -199,7 +199,7 @@ struct isif_black_clamp { }; /************************************************************************* -** Color Space Convertion (CSC) +** Color Space Conversion (CSC) *************************************************************************/ #define ISIF_CSC_NUM_COEFF 16 struct isif_color_space_conv { diff --git a/include/media/lirc.h b/include/media/lirc.h index 6678a169fd9e..4b3ab2966b5a 100644 --- a/include/media/lirc.h +++ b/include/media/lirc.h @@ -137,7 +137,7 @@ */ #define LIRC_SET_REC_FILTER_SPACE _IOW('i', 0x0000001b, __u32) /* - * if filter cannot be set independantly for pulse/space, this should + * if filter cannot be set independently for pulse/space, this should * be used */ #define LIRC_SET_REC_FILTER _IOW('i', 0x0000001c, __u32) diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h index 6b75a6971346..cdf2e8ac4309 100644 --- a/include/net/9p/9p.h +++ b/include/net/9p/9p.h @@ -119,7 +119,7 @@ do { \ * @P9_TREAD: request to transfer data from a file or directory * @P9_RREAD: response with data requested * @P9_TWRITE: reuqest to transfer data to a file - * @P9_RWRITE: response with out much data was transfered to file + * @P9_RWRITE: response with out much data was transferred to file * @P9_TCLUNK: forget about a handle to an entity within the file system * @P9_RCLUNK: response when server has forgotten about the handle * @P9_TREMOVE: request to remove an entity from the hierarchy @@ -294,7 +294,7 @@ enum p9_perm_t { * * QID types are a subset of permissions - they are primarily * used to differentiate semantics for a file system entity via - * a jump-table. Their value is also the most signifigant 16 bits + * a jump-table. Their value is also the most significant 16 bits * of the permission_t * * See Also: http://plan9.bell-labs.com/magic/man2html/2/stat @@ -366,8 +366,8 @@ struct p9_qid { /** * struct p9_stat - file system metadata information * @size: length prefix for this stat structure instance - * @type: the type of the server (equivilent to a major number) - * @dev: the sub-type of the server (equivilent to a minor number) + * @type: the type of the server (equivalent to a major number) + * @dev: the sub-type of the server (equivalent to a minor number) * @qid: unique id from the server of type &p9_qid * @mode: Plan 9 format permissions of type &p9_perm_t * @atime: Last access/read time diff --git a/include/net/9p/client.h b/include/net/9p/client.h index 0a30977e3c1f..85c1413f054d 100644 --- a/include/net/9p/client.h +++ b/include/net/9p/client.h @@ -101,7 +101,7 @@ enum p9_req_status_t { * Transport use an array to track outstanding requests * instead of a list. While this may incurr overhead during initial * allocation or expansion, it makes request lookup much easier as the - * tag id is a index into an array. (We use tag+1 so that we can accomodate + * tag id is a index into an array. (We use tag+1 so that we can accommodate * the -1 tag for the T_VERSION request). * This also has the nice effect of only having to allocate wait_queues * once, instead of constantly allocating and freeing them. Its possible diff --git a/include/net/9p/transport.h b/include/net/9p/transport.h index 82868f18c573..8f08c736c4c3 100644 --- a/include/net/9p/transport.h +++ b/include/net/9p/transport.h @@ -30,7 +30,7 @@ /* Default. Add Payload to PDU before sending it down to transport layer */ #define P9_TRANS_PREF_PAYLOAD_DEF 0x0 -/* Send pay load seperately to transport layer along with PDU.*/ +/* Send pay load separately to transport layer along with PDU.*/ #define P9_TRANS_PREF_PAYLOAD_SEP 0x1 /** diff --git a/include/net/caif/cfcnfg.h b/include/net/caif/cfcnfg.h index f688478bfb84..f33d36341132 100644 --- a/include/net/caif/cfcnfg.h +++ b/include/net/caif/cfcnfg.h @@ -69,7 +69,7 @@ void cfcnfg_remove(struct cfcnfg *cfg); * cfcnfg_add_adapt_layer to specify PHY for the link. * @pref: The phy (link layer) preference. * @fcs: Specify if checksum is used in CAIF Framing Layer. - * @stx: Specify if Start Of Frame eXtention is used. + * @stx: Specify if Start Of Frame extension is used. */ void diff --git a/include/net/gen_stats.h b/include/net/gen_stats.h index fa157712e982..a79b6cfb02a8 100644 --- a/include/net/gen_stats.h +++ b/include/net/gen_stats.h @@ -11,7 +11,7 @@ struct gnet_dump { struct sk_buff * skb; struct nlattr * tail; - /* Backward compatability */ + /* Backward compatibility */ int compat_tc_stats; int compat_xstats; void * xstats; diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index 30b49ed72f0d..814b434db749 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h @@ -92,7 +92,7 @@ static inline struct net *skb_sknet(const struct sk_buff *skb) } /* * This one needed for single_open_net since net is stored directly in - * private not as a struct i.e. seq_file_net cant be used. + * private not as a struct i.e. seq_file_net can't be used. */ static inline struct net *seq_file_single_net(struct seq_file *seq) { diff --git a/include/net/irda/irlap.h b/include/net/irda/irlap.h index 17fcd964f9d9..fb4b76d5d7f1 100644 --- a/include/net/irda/irlap.h +++ b/include/net/irda/irlap.h @@ -204,7 +204,7 @@ struct irlap_cb { notify_t notify; /* Callbacks to IrLMP */ - int mtt_required; /* Minumum turnaround time required */ + int mtt_required; /* Minimum turnaround time required */ int xbofs_delay; /* Nr of XBOF's used to MTT */ int bofs_count; /* Negotiated extra BOFs */ int next_bofs; /* Negotiated extra BOFs after next frame */ diff --git a/include/net/irda/wrapper.h b/include/net/irda/wrapper.h index 2942ad6ab932..eef53ebe3d76 100644 --- a/include/net/irda/wrapper.h +++ b/include/net/irda/wrapper.h @@ -42,7 +42,7 @@ #define IRDA_TRANS 0x20 /* Asynchronous transparency modifier */ -/* States for receving a frame in async mode */ +/* States for receiving a frame in async mode */ enum { OUTSIDE_FRAME, BEGIN_FRAME, diff --git a/include/net/iucv/iucv.h b/include/net/iucv/iucv.h index 205a3360156e..1121baa9f695 100644 --- a/include/net/iucv/iucv.h +++ b/include/net/iucv/iucv.h @@ -173,7 +173,7 @@ struct iucv_handler { /* * The message_pending function is called after an icuv interrupt * type 0x06 or type 0x07 has been received. A new message is - * availabe and can be received with iucv_message_receive. + * available and can be received with iucv_message_receive. */ void (*message_pending)(struct iucv_path *, struct iucv_message *); /* diff --git a/include/net/iw_handler.h b/include/net/iw_handler.h index 3afdb21cc31d..5d5a6a4732ef 100644 --- a/include/net/iw_handler.h +++ b/include/net/iw_handler.h @@ -91,7 +91,7 @@ * -------------------- * The implementation goals were as follow : * o Obvious : you should not need a PhD to understand what's happening, - * the benefit is easier maintainance. + * the benefit is easier maintenance. * o Flexible : it should accommodate a wide variety of driver * implementations and be as flexible as the old API. * o Lean : it should be efficient memory wise to minimise the impact @@ -129,7 +129,7 @@ * * Functions prototype uses union iwreq_data * ----------------------------------------- - * Some would have prefered functions defined this way : + * Some would have preferred functions defined this way : * static int mydriver_ioctl_setrate(struct net_device *dev, * long rate, int auto) * 1) The kernel code doesn't "validate" the content of iwreq_data, and diff --git a/include/net/mac80211.h b/include/net/mac80211.h index cefe1b37c493..cb13239fe8e3 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1294,7 +1294,7 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw, * acceleration (i.e. iwlwifi). Those drivers should provide update_tkip_key * handler. * The update_tkip_key() call updates the driver with the new phase 1 key. - * This happens everytime the iv16 wraps around (every 65536 packets). The + * This happens every time the iv16 wraps around (every 65536 packets). The * set_key() call will happen only once for each key (unless the AP did * rekeying), it will not include a valid phase 1 key. The valid phase 1 key is * provided by update_tkip_key only. The trigger that makes mac80211 call this diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h index d9549af6929a..65afc4966204 100644 --- a/include/net/pkt_sched.h +++ b/include/net/pkt_sched.h @@ -32,7 +32,7 @@ static inline void *qdisc_priv(struct Qdisc *q) The result: [34]86 is not good choice for QoS router :-( - The things are not so bad, because we may use artifical + The things are not so bad, because we may use artificial clock evaluated by integration of network data flow in the most critical places. */ diff --git a/include/net/sock.h b/include/net/sock.h index da0534d3401c..01810a3f19df 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1749,7 +1749,7 @@ void sock_net_set(struct sock *sk, struct net *net) /* * Kernel sockets, f.e. rtnl or icmp_socket, are a part of a namespace. - * They should not hold a referrence to a namespace in order to allow + * They should not hold a reference to a namespace in order to allow * to stop it. * Sockets after sk_change_net should be released using sk_release_kernel */ diff --git a/include/net/transp_v6.h b/include/net/transp_v6.h index eeb077dd735f..a8122dc56410 100644 --- a/include/net/transp_v6.h +++ b/include/net/transp_v6.h @@ -16,7 +16,7 @@ extern struct proto tcpv6_prot; struct flowi6; -/* extention headers */ +/* extension headers */ extern int ipv6_exthdrs_init(void); extern void ipv6_exthdrs_exit(void); extern int ipv6_frag_init(void); diff --git a/include/net/wimax.h b/include/net/wimax.h index 3461aa1df1e0..c799ba7b708b 100644 --- a/include/net/wimax.h +++ b/include/net/wimax.h @@ -286,7 +286,7 @@ struct wimax_dev; * does not disconnect the device from the bus and return 0. * If that fails, it should resort to some sort of cold or bus * reset (even if it implies a bus disconnection and device - * dissapearance). In that case, -ENODEV should be returned to + * disappearance). In that case, -ENODEV should be returned to * indicate the device is gone. * This operation has to be synchronous, and return only when the * reset is complete. In case of having had to resort to bus/cold diff --git a/include/net/wpan-phy.h b/include/net/wpan-phy.h index 85926231c07a..d86fffd3c03c 100644 --- a/include/net/wpan-phy.h +++ b/include/net/wpan-phy.h @@ -28,7 +28,7 @@ struct wpan_phy { struct mutex pib_lock; /* - * This is a PIB acording to 802.15.4-2006. + * This is a PIB according to 802.15.4-2006. * We do not provide timing-related variables, as they * aren't used outside of driver */ diff --git a/include/rxrpc/packet.h b/include/rxrpc/packet.h index 9b2c30897e50..f2902ef7ab75 100644 --- a/include/rxrpc/packet.h +++ b/include/rxrpc/packet.h @@ -148,7 +148,7 @@ struct rxkad_challenge { * Kerberos security type-2 response packet */ struct rxkad_response { - __be32 version; /* version of this reponse type */ + __be32 version; /* version of this response type */ __be32 __pad; /* encrypted bit of the response */ diff --git a/include/scsi/fc/fc_fcp.h b/include/scsi/fc/fc_fcp.h index 8a143ca79878..652dec230514 100644 --- a/include/scsi/fc/fc_fcp.h +++ b/include/scsi/fc/fc_fcp.h @@ -75,7 +75,7 @@ struct fcp_cmnd32 { #define FCP_PTA_SIMPLE 0 /* simple task attribute */ #define FCP_PTA_HEADQ 1 /* head of queue task attribute */ #define FCP_PTA_ORDERED 2 /* ordered task attribute */ -#define FCP_PTA_ACA 4 /* auto. contigent allegiance */ +#define FCP_PTA_ACA 4 /* auto. contingent allegiance */ #define FCP_PTA_MASK 7 /* mask for task attribute field */ #define FCP_PRI_SHIFT 3 /* priority field starts in bit 3 */ #define FCP_PRI_RESVD_MASK 0x80 /* reserved bits in priority field */ diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h index c3e1cbcc2ad2..ddb04568a509 100644 --- a/include/scsi/iscsi_if.h +++ b/include/scsi/iscsi_if.h @@ -292,7 +292,7 @@ enum iscsi_param { ISCSI_PARAM_PERSISTENT_PORT, ISCSI_PARAM_SESS_RECOVERY_TMO, - /* pased in through bind conn using transport_fd */ + /* passed in through bind conn using transport_fd */ ISCSI_PARAM_CONN_PORT, ISCSI_PARAM_CONN_ADDRESS, diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h index 24193c1b0da0..a3cbda4ddb5c 100644 --- a/include/scsi/libfc.h +++ b/include/scsi/libfc.h @@ -260,7 +260,7 @@ struct fcoe_dev_stats { /** * struct fc_seq_els_data - ELS data used for passing ELS specific responses * @reason: The reason for rejection - * @explan: The explaination of the rejection + * @explan: The explanation of the rejection * * Mainly used by the exchange manager layer. */ @@ -525,7 +525,7 @@ struct libfc_function_template { struct fc_frame *); /* - * Send an ELS response using infomation from the received frame. + * Send an ELS response using information from the received frame. * * STATUS: OPTIONAL */ @@ -663,7 +663,7 @@ struct libfc_function_template { int (*rport_logoff)(struct fc_rport_priv *); /* - * Recieve a request from a remote port. + * Receive a request from a remote port. * * STATUS: OPTIONAL */ @@ -704,7 +704,7 @@ struct libfc_function_template { void *)); /* - * Cleanup the FCP layer, used durring link down and reset + * Cleanup the FCP layer, used during link down and reset * * STATUS: OPTIONAL */ diff --git a/include/scsi/libiscsi_tcp.h b/include/scsi/libiscsi_tcp.h index e6b9fd2eea34..ac0cc1d925ef 100644 --- a/include/scsi/libiscsi_tcp.h +++ b/include/scsi/libiscsi_tcp.h @@ -52,7 +52,7 @@ struct iscsi_segment { iscsi_segment_done_fn_t *done; }; -/* Socket connection recieve helper */ +/* Socket connection receive helper */ struct iscsi_tcp_recv { struct iscsi_hdr *hdr; struct iscsi_segment segment; diff --git a/include/scsi/osd_initiator.h b/include/scsi/osd_initiator.h index 53a9e886612b..0a5079974fe9 100644 --- a/include/scsi/osd_initiator.h +++ b/include/scsi/osd_initiator.h @@ -265,7 +265,7 @@ int osd_execute_request_async(struct osd_request *or, * @osi - Recievs a more detailed error report information (optional). * @silent - Do not print to dmsg (Even if enabled) * @bad_obj_list - Some commands act on multiple objects. Failed objects will - * be recieved here (optional) + * be received here (optional) * @max_obj - Size of @bad_obj_list. * @bad_attr_list - List of failing attributes (optional) * @max_attr - Size of @bad_attr_list. diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index e7e385842a38..f1f2644137b8 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -46,7 +46,7 @@ struct blk_queue_tags; enum { SCSI_QDEPTH_DEFAULT, /* default requested change, e.g. from sysfs */ SCSI_QDEPTH_QFULL, /* scsi-ml requested due to queue full */ - SCSI_QDEPTH_RAMP_UP, /* scsi-ml requested due to threshhold event */ + SCSI_QDEPTH_RAMP_UP, /* scsi-ml requested due to threshold event */ }; struct scsi_host_template { diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h index 59816fe31e68..2a65167a8f10 100644 --- a/include/scsi/scsi_transport_fc.h +++ b/include/scsi/scsi_transport_fc.h @@ -192,9 +192,9 @@ struct fc_vport_identifiers { * * This structure exists for each FC port is a virtual FC port. Virtual * ports share the physical link with the Physical port. Each virtual - * ports has a unique presense on the SAN, and may be instantiated via + * ports has a unique presence on the SAN, and may be instantiated via * NPIV, Virtual Fabrics, or via additional ALPAs. As the vport is a - * unique presense, each vport has it's own view of the fabric, + * unique presence, each vport has it's own view of the fabric, * authentication privilege, and priorities. * * A virtual port may support 1 or more FC4 roles. Typically it is a @@ -370,7 +370,7 @@ struct fc_rport { /* aka fc_starget_attrs */ /* * FC SCSI Target Attributes * - * The SCSI Target is considered an extention of a remote port (as + * The SCSI Target is considered an extension of a remote port (as * a remote port can be more than a SCSI Target). Within the scsi * subsystem, we leave the Target as a separate entity. Doing so * provides backward compatibility with prior FC transport api's, diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h index f1dcefe4532b..02cbb50225bb 100644 --- a/include/sound/ac97_codec.h +++ b/include/sound/ac97_codec.h @@ -385,7 +385,7 @@ #define AC97_SCAP_DETECT_BY_VENDOR (1<<8) /* use vendor registers for read tests */ #define AC97_SCAP_NO_SPDIF (1<<9) /* don't build SPDIF controls */ #define AC97_SCAP_EAPD_LED (1<<10) /* EAPD as mute LED */ -#define AC97_SCAP_POWER_SAVE (1<<11) /* capable for aggresive power-saving */ +#define AC97_SCAP_POWER_SAVE (1<<11) /* capable for aggressive power-saving */ /* ac97->flags */ #define AC97_HAS_PC_BEEP (1<<0) /* force PC Speaker usage */ diff --git a/include/sound/control.h b/include/sound/control.h index e67db2869360..404acb859cee 100644 --- a/include/sound/control.h +++ b/include/sound/control.h @@ -191,7 +191,7 @@ int _snd_ctl_add_slave(struct snd_kcontrol *master, struct snd_kcontrol *slave, * Returns zero if successful or a negative error code. * * All slaves must be the same type (returning the same information - * via info callback). The fucntion doesn't check it, so it's your + * via info callback). The function doesn't check it, so it's your * responsibility. * * Also, some additional limitations: diff --git a/include/sound/cs46xx_dsp_spos.h b/include/sound/cs46xx_dsp_spos.h index 49b03c9e5e55..8008c59288a6 100644 --- a/include/sound/cs46xx_dsp_spos.h +++ b/include/sound/cs46xx_dsp_spos.h @@ -147,7 +147,7 @@ struct dsp_pcm_channel_descriptor { }; struct dsp_spos_instance { - struct dsp_symbol_desc symbol_table; /* currently availble loaded symbols in SP */ + struct dsp_symbol_desc symbol_table; /* currently available loaded symbols in SP */ int nmodules; struct dsp_module_desc * modules; /* modules loaded into SP */ diff --git a/include/sound/hdspm.h b/include/sound/hdspm.h index 1774ff5ff632..1f59ea2a4a76 100644 --- a/include/sound/hdspm.h +++ b/include/sound/hdspm.h @@ -193,7 +193,7 @@ struct hdspm_version { * 32768 Bytes */ -/* organisation is 64 channelfader in a continous memory block */ +/* organisation is 64 channelfader in a continuous memory block */ /* equivalent to hardware definition, maybe for future feature of mmap of * them */ diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index 979ed84e07d6..5534fdf4d670 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -23,7 +23,7 @@ /* * SoC dynamic audio power management * - * We can have upto 4 power domains + * We can have up to 4 power domains * 1. Codec domain - VREF, VMID * Usually controlled at codec probe/remove, although can be set * at stream time if power is not needed for sidetone, etc. diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index c15ed5026fb5..1d3b5b2f0dbc 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -22,7 +22,7 @@ * Note that both include/scsi/scsi_cmnd.h:MAX_COMMAND_SIZE and * include/linux/blkdev.h:BLOCK_MAX_CDB as of v2.6.36-rc4 still use * 16-byte CDBs by default and require an extra allocation for - * 32-byte CDBs to becasue of legacy issues. + * 32-byte CDBs to because of legacy issues. * * Within TCM Core there are no such legacy limitiations, so we go ahead * use 32-byte CDBs by default and use include/scsi/scsi.h:scsi_command_size() @@ -302,7 +302,7 @@ struct t10_wwn { /* - * Used by TCM Core internally to signal if >= SPC-3 peristent reservations + * Used by TCM Core internally to signal if >= SPC-3 persistent reservations * emulation is enabled or disabled, or running in with TCM/pSCSI passthrough * mode */ @@ -934,7 +934,7 @@ struct se_portal_group { struct list_head acl_node_list; struct se_lun *tpg_lun_list; struct se_lun tpg_virt_lun0; - /* List of TCM sessions assoicated wth this TPG */ + /* List of TCM sessions associated wth this TPG */ struct list_head tpg_sess_list; /* Pointer to $FABRIC_MOD dependent code */ struct target_core_fabric_ops *se_tpg_tfo; diff --git a/include/target/target_core_fabric_ops.h b/include/target/target_core_fabric_ops.h index 5eb8b1ae59d1..dc78f77f9450 100644 --- a/include/target/target_core_fabric_ops.h +++ b/include/target/target_core_fabric_ops.h @@ -35,7 +35,7 @@ struct target_core_fabric_ops { /* * Optional function pointer for TCM to perform command map * from TCM processing thread context, for those struct se_cmd - * initally allocated in interrupt context. + * initially allocated in interrupt context. */ int (*new_cmd_map)(struct se_cmd *); /* diff --git a/include/video/kyro.h b/include/video/kyro.h index dba7de2ee4a8..c563968e926c 100644 --- a/include/video/kyro.h +++ b/include/video/kyro.h @@ -32,7 +32,7 @@ struct kyrofb_info { u32 PIXCLK; /* Pixel Clock */ u32 HCLK; /* Hor Clock */ - /* Usefull to hold depth here for Linux */ + /* Useful to hold depth here for Linux */ u8 PIXDEPTH; #ifdef CONFIG_MTRR diff --git a/include/video/neomagic.h b/include/video/neomagic.h index 08b663782956..bc5013e8059d 100644 --- a/include/video/neomagic.h +++ b/include/video/neomagic.h @@ -129,7 +129,7 @@ struct neofb_par { unsigned char CRTC[25]; /* Crtc Controller */ unsigned char Sequencer[5]; /* Video Sequencer */ unsigned char Graphics[9]; /* Video Graphics */ - unsigned char Attribute[21]; /* Video Atribute */ + unsigned char Attribute[21]; /* Video Attribute */ unsigned char GeneralLockReg; unsigned char ExtCRTDispAddr; diff --git a/include/video/newport.h b/include/video/newport.h index 001b935e71c4..3d7c4b492ec6 100644 --- a/include/video/newport.h +++ b/include/video/newport.h @@ -5,7 +5,7 @@ * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * Ulf Carlsson - Compability with the IRIX structures added + * Ulf Carlsson - Compatibility with the IRIX structures added */ #ifndef _SGI_NEWPORT_H diff --git a/include/video/sisfb.h b/include/video/sisfb.h index fdd74f1a6791..6dc5df9e43f3 100644 --- a/include/video/sisfb.h +++ b/include/video/sisfb.h @@ -151,7 +151,7 @@ struct sisfb_cmd { __u32 sisfb_result[4]; }; -/* Addtional IOCTLs for communication sisfb <> X driver */ +/* Additional IOCTLs for communication sisfb <> X driver */ /* If changing this, vgatypes.h must also be changed (for X driver) */ /* ioctl for identifying and giving some info (esp. memory heap start) */ diff --git a/include/video/sstfb.h b/include/video/sstfb.h index b52f07381243..c449eace12cd 100644 --- a/include/video/sstfb.h +++ b/include/video/sstfb.h @@ -156,7 +156,7 @@ #define DAC_READ FBIINIT2 /* in remap mode */ #define FBIINIT3 0x021c /* fbi controls */ # define DISABLE_TEXTURE BIT(6) -# define Y_SWAP_ORIGIN_SHIFT 22 /* Y swap substraction value */ +# define Y_SWAP_ORIGIN_SHIFT 22 /* Y swap subtraction value */ #define HSYNC 0x0220 #define VSYNC 0x0224 #define DAC_DATA 0x022c @@ -212,9 +212,9 @@ # define DACREG_CR0_24BPP 0x50 /* mode 5 */ #define DACREG_CR1_I 0x05 #define DACREG_CC_I 0x06 -# define DACREG_CC_CLKA BIT(7) /* clk A controled by regs */ +# define DACREG_CC_CLKA BIT(7) /* clk A controlled by regs */ # define DACREG_CC_CLKA_C (2<<4) /* clk A uses reg C */ -# define DACREG_CC_CLKB BIT(3) /* clk B controled by regs */ +# define DACREG_CC_CLKB BIT(3) /* clk B controlled by regs */ # define DACREG_CC_CLKB_D 3 /* clkB uses reg D */ #define DACREG_AC0_I 0x48 /* clock A reg C */ #define DACREG_AC1_I 0x49 diff --git a/include/xen/interface/elfnote.h b/include/xen/interface/elfnote.h index 7a8262c375cc..0360b15f4883 100644 --- a/include/xen/interface/elfnote.h +++ b/include/xen/interface/elfnote.h @@ -51,7 +51,7 @@ /* * The offset of the ELF paddr field from the acutal required - * psuedo-physical address (numeric). + * pseudo-physical address (numeric). * * This is used to maintain backwards compatibility with older kernels * which wrote __PAGE_OFFSET into that field. This field defaults to 0 diff --git a/init/do_mounts.c b/init/do_mounts.c index 3e0112157795..c0851a8e030c 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -186,7 +186,7 @@ dev_t name_to_dev_t(char *name) goto done; /* - * try non-existant, but valid partition, which may only exist + * try non-existent, but valid partition, which may only exist * after revalidating the disk, like partitioned md devices */ while (p > s && isdigit(p[-1])) diff --git a/ipc/msg.c b/ipc/msg.c index 0e732e92e22f..7385de25788a 100644 --- a/ipc/msg.c +++ b/ipc/msg.c @@ -704,7 +704,7 @@ long do_msgsnd(int msqid, long mtype, void __user *mtext, msq->q_stime = get_seconds(); if (!pipelined_send(msq, msg)) { - /* noone is waiting for this message, enqueue it */ + /* no one is waiting for this message, enqueue it */ list_add_tail(&msg->m_list, &msq->q_messages); msq->q_cbytes += msgsz; msq->q_qnum++; @@ -842,7 +842,7 @@ long do_msgrcv(int msqid, long *pmtype, void __user *mtext, * Disable preemption. We don't hold a reference to the queue * and getting a reference would defeat the idea of a lockless * operation, thus the code relies on rcu to guarantee the - * existance of msq: + * existence of msq: * Prior to destruction, expunge_all(-EIRDM) changes r_msg. * Thus if r_msg is -EAGAIN, then the queue not yet destroyed. * rcu_read_lock() prevents preemption between reading r_msg diff --git a/ipc/sem.c b/ipc/sem.c index ae040a0727c2..34193ed69fbe 100644 --- a/ipc/sem.c +++ b/ipc/sem.c @@ -1362,7 +1362,7 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops, * semid identifiers are not unique - find_alloc_undo may have * allocated an undo structure, it was invalidated by an RMID * and now a new array with received the same id. Check and fail. - * This case can be detected checking un->semid. The existance of + * This case can be detected checking un->semid. The existence of * "un" itself is guaranteed by rcu. */ error = -EIDRM; diff --git a/ipc/shm.c b/ipc/shm.c index 8644452f5c4c..729acb7e3148 100644 --- a/ipc/shm.c +++ b/ipc/shm.c @@ -1056,7 +1056,7 @@ SYSCALL_DEFINE1(shmdt, char __user *, shmaddr) /* * We need look no further than the maximum address a fragment * could possibly have landed at. Also cast things to loff_t to - * prevent overflows and make comparisions vs. equal-width types. + * prevent overflows and make comparisons vs. equal-width types. */ size = PAGE_ALIGN(size); while (vma && (loff_t)(vma->vm_end - addr) <= size) { diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c index 37b2bea170c8..e99dda04b126 100644 --- a/kernel/audit_tree.c +++ b/kernel/audit_tree.c @@ -607,7 +607,7 @@ void audit_trim_trees(void) spin_lock(&hash_lock); list_for_each_entry(node, &tree->chunks, list) { struct audit_chunk *chunk = find_chunk(node); - /* this could be NULL if the watch is dieing else where... */ + /* this could be NULL if the watch is dying else where... */ struct inode *inode = chunk->mark.i.inode; node->index |= 1U<<31; if (iterate_mounts(compare_root, inode, root_mnt)) diff --git a/kernel/auditsc.c b/kernel/auditsc.c index f49a0318c2ed..b33513a08beb 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -1011,7 +1011,7 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, /* * to_send and len_sent accounting are very loose estimates. We aren't * really worried about a hard cap to MAX_EXECVE_AUDIT_LEN so much as being - * within about 500 bytes (next page boundry) + * within about 500 bytes (next page boundary) * * why snprintf? an int is up to 12 digits long. if we just assumed when * logging that a[%d]= was going to be 16 characters long we would be wasting diff --git a/kernel/cgroup.c b/kernel/cgroup.c index e31b220a743d..25c7eb52de1a 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -157,7 +157,7 @@ struct css_id { }; /* - * cgroup_event represents events which userspace want to recieve. + * cgroup_event represents events which userspace want to receive. */ struct cgroup_event { /* diff --git a/kernel/cpu.c b/kernel/cpu.c index c95fc4df0faa..12b7458f23b1 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -126,7 +126,7 @@ static void cpu_hotplug_done(void) #else /* #if CONFIG_HOTPLUG_CPU */ static void cpu_hotplug_begin(void) {} static void cpu_hotplug_done(void) {} -#endif /* #esle #if CONFIG_HOTPLUG_CPU */ +#endif /* #else #if CONFIG_HOTPLUG_CPU */ /* Need to know about CPUs going up/down? */ int __ref register_cpu_notifier(struct notifier_block *nb) diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c index cefd4a11f6d9..bad6786dee88 100644 --- a/kernel/debug/debug_core.c +++ b/kernel/debug/debug_core.c @@ -538,7 +538,7 @@ return_normal: /* * For single stepping, try to only enter on the processor - * that was single stepping. To gaurd against a deadlock, the + * that was single stepping. To guard against a deadlock, the * kernel will only try for the value of sstep_tries before * giving up and continuing on. */ diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c index 6bc6e3bc4f9c..be14779bcef6 100644 --- a/kernel/debug/kdb/kdb_main.c +++ b/kernel/debug/kdb/kdb_main.c @@ -441,9 +441,9 @@ static int kdb_check_regs(void) * symbol name, and offset to the caller. * * The argument may consist of a numeric value (decimal or - * hexidecimal), a symbol name, a register name (preceeded by the + * hexidecimal), a symbol name, a register name (preceded by the * percent sign), an environment variable with a numeric value - * (preceeded by a dollar sign) or a simple arithmetic expression + * (preceded by a dollar sign) or a simple arithmetic expression * consisting of a symbol name, +/-, and a numeric constant value * (offset). * Parameters: @@ -1335,7 +1335,7 @@ void kdb_print_state(const char *text, int value) * error The hardware-defined error code * reason2 kdb's current reason code. * Initially error but can change - * acording to kdb state. + * according to kdb state. * db_result Result code from break or debug point. * regs The exception frame at time of fault/breakpoint. * should always be valid. diff --git a/kernel/debug/kdb/kdb_support.c b/kernel/debug/kdb/kdb_support.c index 6b2485dcb050..5532dd37aa86 100644 --- a/kernel/debug/kdb/kdb_support.c +++ b/kernel/debug/kdb/kdb_support.c @@ -545,7 +545,7 @@ int kdb_putword(unsigned long addr, unsigned long word, size_t size) * Mask for process state. * Notes: * The mask folds data from several sources into a single long value, so - * be carefull not to overlap the bits. TASK_* bits are in the LSB, + * be careful not to overlap the bits. TASK_* bits are in the LSB, * special cases like UNRUNNABLE are in the MSB. As of 2.6.10-rc1 there * is no overlap between TASK_* and EXIT_* but that may not always be * true, so EXIT_* bits are shifted left 16 bits before being stored in diff --git a/kernel/exit.c b/kernel/exit.c index 6a488ad2dce5..f5d2f63bae0b 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -841,7 +841,7 @@ static void exit_notify(struct task_struct *tsk, int group_dead) /* Let father know we died * * Thread signals are configurable, but you aren't going to use - * that to send signals to arbitary processes. + * that to send signals to arbitrary processes. * That stops right now. * * If the parent exec id doesn't match the exec id we saved diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 1dafc8652bd8..4af1e2b244cb 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -415,7 +415,7 @@ out: * @desc: the interrupt description structure for this irq * * Interrupt occures on the falling and/or rising edge of a hardware - * signal. The occurence is latched into the irq controller hardware + * signal. The occurrence is latched into the irq controller hardware * and must be acked in order to be reenabled. After the ack another * interrupt can happen on the same source even before the first one * is handled by the associated event handler. If this happens it diff --git a/kernel/irq/migration.c b/kernel/irq/migration.c index bc6194698dfd..47420908fba0 100644 --- a/kernel/irq/migration.c +++ b/kernel/irq/migration.c @@ -35,7 +35,7 @@ void irq_move_masked_irq(struct irq_data *idata) * do the disable, re-program, enable sequence. * This is *not* particularly important for level triggered * but in a edge trigger case, we might be setting rte - * when an active trigger is comming in. This could + * when an active trigger is coming in. This could * cause some ioapics to mal-function. * Being paranoid i guess! * diff --git a/kernel/kexec.c b/kernel/kexec.c index ec19b92c7ebd..e7e3d9788dc3 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c @@ -144,7 +144,7 @@ static int do_kimage_alloc(struct kimage **rimage, unsigned long entry, /* Initialize the list of destination pages */ INIT_LIST_HEAD(&image->dest_pages); - /* Initialize the list of unuseable pages */ + /* Initialize the list of unusable pages */ INIT_LIST_HEAD(&image->unuseable_pages); /* Read in the segments */ @@ -454,7 +454,7 @@ static struct page *kimage_alloc_normal_control_pages(struct kimage *image, /* Deal with the destination pages I have inadvertently allocated. * * Ideally I would convert multi-page allocations into single - * page allocations, and add everyting to image->dest_pages. + * page allocations, and add everything to image->dest_pages. * * For now it is simpler to just free the pages. */ @@ -602,7 +602,7 @@ static void kimage_free_extra_pages(struct kimage *image) /* Walk through and free any extra destination pages I may have */ kimage_free_page_list(&image->dest_pages); - /* Walk through and free any unuseable pages I have cached */ + /* Walk through and free any unusable pages I have cached */ kimage_free_page_list(&image->unuseable_pages); } diff --git a/kernel/kthread.c b/kernel/kthread.c index 684ab3f7dd72..3b34d2732bce 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -139,7 +139,7 @@ static void create_kthread(struct kthread_create_info *create) * in @node, to get NUMA affinity for kthread stack, or else give -1. * When woken, the thread will run @threadfn() with @data as its * argument. @threadfn() can either call do_exit() directly if it is a - * standalone thread for which noone will call kthread_stop(), or + * standalone thread for which no one will call kthread_stop(), or * return when 'kthread_should_stop()' is true (which means * kthread_stop() has been called). The return value should be zero * or a negative error number; it will be passed to kthread_stop(). diff --git a/kernel/latencytop.c b/kernel/latencytop.c index ee74b35e528d..376066e10413 100644 --- a/kernel/latencytop.c +++ b/kernel/latencytop.c @@ -153,7 +153,7 @@ static inline void store_stacktrace(struct task_struct *tsk, } /** - * __account_scheduler_latency - record an occured latency + * __account_scheduler_latency - record an occurred latency * @tsk - the task struct of the task hitting the latency * @usecs - the duration of the latency in microseconds * @inter - 1 if the sleep was interruptible, 0 if uninterruptible diff --git a/kernel/lockdep.c b/kernel/lockdep.c index 0d2058da80f5..53a68956f131 100644 --- a/kernel/lockdep.c +++ b/kernel/lockdep.c @@ -2309,7 +2309,7 @@ void trace_hardirqs_on_caller(unsigned long ip) if (unlikely(curr->hardirqs_enabled)) { /* * Neither irq nor preemption are disabled here - * so this is racy by nature but loosing one hit + * so this is racy by nature but losing one hit * in a stat is not a big deal. */ __debug_atomic_inc(redundant_hardirqs_on); @@ -2620,7 +2620,7 @@ static int mark_lock(struct task_struct *curr, struct held_lock *this, if (!graph_lock()) return 0; /* - * Make sure we didnt race: + * Make sure we didn't race: */ if (unlikely(hlock_class(this)->usage_mask & new_mask)) { graph_unlock(); diff --git a/kernel/module.c b/kernel/module.c index 1f9f7bc56ca1..d5938a5c19c4 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -809,7 +809,7 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user, wait_for_zero_refcount(mod); mutex_unlock(&module_mutex); - /* Final destruction now noone is using it. */ + /* Final destruction now no one is using it. */ if (mod->exit != NULL) mod->exit(); blocking_notifier_call_chain(&module_notify_list, @@ -2777,7 +2777,7 @@ static struct module *load_module(void __user *umod, mod->state = MODULE_STATE_COMING; /* Now sew it into the lists so we can get lockdep and oops - * info during argument parsing. Noone should access us, since + * info during argument parsing. No one should access us, since * strong_try_module_get() will fail. * lockdep/oops can run asynchronous, so use the RCU list insertion * function to insert in a way safe to concurrent readers. @@ -2971,7 +2971,7 @@ static const char *get_ksymbol(struct module *mod, else nextval = (unsigned long)mod->module_core+mod->core_text_size; - /* Scan for closest preceeding symbol, and next symbol. (ELF + /* Scan for closest preceding symbol, and next symbol. (ELF starts real symbols at 1). */ for (i = 1; i < mod->num_symtab; i++) { if (mod->symtab[i].st_shndx == SHN_UNDEF) diff --git a/kernel/mutex.c b/kernel/mutex.c index a5889fb28ecf..c4195fa98900 100644 --- a/kernel/mutex.c +++ b/kernel/mutex.c @@ -245,7 +245,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, } __set_task_state(task, state); - /* didnt get the lock, go to sleep: */ + /* didn't get the lock, go to sleep: */ spin_unlock_mutex(&lock->wait_lock, flags); preempt_enable_no_resched(); schedule(); diff --git a/kernel/padata.c b/kernel/padata.c index 751019415d23..b91941df5e63 100644 --- a/kernel/padata.c +++ b/kernel/padata.c @@ -262,7 +262,7 @@ static void padata_reorder(struct parallel_data *pd) /* * This cpu has to do the parallel processing of the next * object. It's waiting in the cpu's parallelization queue, - * so exit imediately. + * so exit immediately. */ if (PTR_ERR(padata) == -ENODATA) { del_timer(&pd->timer); @@ -284,7 +284,7 @@ static void padata_reorder(struct parallel_data *pd) /* * The next object that needs serialization might have arrived to * the reorder queues in the meantime, we will be called again - * from the timer function if noone else cares for it. + * from the timer function if no one else cares for it. */ if (atomic_read(&pd->reorder_objects) && !(pinst->flags & PADATA_RESET)) @@ -515,7 +515,7 @@ static void __padata_stop(struct padata_instance *pinst) put_online_cpus(); } -/* Replace the internal control stucture with a new one. */ +/* Replace the internal control structure with a new one. */ static void padata_replace(struct padata_instance *pinst, struct parallel_data *pd_new) { @@ -768,7 +768,7 @@ static int __padata_remove_cpu(struct padata_instance *pinst, int cpu) } /** - * padata_remove_cpu - remove a cpu from the one or both(serial and paralell) + * padata_remove_cpu - remove a cpu from the one or both(serial and parallel) * padata cpumasks. * * @pinst: padata instance diff --git a/kernel/params.c b/kernel/params.c index 0da1411222b9..7ab388a48a2e 100644 --- a/kernel/params.c +++ b/kernel/params.c @@ -95,7 +95,7 @@ static int parse_one(char *param, /* Find parameter */ for (i = 0; i < num_params; i++) { if (parameq(param, params[i].name)) { - /* Noone handled NULL, so do it here. */ + /* No one handled NULL, so do it here. */ if (!val && params[i].ops->set != param_set_bool) return -EINVAL; DEBUGP("They are equal! Calling %p\n", diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c index 67fea9d25d55..0791b13df7bf 100644 --- a/kernel/posix-cpu-timers.c +++ b/kernel/posix-cpu-timers.c @@ -1347,7 +1347,7 @@ void run_posix_cpu_timers(struct task_struct *tsk) /* * Now that all the timers on our list have the firing flag, - * noone will touch their list entries but us. We'll take + * no one will touch their list entries but us. We'll take * each timer's lock before clearing its firing flag, so no * timer call will interfere. */ diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c index 4c0124919f9a..e5498d7405c3 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c @@ -313,7 +313,7 @@ static void schedule_next_timer(struct k_itimer *timr) * restarted (i.e. we have flagged this in the sys_private entry of the * info block). * - * To protect aginst the timer going away while the interrupt is queued, + * To protect against the timer going away while the interrupt is queued, * we require that the it_requeue_pending flag be set. */ void do_schedule_next_timer(struct siginfo *info) diff --git a/kernel/power/main.c b/kernel/power/main.c index 8eaba5f27b10..de9aef8742f4 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -224,7 +224,7 @@ power_attr(state); * writing to 'state'. It first should read from 'wakeup_count' and store * the read value. Then, after carrying out its own preparations for the system * transition to a sleep state, it should write the stored value to - * 'wakeup_count'. If that fails, at least one wakeup event has occured since + * 'wakeup_count'. If that fails, at least one wakeup event has occurred since * 'wakeup_count' was read and 'state' should not be written to. Otherwise, it * is allowed to write to 'state', but the transition will be aborted if there * are any wakeup events detected after 'wakeup_count' was written to. diff --git a/kernel/sched.c b/kernel/sched.c index f592ce6f8616..865b433fac5b 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2309,7 +2309,7 @@ unsigned long wait_task_inactive(struct task_struct *p, long match_state) * Cause a process which is running on another CPU to enter * kernel-mode, without any delay. (to get signals handled.) * - * NOTE: this function doesnt have to take the runqueue lock, + * NOTE: this function doesn't have to take the runqueue lock, * because all it wants to ensure is that the remote task enters * the kernel. If the IPI races and the task has been migrated * to another CPU then no harm is done and the purpose has been @@ -4997,7 +4997,7 @@ recheck: */ raw_spin_lock_irqsave(&p->pi_lock, flags); /* - * To be able to change p->policy safely, the apropriate + * To be able to change p->policy safely, the appropriate * runqueue lock must be held. */ rq = __task_rq_lock(p); @@ -5705,7 +5705,7 @@ void show_state_filter(unsigned long state_filter) do_each_thread(g, p) { /* * reset the NMI-timeout, listing all files on a slow - * console might take alot of time: + * console might take a lot of time: */ touch_nmi_watchdog(); if (!state_filter || (p->state & state_filter)) diff --git a/kernel/sched_autogroup.c b/kernel/sched_autogroup.c index 5946ac515602..429242f3c484 100644 --- a/kernel/sched_autogroup.c +++ b/kernel/sched_autogroup.c @@ -179,7 +179,7 @@ void sched_autogroup_create_attach(struct task_struct *p) struct autogroup *ag = autogroup_create(); autogroup_move_group(p, ag); - /* drop extra refrence added by autogroup_create() */ + /* drop extra reference added by autogroup_create() */ autogroup_kref_put(ag); } EXPORT_SYMBOL(sched_autogroup_create_attach); diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 3f7ec9e27ee1..3cb7f07887a1 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -3061,7 +3061,7 @@ static inline void calculate_imbalance(struct sd_lb_stats *sds, int this_cpu, /* * if *imbalance is less than the average load per runnable task - * there is no gaurantee that any tasks will be moved so we'll have + * there is no guarantee that any tasks will be moved so we'll have * a think about bumping its value to force at least one task to be * moved */ diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c index db308cb08b75..e7cebdc65f82 100644 --- a/kernel/sched_rt.c +++ b/kernel/sched_rt.c @@ -1378,7 +1378,7 @@ retry: task = pick_next_pushable_task(rq); if (task_cpu(next_task) == rq->cpu && task == next_task) { /* - * If we get here, the task hasnt moved at all, but + * If we get here, the task hasn't moved at all, but * it has failed to push. We will not try again, * since the other cpus will pull from us when they * are ready. @@ -1488,7 +1488,7 @@ static int pull_rt_task(struct rq *this_rq) /* * We continue with the search, just in * case there's an even higher prio task - * in another runqueue. (low likelyhood + * in another runqueue. (low likelihood * but possible) */ } diff --git a/kernel/signal.c b/kernel/signal.c index 1186cf7fac77..f486d10f3b8e 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1885,7 +1885,7 @@ relock: for (;;) { struct k_sigaction *ka; /* - * Tracing can induce an artifical signal and choose sigaction. + * Tracing can induce an artificial signal and choose sigaction. * The return value in @signr determines the default action, * but @info->si_signo is the signal number we will report. */ diff --git a/kernel/softirq.c b/kernel/softirq.c index 735d87095172..174f976c2874 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -567,7 +567,7 @@ static void __tasklet_hrtimer_trampoline(unsigned long data) /** * tasklet_hrtimer_init - Init a tasklet/hrtimer combo for softirq callbacks * @ttimer: tasklet_hrtimer which is initialized - * @function: hrtimer callback funtion which gets called from softirq context + * @function: hrtimer callback function which gets called from softirq context * @which_clock: clock id (CLOCK_MONOTONIC/CLOCK_REALTIME) * @mode: hrtimer mode (HRTIMER_MODE_ABS/HRTIMER_MODE_REL) */ diff --git a/kernel/time/jiffies.c b/kernel/time/jiffies.c index b2fa506667c0..a470154e0408 100644 --- a/kernel/time/jiffies.c +++ b/kernel/time/jiffies.c @@ -34,7 +34,7 @@ * inaccuracies caused by missed or lost timer * interrupts and the inability for the timer * interrupt hardware to accuratly tick at the - * requested HZ value. It is also not reccomended + * requested HZ value. It is also not recommended * for "tick-less" systems. */ #define NSEC_PER_JIFFY ((u32)((((u64)NSEC_PER_SEC)<<8)/ACTHZ)) diff --git a/kernel/time/timer_stats.c b/kernel/time/timer_stats.c index 2f3b585b8d7d..a5d0a3a85dd8 100644 --- a/kernel/time/timer_stats.c +++ b/kernel/time/timer_stats.c @@ -236,7 +236,7 @@ void timer_stats_update_stats(void *timer, pid_t pid, void *startf, unsigned int timer_flag) { /* - * It doesnt matter which lock we take: + * It doesn't matter which lock we take: */ raw_spinlock_t *lock; struct entry *entry, input; diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index c075f4ea6b94..ee24fa1935ac 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -1268,7 +1268,7 @@ static int ftrace_update_code(struct module *mod) p->flags = 0L; /* - * Do the initial record convertion from mcount jump + * Do the initial record conversion from mcount jump * to the NOP instructions. */ if (!ftrace_code_disable(mod, p)) { @@ -3425,7 +3425,7 @@ graph_init_task(struct task_struct *t, struct ftrace_ret_stack *ret_stack) atomic_set(&t->tracing_graph_pause, 0); atomic_set(&t->trace_overrun, 0); t->ftrace_timestamp = 0; - /* make curr_ret_stack visable before we add the ret_stack */ + /* make curr_ret_stack visible before we add the ret_stack */ smp_wmb(); t->ret_stack = ret_stack; } diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index d9c8bcafb120..0ef7b4b2a1f7 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -1478,7 +1478,7 @@ static inline unsigned long rb_page_entries(struct buffer_page *bpage) return local_read(&bpage->entries) & RB_WRITE_MASK; } -/* Size is determined by what has been commited */ +/* Size is determined by what has been committed */ static inline unsigned rb_page_size(struct buffer_page *bpage) { return rb_page_commit(bpage); @@ -2932,7 +2932,7 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer) /* * cpu_buffer->pages just needs to point to the buffer, it * has no specific buffer page to point to. Lets move it out - * of our way so we don't accidently swap it. + * of our way so we don't accidentally swap it. */ cpu_buffer->pages = reader->list.prev; diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 9541c27c1cf2..d38c16a06a6f 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -3239,7 +3239,7 @@ waitagain: trace_seq_init(&iter->seq); /* - * If there was nothing to send to user, inspite of consuming trace + * If there was nothing to send to user, in spite of consuming trace * entries, go back to wait for more entries. */ if (sret == -EBUSY) diff --git a/kernel/trace/trace_clock.c b/kernel/trace/trace_clock.c index 685a67d55db0..6302747a1398 100644 --- a/kernel/trace/trace_clock.c +++ b/kernel/trace/trace_clock.c @@ -46,7 +46,7 @@ u64 notrace trace_clock_local(void) } /* - * trace_clock(): 'inbetween' trace clock. Not completely serialized, + * trace_clock(): 'between' trace clock. Not completely serialized, * but not completely incorrect when crossing CPUs either. * * This is based on cpu_clock(), which will allow at most ~1 jiffy of diff --git a/kernel/trace/trace_entries.h b/kernel/trace/trace_entries.h index 1516cb3ec549..e32744c84d94 100644 --- a/kernel/trace/trace_entries.h +++ b/kernel/trace/trace_entries.h @@ -27,7 +27,7 @@ * in the structure. * * * for structures within structures, the format of the internal - * structure is layed out. This allows the internal structure + * structure is laid out. This allows the internal structure * to be deciphered for the format file. Although these macros * may become out of sync with the internal structure, they * will create a compile error if it happens. Since the diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c index 76b05980225c..962cdb24ed81 100644 --- a/kernel/trace/trace_functions_graph.c +++ b/kernel/trace/trace_functions_graph.c @@ -905,7 +905,7 @@ print_graph_prologue(struct trace_iterator *iter, struct trace_seq *s, * * returns 1 if * - we are inside irq code - * - we just extered irq code + * - we just entered irq code * * retunns 0 if * - funcgraph-interrupts option is set diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c index 92b6e1e12d98..a4969b47afc1 100644 --- a/kernel/trace/trace_irqsoff.c +++ b/kernel/trace/trace_irqsoff.c @@ -80,7 +80,7 @@ static struct tracer_flags tracer_flags = { * skip the latency if the sequence has changed - some other section * did a maximum and could disturb our measurement with serial console * printouts, etc. Truly coinciding maximum latencies should be rare - * and what happens together happens separately as well, so this doesnt + * and what happens together happens separately as well, so this doesn't * decrease the validity of the maximum found: */ static __cacheline_aligned_in_smp unsigned long max_sequence; diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 8435b43b1782..35d55a386145 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -1839,7 +1839,7 @@ static void unregister_probe_event(struct trace_probe *tp) kfree(tp->call.print_fmt); } -/* Make a debugfs interface for controling probe points */ +/* Make a debugfs interface for controlling probe points */ static __init int init_kprobe_trace(void) { struct dentry *d_tracer; diff --git a/kernel/user-return-notifier.c b/kernel/user-return-notifier.c index eb27fd3430a2..92cb706c7fc8 100644 --- a/kernel/user-return-notifier.c +++ b/kernel/user-return-notifier.c @@ -20,7 +20,7 @@ EXPORT_SYMBOL_GPL(user_return_notifier_register); /* * Removes a registered user return notifier. Must be called from atomic - * context, and from the same cpu registration occured in. + * context, and from the same cpu registration occurred in. */ void user_return_notifier_unregister(struct user_return_notifier *urn) { diff --git a/kernel/wait.c b/kernel/wait.c index b0310eb6cc1e..f45ea8d2a1ce 100644 --- a/kernel/wait.c +++ b/kernel/wait.c @@ -142,7 +142,7 @@ EXPORT_SYMBOL(finish_wait); * woken up through the queue. * * This prevents waiter starvation where an exclusive waiter - * aborts and is woken up concurrently and noone wakes up + * aborts and is woken up concurrently and no one wakes up * the next waiter. */ void abort_exclusive_wait(wait_queue_head_t *q, wait_queue_t *wait, diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 04ef830690ec..8859a41806dd 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -1291,7 +1291,7 @@ __acquires(&gcwq->lock) return true; spin_unlock_irq(&gcwq->lock); - /* CPU has come up inbetween, retry migration */ + /* CPU has come up in between, retry migration */ cpu_relax(); } } diff --git a/lib/bitmap.c b/lib/bitmap.c index 741fae905ae3..91e0ccfdb424 100644 --- a/lib/bitmap.c +++ b/lib/bitmap.c @@ -830,7 +830,7 @@ EXPORT_SYMBOL(bitmap_bitremap); * @orig (i.e. bits 3, 5, 7 and 9) were also set. * * When bit 11 is set in @orig, it means turn on the bit in - * @dst corresponding to whatever is the twelth bit that is + * @dst corresponding to whatever is the twelfth bit that is * turned on in @relmap. In the above example, there were * only ten bits turned on in @relmap (30..39), so that bit * 11 was set in @orig had no affect on @dst. diff --git a/lib/btree.c b/lib/btree.c index c9c6f0351526..2a34392bcecc 100644 --- a/lib/btree.c +++ b/lib/btree.c @@ -11,7 +11,7 @@ * see http://programming.kicks-ass.net/kernel-patches/vma_lookup/btree.patch * * A relatively simple B+Tree implementation. I have written it as a learning - * excercise to understand how B+Trees work. Turned out to be useful as well. + * exercise to understand how B+Trees work. Turned out to be useful as well. * * B+Trees can be used similar to Linux radix trees (which don't have anything * in common with textbook radix trees, beware). Prerequisite for them working @@ -541,7 +541,7 @@ static void rebalance(struct btree_head *head, struct btree_geo *geo, int i, no_left, no_right; if (fill == 0) { - /* Because we don't steal entries from a neigbour, this case + /* Because we don't steal entries from a neighbour, this case * can happen. Parent node contains a single child, this * node, so merging with a sibling never happens. */ diff --git a/lib/decompress_unxz.c b/lib/decompress_unxz.c index cecd23df2b9a..9f34eb56854d 100644 --- a/lib/decompress_unxz.c +++ b/lib/decompress_unxz.c @@ -83,7 +83,7 @@ * safety_margin = 128 + uncompressed_size * 8 / 32768 + 65536 * = 128 + (uncompressed_size >> 12) + 65536 * - * For comparision, according to arch/x86/boot/compressed/misc.c, the + * For comparison, according to arch/x86/boot/compressed/misc.c, the * equivalent formula for Deflate is this: * * safety_margin = 18 + (uncompressed_size >> 12) + 32768 diff --git a/lib/parser.c b/lib/parser.c index 6e89eca5cca0..dcbaaef6cf11 100644 --- a/lib/parser.c +++ b/lib/parser.c @@ -13,7 +13,7 @@ /** * match_one: - Determines if a string matches a simple pattern - * @s: the string to examine for presense of the pattern + * @s: the string to examine for presence of the pattern * @p: the string containing the pattern * @args: array of %MAX_OPT_ARGS &substring_t elements. Used to return match * locations. diff --git a/lib/timerqueue.c b/lib/timerqueue.c index e3a1050e6820..191176a43e9a 100644 --- a/lib/timerqueue.c +++ b/lib/timerqueue.c @@ -5,7 +5,7 @@ * Uses rbtrees for quick list adds and expiration. * * NOTE: All of the following functions need to be serialized - * to avoid races. No locking is done by this libary code. + * to avoid races. No locking is done by this library code. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/mm/backing-dev.c b/mm/backing-dev.c index 0d9a036ada66..befc87531e4f 100644 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c @@ -787,7 +787,7 @@ EXPORT_SYMBOL(congestion_wait); * jiffies for either a BDI to exit congestion of the given @sync queue * or a write to complete. * - * In the absense of zone congestion, cond_resched() is called to yield + * In the absence of zone congestion, cond_resched() is called to yield * the processor if necessary but otherwise does not sleep. * * The return value is 0 if the sleep is for the full timeout. Otherwise, diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 06de5aa4d644..8ee3bd8ec5b5 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -146,7 +146,7 @@ static long region_chg(struct list_head *head, long f, long t) if (rg->from > t) return chg; - /* We overlap with this area, if it extends futher than + /* We overlap with this area, if it extends further than * us then we must extend ourselves. Account for its * existing reservation. */ if (rg->to > t) { @@ -842,7 +842,7 @@ struct page *alloc_huge_page_node(struct hstate *h, int nid) } /* - * Increase the hugetlb pool such that it can accomodate a reservation + * Increase the hugetlb pool such that it can accommodate a reservation * of size 'delta'. */ static int gather_surplus_pages(struct hstate *h, int delta) @@ -890,7 +890,7 @@ retry: /* * The surplus_list now contains _at_least_ the number of extra pages - * needed to accomodate the reservation. Add the appropriate number + * needed to accommodate the reservation. Add the appropriate number * of pages to the hugetlb pool and free the extras back to the buddy * allocator. Commit the entire reservation here to prevent another * process from stealing the pages as they are added to the pool but @@ -2043,7 +2043,7 @@ static void hugetlb_vm_op_open(struct vm_area_struct *vma) * This new VMA should share its siblings reservation map if present. * The VMA will only ever have a valid reservation map pointer where * it is being copied for another still existing VMA. As that VMA - * has a reference to the reservation map it cannot dissappear until + * has a reference to the reservation map it cannot disappear until * after this open call completes. It is therefore safe to take a * new reference here without additional locking. */ @@ -2490,7 +2490,7 @@ static int hugetlb_no_page(struct mm_struct *mm, struct vm_area_struct *vma, /* * Currently, we are forced to kill the process in the event the * original mapper has unmapped pages from the child due to a failed - * COW. Warn that such a situation has occured as it may not be obvious + * COW. Warn that such a situation has occurred as it may not be obvious */ if (is_vma_resv_set(vma, HPAGE_RESV_UNMAPPED)) { printk(KERN_WARNING diff --git a/mm/hwpoison-inject.c b/mm/hwpoison-inject.c index 0948f1072d6b..c7fc7fd00e32 100644 --- a/mm/hwpoison-inject.c +++ b/mm/hwpoison-inject.c @@ -1,4 +1,4 @@ -/* Inject a hwpoison memory failure on a arbitary pfn */ +/* Inject a hwpoison memory failure on a arbitrary pfn */ #include #include #include diff --git a/mm/internal.h b/mm/internal.h index 3438dd43a062..9d0ced8e505e 100644 --- a/mm/internal.h +++ b/mm/internal.h @@ -162,7 +162,7 @@ static inline struct page *mem_map_offset(struct page *base, int offset) } /* - * Iterator over all subpages withing the maximally aligned gigantic + * Iterator over all subpages within the maximally aligned gigantic * page 'base'. Handle any discontiguity in the mem_map. */ static inline struct page *mem_map_next(struct page *iter, diff --git a/mm/kmemleak.c b/mm/kmemleak.c index 84225f3b7190..c1d5867543e4 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c @@ -265,7 +265,7 @@ static void kmemleak_disable(void); } while (0) /* - * Macro invoked when a serious kmemleak condition occured and cannot be + * Macro invoked when a serious kmemleak condition occurred and cannot be * recovered from. Kmemleak will be disabled and further allocation/freeing * tracing no longer available. */ @@ -1006,7 +1006,7 @@ static bool update_checksum(struct kmemleak_object *object) /* * Memory scanning is a long process and it needs to be interruptable. This - * function checks whether such interrupt condition occured. + * function checks whether such interrupt condition occurred. */ static int scan_should_stop(void) { @@ -1733,7 +1733,7 @@ static int __init kmemleak_late_init(void) if (atomic_read(&kmemleak_error)) { /* - * Some error occured and kmemleak was disabled. There is a + * Some error occurred and kmemleak was disabled. There is a * small chance that kmemleak_disable() was called immediately * after setting kmemleak_initialized and we may end up with * two clean-up threads but serialized by scan_mutex. diff --git a/mm/ksm.c b/mm/ksm.c index 1bbe785aa559..942dfc73a2ff 100644 --- a/mm/ksm.c +++ b/mm/ksm.c @@ -720,7 +720,7 @@ static int write_protect_page(struct vm_area_struct *vma, struct page *page, swapped = PageSwapCache(page); flush_cache_page(vma, addr, page_to_pfn(page)); /* - * Ok this is tricky, when get_user_pages_fast() run it doesnt + * Ok this is tricky, when get_user_pages_fast() run it doesn't * take any lock, therefore the check that we are going to make * with the pagecount against the mapcount is racey and * O_DIRECT can happen right after the check. diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 1f0b460fe58c..010f9166fa6e 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -1466,7 +1466,7 @@ static int mem_cgroup_hierarchical_reclaim(struct mem_cgroup *root_mem, break; } /* - * We want to do more targetted reclaim. + * We want to do more targeted reclaim. * excess >> 2 is not to excessive so as to * reclaim too much, nor too less that we keep * coming back to reclaim from this cgroup @@ -2265,7 +2265,7 @@ void mem_cgroup_split_huge_fixup(struct page *head, struct page *tail) * - compound_lock is held when nr_pages > 1 * * This function doesn't do "charge" nor css_get to new cgroup. It should be - * done by a caller(__mem_cgroup_try_charge would be usefull). If @uncharge is + * done by a caller(__mem_cgroup_try_charge would be useful). If @uncharge is * true, this function does "uncharge" from old cgroup, but it doesn't if * @uncharge is false, so a caller should do "uncharge". */ @@ -2318,7 +2318,7 @@ static int mem_cgroup_move_account(struct page *page, * We charges against "to" which may not have any tasks. Then, "to" * can be under rmdir(). But in current implementation, caller of * this function is just force_empty() and move charge, so it's - * garanteed that "to" is never removed. So, we don't check rmdir + * guaranteed that "to" is never removed. So, we don't check rmdir * status here. */ move_unlock_page_cgroup(pc, &flags); @@ -2648,7 +2648,7 @@ static void mem_cgroup_do_uncharge(struct mem_cgroup *mem, batch->memcg = mem; /* * do_batch > 0 when unmapping pages or inode invalidate/truncate. - * In those cases, all pages freed continously can be expected to be in + * In those cases, all pages freed continuously can be expected to be in * the same cgroup and we have chance to coalesce uncharges. * But we do uncharge one by one if this is killed by OOM(TIF_MEMDIE) * because we want to do uncharge as soon as possible. diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 37feb9fec228..2b9a5eef39e0 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -208,7 +208,7 @@ static int kill_proc_ao(struct task_struct *t, unsigned long addr, int trapno, * Don't use force here, it's convenient if the signal * can be temporarily blocked. * This could cause a loop when the user sets SIGBUS - * to SIG_IGN, but hopefully noone will do that? + * to SIG_IGN, but hopefully no one will do that? */ ret = send_sig_info(SIGBUS, &si, t); /* synchronous? */ if (ret < 0) @@ -634,7 +634,7 @@ static int me_pagecache_dirty(struct page *p, unsigned long pfn) * when the page is reread or dropped. If an * application assumes it will always get error on * fsync, but does other operations on the fd before - * and the page is dropped inbetween then the error + * and the page is dropped between then the error * will not be properly reported. * * This can already happen even without hwpoisoned @@ -728,7 +728,7 @@ static int me_huge_page(struct page *p, unsigned long pfn) * The table matches them in order and calls the right handler. * * This is quite tricky because we can access page at any time - * in its live cycle, so all accesses have to be extremly careful. + * in its live cycle, so all accesses have to be extremely careful. * * This is not complete. More states could be added. * For any missing state don't attempt recovery. diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 321fc7455df7..a2acaf820fe5 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -724,7 +724,7 @@ do_migrate_range(unsigned long start_pfn, unsigned long end_pfn) pfn); dump_page(page); #endif - /* Becasue we don't have big zone->lock. we should + /* Because we don't have big zone->lock. we should check this again here. */ if (page_count(page)) { not_managed++; diff --git a/mm/migrate.c b/mm/migrate.c index b0406d739ea7..34132f8e9109 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -375,7 +375,7 @@ void migrate_page_copy(struct page *newpage, struct page *page) * redo the accounting that clear_page_dirty_for_io undid, * but we can't use set_page_dirty because that function * is actually a signal that all of the page has become dirty. - * Wheras only part of our page may be dirty. + * Whereas only part of our page may be dirty. */ __set_page_dirty_nobuffers(newpage); } diff --git a/mm/nobootmem.c b/mm/nobootmem.c index e99f6cd1da1f..9109049f0bbc 100644 --- a/mm/nobootmem.c +++ b/mm/nobootmem.c @@ -150,7 +150,7 @@ unsigned long __init free_all_bootmem(void) { /* * We need to use MAX_NUMNODES instead of NODE_DATA(0)->node_id - * because in some case like Node0 doesnt have RAM installed + * because in some case like Node0 doesn't have RAM installed * low ram will be on Node1 * Use MAX_NUMNODES will make sure all ranges in early_node_map[] * will be used instead of only Node0 related diff --git a/mm/page_alloc.c b/mm/page_alloc.c index d6e7ba7373be..2747f5e5abc1 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -942,7 +942,7 @@ __rmqueue_fallback(struct zone *zone, int order, int start_migratetype) * If breaking a large block of pages, move all free * pages to the preferred allocation list. If falling * back for a reclaimable kernel allocation, be more - * agressive about taking ownership of free pages + * aggressive about taking ownership of free pages */ if (unlikely(current_order >= (pageblock_order >> 1)) || start_migratetype == MIGRATE_RECLAIMABLE || @@ -3926,7 +3926,7 @@ static void __init find_usable_zone_for_movable(void) /* * The zone ranges provided by the architecture do not include ZONE_MOVABLE - * because it is sized independant of architecture. Unlike the other zones, + * because it is sized independent of architecture. Unlike the other zones, * the starting point for ZONE_MOVABLE is not fixed. It may be different * in each node depending on the size of each node and how evenly kernelcore * is distributed. This helper function adjusts the zone ranges diff --git a/mm/page_cgroup.c b/mm/page_cgroup.c index a12cc3fa9859..99055010cece 100644 --- a/mm/page_cgroup.c +++ b/mm/page_cgroup.c @@ -377,7 +377,7 @@ not_enough_page: * @new: new id * * Returns old id at success, 0 at failure. - * (There is no mem_cgroup useing 0 as its id) + * (There is no mem_cgroup using 0 as its id) */ unsigned short swap_cgroup_cmpxchg(swp_entry_t ent, unsigned short old, unsigned short new) diff --git a/mm/percpu.c b/mm/percpu.c index 55d4d113fbd3..a160db39b810 100644 --- a/mm/percpu.c +++ b/mm/percpu.c @@ -342,7 +342,7 @@ static void pcpu_chunk_relocate(struct pcpu_chunk *chunk, int oslot) * @chunk: chunk of interest * * Determine whether area map of @chunk needs to be extended to - * accomodate a new allocation. + * accommodate a new allocation. * * CONTEXT: * pcpu_lock. @@ -431,7 +431,7 @@ out_unlock: * depending on @head, is reduced by @tail bytes and @tail byte block * is inserted after the target block. * - * @chunk->map must have enough free slots to accomodate the split. + * @chunk->map must have enough free slots to accommodate the split. * * CONTEXT: * pcpu_lock. @@ -1435,7 +1435,7 @@ static struct pcpu_alloc_info * __init pcpu_build_alloc_info( /* * Determine min_unit_size, alloc_size and max_upa such that * alloc_size is multiple of atom_size and is the smallest - * which can accomodate 4k aligned segments which are equal to + * which can accommodate 4k aligned segments which are equal to * or larger than min_unit_size. */ min_unit_size = max_t(size_t, size_sum, PCPU_MIN_UNIT_SIZE); @@ -1550,7 +1550,7 @@ static struct pcpu_alloc_info * __init pcpu_build_alloc_info( * @atom_size: allocation atom size * @cpu_distance_fn: callback to determine distance between cpus, optional * @alloc_fn: function to allocate percpu page - * @free_fn: funtion to free percpu page + * @free_fn: function to free percpu page * * This is a helper to ease setting up embedded first percpu chunk and * can be called where pcpu_setup_first_chunk() is expected. @@ -1678,7 +1678,7 @@ out_free: * pcpu_page_first_chunk - map the first chunk using PAGE_SIZE pages * @reserved_size: the size of reserved percpu area in bytes * @alloc_fn: function to allocate percpu page, always called with PAGE_SIZE - * @free_fn: funtion to free percpu page, always called with PAGE_SIZE + * @free_fn: function to free percpu page, always called with PAGE_SIZE * @populate_pte_fn: function to populate pte * * This is a helper to ease setting up page-remapped first percpu diff --git a/mm/slab.c b/mm/slab.c index 568803f121a8..46a9c163a92f 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -878,7 +878,7 @@ static struct array_cache *alloc_arraycache(int node, int entries, nc = kmalloc_node(memsize, gfp, node); /* * The array_cache structures contain pointers to free object. - * However, when such objects are allocated or transfered to another + * However, when such objects are allocated or transferred to another * cache the pointers are not cleared and they could be counted as * valid references during a kmemleak scan. Therefore, kmemleak must * not scan such objects. @@ -2606,7 +2606,7 @@ EXPORT_SYMBOL(kmem_cache_shrink); * * The cache must be empty before calling this function. * - * The caller must guarantee that noone will allocate memory from the cache + * The caller must guarantee that no one will allocate memory from the cache * during the kmem_cache_destroy(). */ void kmem_cache_destroy(struct kmem_cache *cachep) diff --git a/mm/slub.c b/mm/slub.c index f881874843a5..94d2a33a866e 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -64,7 +64,7 @@ * we must stay away from it for a while since we may cause a bouncing * cacheline if we try to acquire the lock. So go onto the next slab. * If all pages are busy then we may allocate a new slab instead of reusing - * a partial slab. A new slab has noone operating on it and thus there is + * a partial slab. A new slab has no one operating on it and thus there is * no danger of cacheline contention. * * Interrupts are disabled during allocation and deallocation in order to @@ -1929,7 +1929,7 @@ redo: else { #ifdef CONFIG_CMPXCHG_LOCAL /* - * The cmpxchg will only match if there was no additonal + * The cmpxchg will only match if there was no additional * operation and if we are on the right processor. * * The cmpxchg does the following atomically (without lock semantics!) @@ -3547,7 +3547,7 @@ void *__kmalloc_track_caller(size_t size, gfp_t gfpflags, unsigned long caller) ret = slab_alloc(s, gfpflags, NUMA_NO_NODE, caller); - /* Honor the call site pointer we recieved. */ + /* Honor the call site pointer we received. */ trace_kmalloc(caller, ret, size, s->size, gfpflags); return ret; @@ -3577,7 +3577,7 @@ void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags, ret = slab_alloc(s, gfpflags, node, caller); - /* Honor the call site pointer we recieved. */ + /* Honor the call site pointer we received. */ trace_kmalloc_node(caller, ret, size, s->size, gfpflags, node); return ret; diff --git a/mm/sparse.c b/mm/sparse.c index 93250207c5cf..aa64b12831a2 100644 --- a/mm/sparse.c +++ b/mm/sparse.c @@ -500,7 +500,7 @@ void __init sparse_init(void) * so alloc 2M (with 2M align) and 24 bytes in turn will * make next 2M slip to one more 2M later. * then in big system, the memory will have a lot of holes... - * here try to allocate 2M pages continously. + * here try to allocate 2M pages continuously. * * powerpc need to call sparse_init_one_section right after each * sparse_early_mem_map_alloc, so allocate usemap_map at first. diff --git a/mm/util.c b/mm/util.c index f126975ef23e..e7b103a6fd21 100644 --- a/mm/util.c +++ b/mm/util.c @@ -227,7 +227,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm) /* * Like get_user_pages_fast() except its IRQ-safe in that it won't fall * back to the regular GUP. - * If the architecture not support this fucntion, simply return with no + * If the architecture not support this function, simply return with no * page pinned */ int __attribute__((weak)) __get_user_pages_fast(unsigned long start, diff --git a/mm/vmscan.c b/mm/vmscan.c index f73b8657c2d0..c7f5a6d4b75b 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1065,7 +1065,7 @@ static unsigned long isolate_lru_pages(unsigned long nr_to_scan, * surrounding the tag page. Only take those pages of * the same active state as that tag page. We may safely * round the target page pfn down to the requested order - * as the mem_map is guarenteed valid out to MAX_ORDER, + * as the mem_map is guaranteed valid out to MAX_ORDER, * where that page is in a different zone we will detect * it from its zone id and abort this block scan. */ @@ -2224,7 +2224,7 @@ unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem_cont, * o a 16M DMA zone that is balanced will not balance a zone on any * reasonable sized machine * o On all other machines, the top zone must be at least a reasonable - * precentage of the middle zones. For example, on 32-bit x86, highmem + * percentage of the middle zones. For example, on 32-bit x86, highmem * would need to be at least 256M for it to be balance a whole node. * Similarly, on x86-64 the Normal zone would need to be at least 1G * to balance a node on its own. These seemed like reasonable ratios. diff --git a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c index d1314cf18adf..d940c49d168a 100644 --- a/net/8021q/vlanproc.c +++ b/net/8021q/vlanproc.c @@ -54,7 +54,7 @@ static const char name_conf[] = "config"; /* * Structures for interfacing with the /proc filesystem. - * VLAN creates its own directory /proc/net/vlan with the folowing + * VLAN creates its own directory /proc/net/vlan with the following * entries: * config device status/configuration * entry for each device diff --git a/net/9p/client.c b/net/9p/client.c index 2ccbf04d37df..48b8e084e710 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -178,7 +178,7 @@ free_and_return: * @tag: numeric id for transaction * * this is a simple array lookup, but will grow the - * request_slots as necessary to accomodate transaction + * request_slots as necessary to accommodate transaction * ids which did not previously have a slot. * * this code relies on the client spinlock to manage locks, its diff --git a/net/9p/trans_common.c b/net/9p/trans_common.c index 9172ab78fcb0..d47880e971dd 100644 --- a/net/9p/trans_common.c +++ b/net/9p/trans_common.c @@ -36,7 +36,7 @@ p9_release_req_pages(struct trans_rpage_info *rpinfo) EXPORT_SYMBOL(p9_release_req_pages); /** - * p9_nr_pages - Return number of pages needed to accomodate the payload. + * p9_nr_pages - Return number of pages needed to accommodate the payload. */ int p9_nr_pages(struct p9_req_t *req) @@ -55,7 +55,7 @@ EXPORT_SYMBOL(p9_nr_pages); * @req: Request to be sent to server. * @pdata_off: data offset into the first page after translation (gup). * @pdata_len: Total length of the IO. gup may not return requested # of pages. - * @nr_pages: number of pages to accomodate the payload + * @nr_pages: number of pages to accommodate the payload * @rw: Indicates if the pages are for read or write. */ int diff --git a/net/9p/util.c b/net/9p/util.c index b84619b5ba22..da6af81e59d9 100644 --- a/net/9p/util.c +++ b/net/9p/util.c @@ -67,7 +67,7 @@ EXPORT_SYMBOL(p9_idpool_create); /** * p9_idpool_destroy - create a new per-connection id pool - * @p: idpool to destory + * @p: idpool to destroy */ void p9_idpool_destroy(struct p9_idpool *p) diff --git a/net/atm/br2684.c b/net/atm/br2684.c index fce2eae8d476..2252c2085dac 100644 --- a/net/atm/br2684.c +++ b/net/atm/br2684.c @@ -509,7 +509,7 @@ static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg) write_lock_irq(&devs_lock); net_dev = br2684_find_dev(&be.ifspec); if (net_dev == NULL) { - pr_err("tried to attach to non-existant device\n"); + pr_err("tried to attach to non-existent device\n"); err = -ENXIO; goto error; } diff --git a/net/atm/lec.h b/net/atm/lec.h index 9d14d196cc1d..dfc071966463 100644 --- a/net/atm/lec.h +++ b/net/atm/lec.h @@ -35,7 +35,7 @@ struct lecdatahdr_8025 { * Operations that LANE2 capable device can do. Two first functions * are used to make the device do things. See spec 3.1.3 and 3.1.4. * - * The third function is intented for the MPOA component sitting on + * The third function is intended for the MPOA component sitting on * top of the LANE device. The MPOA component assigns it's own function * to (*associate_indicator)() and the LANE device will use that * function to tell about TLVs it sees floating through. diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 9ed26140a269..824e1f6e50f2 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -474,7 +474,7 @@ void interface_rx(struct net_device *soft_iface, goto dropped; skb->protocol = eth_type_trans(skb, soft_iface); - /* should not be neccesary anymore as we use skb_pull_rcsum() + /* should not be necessary anymore as we use skb_pull_rcsum() * TODO: please verify this and remove this TODO * -- Dec 21st 2009, Simon Wunderlich */ diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index b372fb8bcdcf..42d5ff02cb59 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1877,7 +1877,7 @@ static void hci_tx_task(unsigned long arg) read_unlock(&hci_task_lock); } -/* ----- HCI RX task (incoming data proccessing) ----- */ +/* ----- HCI RX task (incoming data processing) ----- */ /* ACL data packet */ static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index fc85e7ae33c7..36b9c5d0ebe3 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -679,7 +679,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch if (opt == BT_FLUSHABLE_OFF) { struct l2cap_conn *conn = l2cap_pi(sk)->conn; - /* proceed futher only when we have l2cap_conn and + /* proceed further only when we have l2cap_conn and No Flush support in the LM */ if (!conn || !lmp_no_flush_capable(conn->hcon->hdev)) { err = -EINVAL; diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c index 88485cc74dc3..cc4d3c5ab1c6 100644 --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c @@ -169,7 +169,7 @@ void br_fdb_flush(struct net_bridge *br) spin_unlock_bh(&br->hash_lock); } -/* Flush all entries refering to a specific port. +/* Flush all entries referring to a specific port. * if do_all is set also flush static entries */ void br_fdb_delete_by_port(struct net_bridge *br, diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c index cb43312b846e..3d9fca0e3370 100644 --- a/net/bridge/br_ioctl.c +++ b/net/bridge/br_ioctl.c @@ -106,7 +106,7 @@ static int add_del_if(struct net_bridge *br, int ifindex, int isadd) /* * Legacy ioctl's through SIOCDEVPRIVATE * This interface is deprecated because it was too difficult to - * to do the translation for 32/64bit ioctl compatability. + * to do the translation for 32/64bit ioctl compatibility. */ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c index 8184c031d028..37a4034dfc29 100644 --- a/net/caif/caif_socket.c +++ b/net/caif/caif_socket.c @@ -852,7 +852,7 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr, sock->state = SS_CONNECTING; sk->sk_state = CAIF_CONNECTING; - /* Check priority value comming from socket */ + /* Check priority value coming from socket */ /* if priority value is out of range it will be ajusted */ if (cf_sk->sk.sk_priority > CAIF_PRIO_MAX) cf_sk->conn_req.priority = CAIF_PRIO_MAX; diff --git a/net/can/bcm.c b/net/can/bcm.c index 871a0ad51025..57b1aed79014 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c @@ -387,7 +387,7 @@ static void bcm_tx_timeout_tsklet(unsigned long data) } /* - * bcm_tx_timeout_handler - performes cyclic CAN frame transmissions + * bcm_tx_timeout_handler - performs cyclic CAN frame transmissions */ static enum hrtimer_restart bcm_tx_timeout_handler(struct hrtimer *hrtimer) { diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index 02212ed50852..8d4ee7e01793 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c @@ -917,7 +917,7 @@ EXPORT_SYMBOL(ceph_osdc_set_request_linger); /* * Pick an osd (the first 'up' osd in the pg), allocate the osd struct * (as needed), and set the request r_osd appropriately. If there is - * no up osd, set r_osd to NULL. Move the request to the appropiate list + * no up osd, set r_osd to NULL. Move the request to the appropriate list * (unsent, homeless) or leave on in-flight lru. * * Return 0 if unchanged, 1 if changed, or negative on error. diff --git a/net/core/dev.c b/net/core/dev.c index 563ddc28139d..56c3e00098c0 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2071,7 +2071,7 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, u32 features; /* - * If device doesnt need skb->dst, release it right now while + * If device doesn't need skb->dst, release it right now while * its hot in this cpu cache */ if (dev->priv_flags & IFF_XMIT_DST_RELEASE) @@ -2131,7 +2131,7 @@ gso: nskb->next = NULL; /* - * If device doesnt need nskb->dst, release it right now while + * If device doesn't need nskb->dst, release it right now while * its hot in this cpu cache */ if (dev->priv_flags & IFF_XMIT_DST_RELEASE) @@ -2950,8 +2950,8 @@ EXPORT_SYMBOL_GPL(br_fdb_test_addr_hook); * when CONFIG_NET_CLS_ACT is? otherwise some useless instructions * a compare and 2 stores extra right now if we dont have it on * but have CONFIG_NET_CLS_ACT - * NOTE: This doesnt stop any functionality; if you dont have - * the ingress scheduler, you just cant add policies on ingress. + * NOTE: This doesn't stop any functionality; if you dont have + * the ingress scheduler, you just can't add policies on ingress. * */ static int ing_filter(struct sk_buff *skb, struct netdev_queue *rxq) @@ -3780,7 +3780,7 @@ static void net_rx_action(struct softirq_action *h) * with netpoll's poll_napi(). Only the entity which * obtains the lock and sees NAPI_STATE_SCHED set will * actually make the ->poll() call. Therefore we avoid - * accidently calling ->poll() when NAPI is not scheduled. + * accidentally calling ->poll() when NAPI is not scheduled. */ work = 0; if (test_bit(NAPI_STATE_SCHED, &n->state)) { @@ -6316,7 +6316,7 @@ static void __net_exit default_device_exit(struct net *net) if (dev->rtnl_link_ops) continue; - /* Push remaing network devices to init_net */ + /* Push remaining network devices to init_net */ snprintf(fb_name, IFNAMSIZ, "dev%d", dev->ifindex); err = dev_change_net_namespace(dev, &init_net, fb_name); if (err) { diff --git a/net/core/filter.c b/net/core/filter.c index 232b1873bb28..afb8afb066bb 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -425,7 +425,7 @@ EXPORT_SYMBOL(sk_run_filter); * As we dont want to clear mem[] array for each packet going through * sk_run_filter(), we check that filter loaded by user never try to read * a cell if not previously written, and we check all branches to be sure - * a malicious user doesnt try to abuse us. + * a malicious user doesn't try to abuse us. */ static int check_load_and_stores(struct sock_filter *filter, int flen) { diff --git a/net/core/link_watch.c b/net/core/link_watch.c index 01a1101b5936..a7b342131869 100644 --- a/net/core/link_watch.c +++ b/net/core/link_watch.c @@ -129,7 +129,7 @@ static void linkwatch_schedule_work(int urgent) if (!cancel_delayed_work(&linkwatch_work)) return; - /* Otherwise we reschedule it again for immediate exection. */ + /* Otherwise we reschedule it again for immediate execution. */ schedule_delayed_work(&linkwatch_work, 0); } diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 49f7ea5b4c75..d7c4bb4b1820 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -196,7 +196,7 @@ EXPORT_SYMBOL_GPL(__rtnl_register); * as failure of this function is very unlikely, it can only happen due * to lack of memory when allocating the chain to store all message * handlers for a protocol. Meant for use in init functions where lack - * of memory implies no sense in continueing. + * of memory implies no sense in continuing. */ void rtnl_register(int protocol, int msgtype, rtnl_doit_func doit, rtnl_dumpit_func dumpit) @@ -1440,7 +1440,7 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, errout: if (err < 0 && modified && net_ratelimit()) printk(KERN_WARNING "A link change request failed with " - "some changes comitted already. Interface %s may " + "some changes committed already. Interface %s may " "have been left with an inconsistent configuration, " "please check.\n", dev->name); diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 801dd08908f9..7ebeed0a877c 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -2267,7 +2267,7 @@ EXPORT_SYMBOL(skb_prepare_seq_read); * of bytes already consumed and the next call to * skb_seq_read() will return the remaining part of the block. * - * Note 1: The size of each block of data returned can be arbitary, + * Note 1: The size of each block of data returned can be arbitrary, * this limitation is the cost for zerocopy seqeuental * reads of potentially non linear data. * diff --git a/net/core/sock.c b/net/core/sock.c index 7dfed792434d..6e819780c232 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -215,7 +215,7 @@ __u32 sysctl_rmem_max __read_mostly = SK_RMEM_MAX; __u32 sysctl_wmem_default __read_mostly = SK_WMEM_MAX; __u32 sysctl_rmem_default __read_mostly = SK_RMEM_MAX; -/* Maximal space eaten by iovec or ancilliary data plus some space */ +/* Maximal space eaten by iovec or ancillary data plus some space */ int sysctl_optmem_max __read_mostly = sizeof(unsigned long)*(2*UIO_MAXIOV+512); EXPORT_SYMBOL(sysctl_optmem_max); @@ -1175,7 +1175,7 @@ static void __sk_free(struct sock *sk) void sk_free(struct sock *sk) { /* - * We substract one from sk_wmem_alloc and can know if + * We subtract one from sk_wmem_alloc and can know if * some packets are still in some tx queue. * If not null, sock_wfree() will call __sk_free(sk) later */ @@ -1185,10 +1185,10 @@ void sk_free(struct sock *sk) EXPORT_SYMBOL(sk_free); /* - * Last sock_put should drop referrence to sk->sk_net. It has already - * been dropped in sk_change_net. Taking referrence to stopping namespace + * Last sock_put should drop reference to sk->sk_net. It has already + * been dropped in sk_change_net. Taking reference to stopping namespace * is not an option. - * Take referrence to a socket to remove it from hash _alive_ and after that + * Take reference to a socket to remove it from hash _alive_ and after that * destroy it in the context of init_net. */ void sk_release_kernel(struct sock *sk) diff --git a/net/dccp/output.c b/net/dccp/output.c index 784d30210543..136d41cbcd02 100644 --- a/net/dccp/output.c +++ b/net/dccp/output.c @@ -143,7 +143,7 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb) } /** - * dccp_determine_ccmps - Find out about CCID-specfic packet-size limits + * dccp_determine_ccmps - Find out about CCID-specific packet-size limits * We only consider the HC-sender CCID for setting the CCMPS (RFC 4340, 14.), * since the RX CCID is restricted to feedback packets (Acks), which are small * in comparison with the data traffic. A value of 0 means "no current CCMPS". diff --git a/net/dsa/mv88e6131.c b/net/dsa/mv88e6131.c index bb2b41bc854e..d951f93644bf 100644 --- a/net/dsa/mv88e6131.c +++ b/net/dsa/mv88e6131.c @@ -124,7 +124,7 @@ static int mv88e6131_setup_global(struct dsa_switch *ds) * Ignore removed tag data on doubly tagged packets, disable * flow control messages, force flow control priority to the * highest, and send all special multicast frames to the CPU - * port at the higest priority. + * port at the highest priority. */ REG_WRITE(REG_GLOBAL2, 0x05, 0x00ff); diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index 094e150c6260..a0af7ea87870 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c @@ -112,7 +112,7 @@ int cipso_v4_rbm_strictvalid = 1; /* The maximum number of category ranges permitted in the ranged category tag * (tag #5). You may note that the IETF draft states that the maximum number * of category ranges is 7, but if the low end of the last category range is - * zero then it is possibile to fit 8 category ranges because the zero should + * zero then it is possible to fit 8 category ranges because the zero should * be omitted. */ #define CIPSO_V4_TAG_RNG_CAT_MAX 8 @@ -438,7 +438,7 @@ cache_add_failure: * * Description: * Search the DOI definition list for a DOI definition with a DOI value that - * matches @doi. The caller is responsibile for calling rcu_read_[un]lock(). + * matches @doi. The caller is responsible for calling rcu_read_[un]lock(). * Returns a pointer to the DOI definition on success and NULL on failure. */ static struct cipso_v4_doi *cipso_v4_doi_search(u32 doi) @@ -1293,7 +1293,7 @@ static int cipso_v4_gentag_rbm(const struct cipso_v4_doi *doi_def, return ret_val; /* This will send packets using the "optimized" format when - * possibile as specified in section 3.4.2.6 of the + * possible as specified in section 3.4.2.6 of the * CIPSO draft. */ if (cipso_v4_rbm_optfmt && ret_val > 0 && ret_val <= 10) tag_len = 14; @@ -1752,7 +1752,7 @@ validate_return: } /** - * cipso_v4_error - Send the correct reponse for a bad packet + * cipso_v4_error - Send the correct response for a bad packet * @skb: the packet * @error: the error code * @gateway: CIPSO gateway flag diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index b92c86f6e9b3..e9013d6c1f51 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -12,7 +12,7 @@ * * Hans Liss Uppsala Universitet * - * This work is based on the LPC-trie which is originally descibed in: + * This work is based on the LPC-trie which is originally described in: * * An experimental study of compression methods for dynamic tries * Stefan Nilsson and Matti Tikkanen. Algorithmica, 33(1):19-33, 2002. diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index a91dc1611081..e5f8a71d3a2a 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -704,7 +704,7 @@ static void icmp_unreach(struct sk_buff *skb) */ /* - * Check the other end isnt violating RFC 1122. Some routers send + * Check the other end isn't violating RFC 1122. Some routers send * bogus responses to broadcast frames. If you see this message * first check your netmask matches at both ends, if it does then * get the other vendor to fix their kit. diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 67f241b97649..459c011b1d4a 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -603,7 +603,7 @@ slow_path: /* IF: it doesn't fit, use 'mtu' - the data space left */ if (len > mtu) len = mtu; - /* IF: we are not sending upto and including the packet end + /* IF: we are not sending up to and including the packet end then align the next start on an eight byte boundary */ if (len < left) { len &= ~7; diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index 2b097752426b..cbff2ecccf3d 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c @@ -1444,7 +1444,7 @@ static int __init ip_auto_config(void) root_server_addr = addr; /* - * Use defaults whereever applicable. + * Use defaults wherever applicable. */ if (ic_defaults() < 0) return -1; diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 4b5d457c2d76..89bc7e66d598 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -76,7 +76,7 @@ static inline int arp_devaddr_compare(const struct arpt_devaddr_info *ap, } /* - * Unfortunatly, _b and _mask are not aligned to an int (or long int) + * Unfortunately, _b and _mask are not aligned to an int (or long int) * Some arches dont care, unrolling the loop is a win on them. * For other arches, we only have a 16bit alignement. */ @@ -1874,7 +1874,7 @@ static int __init arp_tables_init(void) if (ret < 0) goto err1; - /* Noone else will be downing sem now, so we won't sleep */ + /* No one else will be downing sem now, so we won't sleep */ ret = xt_register_targets(arpt_builtin_tg, ARRAY_SIZE(arpt_builtin_tg)); if (ret < 0) goto err2; diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index ffcea0d1678e..704915028009 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -2233,7 +2233,7 @@ static int __init ip_tables_init(void) if (ret < 0) goto err1; - /* Noone else will be downing sem now, so we won't sleep */ + /* No one else will be downing sem now, so we won't sleep */ ret = xt_register_targets(ipt_builtin_tg, ARRAY_SIZE(ipt_builtin_tg)); if (ret < 0) goto err2; diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c index 21bcf471b25a..9c71b2755ce3 100644 --- a/net/ipv4/netfilter/nf_nat_core.c +++ b/net/ipv4/netfilter/nf_nat_core.c @@ -521,7 +521,7 @@ int nf_nat_protocol_register(const struct nf_nat_protocol *proto) } EXPORT_SYMBOL(nf_nat_protocol_register); -/* Noone stores the protocol anywhere; simply delete it. */ +/* No one stores the protocol anywhere; simply delete it. */ void nf_nat_protocol_unregister(const struct nf_nat_protocol *proto) { spin_lock_bh(&nf_nat_lock); @@ -532,7 +532,7 @@ void nf_nat_protocol_unregister(const struct nf_nat_protocol *proto) } EXPORT_SYMBOL(nf_nat_protocol_unregister); -/* Noone using conntrack by the time this called. */ +/* No one using conntrack by the time this called. */ static void nf_nat_cleanup_conntrack(struct nf_conn *ct) { struct nf_conn_nat *nat = nf_ct_ext_find(ct, NF_CT_EXT_NAT); diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 2d3c72e5bbbf..bceaec42c37d 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -622,7 +622,7 @@ do_confirm: static void raw_close(struct sock *sk, long timeout) { /* - * Raw sockets may have direct kernel refereneces. Kill them. + * Raw sockets may have direct kernel references. Kill them. */ ip_ra_control(sk, 0, NULL); diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 4b0c81180804..ea107515c53e 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -821,7 +821,7 @@ static int has_noalias(const struct rtable *head, const struct rtable *rth) } /* - * Pertubation of rt_genid by a small quantity [1..256] + * Perturbation of rt_genid by a small quantity [1..256] * Using 8 bits of shuffling ensure we can call rt_cache_invalidate() * many times (2^24) without giving recent rt_genid. * Jenkins hash is strong enough that litle changes of rt_genid are OK. @@ -1191,7 +1191,7 @@ restart: #endif /* * Since lookup is lockfree, we must make sure - * previous writes to rt are comitted to memory + * previous writes to rt are committed to memory * before making rt visible to other CPUS. */ rcu_assign_pointer(rt_hash_table[hash].chain, rt); diff --git a/net/ipv4/tcp_lp.c b/net/ipv4/tcp_lp.c index 656d431c99ad..72f7218b03f5 100644 --- a/net/ipv4/tcp_lp.c +++ b/net/ipv4/tcp_lp.c @@ -12,7 +12,7 @@ * within cong_avoid. * o Error correcting in remote HZ, therefore remote HZ will be keeped * on checking and updating. - * o Handling calculation of One-Way-Delay (OWD) within rtt_sample, sicne + * o Handling calculation of One-Way-Delay (OWD) within rtt_sample, since * OWD have a similar meaning as RTT. Also correct the buggy formular. * o Handle reaction for Early Congestion Indication (ECI) within * pkts_acked, as mentioned within pseudo code. diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index dfa5beb0c1c8..64f30eca1c67 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -73,7 +73,7 @@ static void tcp_event_new_data_sent(struct sock *sk, struct sk_buff *skb) tcp_advance_send_head(sk, skb); tp->snd_nxt = TCP_SKB_CB(skb)->end_seq; - /* Don't override Nagle indefinately with F-RTO */ + /* Don't override Nagle indefinitely with F-RTO */ if (tp->frto_counter == 2) tp->frto_counter = 3; diff --git a/net/ipv4/tcp_yeah.c b/net/ipv4/tcp_yeah.c index dc7f43179c9a..05c3b6f0e8e1 100644 --- a/net/ipv4/tcp_yeah.c +++ b/net/ipv4/tcp_yeah.c @@ -20,7 +20,7 @@ #define TCP_YEAH_DELTA 3 //log minimum fraction of cwnd to be removed on loss #define TCP_YEAH_EPSILON 1 //log maximum fraction to be removed on early decongestion #define TCP_YEAH_PHY 8 //lin maximum delta from base -#define TCP_YEAH_RHO 16 //lin minumum number of consecutive rtt to consider competition on loss +#define TCP_YEAH_RHO 16 //lin minimum number of consecutive rtt to consider competition on loss #define TCP_YEAH_ZETA 50 //lin minimum number of state switchs to reset reno_count #define TCP_SCALABLE_AI_CNT 100U diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 588f47af5faf..f87a8eb76f3b 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -189,7 +189,7 @@ static int udp_lib_lport_inuse2(struct net *net, __u16 num, * @sk: socket struct in question * @snum: port number to look up * @saddr_comp: AF-dependent comparison of bound local IP addresses - * @hash2_nulladdr: AF-dependant hash value in secondary hash chains, + * @hash2_nulladdr: AF-dependent hash value in secondary hash chains, * with NULL address */ int udp_lib_get_port(struct sock *sk, unsigned short snum, diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 3daaf3c7703c..1493534116df 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -1084,7 +1084,7 @@ static int ipv6_get_saddr_eval(struct net *net, case IPV6_SADDR_RULE_PRIVACY: { /* Rule 7: Prefer public address - * Note: prefer temprary address if use_tempaddr >= 2 + * Note: prefer temporary address if use_tempaddr >= 2 */ int preftmp = dst->prefs & (IPV6_PREFER_SRC_PUBLIC|IPV6_PREFER_SRC_TMP) ? !!(dst->prefs & IPV6_PREFER_SRC_TMP) : @@ -1968,7 +1968,7 @@ ok: * to the stored lifetime since we'll * be updating the timestamp below, * else we'll set it back to the - * minumum. + * minimum. */ if (prefered_lft != ifp->prefered_lft) { valid_lft = stored_lft; diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 4b13d5d8890e..afcc7099f96d 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -1113,7 +1113,7 @@ static int __init inet6_init(void) /* * ipngwg API draft makes clear that the correct semantics * for TCP and UDP is to consider one TCP and UDP instance - * in a host availiable by both INET and INET6 APIs and + * in a host available by both INET and INET6 APIs and * able to communicate via both network protocols. */ diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 18208876aa8a..46cf7bea6769 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -779,7 +779,7 @@ slow_path: /* IF: it doesn't fit, use 'mtu' - the data space left */ if (len > mtu) len = mtu; - /* IF: we are not sending upto and including the packet end + /* IF: we are not sending up to and including the packet end then align the next start on an eight byte boundary */ if (len < left) { len &= ~7; diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 0b2af9b85cec..5a1c6f27ffaf 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -2248,7 +2248,7 @@ static int __init ip6_tables_init(void) if (ret < 0) goto err1; - /* Noone else will be downing sem now, so we won't sleep */ + /* No one else will be downing sem now, so we won't sleep */ ret = xt_register_targets(ip6t_builtin_tg, ARRAY_SIZE(ip6t_builtin_tg)); if (ret < 0) goto err2; diff --git a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c index 97c5b21b9674..cdd6d045e42e 100644 --- a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c +++ b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c @@ -71,7 +71,7 @@ static unsigned int ipv6_defrag(unsigned int hooknum, if (reasm == NULL) return NF_STOLEN; - /* error occured or not fragmented */ + /* error occurred or not fragmented */ if (reasm == skb) return NF_ACCEPT; diff --git a/net/irda/irlap.c b/net/irda/irlap.c index 783c5f367d29..005b424494a0 100644 --- a/net/irda/irlap.c +++ b/net/irda/irlap.c @@ -165,7 +165,7 @@ struct irlap_cb *irlap_open(struct net_device *dev, struct qos_info *qos, irlap_apply_default_connection_parameters(self); - self->N3 = 3; /* # connections attemts to try before giving up */ + self->N3 = 3; /* # connections attempts to try before giving up */ self->state = LAP_NDM; diff --git a/net/irda/irlap_event.c b/net/irda/irlap_event.c index d434c8880745..bb47021c9a55 100644 --- a/net/irda/irlap_event.c +++ b/net/irda/irlap_event.c @@ -708,7 +708,7 @@ static int irlap_state_reply(struct irlap_cb *self, IRLAP_EVENT event, self->frame_sent = TRUE; } - /* Readjust our timer to accomodate devices + /* Readjust our timer to accommodate devices * doing faster or slower discovery than us... * Jean II */ irlap_start_query_timer(self, info->S, info->s); @@ -931,7 +931,7 @@ static int irlap_state_setup(struct irlap_cb *self, IRLAP_EVENT event, irlap_send_rr_frame(self, CMD_FRAME); /* The timer is set to half the normal timer to quickly - * detect a failure to negociate the new connection + * detect a failure to negotiate the new connection * parameters. IrLAP 6.11.3.2, note 3. * Note that currently we don't process this failure * properly, as we should do a quick disconnect. @@ -1052,7 +1052,7 @@ static int irlap_state_xmit_p(struct irlap_cb *self, IRLAP_EVENT event, return -EPROTO; } - /* Substract space used by this skb */ + /* Subtract space used by this skb */ self->bytes_left -= skb->len; #else /* CONFIG_IRDA_DYNAMIC_WINDOW */ /* Window has been adjusted for the max packet @@ -1808,7 +1808,7 @@ static int irlap_state_xmit_s(struct irlap_cb *self, IRLAP_EVENT event, return -EPROTO; /* Try again later */ } - /* Substract space used by this skb */ + /* Subtract space used by this skb */ self->bytes_left -= skb->len; #else /* CONFIG_IRDA_DYNAMIC_WINDOW */ /* Window has been adjusted for the max packet diff --git a/net/irda/irlap_frame.c b/net/irda/irlap_frame.c index 688222cbf55b..8c004161a843 100644 --- a/net/irda/irlap_frame.c +++ b/net/irda/irlap_frame.c @@ -848,7 +848,7 @@ void irlap_send_data_primary_poll(struct irlap_cb *self, struct sk_buff *skb) * though IrLAP is currently sending the *last* frame of the * tx-window, the driver most likely has only just started * sending the *first* frame of the same tx-window. - * I.e. we are always at the very begining of or Tx window. + * I.e. we are always at the very beginning of or Tx window. * Now, we are supposed to set the final timer from the end * of our tx-window to let the other peer reply. So, we need * to add extra time to compensate for the fact that we diff --git a/net/irda/irlmp_event.c b/net/irda/irlmp_event.c index c1fb5db81042..9505a7d06f1a 100644 --- a/net/irda/irlmp_event.c +++ b/net/irda/irlmp_event.c @@ -498,7 +498,7 @@ static int irlmp_state_disconnected(struct lsap_cb *self, IRLMP_EVENT event, switch (event) { #ifdef CONFIG_IRDA_ULTRA case LM_UDATA_INDICATION: - /* This is most bizzare. Those packets are aka unreliable + /* This is most bizarre. Those packets are aka unreliable * connected, aka IrLPT or SOCK_DGRAM/IRDAPROTO_UNITDATA. * Why do we pass them as Ultra ??? Jean II */ irlmp_connless_data_indication(self, skb); diff --git a/net/irda/irnet/irnet.h b/net/irda/irnet/irnet.h index 0d82ff5aeff1..979ecb2435a7 100644 --- a/net/irda/irnet/irnet.h +++ b/net/irda/irnet/irnet.h @@ -73,7 +73,7 @@ * Infinite thanks to those brave souls for providing the infrastructure * upon which IrNET is built. * - * Thanks to all my collegues in HP for helping me. In particular, + * Thanks to all my colleagues in HP for helping me. In particular, * thanks to Salil Pradhan and Bill Serra for W2k testing... * Thanks to Luiz Magalhaes for irnetd and much testing... * diff --git a/net/irda/irqueue.c b/net/irda/irqueue.c index 849aaf0dabb5..9715e6e5900b 100644 --- a/net/irda/irqueue.c +++ b/net/irda/irqueue.c @@ -40,7 +40,7 @@ * o the hash function for ints is pathetic (but could be changed) * o locking is sometime suspicious (especially during enumeration) * o most users have only a few elements (== overhead) - * o most users never use seach, so don't benefit from hashing + * o most users never use search, so don't benefit from hashing * Problem already fixed : * o not 64 bit compliant (most users do hashv = (int) self) * o hashbin_remove() is broken => use hashbin_remove_this() diff --git a/net/irda/irttp.c b/net/irda/irttp.c index f6054f9ccbe3..9d9af4606970 100644 --- a/net/irda/irttp.c +++ b/net/irda/irttp.c @@ -1193,7 +1193,7 @@ EXPORT_SYMBOL(irttp_connect_request); /* * Function irttp_connect_confirm (handle, qos, skb) * - * Sevice user confirms TSAP connection with peer. + * Service user confirms TSAP connection with peer. * */ static void irttp_connect_confirm(void *instance, void *sap, diff --git a/net/irda/qos.c b/net/irda/qos.c index 2b00974e5bae..1b51bcf42394 100644 --- a/net/irda/qos.c +++ b/net/irda/qos.c @@ -39,16 +39,16 @@ #include /* - * Maximum values of the baud rate we negociate with the other end. + * Maximum values of the baud rate we negotiate with the other end. * Most often, you don't have to change that, because Linux-IrDA will * use the maximum offered by the link layer, which usually works fine. * In some very rare cases, you may want to limit it to lower speeds... */ int sysctl_max_baud_rate = 16000000; /* - * Maximum value of the lap disconnect timer we negociate with the other end. + * Maximum value of the lap disconnect timer we negotiate with the other end. * Most often, the value below represent the best compromise, but some user - * may want to keep the LAP alive longuer or shorter in case of link failure. + * may want to keep the LAP alive longer or shorter in case of link failure. * Remember that the threshold time (early warning) is fixed to 3s... */ int sysctl_max_noreply_time = 12; @@ -411,7 +411,7 @@ static void irlap_adjust_qos_settings(struct qos_info *qos) * Fix tx data size according to user limits - Jean II */ if (qos->data_size.value > sysctl_max_tx_data_size) - /* Allow non discrete adjustement to avoid loosing capacity */ + /* Allow non discrete adjustement to avoid losing capacity */ qos->data_size.value = sysctl_max_tx_data_size; /* * Override Tx window if user request it. - Jean II diff --git a/net/irda/timer.c b/net/irda/timer.c index 0335ba0cc593..f418cb2ad49c 100644 --- a/net/irda/timer.c +++ b/net/irda/timer.c @@ -59,7 +59,7 @@ void irlap_start_query_timer(struct irlap_cb *self, int S, int s) * slot time, plus add some extra time to properly receive the last * discovery packet (which is longer due to extra discovery info), * to avoid messing with for incomming connections requests and - * to accomodate devices that perform discovery slower than us. + * to accommodate devices that perform discovery slower than us. * Jean II */ timeout = ((sysctl_slot_timeout * HZ / 1000) * (S - s) + XIDEXTRA_TIMEOUT + SMALLBUSY_TIMEOUT); diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index 9637e45744fa..986b2a5e8769 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c @@ -250,7 +250,7 @@ static struct device *af_iucv_dev; * PRMDATA[0..6] socket data (max 7 bytes); * PRMDATA[7] socket data length value (len is 0xff - PRMDATA[7]) * - * The socket data length is computed by substracting the socket data length + * The socket data length is computed by subtracting the socket data length * value from 0xFF. * If the socket data len is greater 7, then PRMDATA can be used for special * notifications (see iucv_sock_shutdown); and further, diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c index 1ee5dab3cfae..8f156bd86be7 100644 --- a/net/iucv/iucv.c +++ b/net/iucv/iucv.c @@ -735,7 +735,7 @@ static void iucv_cleanup_queue(void) struct iucv_irq_list *p, *n; /* - * When a path is severed, the pathid can be reused immediatly + * When a path is severed, the pathid can be reused immediately * on a iucv connect or a connection pending interrupt. Remove * all entries from the task queue that refer to a stale pathid * (iucv_path_table[ix] == NULL). Only then do the iucv connect @@ -807,7 +807,7 @@ void iucv_unregister(struct iucv_handler *handler, int smp) spin_lock_bh(&iucv_table_lock); /* Remove handler from the iucv_handler_list. */ list_del_init(&handler->list); - /* Sever all pathids still refering to the handler. */ + /* Sever all pathids still referring to the handler. */ list_for_each_entry_safe(p, n, &handler->paths, list) { iucv_sever_pathid(p->pathid, NULL); iucv_path_table[p->pathid] = NULL; diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index a40401701424..c18396c248d7 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -97,7 +97,7 @@ struct ieee80211_bss { size_t supp_rates_len; /* - * During assocation, we save an ERP value from a probe response so + * During association, we save an ERP value from a probe response so * that we can feed ERP info to the driver when handling the * association completes. these fields probably won't be up-to-date * otherwise, you probably don't want to use them. diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 8d65b47d9837..336ca9d0c5c4 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -628,7 +628,7 @@ void mesh_path_discard_frame(struct sk_buff *skb, * * @mpath: mesh path whose queue has to be freed * - * Locking: the function must me called withing a rcu_read_lock region + * Locking: the function must me called within a rcu_read_lock region */ void mesh_path_flush_pending(struct mesh_path *mpath) { diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index 8212a8bebf06..78e67d22dc1f 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -259,7 +259,7 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) } } - /* try to sample up to half of the availble rates during each interval */ + /* try to sample up to half of the available rates during each interval */ mi->sample_count *= 4; cur_prob = 0; diff --git a/net/mac80211/rc80211_pid.h b/net/mac80211/rc80211_pid.h index 6510f8ee738e..19111c7bf454 100644 --- a/net/mac80211/rc80211_pid.h +++ b/net/mac80211/rc80211_pid.h @@ -77,7 +77,7 @@ union rc_pid_event_data { }; struct rc_pid_event { - /* The time when the event occured */ + /* The time when the event occurred */ unsigned long timestamp; /* Event ID number */ diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 5c1930ba8ebe..c50b68423c7b 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -381,7 +381,7 @@ static void ieee80211_parse_qos(struct ieee80211_rx_data *rx) * specs were sane enough this time around to require padding each A-MSDU * subframe to a length that is a multiple of four. * - * Padding like Atheros hardware adds which is inbetween the 802.11 header and + * Padding like Atheros hardware adds which is between the 802.11 header and * the payload is not supported, the driver is required to move the 802.11 * header to be directly in front of the payload in that case. */ diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index d0311a322ddd..13e8c30adf01 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -47,9 +47,9 @@ * Station entries are added by mac80211 when you establish a link with a * peer. This means different things for the different type of interfaces * we support. For a regular station this mean we add the AP sta when we - * receive an assocation response from the AP. For IBSS this occurs when + * receive an association response from the AP. For IBSS this occurs when * get to know about a peer on the same IBSS. For WDS we add the sta for - * the peer imediately upon device open. When using AP mode we add stations + * the peer immediately upon device open. When using AP mode we add stations * for each respective station upon request from userspace through nl80211. * * In order to remove a STA info structure, various sta_info_destroy_*() diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 57681149e37f..b2f95966c7f4 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -173,7 +173,7 @@ struct sta_ampdu_mlme { /** * enum plink_state - state of a mesh peer link finite state machine * - * @PLINK_LISTEN: initial state, considered the implicit state of non existant + * @PLINK_LISTEN: initial state, considered the implicit state of non existent * mesh peer links * @PLINK_OPN_SNT: mesh plink open frame has been sent to this mesh peer * @PLINK_OPN_RCVD: mesh plink open frame has been received from this mesh peer diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c index d6b48230a540..253326e8d990 100644 --- a/net/netfilter/ipset/ip_set_core.c +++ b/net/netfilter/ipset/ip_set_core.c @@ -893,7 +893,7 @@ ip_set_swap(struct sock *ctnl, struct sk_buff *skb, to = ip_set_list[to_id]; /* Features must not change. - * Not an artifical restriction anymore, as we must prevent + * Not an artificial restriction anymore, as we must prevent * possible loops created by swapping in setlist type of sets. */ if (!(from->type->features == to->type->features && from->type->family == to->type->family)) diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c index f289306cbf12..c97bd45975be 100644 --- a/net/netfilter/ipvs/ip_vs_conn.c +++ b/net/netfilter/ipvs/ip_vs_conn.c @@ -595,7 +595,7 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest) atomic_inc(&dest->inactconns); } else { /* It is a persistent connection/template, so increase - the peristent connection counter */ + the persistent connection counter */ atomic_inc(&dest->persistconns); } @@ -657,7 +657,7 @@ static inline void ip_vs_unbind_dest(struct ip_vs_conn *cp) } } else { /* It is a persistent connection/template, so decrease - the peristent connection counter */ + the persistent connection counter */ atomic_dec(&dest->persistconns); } diff --git a/net/netfilter/ipvs/ip_vs_lblc.c b/net/netfilter/ipvs/ip_vs_lblc.c index f276df9896b3..87e40ea77a95 100644 --- a/net/netfilter/ipvs/ip_vs_lblc.c +++ b/net/netfilter/ipvs/ip_vs_lblc.c @@ -131,7 +131,7 @@ static inline void ip_vs_lblc_free(struct ip_vs_lblc_entry *en) { list_del(&en->list); /* - * We don't kfree dest because it is refered either by its service + * We don't kfree dest because it is referred either by its service * or the trash dest list. */ atomic_dec(&en->dest->refcnt); diff --git a/net/netfilter/ipvs/ip_vs_lblcr.c b/net/netfilter/ipvs/ip_vs_lblcr.c index cb1c9913d38b..90f618ab6dda 100644 --- a/net/netfilter/ipvs/ip_vs_lblcr.c +++ b/net/netfilter/ipvs/ip_vs_lblcr.c @@ -152,7 +152,7 @@ static void ip_vs_dest_set_eraseall(struct ip_vs_dest_set *set) write_lock(&set->lock); list_for_each_entry_safe(e, ep, &set->list, list) { /* - * We don't kfree dest because it is refered either + * We don't kfree dest because it is referred either * by its service or by the trash dest list. */ atomic_dec(&e->dest->refcnt); diff --git a/net/netfilter/ipvs/ip_vs_proto_sctp.c b/net/netfilter/ipvs/ip_vs_proto_sctp.c index b027ccc49f43..d12ed53ec95f 100644 --- a/net/netfilter/ipvs/ip_vs_proto_sctp.c +++ b/net/netfilter/ipvs/ip_vs_proto_sctp.c @@ -566,7 +566,7 @@ static struct ipvs_sctp_nextstate * SHUTDOWN sent from the client, waitinf for SHUT ACK from the server */ /* - * We recieved the data chuck, keep the state unchanged. I assume + * We received the data chuck, keep the state unchanged. I assume * that still data chuncks can be received by both the peers in * SHUDOWN state */ @@ -633,7 +633,7 @@ static struct ipvs_sctp_nextstate * SHUTDOWN sent from the server, waitinf for SHUTDOWN ACK from client */ /* - * We recieved the data chuck, keep the state unchanged. I assume + * We received the data chuck, keep the state unchanged. I assume * that still data chuncks can be received by both the peers in * SHUDOWN state */ @@ -701,7 +701,7 @@ static struct ipvs_sctp_nextstate * SHUTDOWN ACK from the client, awaiting for SHUTDOWN COM from server */ /* - * We recieved the data chuck, keep the state unchanged. I assume + * We received the data chuck, keep the state unchanged. I assume * that still data chuncks can be received by both the peers in * SHUDOWN state */ @@ -771,7 +771,7 @@ static struct ipvs_sctp_nextstate * SHUTDOWN ACK from the server, awaiting for SHUTDOWN COM from client */ /* - * We recieved the data chuck, keep the state unchanged. I assume + * We received the data chuck, keep the state unchanged. I assume * that still data chuncks can be received by both the peers in * SHUDOWN state */ diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 941286ca911d..2e1c11f78419 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -453,7 +453,7 @@ __nf_conntrack_confirm(struct sk_buff *skb) REJECT will give spurious warnings here. */ /* NF_CT_ASSERT(atomic_read(&ct->ct_general.use) == 1); */ - /* No external references means noone else could have + /* No external references means no one else could have confirmed us. */ NF_CT_ASSERT(!nf_ct_is_confirmed(ct)); pr_debug("Confirming conntrack %p\n", ct); @@ -901,7 +901,7 @@ nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum, ret = l3proto->get_l4proto(skb, skb_network_offset(skb), &dataoff, &protonum); if (ret <= 0) { - pr_debug("not prepared to track yet or error occured\n"); + pr_debug("not prepared to track yet or error occurred\n"); NF_CT_STAT_INC_ATOMIC(net, error); NF_CT_STAT_INC_ATOMIC(net, invalid); ret = -ret; diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c index 9ae57c57c50e..2e664a69d7db 100644 --- a/net/netfilter/nf_conntrack_proto_dccp.c +++ b/net/netfilter/nf_conntrack_proto_dccp.c @@ -98,7 +98,7 @@ static const char * const dccp_state_names[] = { #define sIV CT_DCCP_INVALID /* - * DCCP state transistion table + * DCCP state transition table * * The assumption is the same as for TCP tracking: * diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c index 6f4ee70f460b..6772b1154654 100644 --- a/net/netfilter/nf_conntrack_proto_sctp.c +++ b/net/netfilter/nf_conntrack_proto_sctp.c @@ -107,9 +107,9 @@ static const u8 sctp_conntracks[2][9][SCTP_CONNTRACK_MAX] = { /* abort */ {sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL}, /* shutdown */ {sCL, sCL, sCW, sCE, sSS, sSS, sSR, sSA}, /* shutdown_ack */ {sSA, sCL, sCW, sCE, sES, sSA, sSA, sSA}, -/* error */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Cant have Stale cookie*/ +/* error */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Can't have Stale cookie*/ /* cookie_echo */ {sCL, sCL, sCE, sCE, sES, sSS, sSR, sSA},/* 5.2.4 - Big TODO */ -/* cookie_ack */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Cant come in orig dir */ +/* cookie_ack */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Can't come in orig dir */ /* shutdown_comp*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sCL} }, { @@ -121,7 +121,7 @@ static const u8 sctp_conntracks[2][9][SCTP_CONNTRACK_MAX] = { /* shutdown */ {sIV, sCL, sCW, sCE, sSR, sSS, sSR, sSA}, /* shutdown_ack */ {sIV, sCL, sCW, sCE, sES, sSA, sSA, sSA}, /* error */ {sIV, sCL, sCW, sCL, sES, sSS, sSR, sSA}, -/* cookie_echo */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Cant come in reply dir */ +/* cookie_echo */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Can't come in reply dir */ /* cookie_ack */ {sIV, sCL, sCW, sES, sES, sSS, sSR, sSA}, /* shutdown_comp*/ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sCL} } diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index bcf47eb518ef..237cc1981b89 100644 --- a/net/netfilter/nf_conntrack_sip.c +++ b/net/netfilter/nf_conntrack_sip.c @@ -707,7 +707,7 @@ static const char *ct_sdp_header_search(const char *dptr, const char *limit, } /* Locate a SDP header (optionally a substring within the header value), - * optionally stopping at the first occurence of the term header, parse + * optionally stopping at the first occurrence of the term header, parse * it and return the offset and length of the data we're interested in. */ int ct_sip_get_sdp_header(const struct nf_conn *ct, const char *dptr, diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c index 5ab22e2bbd7d..5b466cd1272f 100644 --- a/net/netfilter/nf_queue.c +++ b/net/netfilter/nf_queue.c @@ -134,7 +134,7 @@ static int __nf_queue(struct sk_buff *skb, const struct nf_afinfo *afinfo; const struct nf_queue_handler *qh; - /* QUEUE == DROP if noone is waiting, to be safe. */ + /* QUEUE == DROP if no one is waiting, to be safe. */ rcu_read_lock(); qh = rcu_dereference(queue_handler[pf]); diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c index d37b7f80fa37..de0d8e4cbfb6 100644 --- a/net/netlabel/netlabel_domainhash.c +++ b/net/netlabel/netlabel_domainhash.c @@ -109,7 +109,7 @@ static void netlbl_domhsh_free_entry(struct rcu_head *entry) * * Description: * This is the hashing function for the domain hash table, it returns the - * correct bucket number for the domain. The caller is responsibile for + * correct bucket number for the domain. The caller is responsible for * ensuring that the hash table is protected with either a RCU read lock or the * hash table lock. * @@ -134,7 +134,7 @@ static u32 netlbl_domhsh_hash(const char *key) * * Description: * Searches the domain hash table and returns a pointer to the hash table - * entry if found, otherwise NULL is returned. The caller is responsibile for + * entry if found, otherwise NULL is returned. The caller is responsible for * ensuring that the hash table is protected with either a RCU read lock or the * hash table lock. * @@ -165,7 +165,7 @@ static struct netlbl_dom_map *netlbl_domhsh_search(const char *domain) * Searches the domain hash table and returns a pointer to the hash table * entry if an exact match is found, if an exact match is not present in the * hash table then the default entry is returned if valid otherwise NULL is - * returned. The caller is responsibile ensuring that the hash table is + * returned. The caller is responsible ensuring that the hash table is * protected with either a RCU read lock or the hash table lock. * */ @@ -193,7 +193,7 @@ static struct netlbl_dom_map *netlbl_domhsh_search_def(const char *domain) * * Description: * Generate an audit record for adding a new NetLabel/LSM mapping entry with - * the given information. Caller is responsibile for holding the necessary + * the given information. Caller is responsible for holding the necessary * locks. * */ @@ -605,7 +605,7 @@ int netlbl_domhsh_remove_default(struct netlbl_audit *audit_info) * * Description: * Look through the domain hash table searching for an entry to match @domain, - * return a pointer to a copy of the entry or NULL. The caller is responsibile + * return a pointer to a copy of the entry or NULL. The caller is responsible * for ensuring that rcu_read_[un]lock() is called. * */ diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c index 998e85e895d0..4f251b19fbcc 100644 --- a/net/netlabel/netlabel_mgmt.c +++ b/net/netlabel/netlabel_mgmt.c @@ -259,7 +259,7 @@ add_failure: * * Description: * This function is a helper function used by the LISTALL and LISTDEF command - * handlers. The caller is responsibile for ensuring that the RCU read lock + * handlers. The caller is responsible for ensuring that the RCU read lock * is held. Returns zero on success, negative values on failure. * */ diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c index c47a511f203d..7c4dce8fa5e6 100644 --- a/net/rds/ib_send.c +++ b/net/rds/ib_send.c @@ -355,7 +355,7 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context) * * Conceptually, we have two counters: * - send credits: this tells us how many WRs we're allowed - * to submit without overruning the reciever's queue. For + * to submit without overruning the receiver's queue. For * each SEND WR we post, we decrement this by one. * * - posted credits: this tells us how many WRs we recently diff --git a/net/rds/iw_cm.c b/net/rds/iw_cm.c index 712cf2d1f28e..3a60a15d1b4a 100644 --- a/net/rds/iw_cm.c +++ b/net/rds/iw_cm.c @@ -181,7 +181,7 @@ static int rds_iw_init_qp_attrs(struct ib_qp_init_attr *attr, unsigned int send_size, recv_size; int ret; - /* The offset of 1 is to accomodate the additional ACK WR. */ + /* The offset of 1 is to accommodate the additional ACK WR. */ send_size = min_t(unsigned int, rds_iwdev->max_wrs, rds_iw_sysctl_max_send_wr + 1); recv_size = min_t(unsigned int, rds_iwdev->max_wrs, rds_iw_sysctl_max_recv_wr + 1); rds_iw_ring_resize(send_ring, send_size - 1); diff --git a/net/rds/iw_rdma.c b/net/rds/iw_rdma.c index 59509e9a9e72..6deaa77495e3 100644 --- a/net/rds/iw_rdma.c +++ b/net/rds/iw_rdma.c @@ -122,7 +122,7 @@ static int rds_iw_get_device(struct rds_sock *rs, struct rds_iw_device **rds_iwd #else /* FIXME - needs to compare the local and remote * ipaddr/port tuple, but the ipaddr is the only - * available infomation in the rds_sock (as the rest are + * available information in the rds_sock (as the rest are * zero'ed. It doesn't appear to be properly populated * during connection setup... */ diff --git a/net/rds/iw_send.c b/net/rds/iw_send.c index 6280ea020d4e..545d8ee3efb1 100644 --- a/net/rds/iw_send.c +++ b/net/rds/iw_send.c @@ -307,7 +307,7 @@ void rds_iw_send_cq_comp_handler(struct ib_cq *cq, void *context) * * Conceptually, we have two counters: * - send credits: this tells us how many WRs we're allowed - * to submit without overruning the reciever's queue. For + * to submit without overruning the receiver's queue. For * each SEND WR we post, we decrement this by one. * * - posted credits: this tells us how many WRs we recently diff --git a/net/rds/send.c b/net/rds/send.c index 35b9c2e9caf1..d58ae5f9339e 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -116,7 +116,7 @@ static void release_in_xmit(struct rds_connection *conn) } /* - * We're making the concious trade-off here to only send one message + * We're making the conscious trade-off here to only send one message * down the connection at a time. * Pro: * - tx queueing is a simple fifo list diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c index 08dcd2f29cdc..479cae57d187 100644 --- a/net/rose/rose_route.c +++ b/net/rose/rose_route.c @@ -587,7 +587,7 @@ static int rose_clear_routes(void) /* * Check that the device given is a valid AX.25 interface that is "up". - * called whith RTNL + * called with RTNL */ static struct net_device *rose_ax25_dev_find(char *devname) { diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 15873e14cb54..14b42f4ad791 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -999,7 +999,7 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, void *arg) switch (n->nlmsg_type) { case RTM_NEWACTION: /* we are going to assume all other flags - * imply create only if it doesnt exist + * imply create only if it doesn't exist * Note that CREATE | EXCL implies that * but since we want avoid ambiguity (eg when flags * is zero) then just set this diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c index 50c7c06c019d..7affe9a92757 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c @@ -161,7 +161,7 @@ static int tcf_pedit(struct sk_buff *skb, struct tc_action *a, } if (offset > 0 && offset > skb->len) { pr_info("tc filter pedit" - " offset %d cant exceed pkt length %d\n", + " offset %d can't exceed pkt length %d\n", offset, skb->len); goto bad; } diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c index a4de67eca824..49130e8abff0 100644 --- a/net/sched/em_meta.c +++ b/net/sched/em_meta.c @@ -47,7 +47,7 @@ * on the meta type. Obviously, the length of the data must also * be provided for non-numeric types. * - * Additionaly, type dependant modifiers such as shift operators + * Additionally, type dependent modifiers such as shift operators * or mask may be applied to extend the functionaliy. As of now, * the variable length type supports shifting the byte string to * the right, eating up any number of octets and thus supporting diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index e1429a85091f..29b942ce9e82 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c @@ -183,7 +183,7 @@ static inline struct htb_class *htb_find(u32 handle, struct Qdisc *sch) * filters in qdisc and in inner nodes (if higher filter points to the inner * node). If we end up with classid MAJOR:0 we enqueue the skb into special * internal fifo (direct). These packets then go directly thru. If we still - * have no valid leaf we try to use MAJOR:default leaf. It still unsuccessfull + * have no valid leaf we try to use MAJOR:default leaf. It still unsuccessful * then finish and return direct queue. */ #define HTB_DIRECT ((struct htb_class *)-1L) diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index edbbf7ad6623..69c35f6cd13f 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c @@ -160,7 +160,7 @@ static bool loss_4state(struct netem_sched_data *q) u32 rnd = net_random(); /* - * Makes a comparision between rnd and the transition + * Makes a comparison between rnd and the transition * probabilities outgoing from the current state, then decides the * next state and if the next packet has to be transmitted or lost. * The four states correspond to: @@ -212,9 +212,9 @@ static bool loss_4state(struct netem_sched_data *q) * Generates losses according to the Gilbert-Elliot loss model or * its special cases (Gilbert or Simple Gilbert) * - * Makes a comparision between random number and the transition + * Makes a comparison between random number and the transition * probabilities outgoing from the current state, then decides the - * next state. A second random number is extracted and the comparision + * next state. A second random number is extracted and the comparison * with the loss probability of the current state decides if the next * packet will be transmitted or lost. */ diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 6b04287913cd..0698cad61763 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c @@ -1593,7 +1593,7 @@ void sctp_assoc_clean_asconf_ack_cache(const struct sctp_association *asoc) struct sctp_chunk *ack; struct sctp_chunk *tmp; - /* We can remove all the entries from the queue upto + /* We can remove all the entries from the queue up to * the "Peer-Sequence-Number". */ list_for_each_entry_safe(ack, tmp, &asoc->asconf_ack_list, diff --git a/net/sctp/auth.c b/net/sctp/auth.c index ddbbf7c81fa1..865e68fef21c 100644 --- a/net/sctp/auth.c +++ b/net/sctp/auth.c @@ -113,7 +113,7 @@ struct sctp_shared_key *sctp_auth_shkey_create(__u16 key_id, gfp_t gfp) return new; } -/* Free the shared key stucture */ +/* Free the shared key structure */ static void sctp_auth_shkey_free(struct sctp_shared_key *sh_key) { BUG_ON(!list_empty(&sh_key->key_list)); @@ -122,7 +122,7 @@ static void sctp_auth_shkey_free(struct sctp_shared_key *sh_key) kfree(sh_key); } -/* Destory the entire key list. This is done during the +/* Destroy the entire key list. This is done during the * associon and endpoint free process. */ void sctp_auth_destroy_keys(struct list_head *keys) @@ -324,7 +324,7 @@ static struct sctp_auth_bytes *sctp_auth_asoc_create_secret( if (!peer_key_vector || !local_key_vector) goto out; - /* Figure out the order in wich the key_vectors will be + /* Figure out the order in which the key_vectors will be * added to the endpoint shared key. * SCTP-AUTH, Section 6.1: * This is performed by selecting the numerically smaller key diff --git a/net/sctp/input.c b/net/sctp/input.c index 826661be73e7..5436c6921167 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c @@ -1034,7 +1034,7 @@ static struct sctp_association *__sctp_rcv_asconf_lookup( * association. * * This means that any chunks that can help us identify the association need -* to be looked at to find this assocation. +* to be looked at to find this association. */ static struct sctp_association *__sctp_rcv_walk_lookup(struct sk_buff *skb, const union sctp_addr *laddr, diff --git a/net/sctp/output.c b/net/sctp/output.c index 60600d337a3a..b4f3cf06d8da 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c @@ -510,7 +510,7 @@ int sctp_packet_transmit(struct sctp_packet *packet) sh->checksum = sctp_end_cksum(crc32); } else { if (dst->dev->features & NETIF_F_SCTP_CSUM) { - /* no need to seed psuedo checksum for SCTP */ + /* no need to seed pseudo checksum for SCTP */ nskb->ip_summed = CHECKSUM_PARTIAL; nskb->csum_start = (skb_transport_header(nskb) - nskb->head); diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index 26dc005113a0..bf92a5b68f8b 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c @@ -177,13 +177,13 @@ static inline int sctp_cacc_skip_3_2(struct sctp_transport *primary, __u32 tsn) * 3) If the missing report count for TSN t is to be * incremented according to [RFC2960] and * [SCTP_STEWART-2002], and CHANGEOVER_ACTIVE is set, - * then the sender MUST futher execute steps 3.1 and + * then the sender MUST further execute steps 3.1 and * 3.2 to determine if the missing report count for * TSN t SHOULD NOT be incremented. * * 3.3) If 3.1 and 3.2 do not dictate that the missing * report count for t should not be incremented, then - * the sender SOULD increment missing report count for + * the sender SHOULD increment missing report count for * t (according to [RFC2960] and [SCTP_STEWART_2002]). */ static inline int sctp_cacc_skip(struct sctp_transport *primary, @@ -843,7 +843,7 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) case SCTP_CID_ECN_CWR: case SCTP_CID_ASCONF_ACK: one_packet = 1; - /* Fall throught */ + /* Fall through */ case SCTP_CID_SACK: case SCTP_CID_HEARTBEAT: diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index b21b218d564f..5f86ee4b54c1 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c @@ -482,7 +482,7 @@ static void sctp_do_8_2_transport_strike(struct sctp_association *asoc, * If the timer was a heartbeat, we only increment error counts * when we already have an outstanding HEARTBEAT that has not * been acknowledged. - * Additionaly, some tranport states inhibit error increments. + * Additionally, some tranport states inhibit error increments. */ if (!is_hb) { asoc->overall_error_count++; diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 4b4eb7c96bbd..76792083c379 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c @@ -551,7 +551,7 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep, * * This means that if we only want to abort associations * in an authenticated way (i.e AUTH+ABORT), then we - * can't destroy this association just becuase the packet + * can't destroy this association just because the packet * was malformed. */ if (sctp_auth_recv_cid(SCTP_CID_ABORT, asoc)) @@ -1546,7 +1546,7 @@ cleanup: } /* - * Handle simultanous INIT. + * Handle simultaneous INIT. * This means we started an INIT and then we got an INIT request from * our peer. * @@ -2079,7 +2079,7 @@ sctp_disposition_t sctp_sf_shutdown_pending_abort( * RFC 2960, Section 3.3.7 * If an endpoint receives an ABORT with a format error or for an * association that doesn't exist, it MUST silently discard it. - * Becasue the length is "invalid", we can't really discard just + * Because the length is "invalid", we can't really discard just * as we do not know its true length. So, to be safe, discard the * packet. */ @@ -2120,7 +2120,7 @@ sctp_disposition_t sctp_sf_shutdown_sent_abort(const struct sctp_endpoint *ep, * RFC 2960, Section 3.3.7 * If an endpoint receives an ABORT with a format error or for an * association that doesn't exist, it MUST silently discard it. - * Becasue the length is "invalid", we can't really discard just + * Because the length is "invalid", we can't really discard just * as we do not know its true length. So, to be safe, discard the * packet. */ @@ -2381,7 +2381,7 @@ sctp_disposition_t sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep, * RFC 2960, Section 3.3.7 * If an endpoint receives an ABORT with a format error or for an * association that doesn't exist, it MUST silently discard it. - * Becasue the length is "invalid", we can't really discard just + * Because the length is "invalid", we can't really discard just * as we do not know its true length. So, to be safe, discard the * packet. */ @@ -2448,7 +2448,7 @@ sctp_disposition_t sctp_sf_cookie_wait_abort(const struct sctp_endpoint *ep, * RFC 2960, Section 3.3.7 * If an endpoint receives an ABORT with a format error or for an * association that doesn't exist, it MUST silently discard it. - * Becasue the length is "invalid", we can't really discard just + * Because the length is "invalid", we can't really discard just * as we do not know its true length. So, to be safe, discard the * packet. */ @@ -3855,7 +3855,7 @@ gen_shutdown: } /* - * SCTP-AUTH Section 6.3 Receving authenticated chukns + * SCTP-AUTH Section 6.3 Receiving authenticated chukns * * The receiver MUST use the HMAC algorithm indicated in the HMAC * Identifier field. If this algorithm was not specified by the @@ -4231,7 +4231,7 @@ static sctp_disposition_t sctp_sf_abort_violation( * * This means that if we only want to abort associations * in an authenticated way (i.e AUTH+ABORT), then we - * can't destroy this association just becuase the packet + * can't destroy this association just because the packet * was malformed. */ if (sctp_auth_recv_cid(SCTP_CID_ABORT, asoc)) @@ -4402,9 +4402,9 @@ static sctp_disposition_t sctp_sf_violation_ctsn( } /* Handle protocol violation of an invalid chunk bundling. For example, - * when we have an association and we recieve bundled INIT-ACK, or + * when we have an association and we receive bundled INIT-ACK, or * SHUDOWN-COMPLETE, our peer is clearly violationg the "MUST NOT bundle" - * statement from the specs. Additinally, there might be an attacker + * statement from the specs. Additionally, there might be an attacker * on the path and we may not want to continue this communication. */ static sctp_disposition_t sctp_sf_violation_chunk( diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 3951a10605bc..deb82e35a107 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -1193,7 +1193,7 @@ out_free: * an endpoint that is multi-homed. Much like sctp_bindx() this call * allows a caller to specify multiple addresses at which a peer can be * reached. The way the SCTP stack uses the list of addresses to set up - * the association is implementation dependant. This function only + * the association is implementation dependent. This function only * specifies that the stack will try to make use of all the addresses in * the list when needed. * diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c index aa72e89c3ee1..dff27d5e22fd 100644 --- a/net/sctp/ulpevent.c +++ b/net/sctp/ulpevent.c @@ -554,7 +554,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_send_failed( memcpy(&ssf->ssf_info, &chunk->sinfo, sizeof(struct sctp_sndrcvinfo)); /* Per TSVWG discussion with Randy. Allow the application to - * ressemble a fragmented message. + * resemble a fragmented message. */ ssf->ssf_info.sinfo_flags = chunk->chunk_hdr->flags; diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c index 17678189d054..f2d1de7f2ffb 100644 --- a/net/sctp/ulpqueue.c +++ b/net/sctp/ulpqueue.c @@ -240,7 +240,7 @@ int sctp_ulpq_tail_event(struct sctp_ulpq *ulpq, struct sctp_ulpevent *event) } else { /* * If fragment interleave is enabled, we - * can queue this to the recieve queue instead + * can queue this to the receive queue instead * of the lobby. */ if (sctp_sk(sk)->frag_interleave) diff --git a/net/socket.c b/net/socket.c index 5212447c86e7..310d16b1b3c9 100644 --- a/net/socket.c +++ b/net/socket.c @@ -2986,7 +2986,7 @@ out: /* Since old style bridge ioctl's endup using SIOCDEVPRIVATE * for some operations; this forces use of the newer bridge-utils that - * use compatiable ioctls + * use compatible ioctls */ static int old_bridge_ioctl(compat_ulong_t __user *argp) { diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index bcdae78fdfc6..8d0f7d3c71c8 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c @@ -1101,7 +1101,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp) /* credential is: * version(==1), proc(0,1,2,3), seq, service (1,2,3), handle - * at least 5 u32s, and is preceeded by length, so that makes 6. + * at least 5 u32s, and is preceded by length, so that makes 6. */ if (argv->iov_len < 5 * 4) diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 1e336a06d3e6..bf005d3c65ef 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -504,7 +504,7 @@ static int xs_nospace(struct rpc_task *task) * EAGAIN: The socket was blocked, please call again later to * complete the request * ENOTCONN: Caller needs to invoke connect logic then call again - * other: Some other error occured, the request was not sent + * other: Some other error occurred, the request was not sent */ static int xs_udp_send_request(struct rpc_task *task) { @@ -590,7 +590,7 @@ static inline void xs_encode_tcp_record_marker(struct xdr_buf *buf) * EAGAIN: The socket was blocked, please call again later to * complete the request * ENOTCONN: Caller needs to invoke connect logic then call again - * other: Some other error occured, the request was not sent + * other: Some other error occurred, the request was not sent * * XXX: In the case of soft timeouts, should we eventually give up * if sendmsg is not able to make progress? diff --git a/net/tipc/link.c b/net/tipc/link.c index 43639ff1cbec..ebf338f7b14e 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -2471,7 +2471,7 @@ exit: * A pending message being re-assembled must store certain values * to handle subsequent fragments correctly. The following functions * help storing these values in unused, available fields in the - * pending message. This makes dynamic memory allocation unecessary. + * pending message. This makes dynamic memory allocation unnecessary. */ static void set_long_msg_seqno(struct sk_buff *buf, u32 seqno) diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c index c9fa6dfcf287..80025a1b3bfd 100644 --- a/net/tipc/name_distr.c +++ b/net/tipc/name_distr.c @@ -160,7 +160,7 @@ void tipc_named_withdraw(struct publication *publ) buf = named_prepare_buf(WITHDRAWAL, ITEM_SIZE, 0); if (!buf) { - warn("Withdrawl distribution failure\n"); + warn("Withdrawal distribution failure\n"); return; } diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 1663e1a2efdd..3a43a8304768 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -207,7 +207,7 @@ static int unix_mkname(struct sockaddr_un *sunaddr, int len, unsigned *hashp) /* * This may look like an off by one error but it is a bit more * subtle. 108 is the longest valid AF_UNIX path for a binding. - * sun_path[108] doesnt as such exist. However in kernel space + * sun_path[108] doesn't as such exist. However in kernel space * we are guaranteed that it is a valid memory location in our * kernel address buffer. */ diff --git a/net/wanrouter/wanproc.c b/net/wanrouter/wanproc.c index 11f25c7a7a05..f346395314ba 100644 --- a/net/wanrouter/wanproc.c +++ b/net/wanrouter/wanproc.c @@ -51,7 +51,7 @@ /* * Structures for interfacing with the /proc filesystem. - * Router creates its own directory /proc/net/router with the folowing + * Router creates its own directory /proc/net/router with the following * entries: * config device configuration * status global device statistics diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 3332d5bce317..ab801a1097b2 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -809,7 +809,7 @@ static void handle_channel(struct wiphy *wiphy, if (r) { /* * We will disable all channels that do not match our - * recieved regulatory rule unless the hint is coming + * received regulatory rule unless the hint is coming * from a Country IE and the Country IE had no information * about a band. The IEEE 802.11 spec allows for an AP * to send only a subset of the regulatory rules allowed, @@ -838,7 +838,7 @@ static void handle_channel(struct wiphy *wiphy, request_wiphy && request_wiphy == wiphy && request_wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY) { /* - * This gaurantees the driver's requested regulatory domain + * This guarantees the driver's requested regulatory domain * will always be used as a base for further regulatory * settings */ diff --git a/net/x25/x25_facilities.c b/net/x25/x25_facilities.c index 406207515b5e..f77e4e75f914 100644 --- a/net/x25/x25_facilities.c +++ b/net/x25/x25_facilities.c @@ -31,7 +31,7 @@ * x25_parse_facilities - Parse facilities from skb into the facilities structs * * @skb: sk_buff to parse - * @facilities: Regular facilites, updated as facilities are found + * @facilities: Regular facilities, updated as facilities are found * @dte_facs: ITU DTE facilities, updated as DTE facilities are found * @vc_fac_mask: mask is updated with all facilities found * diff --git a/net/x25/x25_forward.c b/net/x25/x25_forward.c index 25a810793968..c541b622ae16 100644 --- a/net/x25/x25_forward.c +++ b/net/x25/x25_forward.c @@ -31,7 +31,7 @@ int x25_forward_call(struct x25_address *dest_addr, struct x25_neigh *from, goto out_no_route; if ((neigh_new = x25_get_neigh(rt->dev)) == NULL) { - /* This shouldnt happen, if it occurs somehow + /* This shouldn't happen, if it occurs somehow * do something sensible */ goto out_put_route; @@ -45,7 +45,7 @@ int x25_forward_call(struct x25_address *dest_addr, struct x25_neigh *from, } /* Remote end sending a call request on an already - * established LCI? It shouldnt happen, just in case.. + * established LCI? It shouldn't happen, just in case.. */ read_lock_bh(&x25_forward_list_lock); list_for_each(entry, &x25_forward_list) { diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 3d15d3e1b2c4..5d1d60d3ca83 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -894,7 +894,7 @@ static int build_spdinfo(struct sk_buff *skb, struct net *net, u32 *f; nlh = nlmsg_put(skb, pid, seq, XFRM_MSG_NEWSPDINFO, sizeof(u32), 0); - if (nlh == NULL) /* shouldnt really happen ... */ + if (nlh == NULL) /* shouldn't really happen ... */ return -EMSGSIZE; f = nlmsg_data(nlh); @@ -954,7 +954,7 @@ static int build_sadinfo(struct sk_buff *skb, struct net *net, u32 *f; nlh = nlmsg_put(skb, pid, seq, XFRM_MSG_NEWSADINFO, sizeof(u32), 0); - if (nlh == NULL) /* shouldnt really happen ... */ + if (nlh == NULL) /* shouldn't really happen ... */ return -EMSGSIZE; f = nlmsg_data(nlh); @@ -1361,7 +1361,7 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, if (!xp) return err; - /* shouldnt excl be based on nlh flags?? + /* shouldn't excl be based on nlh flags?? * Aha! this is anti-netlink really i.e more pfkey derived * in netlink excl is a flag and you wouldnt need * a type XFRM_MSG_UPDPOLICY - JHS */ diff --git a/samples/Kconfig b/samples/Kconfig index e03cf0e374d7..41063e7592d2 100644 --- a/samples/Kconfig +++ b/samples/Kconfig @@ -55,7 +55,7 @@ config SAMPLE_KFIFO If in doubt, say "N" here. config SAMPLE_KDB - tristate "Build kdb command exmaple -- loadable modules only" + tristate "Build kdb command example -- loadable modules only" depends on KGDB_KDB && m help Build an example of how to dynamically add the hello diff --git a/samples/hw_breakpoint/data_breakpoint.c b/samples/hw_breakpoint/data_breakpoint.c index bd0f337afcab..063653955f9f 100644 --- a/samples/hw_breakpoint/data_breakpoint.c +++ b/samples/hw_breakpoint/data_breakpoint.c @@ -19,7 +19,7 @@ * * This file is a kernel module that places a breakpoint over ksym_name kernel * variable using Hardware Breakpoint register. The corresponding handler which - * prints a backtrace is invoked everytime a write operation is performed on + * prints a backtrace is invoked every time a write operation is performed on * that variable. * * Copyright (C) IBM Corporation, 2009 diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 7d22056582c1..56dfafc73c1a 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -35,14 +35,14 @@ # KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined # symbols in the final module linking stage # KBUILD_MODPOST_NOFINAL can be set to skip the final link of modules. -# This is solely usefull to speed up test compiles +# This is solely useful to speed up test compiles PHONY := _modpost _modpost: __modpost include include/config/auto.conf include scripts/Kbuild.include -# When building external modules load the Kbuild file to retreive EXTRA_SYMBOLS info +# When building external modules load the Kbuild file to retrieve EXTRA_SYMBOLS info ifneq ($(KBUILD_EXTMOD),) # set src + obj - they may be used when building the .mod.c file diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 8f9e394298cd..d8670810db65 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1946,13 +1946,13 @@ sub process { # printk should use KERN_* levels. Note that follow on printk's on the # same line do not need a level, so we use the current block context # to try and find and validate the current printk. In summary the current -# printk includes all preceeding printk's which have no newline on the end. +# printk includes all preceding printk's which have no newline on the end. # we assume the first bad printk is the one to report. if ($line =~ /\bprintk\((?!KERN_)\s*"/) { my $ok = 0; for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) { #print "CHECK<$lines[$ln - 1]\n"; - # we have a preceeding printk if it ends + # we have a preceding printk if it ends # with "\n" ignore it, else it is to blame if ($lines[$ln - 1] =~ m{\bprintk\(}) { if ($rawlines[$ln - 1] !~ m{\\n"}) { @@ -2044,7 +2044,7 @@ sub process { for (my $n = 0; $n < $#elements; $n += 2) { $off += length($elements[$n]); - # Pick up the preceeding and succeeding characters. + # Pick up the preceding and succeeding characters. my $ca = substr($opline, 0, $off); my $cc = ''; if (length($opline) >= ($off + length($elements[$n + 1]))) { diff --git a/scripts/dtc/libfdt/libfdt.h b/scripts/dtc/libfdt/libfdt.h index ce80e4fb41b2..ff6246f000ce 100644 --- a/scripts/dtc/libfdt/libfdt.h +++ b/scripts/dtc/libfdt/libfdt.h @@ -61,7 +61,7 @@ #define FDT_ERR_NOTFOUND 1 /* FDT_ERR_NOTFOUND: The requested node or property does not exist */ #define FDT_ERR_EXISTS 2 - /* FDT_ERR_EXISTS: Attemped to create a node or property which + /* FDT_ERR_EXISTS: Attempted to create a node or property which * already exists */ #define FDT_ERR_NOSPACE 3 /* FDT_ERR_NOSPACE: Operation needed to expand the device diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c index c9209d5c999e..26d0e1e60c0c 100644 --- a/scripts/dtc/livetree.c +++ b/scripts/dtc/livetree.c @@ -155,7 +155,7 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node) } } - /* if no collision occured, add child to the old node. */ + /* if no collision occurred, add child to the old node. */ if (new_child) add_child(old_node, new_child); } diff --git a/scripts/gen_initramfs_list.sh b/scripts/gen_initramfs_list.sh index 55caecdad995..e12b1a7525cf 100644 --- a/scripts/gen_initramfs_list.sh +++ b/scripts/gen_initramfs_list.sh @@ -284,7 +284,7 @@ while [ $# -gt 0 ]; do done # If output_file is set we will generate cpio archive and compress it -# we are carefull to delete tmp files +# we are careful to delete tmp files if [ ! -z ${output_file} ]; then if [ -z ${cpio_file} ]; then cpio_tfile="$(mktemp ${TMPDIR:-/tmp}/cpiofile.XXXXXX)" diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 9f85012acf0d..d793001929cf 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1705,7 +1705,7 @@ sub push_parameter($$$) { $param = xml_escape($param); - # strip spaces from $param so that it is one continous string + # strip spaces from $param so that it is one continuous string # on @parameterlist; # this fixes a problem where check_sections() cannot find # a parameter like "addr[6 + 2]" because it actually appears diff --git a/scripts/package/buildtar b/scripts/package/buildtar index 83c9c04102f2..8a7b15598ea9 100644 --- a/scripts/package/buildtar +++ b/scripts/package/buildtar @@ -92,7 +92,7 @@ case "${ARCH}" in echo "" >&2 echo '** ** ** WARNING ** ** **' >&2 echo "" >&2 - echo "Your architecture did not define any architecture-dependant files" >&2 + echo "Your architecture did not define any architecture-dependent files" >&2 echo "to be placed into the tarball. Please add those to ${0} ..." >&2 echo "" >&2 sleep 5 diff --git a/scripts/rt-tester/rt-tester.py b/scripts/rt-tester/rt-tester.py index 8c81d76959ee..34186cac1d2f 100644 --- a/scripts/rt-tester/rt-tester.py +++ b/scripts/rt-tester/rt-tester.py @@ -180,7 +180,7 @@ while 1: for s in stat: s = s.strip() if s.startswith(testop[0]): - # Seperate status value + # Separate status value val = s[2:].strip() query = analyse(val, testop, dat) break diff --git a/security/apparmor/match.c b/security/apparmor/match.c index 5cb4dc1f6992..06d764ccbbe5 100644 --- a/security/apparmor/match.c +++ b/security/apparmor/match.c @@ -195,7 +195,7 @@ void aa_dfa_free_kref(struct kref *kref) * * Unpack a dfa that has been serialized. To find information on the dfa * format look in Documentation/apparmor.txt - * Assumes the dfa @blob stream has been aligned on a 8 byte boundry + * Assumes the dfa @blob stream has been aligned on a 8 byte boundary * * Returns: an unpacked dfa ready for matching or ERR_PTR on failure */ diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c index eb3700e9fd37..e33aaf7e5744 100644 --- a/security/apparmor/policy_unpack.c +++ b/security/apparmor/policy_unpack.c @@ -359,7 +359,7 @@ fail: * @e: serialized data extent information (NOT NULL) * @profile: profile to add the accept table to (NOT NULL) * - * Returns: 1 if table succesfully unpacked + * Returns: 1 if table successfully unpacked */ static bool unpack_trans_table(struct aa_ext *e, struct aa_profile *profile) { diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c index 1c2fc46544bf..c3bf3ed07b06 100644 --- a/security/selinux/netlabel.c +++ b/security/selinux/netlabel.c @@ -151,7 +151,7 @@ void selinux_netlbl_sk_security_free(struct sk_security_struct *sksec) * * Description: * Called when the NetLabel state of a sk_security_struct needs to be reset. - * The caller is responsibile for all the NetLabel sk_security_struct locking. + * The caller is responsible for all the NetLabel sk_security_struct locking. * */ void selinux_netlbl_sk_security_reset(struct sk_security_struct *sksec) diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index ea7c01f4a2bf..6ef4af47dac4 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -2806,7 +2806,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) case AUDIT_SUBJ_CLR: case AUDIT_OBJ_LEV_LOW: case AUDIT_OBJ_LEV_HIGH: - /* we do not allow a range, indicated by the presense of '-' */ + /* we do not allow a range, indicated by the presence of '-' */ if (strchr(rulestr, '-')) return -EINVAL; break; @@ -3075,7 +3075,7 @@ static void security_netlbl_cache_add(struct netlbl_lsm_secattr *secattr, * Description: * Convert the given NetLabel security attributes in @secattr into a * SELinux SID. If the @secattr field does not contain a full SELinux - * SID/context then use SECINITSID_NETMSG as the foundation. If possibile the + * SID/context then use SECINITSID_NETMSG as the foundation. If possible the * 'cache' field of @secattr is set and the CACHE flag is set; this is to * allow the @secattr to be used by NetLabel to cache the secattr to SID * conversion for future lookups. Returns zero on success, negative values on diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c index 86453db4333d..9637e107f7ea 100644 --- a/security/smack/smack_access.c +++ b/security/smack/smack_access.c @@ -431,7 +431,7 @@ char *smk_import(const char *string, int len) * smack_from_secid - find the Smack label associated with a secid * @secid: an integer that might be associated with a Smack label * - * Returns a pointer to the appropraite Smack label if there is one, + * Returns a pointer to the appropriate Smack label if there is one, * otherwise a pointer to the invalid Smack label. */ char *smack_from_secid(const u32 secid) diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 23c7a6d0c80c..c6f8fcadae07 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -1794,7 +1794,7 @@ static void smack_set_catset(char *catset, struct netlbl_lsm_secattr *sap) * Casey says that CIPSO is good enough for now. * It can be used to effect. * It can also be abused to effect when necessary. - * Appologies to the TSIG group in general and GW in particular. + * Apologies to the TSIG group in general and GW in particular. */ static void smack_to_secattr(char *smack, struct netlbl_lsm_secattr *nlsp) { @@ -2530,7 +2530,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) switch (sbp->s_magic) { case SMACK_MAGIC: /* - * Casey says that it's a little embarassing + * Casey says that it's a little embarrassing * that the smack file system doesn't do * extended attributes. */ @@ -3084,7 +3084,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, /* * We need to decide if we want to label the incoming connection here * if we do we only need to label the request_sock and the stack will - * propogate the wire-label to the sock when it is created. + * propagate the wire-label to the sock when it is created. */ hdr = ip_hdr(skb); addr.sin_addr.s_addr = hdr->saddr; diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index 90d1bbaaa6f3..f93460156dce 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c @@ -208,7 +208,7 @@ static ssize_t smk_write_load_list(struct file *file, const char __user *buf, if (*ppos != 0) return -EINVAL; /* - * Minor hack for backward compatability + * Minor hack for backward compatibility */ if (count < (SMK_OLOADLEN) || count > SMK_LOADLEN) return -EINVAL; @@ -223,7 +223,7 @@ static ssize_t smk_write_load_list(struct file *file, const char __user *buf, } /* - * More on the minor hack for backward compatability + * More on the minor hack for backward compatibility */ if (count == (SMK_OLOADLEN)) data[SMK_OLOADLEN] = '-'; @@ -927,7 +927,7 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf, } } else { /* we delete the unlabeled entry, only if the previous label - * wasnt the special CIPSO option */ + * wasn't the special CIPSO option */ if (skp->smk_label != smack_cipso_option) rc = netlbl_cfg_unlbl_static_del(&init_net, NULL, &skp->smk_host.sin_addr, &skp->smk_mask, diff --git a/security/tomoyo/load_policy.c b/security/tomoyo/load_policy.c index bbada7ca1b91..3312e5624f24 100644 --- a/security/tomoyo/load_policy.c +++ b/security/tomoyo/load_policy.c @@ -23,7 +23,7 @@ static bool tomoyo_policy_loader_exists(void) * If the initrd includes /sbin/init but real-root-dev has not * mounted on / yet, activating MAC will block the system since * policies are not loaded yet. - * Thus, let do_execve() call this function everytime. + * Thus, let do_execve() call this function every time. */ struct path path; diff --git a/sound/aoa/codecs/tas.c b/sound/aoa/codecs/tas.c index fd2188c3df2b..58804c7acfcf 100644 --- a/sound/aoa/codecs/tas.c +++ b/sound/aoa/codecs/tas.c @@ -170,7 +170,7 @@ static void tas_set_volume(struct tas *tas) /* analysing the volume and mixer tables shows * that they are similar enough when we shift * the mixer table down by 4 bits. The error - * is miniscule, in just one item the error + * is minuscule, in just one item the error * is 1, at a value of 0x07f17b (mixer table * value is 0x07f17a) */ tmp = tas_gaintable[left]; diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c index 917e4055ee30..150cb7edffee 100644 --- a/sound/core/pcm_memory.c +++ b/sound/core/pcm_memory.c @@ -253,7 +253,7 @@ static int snd_pcm_lib_preallocate_pages1(struct snd_pcm_substream *substream, * snd_pcm_lib_preallocate_pages - pre-allocation for the given DMA type * @substream: the pcm substream instance * @type: DMA type (SNDRV_DMA_TYPE_*) - * @data: DMA type dependant data + * @data: DMA type dependent data * @size: the requested pre-allocation size in bytes * @max: the max. allowed pre-allocation size * @@ -278,10 +278,10 @@ int snd_pcm_lib_preallocate_pages(struct snd_pcm_substream *substream, EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages); /** - * snd_pcm_lib_preallocate_pages_for_all - pre-allocation for continous memory type (all substreams) + * snd_pcm_lib_preallocate_pages_for_all - pre-allocation for continuous memory type (all substreams) * @pcm: the pcm instance * @type: DMA type (SNDRV_DMA_TYPE_*) - * @data: DMA type dependant data + * @data: DMA type dependent data * @size: the requested pre-allocation size in bytes * @max: the max. allowed pre-allocation size * diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index fe5c8036beba..1a07750f3836 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -460,7 +460,7 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream, PM_QOS_CPU_DMA_LATENCY, usecs); return 0; _error: - /* hardware might be unuseable from this time, + /* hardware might be unusable from this time, so we force application to retry to set the correct hardware parameter settings */ runtime->status->state = SNDRV_PCM_STATE_OPEN; diff --git a/sound/core/seq/seq_dummy.c b/sound/core/seq/seq_dummy.c index f3bdc54b429a..1d7d90ca455e 100644 --- a/sound/core/seq/seq_dummy.c +++ b/sound/core/seq/seq_dummy.c @@ -50,7 +50,7 @@ option snd-seq-dummy ports=4 - The modle option "duplex=1" enables duplex operation to the port. + The model option "duplex=1" enables duplex operation to the port. In duplex mode, a pair of ports are created instead of single port, and events are tunneled between pair-ports. For example, input to port A is sent to output port of another port B and vice versa. diff --git a/sound/core/vmaster.c b/sound/core/vmaster.c index a89948ae9e8d..a39d3d8c2f9c 100644 --- a/sound/core/vmaster.c +++ b/sound/core/vmaster.c @@ -233,7 +233,7 @@ static void slave_free(struct snd_kcontrol *kcontrol) * Add a slave control to the group with the given master control * * All slaves must be the same type (returning the same information - * via info callback). The fucntion doesn't check it, so it's your + * via info callback). The function doesn't check it, so it's your * responsibility. * * Also, some additional limitations: diff --git a/sound/drivers/pcm-indirect2.c b/sound/drivers/pcm-indirect2.c index 3c93c23e4883..e73fafd761b3 100644 --- a/sound/drivers/pcm-indirect2.c +++ b/sound/drivers/pcm-indirect2.c @@ -264,7 +264,7 @@ snd_pcm_indirect2_playback_transfer(struct snd_pcm_substream *substream, if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2)) diff += runtime->boundary; /* number of bytes "added" by ALSA increases the number of - * bytes which are ready to "be transfered to HW"/"played" + * bytes which are ready to "be transferred to HW"/"played" * Then, set rec->appl_ptr to not count bytes twice next time. */ rec->sw_ready += (int)frames_to_bytes(runtime, diff); @@ -330,7 +330,7 @@ snd_pcm_indirect2_playback_transfer(struct snd_pcm_substream *substream, /* copy bytes from intermediate buffer position sw_data to the * HW and return number of bytes actually written * Furthermore, set hw_ready to 0, if the fifo isn't empty - * now => more could be transfered to fifo + * now => more could be transferred to fifo */ bytes = copy(substream, rec, bytes); rec->bytes2hw += bytes; diff --git a/sound/drivers/vx/vx_pcm.c b/sound/drivers/vx/vx_pcm.c index 35a2f71a6af5..5e897b236cec 100644 --- a/sound/drivers/vx/vx_pcm.c +++ b/sound/drivers/vx/vx_pcm.c @@ -1189,7 +1189,7 @@ void vx_pcm_update_intr(struct vx_core *chip, unsigned int events) /* - * vx_init_audio_io - check the availabe audio i/o and allocate pipe arrays + * vx_init_audio_io - check the available audio i/o and allocate pipe arrays */ static int vx_init_audio_io(struct vx_core *chip) { diff --git a/sound/isa/sb/emu8000.c b/sound/isa/sb/emu8000.c index 0c40951b6523..5d61f5a29130 100644 --- a/sound/isa/sb/emu8000.c +++ b/sound/isa/sb/emu8000.c @@ -370,7 +370,7 @@ init_arrays(struct snd_emu8000 *emu) /* * Size the onboard memory. - * This is written so as not to need arbitary delays after the write. It + * This is written so as not to need arbitrary delays after the write. It * seems that the only way to do this is to use the one channel and keep * reallocating between read and write. */ diff --git a/sound/isa/wavefront/wavefront_midi.c b/sound/isa/wavefront/wavefront_midi.c index f14a7c0b6998..65329f3abc30 100644 --- a/sound/isa/wavefront/wavefront_midi.c +++ b/sound/isa/wavefront/wavefront_midi.c @@ -537,7 +537,7 @@ snd_wavefront_midi_start (snd_wavefront_card_t *card) } /* Turn on Virtual MIDI, but first *always* turn it off, - since otherwise consectutive reloads of the driver will + since otherwise consecutive reloads of the driver will never cause the hardware to generate the initial "internal" or "external" source bytes in the MIDI data stream. This is pretty important, since the internal hardware generally will diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c index 9191b32d9130..2a42cc377957 100644 --- a/sound/isa/wss/wss_lib.c +++ b/sound/isa/wss/wss_lib.c @@ -424,7 +424,7 @@ void snd_wss_mce_down(struct snd_wss *chip) /* * Wait for (possible -- during init auto-calibration may not be set) - * calibration process to start. Needs upto 5 sample periods on AD1848 + * calibration process to start. Needs up to 5 sample periods on AD1848 * which at the slowest possible rate of 5.5125 kHz means 907 us. */ msleep(1); diff --git a/sound/oss/ac97_codec.c b/sound/oss/ac97_codec.c index 854c303264dc..0cd23d94888f 100644 --- a/sound/oss/ac97_codec.c +++ b/sound/oss/ac97_codec.c @@ -28,7 +28,7 @@ * * History * May 02, 2003 Liam Girdwood - * Removed non existant WM9700 + * Removed non existent WM9700 * Added support for WM9705, WM9708, WM9709, WM9710, WM9711 * WM9712 and WM9717 * Mar 28, 2002 Randolph Bentson @@ -441,7 +441,7 @@ static void ac97_set_mixer(struct ac97_codec *codec, unsigned int oss_mixer, uns } /* read or write the recmask, the ac97 can really have left and right recording - inputs independantly set, but OSS doesn't seem to want us to express that to + inputs independently set, but OSS doesn't seem to want us to express that to the user. the caller guarantees that we have a supported bit set, and they must be holding the card's spinlock */ static int ac97_recmask_io(struct ac97_codec *codec, int rw, int mask) @@ -754,7 +754,7 @@ int ac97_probe_codec(struct ac97_codec *codec) if((codec->codec_ops == &null_ops) && (f & 4)) codec->codec_ops = &default_digital_ops; - /* A device which thinks its a modem but isnt */ + /* A device which thinks its a modem but isn't */ if(codec->flags & AC97_DELUDED_MODEM) codec->modem = 0; diff --git a/sound/oss/audio.c b/sound/oss/audio.c index 7df48a25c4ee..4b958b1c497c 100644 --- a/sound/oss/audio.c +++ b/sound/oss/audio.c @@ -514,7 +514,7 @@ int audio_ioctl(int dev, struct file *file, unsigned int cmd, void __user *arg) count += dmap->bytes_in_use; /* Pointer wrap not handled yet */ count += dmap->byte_counter; - /* Substract current count from the number of bytes written by app */ + /* Subtract current count from the number of bytes written by app */ count = dmap->user_counter - count; if (count < 0) count = 0; @@ -931,7 +931,7 @@ static int dma_ioctl(int dev, unsigned int cmd, void __user *arg) if (count < dmap_out->fragment_size && dmap_out->qhead != 0) count += dmap_out->bytes_in_use; /* Pointer wrap not handled yet */ count += dmap_out->byte_counter; - /* Substract current count from the number of bytes written by app */ + /* Subtract current count from the number of bytes written by app */ count = dmap_out->user_counter - count; if (count < 0) count = 0; diff --git a/sound/oss/dmasound/dmasound_core.c b/sound/oss/dmasound/dmasound_core.c index 87e2c72651f5..c918313c2206 100644 --- a/sound/oss/dmasound/dmasound_core.c +++ b/sound/oss/dmasound/dmasound_core.c @@ -1021,7 +1021,7 @@ static int sq_ioctl(struct file *file, u_int cmd, u_long arg) case SNDCTL_DSP_SYNC: /* This call, effectively, has the same behaviour as SNDCTL_DSP_RESET except that it waits for output to finish before resetting - everything - read, however, is killed imediately. + everything - read, however, is killed immediately. */ result = 0 ; if (file->f_mode & FMODE_WRITE) { diff --git a/sound/oss/midibuf.c b/sound/oss/midibuf.c index ceedb1eff203..8cdb2cfe65c8 100644 --- a/sound/oss/midibuf.c +++ b/sound/oss/midibuf.c @@ -295,7 +295,7 @@ int MIDIbuf_write(int dev, struct file *file, const char __user *buf, int count) for (i = 0; i < n; i++) { - /* BROKE BROKE BROKE - CANT DO THIS WITH CLI !! */ + /* BROKE BROKE BROKE - CAN'T DO THIS WITH CLI !! */ /* yes, think the same, so I removed the cli() brackets QUEUE_BYTE is protected against interrupts */ if (copy_from_user((char *) &tmp_data, &(buf)[c], 1)) { diff --git a/sound/oss/sb_card.c b/sound/oss/sb_card.c index 84ef4d06c1c2..fb5d7250de38 100644 --- a/sound/oss/sb_card.c +++ b/sound/oss/sb_card.c @@ -1,7 +1,7 @@ /* * sound/oss/sb_card.c * - * Detection routine for the ISA Sound Blaster and compatable sound + * Detection routine for the ISA Sound Blaster and compatible sound * cards. * * This file is distributed under the GNU GENERAL PUBLIC LICENSE (GPL) diff --git a/sound/oss/sb_ess.c b/sound/oss/sb_ess.c index 9890cf2066ff..5c773dff5ac5 100644 --- a/sound/oss/sb_ess.c +++ b/sound/oss/sb_ess.c @@ -168,7 +168,7 @@ * corresponding playback levels, unless recmask says they aren't recorded. In * the latter case the recording volumes are 0. * Now recording levels of inputs can be controlled, by changing the playback - * levels. Futhermore several devices can be recorded together (which is not + * levels. Furthermore several devices can be recorded together (which is not * possible with the ES1688). * Besides the separate recording level control for each input, the common * recording level can also be controlled by RECLEV as described above. diff --git a/sound/oss/swarm_cs4297a.c b/sound/oss/swarm_cs4297a.c index 44357d877a27..09d46484bc1a 100644 --- a/sound/oss/swarm_cs4297a.c +++ b/sound/oss/swarm_cs4297a.c @@ -875,7 +875,7 @@ static void start_adc(struct cs4297a_state *s) if (s->prop_adc.fmt & AFMT_S8 || s->prop_adc.fmt & AFMT_U8) { // // now only use 16 bit capture, due to truncation issue - // in the chip, noticable distortion occurs. + // in the chip, noticeable distortion occurs. // allocate buffer and then convert from 16 bit to // 8 bit for the user buffer. // diff --git a/sound/oss/vidc.c b/sound/oss/vidc.c index f0e0caa53200..12ba28e7b933 100644 --- a/sound/oss/vidc.c +++ b/sound/oss/vidc.c @@ -227,7 +227,7 @@ static int vidc_audio_set_speed(int dev, int rate) } else { /*printk("VIDC: internal %d %d %d\n", rate, rate_int, hwrate);*/ hwctrl=0x00000003; - /* Allow rougly 0.4% tolerance */ + /* Allow roughly 0.4% tolerance */ if (diff_int > (rate/256)) rate=rate_int; } diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c index 4382d0fa6b9a..d8f6fd65ebbb 100644 --- a/sound/pci/ad1889.c +++ b/sound/pci/ad1889.c @@ -29,7 +29,7 @@ * PM support * MIDI support * Game Port support - * SG DMA support (this will need *alot* of work) + * SG DMA support (this will need *a lot* of work) */ #include diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c index f53a31e939c1..f8ccc9677c6f 100644 --- a/sound/pci/asihpi/asihpi.c +++ b/sound/pci/asihpi/asihpi.c @@ -963,7 +963,7 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream) /*? also check ASI5000 samplerate source If external, only support external rate. - If internal and other stream playing, cant switch + If internal and other stream playing, can't switch */ init_timer(&dpcm->timer); diff --git a/sound/pci/asihpi/hpi.h b/sound/pci/asihpi/hpi.h index 6fc025c448de..255429c32c1c 100644 --- a/sound/pci/asihpi/hpi.h +++ b/sound/pci/asihpi/hpi.h @@ -725,7 +725,7 @@ enum HPI_AESEBU_ERRORS { #define HPI_PAD_TITLE_LEN 64 /** The text string containing the comment. */ #define HPI_PAD_COMMENT_LEN 256 -/** The PTY when the tuner has not recieved any PTY. */ +/** The PTY when the tuner has not received any PTY. */ #define HPI_PAD_PROGRAM_TYPE_INVALID 0xffff /** \} */ diff --git a/sound/pci/asihpi/hpi6000.c b/sound/pci/asihpi/hpi6000.c index 3e3c2ef6efd8..8c8aac4c567e 100644 --- a/sound/pci/asihpi/hpi6000.c +++ b/sound/pci/asihpi/hpi6000.c @@ -423,7 +423,7 @@ static void subsys_create_adapter(struct hpi_message *phm, ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL); if (!ao.priv) { - HPI_DEBUG_LOG(ERROR, "cant get mem for adapter object\n"); + HPI_DEBUG_LOG(ERROR, "can't get mem for adapter object\n"); phr->error = HPI_ERROR_MEMORY_ALLOC; return; } diff --git a/sound/pci/asihpi/hpi6205.c b/sound/pci/asihpi/hpi6205.c index 620525bdac59..22e9f08dea6d 100644 --- a/sound/pci/asihpi/hpi6205.c +++ b/sound/pci/asihpi/hpi6205.c @@ -466,7 +466,7 @@ static void subsys_create_adapter(struct hpi_message *phm, ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL); if (!ao.priv) { - HPI_DEBUG_LOG(ERROR, "cant get mem for adapter object\n"); + HPI_DEBUG_LOG(ERROR, "can't get mem for adapter object\n"); phr->error = HPI_ERROR_MEMORY_ALLOC; return; } diff --git a/sound/pci/asihpi/hpi_internal.h b/sound/pci/asihpi/hpi_internal.h index af678be0aa15..3b9fd115da36 100644 --- a/sound/pci/asihpi/hpi_internal.h +++ b/sound/pci/asihpi/hpi_internal.h @@ -607,7 +607,7 @@ struct hpi_data_compat32 { #endif struct hpi_buffer { - /** placehoder for backward compatability (see dwBufferSize) */ + /** placehoder for backward compatibility (see dwBufferSize) */ struct hpi_msg_format reserved; u32 command; /**< HPI_BUFFER_CMD_xxx*/ u32 pci_address; /**< PCI physical address of buffer for DSP DMA */ diff --git a/sound/pci/asihpi/hpimsgx.c b/sound/pci/asihpi/hpimsgx.c index bcbdf30a6aa0..360028b9abf5 100644 --- a/sound/pci/asihpi/hpimsgx.c +++ b/sound/pci/asihpi/hpimsgx.c @@ -722,7 +722,7 @@ static u16 HPIMSGX__init(struct hpi_message *phm, return phr->error; } if (hr.error == 0) { - /* the adapter was created succesfully + /* the adapter was created successfully save the mapping for future use */ hpi_entry_points[hr.u.s.adapter_index] = entry_point_func; /* prepare adapter (pre-open streams etc.) */ diff --git a/sound/pci/au88x0/au88x0.h b/sound/pci/au88x0/au88x0.h index ecb8f4daf408..02f6e08f7592 100644 --- a/sound/pci/au88x0/au88x0.h +++ b/sound/pci/au88x0/au88x0.h @@ -104,7 +104,7 @@ #define MIX_PLAYB(x) (vortex->mixplayb[x]) #define MIX_SPDIF(x) (vortex->mixspdif[x]) -#define NR_WTPB 0x20 /* WT channels per eahc bank. */ +#define NR_WTPB 0x20 /* WT channels per each bank. */ /* Structs */ typedef struct { diff --git a/sound/pci/au88x0/au88x0_a3d.c b/sound/pci/au88x0/au88x0_a3d.c index f4aa8ff6f5f9..9ae8b3b17651 100644 --- a/sound/pci/au88x0/au88x0_a3d.c +++ b/sound/pci/au88x0/au88x0_a3d.c @@ -53,7 +53,7 @@ a3dsrc_GetTimeConsts(a3dsrc_t * a, short *HrtfTrack, short *ItdTrack, } #endif -/* Atmospheric absorbtion. */ +/* Atmospheric absorption. */ static void a3dsrc_SetAtmosTarget(a3dsrc_t * a, short aa, short b, short c, short d, @@ -835,7 +835,7 @@ snd_vortex_a3d_filter_put(struct snd_kcontrol *kcontrol, params[i] = ucontrol->value.integer.value[i]; /* Translate generic filter params to a3d filter params. */ vortex_a3d_translate_filter(a->filter, params); - /* Atmospheric absorbtion and filtering. */ + /* Atmospheric absorption and filtering. */ a3dsrc_SetAtmosTarget(a, a->filter[0], a->filter[1], a->filter[2], a->filter[3], a->filter[4]); diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c index 5439d662d104..33f0ba5559a7 100644 --- a/sound/pci/au88x0/au88x0_pcm.c +++ b/sound/pci/au88x0/au88x0_pcm.c @@ -515,7 +515,7 @@ static int __devinit snd_vortex_new_pcm(vortex_t *chip, int idx, int nr) return -ENODEV; /* idx indicates which kind of PCM device. ADB, SPDIF, I2S and A3D share the - * same dma engine. WT uses it own separate dma engine whcih cant capture. */ + * same dma engine. WT uses it own separate dma engine which can't capture. */ if (idx == VORTEX_PCM_ADB) nr_capt = nr; else diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c index 5715c4d05573..9b7a6346037a 100644 --- a/sound/pci/azt3328.c +++ b/sound/pci/azt3328.c @@ -140,7 +140,7 @@ * Possible remedies: * - use speaker (amplifier) output instead of headphone output * (in case crackling is due to overloaded output clipping) - * - plug card into a different PCI slot, preferrably one that isn't shared + * - plug card into a different PCI slot, preferably one that isn't shared * too much (this helps a lot, but not completely!) * - get rid of PCI VGA card, use AGP instead * - upgrade or downgrade BIOS diff --git a/sound/pci/ca0106/ca0106.h b/sound/pci/ca0106/ca0106.h index fc53b9bca26d..e8e8ccc96403 100644 --- a/sound/pci/ca0106/ca0106.h +++ b/sound/pci/ca0106/ca0106.h @@ -51,7 +51,7 @@ * Add support for mute control on SB Live 24bit (cards w/ SPI DAC) * * - * This code was initally based on code from ALSA's emu10k1x.c which is: + * This code was initially based on code from ALSA's emu10k1x.c which is: * Copyright (c) by Francisco Moraes * * This program is free software; you can redistribute it and/or modify @@ -175,7 +175,7 @@ /* CA0106 pointer-offset register set, accessed through the PTR and DATA registers */ /********************************************************************************************************/ -/* Initally all registers from 0x00 to 0x3f have zero contents. */ +/* Initially all registers from 0x00 to 0x3f have zero contents. */ #define PLAYBACK_LIST_ADDR 0x00 /* Base DMA address of a list of pointers to each period/size */ /* One list entry: 4 bytes for DMA address, * 4 bytes for period_size << 16. @@ -223,7 +223,7 @@ * The jack has 4 poles. I will call 1 - Tip, 2 - Next to 1, 3 - Next to 2, 4 - Next to 3 * For Analogue: 1 -> Center Speaker, 2 -> Sub Woofer, 3 -> Ground, 4 -> Ground * For Digital: 1 -> Front SPDIF, 2 -> Rear SPDIF, 3 -> Center/Subwoofer SPDIF, 4 -> Ground. - * Standard 4 pole Video A/V cable with RCA outputs: 1 -> White, 2 -> Yellow, 3 -> Sheild on all three, 4 -> Red. + * Standard 4 pole Video A/V cable with RCA outputs: 1 -> White, 2 -> Yellow, 3 -> Shield on all three, 4 -> Red. * So, from this you can see that you cannot use a Standard 4 pole Video A/V cable with the SB Audigy LS card. */ /* The Front SPDIF PCM gets mixed with samples from the AC97 codec, so can only work for Stereo PCM and not AC3/DTS diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index 01b49388fafd..437759239694 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c @@ -117,7 +117,7 @@ * DAC: Unknown * Trying to handle it like the SB0410. * - * This code was initally based on code from ALSA's emu10k1x.c which is: + * This code was initially based on code from ALSA's emu10k1x.c which is: * Copyright (c) by Francisco Moraes * * This program is free software; you can redistribute it and/or modify diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c index 630aa4998189..84f3f92436b5 100644 --- a/sound/pci/ca0106/ca0106_mixer.c +++ b/sound/pci/ca0106/ca0106_mixer.c @@ -42,7 +42,7 @@ * 0.0.18 * Add support for mute control on SB Live 24bit (cards w/ SPI DAC) * - * This code was initally based on code from ALSA's emu10k1x.c which is: + * This code was initially based on code from ALSA's emu10k1x.c which is: * Copyright (c) by Francisco Moraes * * This program is free software; you can redistribute it and/or modify diff --git a/sound/pci/ca0106/ca0106_proc.c b/sound/pci/ca0106/ca0106_proc.c index ba96428c9f4c..c694464b1168 100644 --- a/sound/pci/ca0106/ca0106_proc.c +++ b/sound/pci/ca0106/ca0106_proc.c @@ -42,7 +42,7 @@ * 0.0.18 * Implement support for Line-in capture on SB Live 24bit. * - * This code was initally based on code from ALSA's emu10k1x.c which is: + * This code was initially based on code from ALSA's emu10k1x.c which is: * Copyright (c) by Francisco Moraes * * This program is free software; you can redistribute it and/or modify diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index b5bb036ef73c..f4e573555da3 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -73,7 +73,7 @@ MODULE_PARM_DESC(mpu_port, "MPU-401 port."); module_param_array(fm_port, long, NULL, 0444); MODULE_PARM_DESC(fm_port, "FM port."); module_param_array(soft_ac3, bool, NULL, 0444); -MODULE_PARM_DESC(soft_ac3, "Sofware-conversion of raw SPDIF packets (model 033 only)."); +MODULE_PARM_DESC(soft_ac3, "Software-conversion of raw SPDIF packets (model 033 only)."); #ifdef SUPPORT_JOYSTICK module_param_array(joystick_port, int, NULL, 0444); MODULE_PARM_DESC(joystick_port, "Joystick port address."); @@ -656,8 +656,8 @@ out: } /* - * Program pll register bits, I assume that the 8 registers 0xf8 upto 0xff - * are mapped onto the 8 ADC/DAC sampling frequency which can be choosen + * Program pll register bits, I assume that the 8 registers 0xf8 up to 0xff + * are mapped onto the 8 ADC/DAC sampling frequency which can be chosen * at the register CM_REG_FUNCTRL1 (0x04). * Problem: other ways are also possible (any information about that?) */ @@ -666,7 +666,7 @@ static void snd_cmipci_set_pll(struct cmipci *cm, unsigned int rate, unsigned in unsigned int reg = CM_REG_PLL + slot; /* * Guess that this programs at reg. 0x04 the pos 15:13/12:10 - * for DSFC/ASFC (000 upto 111). + * for DSFC/ASFC (000 up to 111). */ /* FIXME: Init (Do we've to set an other register first before programming?) */ diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c index b9321544c31c..13f33c0719d3 100644 --- a/sound/pci/ctxfi/ctatc.c +++ b/sound/pci/ctxfi/ctatc.c @@ -1627,7 +1627,7 @@ static struct ct_atc atc_preset __devinitdata = { * Creates and initializes a hardware manager. * * Creates kmallocated ct_atc structure. Initializes hardware. - * Returns 0 if suceeds, or negative error code if fails. + * Returns 0 if succeeds, or negative error code if fails. */ int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci, diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c index 0cf400f879f9..a5c957db5cea 100644 --- a/sound/pci/ctxfi/cthw20k1.c +++ b/sound/pci/ctxfi/cthw20k1.c @@ -1285,7 +1285,7 @@ static int hw_trn_init(struct hw *hw, const struct trn_conf *info) hw_write_20kx(hw, PTPALX, ptp_phys_low); hw_write_20kx(hw, PTPAHX, ptp_phys_high); hw_write_20kx(hw, TRNCTL, trnctl); - hw_write_20kx(hw, TRNIS, 0x200c01); /* realy needed? */ + hw_write_20kx(hw, TRNIS, 0x200c01); /* really needed? */ return 0; } diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c index 957a311514c8..c250614dadd0 100644 --- a/sound/pci/emu10k1/memory.c +++ b/sound/pci/emu10k1/memory.c @@ -248,7 +248,7 @@ static int is_valid_page(struct snd_emu10k1 *emu, dma_addr_t addr) /* * map the given memory block on PTB. * if the block is already mapped, update the link order. - * if no empty pages are found, tries to release unsed memory blocks + * if no empty pages are found, tries to release unused memory blocks * and retry the mapping. */ int snd_emu10k1_memblk_map(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk) diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c index 61b8ab39800f..a81dc44228ea 100644 --- a/sound/pci/emu10k1/p16v.c +++ b/sound/pci/emu10k1/p16v.c @@ -69,7 +69,7 @@ * ADC: Philips 1361T (Stereo 24bit) * DAC: CS4382-K (8-channel, 24bit, 192Khz) * - * This code was initally based on code from ALSA's emu10k1x.c which is: + * This code was initially based on code from ALSA's emu10k1x.c which is: * Copyright (c) by Francisco Moraes * * This program is free software; you can redistribute it and/or modify diff --git a/sound/pci/emu10k1/p16v.h b/sound/pci/emu10k1/p16v.h index 00f4817533b1..4e0ee1a9747a 100644 --- a/sound/pci/emu10k1/p16v.h +++ b/sound/pci/emu10k1/p16v.h @@ -59,7 +59,7 @@ * ADC: Philips 1361T (Stereo 24bit) * DAC: CS4382-K (8-channel, 24bit, 192Khz) * - * This code was initally based on code from ALSA's emu10k1x.c which is: + * This code was initially based on code from ALSA's emu10k1x.c which is: * Copyright (c) by Francisco Moraes * * This program is free software; you can redistribute it and/or modify @@ -86,7 +86,7 @@ * The sample rate is also controlled by the same registers that control the rate of the EMU10K2 sample rate converters. */ -/* Initally all registers from 0x00 to 0x3f have zero contents. */ +/* Initially all registers from 0x00 to 0x3f have zero contents. */ #define PLAYBACK_LIST_ADDR 0x00 /* Base DMA address of a list of pointers to each period/size */ /* One list entry: 4 bytes for DMA address, * 4 bytes for period_size << 16. diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 2c79e96d0324..430f41db6044 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -3661,7 +3661,7 @@ int snd_hda_codec_build_pcms(struct hda_codec *codec) * with the proper parameters for set up. * ops.cleanup should be called in hw_free for clean up of streams. * - * This function returns 0 if successfull, or a negative error code. + * This function returns 0 if successful, or a negative error code. */ int __devinit snd_hda_build_pcms(struct hda_bus *bus) { @@ -4851,7 +4851,7 @@ EXPORT_SYMBOL_HDA(snd_hda_suspend); * * Returns 0 if successful. * - * This fucntion is defined only when POWER_SAVE isn't set. + * This function is defined only when POWER_SAVE isn't set. * In the power-save mode, the codec is resumed dynamically. */ int snd_hda_resume(struct hda_bus *bus) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 0ef0035fe99f..1e5a786c8c27 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -549,7 +549,7 @@ static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, /* * Control the mode of pin widget settings via the mixer. "pc" is used - * instead of "%" to avoid consequences of accidently treating the % as + * instead of "%" to avoid consequences of accidentally treating the % as * being part of a format specifier. Maximum allowed length of a value is * 63 characters plus NULL terminator. * @@ -9836,7 +9836,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), - SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), + SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavilion", ALC883_6ST_DIG), SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG), diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 05fcd60cc46f..1395991c39f2 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -2475,7 +2475,7 @@ static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol, spec->hp_switch = ucontrol->value.integer.value[0] ? nid : 0; - /* check to be sure that the ports are upto date with + /* check to be sure that the ports are up to date with * switch changes */ stac_issue_unsol_event(codec, nid); diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c index 2f6252266a02..3e4f8c12ffce 100644 --- a/sound/pci/ice1712/aureon.c +++ b/sound/pci/ice1712/aureon.c @@ -148,7 +148,7 @@ static void aureon_pca9554_write(struct snd_ice1712 *ice, unsigned char reg, udelay(100); /* * send device address, command and value, - * skipping ack cycles inbetween + * skipping ack cycles in between */ for (j = 0; j < 3; j++) { switch (j) { @@ -2143,7 +2143,7 @@ static int __devinit aureon_init(struct snd_ice1712 *ice) ice->num_total_adcs = 2; } - /* to remeber the register values of CS8415 */ + /* to remember the register values of CS8415 */ ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); if (!ice->akm) return -ENOMEM; diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index 4fc6d8bc637e..f4594d76b6ea 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c @@ -2755,7 +2755,7 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci, return err; } if (c->mpu401_1_name) - /* Prefered name available in card_info */ + /* Preferred name available in card_info */ snprintf(ice->rmidi[0]->name, sizeof(ice->rmidi[0]->name), "%s %d", c->mpu401_1_name, card->number); @@ -2772,7 +2772,7 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci, return err; } if (c->mpu401_2_name) - /* Prefered name available in card_info */ + /* Preferred name available in card_info */ snprintf(ice->rmidi[1]->name, sizeof(ice->rmidi[1]->name), "%s %d", c->mpu401_2_name, diff --git a/sound/pci/ice1712/pontis.c b/sound/pci/ice1712/pontis.c index cdb873f5da50..92c1160d7ab5 100644 --- a/sound/pci/ice1712/pontis.c +++ b/sound/pci/ice1712/pontis.c @@ -768,7 +768,7 @@ static int __devinit pontis_init(struct snd_ice1712 *ice) ice->num_total_dacs = 2; ice->num_total_adcs = 2; - /* to remeber the register values */ + /* to remember the register values */ ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); if (! ice->akm) return -ENOMEM; diff --git a/sound/pci/ice1712/prodigy_hifi.c b/sound/pci/ice1712/prodigy_hifi.c index 6a9fee3ee78f..764cc93dbca4 100644 --- a/sound/pci/ice1712/prodigy_hifi.c +++ b/sound/pci/ice1712/prodigy_hifi.c @@ -1046,7 +1046,7 @@ static int __devinit prodigy_hifi_init(struct snd_ice1712 *ice) * don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten */ ice->gpio.saved[0] = 0; - /* to remeber the register values */ + /* to remember the register values */ ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); if (! ice->akm) @@ -1128,7 +1128,7 @@ static int __devinit prodigy_hd2_init(struct snd_ice1712 *ice) * don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten */ ice->gpio.saved[0] = 0; - /* to remeber the register values */ + /* to remember the register values */ ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); if (! ice->akm) diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 629a5494347a..6c896dbfd796 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -534,7 +534,7 @@ static int snd_intel8x0_codec_semaphore(struct intel8x0 *chip, unsigned int code udelay(10); } while (time--); - /* access to some forbidden (non existant) ac97 registers will not + /* access to some forbidden (non existent) ac97 registers will not * reset the semaphore. So even if you don't get the semaphore, still * continue the access. We don't need the semaphore anyway. */ snd_printk(KERN_ERR "codec_semaphore: semaphore is not ready [0x%x][0x%x]\n", diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c index 2ae8d29500a8..27709f0cd2a6 100644 --- a/sound/pci/intel8x0m.c +++ b/sound/pci/intel8x0m.c @@ -331,7 +331,7 @@ static int snd_intel8x0m_codec_semaphore(struct intel8x0m *chip, unsigned int co udelay(10); } while (time--); - /* access to some forbidden (non existant) ac97 registers will not + /* access to some forbidden (non existent) ac97 registers will not * reset the semaphore. So even if you don't get the semaphore, still * continue the access. We don't need the semaphore anyway. */ snd_printk(KERN_ERR "codec_semaphore: semaphore is not ready [0x%x][0x%x]\n", diff --git a/sound/pci/mixart/mixart_core.c b/sound/pci/mixart/mixart_core.c index d3350f383966..3df0f530f67c 100644 --- a/sound/pci/mixart/mixart_core.c +++ b/sound/pci/mixart/mixart_core.c @@ -265,7 +265,7 @@ int snd_mixart_send_msg(struct mixart_mgr *mgr, struct mixart_msg *request, int if (! timeout) { /* error - no ack */ mutex_unlock(&mgr->msg_mutex); - snd_printk(KERN_ERR "error: no reponse on msg %x\n", msg_frame); + snd_printk(KERN_ERR "error: no response on msg %x\n", msg_frame); return -EIO; } @@ -278,7 +278,7 @@ int snd_mixart_send_msg(struct mixart_mgr *mgr, struct mixart_msg *request, int err = get_msg(mgr, &resp, msg_frame); if( request->message_id != resp.message_id ) - snd_printk(KERN_ERR "REPONSE ERROR!\n"); + snd_printk(KERN_ERR "RESPONSE ERROR!\n"); mutex_unlock(&mgr->msg_mutex); return err; diff --git a/sound/pci/pcxhr/pcxhr_core.c b/sound/pci/pcxhr/pcxhr_core.c index 833e7180ad2d..304411c1fe4b 100644 --- a/sound/pci/pcxhr/pcxhr_core.c +++ b/sound/pci/pcxhr/pcxhr_core.c @@ -1042,11 +1042,11 @@ void pcxhr_msg_tasklet(unsigned long arg) int i, j; if (mgr->src_it_dsp & PCXHR_IRQ_FREQ_CHANGE) - snd_printdd("TASKLET : PCXHR_IRQ_FREQ_CHANGE event occured\n"); + snd_printdd("TASKLET : PCXHR_IRQ_FREQ_CHANGE event occurred\n"); if (mgr->src_it_dsp & PCXHR_IRQ_TIME_CODE) - snd_printdd("TASKLET : PCXHR_IRQ_TIME_CODE event occured\n"); + snd_printdd("TASKLET : PCXHR_IRQ_TIME_CODE event occurred\n"); if (mgr->src_it_dsp & PCXHR_IRQ_NOTIFY) - snd_printdd("TASKLET : PCXHR_IRQ_NOTIFY event occured\n"); + snd_printdd("TASKLET : PCXHR_IRQ_NOTIFY event occurred\n"); if (mgr->src_it_dsp & (PCXHR_IRQ_FREQ_CHANGE | PCXHR_IRQ_TIME_CODE)) { /* clear events FREQ_CHANGE and TIME_CODE */ pcxhr_init_rmh(prmh, CMD_TEST_IT); @@ -1055,7 +1055,7 @@ void pcxhr_msg_tasklet(unsigned long arg) err, prmh->stat[0]); } if (mgr->src_it_dsp & PCXHR_IRQ_ASYNC) { - snd_printdd("TASKLET : PCXHR_IRQ_ASYNC event occured\n"); + snd_printdd("TASKLET : PCXHR_IRQ_ASYNC event occurred\n"); pcxhr_init_rmh(prmh, CMD_ASYNC); prmh->cmd[0] |= 1; /* add SEL_ASYNC_EVENTS */ @@ -1233,7 +1233,7 @@ irqreturn_t pcxhr_interrupt(int irq, void *dev_id) reg = PCXHR_INPL(mgr, PCXHR_PLX_L2PCIDB); PCXHR_OUTPL(mgr, PCXHR_PLX_L2PCIDB, reg); - /* timer irq occured */ + /* timer irq occurred */ if (reg & PCXHR_IRQ_TIMER) { int timer_toggle = reg & PCXHR_IRQ_TIMER; /* is a 24 bit counter */ @@ -1288,7 +1288,7 @@ irqreturn_t pcxhr_interrupt(int irq, void *dev_id) if (reg & PCXHR_IRQ_MASK) { if (reg & PCXHR_IRQ_ASYNC) { /* as we didn't request any async notifications, - * some kind of xrun error will probably occured + * some kind of xrun error will probably occurred */ /* better resynchronize all streams next interrupt : */ mgr->dsp_time_last = PCXHR_DSP_TIME_INVALID; diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c index d5f5b440fc40..9ff247fc8871 100644 --- a/sound/pci/rme96.c +++ b/sound/pci/rme96.c @@ -150,7 +150,7 @@ MODULE_PARM_DESC(enable, "Enable RME Digi96 soundcard."); #define RME96_RCR_BITPOS_F1 28 #define RME96_RCR_BITPOS_F2 29 -/* Additonal register bits */ +/* Additional register bits */ #define RME96_AR_WSEL (1 << 0) #define RME96_AR_ANALOG (1 << 1) #define RME96_AR_FREQPAD_0 (1 << 2) diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index a323eafb9e03..949691a876d3 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -391,7 +391,7 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); /* Status2 Register bits */ /* MADI ONLY */ -#define HDSPM_version0 (1<<0) /* not realy defined but I guess */ +#define HDSPM_version0 (1<<0) /* not really defined but I guess */ #define HDSPM_version1 (1<<1) /* in former cards it was ??? */ #define HDSPM_version2 (1<<2) @@ -936,7 +936,7 @@ struct hdspm { struct snd_kcontrol *playback_mixer_ctls[HDSPM_MAX_CHANNELS]; /* but input to much, so not used */ struct snd_kcontrol *input_mixer_ctls[HDSPM_MAX_CHANNELS]; - /* full mixer accessable over mixer ioctl or hwdep-device */ + /* full mixer accessible over mixer ioctl or hwdep-device */ struct hdspm_mixer *mixer; struct hdspm_tco *tco; /* NULL if no TCO detected */ diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c index 1b8f6742b5fa..2b5c7a95ae1f 100644 --- a/sound/pci/sis7019.c +++ b/sound/pci/sis7019.c @@ -308,7 +308,7 @@ static irqreturn_t sis_interrupt(int irq, void *dev) u32 intr, status; /* We only use the DMA interrupts, and we don't enable any other - * source of interrupts. But, it is possible to see an interupt + * source of interrupts. But, it is possible to see an interrupt * status that didn't actually interrupt us, so eliminate anything * we're not expecting to avoid falsely claiming an IRQ, and an * ensuing endless loop. @@ -773,7 +773,7 @@ static void sis_prepare_timing_voice(struct voice *voice, vperiod = 0; } - /* The interrupt handler implements the timing syncronization, so + /* The interrupt handler implements the timing synchronization, so * setup its state. */ timing->flags |= VOICE_SYNC_TIMING; @@ -1139,7 +1139,7 @@ static int sis_chip_init(struct sis7019 *sis) */ outl(SIS_DMA_CSR_PCI_SETTINGS, io + SIS_DMA_CSR); - /* Reset the syncronization groups for all of the channels + /* Reset the synchronization groups for all of the channels * to be asyncronous. If we start doing SPDIF or 5.1 sound, etc. * we'll need to change how we handle these. Until then, we just * assign sub-mixer 0 to all playback channels, and avoid any diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c index edce8a27e3ee..bc823a547550 100644 --- a/sound/ppc/snd_ps3.c +++ b/sound/ppc/snd_ps3.c @@ -358,7 +358,7 @@ static irqreturn_t snd_ps3_interrupt(int irq, void *dev_id) * filling dummy data, serial automatically start to * consume them and then will generate normal buffer * empty interrupts. - * If both buffer underflow and buffer empty are occured, + * If both buffer underflow and buffer empty are occurred, * it is better to do nomal data transfer than empty one */ snd_ps3_program_dma(card, diff --git a/sound/ppc/snd_ps3_reg.h b/sound/ppc/snd_ps3_reg.h index 03fdee4aaaf2..2e6302079566 100644 --- a/sound/ppc/snd_ps3_reg.h +++ b/sound/ppc/snd_ps3_reg.h @@ -125,7 +125,7 @@ transfers. Any interrupts associated with the canceled transfers will occur as if the transfer had finished. Since this bit is designed to recover from DMA related issues - which are caused by unpredictable situations, it is prefered to wait + which are caused by unpredictable situations, it is preferred to wait for normal DMA transfer end without using this bit. */ #define PS3_AUDIO_CONFIG_CLEAR (1 << 8) /* RWIVF */ @@ -316,13 +316,13 @@ DISABLED=Interrupt generation disabled. /* Audio Port Interrupt Status Register -Indicates Interrupt status, which interrupt has occured, and can clear +Indicates Interrupt status, which interrupt has occurred, and can clear each interrupt in this register. Writing 1b to a field containing 1b clears field and de-asserts interrupt. Writing 0b to a field has no effect. Field vaules are the following: -0 - Interrupt hasn't occured. -1 - Interrupt has occured. +0 - Interrupt hasn't occurred. +1 - Interrupt has occurred. 31 24 23 16 15 8 7 0 @@ -473,7 +473,7 @@ Channel N is out of action by setting 0 to asoen. /* Sampling Rate Specifies the divide ratio of the bit clock (clock output -from bclko) used by the 3-wire Audio Output Clock, whcih +from bclko) used by the 3-wire Audio Output Clock, which is applied to the master clock selected by mcksel. Data output is synchronized with this clock. */ @@ -756,7 +756,7 @@ The STATUS field can be used to monitor the progress of a DMA request. DONE indicates the previous request has completed. EVENT indicates that the DMA engine is waiting for the EVENT to occur. PENDING indicates that the DMA engine has not started processing this -request, but the EVENT has occured. +request, but the EVENT has occurred. DMA indicates that the data transfer is in progress. NOTIFY indicates that the notifier signalling end of transfer is being written. CLEAR indicated that the previous transfer was cleared. @@ -824,7 +824,7 @@ AUDIOFIFO = Audio WriteData FIFO, /* PS3_AUDIO_DMASIZE specifies the number of 128-byte blocks + 1 to transfer. -So a value of 0 means 128-bytes will get transfered. +So a value of 0 means 128-bytes will get transferred. 31 24 23 16 15 8 7 0 diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c index 5d230cee3fa7..7fbfa051f6e1 100644 --- a/sound/soc/atmel/atmel_ssc_dai.c +++ b/sound/soc/atmel/atmel_ssc_dai.c @@ -672,7 +672,7 @@ static int atmel_ssc_resume(struct snd_soc_dai *cpu_dai) /* re-enable interrupts */ ssc_writel(ssc_p->ssc->regs, IER, ssc_p->ssc_state.ssc_imr); - /* Re-enable recieve and transmit as appropriate */ + /* Re-enable receive and transmit as appropriate */ cr = 0; cr |= (ssc_p->ssc_state.ssc_sr & SSC_BIT(SR_RXEN)) ? SSC_BIT(CR_RXEN) : 0; diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c index 4f377c9e868d..eecffb548947 100644 --- a/sound/soc/codecs/alc5623.c +++ b/sound/soc/codecs/alc5623.c @@ -481,7 +481,7 @@ struct _pll_div { }; /* Note : pll code from original alc5623 driver. Not sure of how good it is */ -/* usefull only for master mode */ +/* useful only for master mode */ static const struct _pll_div codec_master_pll_div[] = { { 2048000, 8192000, 0x0ea0}, diff --git a/sound/soc/codecs/lm4857.c b/sound/soc/codecs/lm4857.c index 72de47e5d040..2c2a681da0d7 100644 --- a/sound/soc/codecs/lm4857.c +++ b/sound/soc/codecs/lm4857.c @@ -161,7 +161,7 @@ static const struct snd_kcontrol_new lm4857_controls[] = { lm4857_get_mode, lm4857_set_mode), }; -/* There is a demux inbetween the the input signal and the output signals. +/* There is a demux between the input signal and the output signals. * Currently there is no easy way to model it in ASoC and since it does not make * much of a difference in practice simply connect the input direclty to the * outputs. */ diff --git a/sound/soc/codecs/tlv320aic26.h b/sound/soc/codecs/tlv320aic26.h index 62b1f2261429..67f19c3bebe6 100644 --- a/sound/soc/codecs/tlv320aic26.h +++ b/sound/soc/codecs/tlv320aic26.h @@ -14,14 +14,14 @@ #define AIC26_PAGE_ADDR(page, offset) ((page << 6) | offset) #define AIC26_NUM_REGS AIC26_PAGE_ADDR(3, 0) -/* Page 0: Auxillary data registers */ +/* Page 0: Auxiliary data registers */ #define AIC26_REG_BAT1 AIC26_PAGE_ADDR(0, 0x05) #define AIC26_REG_BAT2 AIC26_PAGE_ADDR(0, 0x06) #define AIC26_REG_AUX AIC26_PAGE_ADDR(0, 0x07) #define AIC26_REG_TEMP1 AIC26_PAGE_ADDR(0, 0x09) #define AIC26_REG_TEMP2 AIC26_PAGE_ADDR(0, 0x0A) -/* Page 1: Auxillary control registers */ +/* Page 1: Auxiliary control registers */ #define AIC26_REG_AUX_ADC AIC26_PAGE_ADDR(1, 0x00) #define AIC26_REG_STATUS AIC26_PAGE_ADDR(1, 0x01) #define AIC26_REG_REFERENCE AIC26_PAGE_ADDR(1, 0x03) diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 3bedab26892f..6c43c13f0430 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -884,7 +884,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream, if (bypass_pll) return 0; - /* Use PLL, compute apropriate setup for j, d, r and p, the closest + /* Use PLL, compute appropriate setup for j, d, r and p, the closest * one wins the game. Try with d==0 first, next with d!=0. * Constraints for j are according to the datasheet. * The sysclk is divided by 1000 to prevent integer overflows. diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index 00b6d87e7bdb..f01f1417da41 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -1020,7 +1020,7 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream) /* * For FIFO bypass mode: * Enable the FIFO bypass (Disable the FIFO use) - * Set the BCLK as continous + * Set the BCLK as continuous */ fifoctrl_a |= DAC33_FBYPAS; aictrl_b |= DAC33_BCLKON; diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 8512800f6326..575238d68e5e 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -281,7 +281,7 @@ static inline void twl4030_check_defaults(struct snd_soc_codec *codec) i, val, twl4030_reg[i]); } } - dev_dbg(codec->dev, "Found %d non maching registers. %s\n", + dev_dbg(codec->dev, "Found %d non-matching registers. %s\n", difference, difference ? "Not OK" : "OK"); } @@ -2018,7 +2018,7 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream, u8 mode; /* If the system master clock is not 26MHz, the voice PCM interface is - * not avilable. + * not available. */ if (twl4030->sysclk != 26000) { dev_err(codec->dev, "The board is configured for %u Hz, while" @@ -2028,7 +2028,7 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream, } /* If the codec mode is not option2, the voice PCM interface is not - * avilable. + * available. */ mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE) & TWL4030_OPT_MODE; diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c index 8f6b5ee6645b..4bbc0a79f01e 100644 --- a/sound/soc/codecs/wm8580.c +++ b/sound/soc/codecs/wm8580.c @@ -772,7 +772,7 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec, reg &= ~(WM8580_PWRDN1_PWDN | WM8580_PWRDN1_ALLDACPD); snd_soc_write(codec, WM8580_PWRDN1, reg); - /* Make VMID high impedence */ + /* Make VMID high impedance */ reg = snd_soc_read(codec, WM8580_ADC_CONTROL1); reg &= ~0x100; snd_soc_write(codec, WM8580_ADC_CONTROL1, reg); diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index 3f09deea8d9d..ffa2ffe5ec11 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c @@ -1312,7 +1312,7 @@ static int wm8753_set_bias_level(struct snd_soc_codec *codec, SNDRV_PCM_FMTBIT_S24_LE) /* - * The WM8753 supports upto 4 different and mutually exclusive DAI + * The WM8753 supports up to 4 different and mutually exclusive DAI * configurations. This gives 2 PCM's available for use, hifi and voice. * NOTE: The Voice PCM cannot play or capture audio to the CPU as it's DAI * is connected between the wm8753 and a BT codec or GSM modem. diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 443ae580445c..9b3bba4df5b3 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -1895,7 +1895,7 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref, pr_debug("Fvco=%dHz\n", target); - /* Find an appropraite FLL_FRATIO and factor it out of the target */ + /* Find an appropriate FLL_FRATIO and factor it out of the target */ for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) { if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) { fll_div->fll_fratio = fll_fratios[i].fll_fratio; diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index 5e0214d6293e..3c7198779c31 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c @@ -176,7 +176,7 @@ static int wm8995_pll_factors(struct device *dev, return 0; } -/* Lookup table specifiying SRATE (table 25 in datasheet); some of the +/* Lookup table specifying SRATE (table 25 in datasheet); some of the * output frequencies have been rounded to the standard frequencies * they are intended to match where the error is slight. */ static struct { diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 3b71dd65c966..500011eb8b2b 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -3137,7 +3137,7 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref, pr_debug("FLL Fvco=%dHz\n", target); - /* Find an appropraite FLL_FRATIO and factor it out of the target */ + /* Find an appropriate FLL_FRATIO and factor it out of the target */ for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) { if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) { fll_div->fll_fratio = fll_fratios[i].fll_fratio; diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c index 28fdfd66661d..3c2ee1bb73cd 100644 --- a/sound/soc/codecs/wm8991.c +++ b/sound/soc/codecs/wm8991.c @@ -981,7 +981,7 @@ static int wm8991_set_dai_pll(struct snd_soc_dai *codec_dai, reg = snd_soc_read(codec, WM8991_CLOCKING_2); snd_soc_write(codec, WM8991_CLOCKING_2, reg | WM8991_SYSCLK_SRC); - /* set up N , fractional mode and pre-divisor if neccessary */ + /* set up N , fractional mode and pre-divisor if necessary */ snd_soc_write(codec, WM8991_PLL1, pll_div.n | WM8991_SDM | (pll_div.div2 ? WM8991_PRESCALE : 0)); snd_soc_write(codec, WM8991_PLL2, (u8)(pll_div.k>>8)); diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index 379fa22c5b6c..056aef904347 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c @@ -324,7 +324,7 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref, pr_debug("Fvco=%dHz\n", target); - /* Find an appropraite FLL_FRATIO and factor it out of the target */ + /* Find an appropriate FLL_FRATIO and factor it out of the target */ for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) { if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) { fll_div->fll_fratio = fll_fratios[i].fll_fratio; diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 3dc64c8b6a5c..3290333b2bb9 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -82,18 +82,18 @@ struct wm8994_priv { int mbc_ena[3]; - /* Platform dependant DRC configuration */ + /* Platform dependent DRC configuration */ const char **drc_texts; int drc_cfg[WM8994_NUM_DRC]; struct soc_enum drc_enum; - /* Platform dependant ReTune mobile configuration */ + /* Platform dependent ReTune mobile configuration */ int num_retune_mobile_texts; const char **retune_mobile_texts; int retune_mobile_cfg[WM8994_NUM_EQ]; struct soc_enum retune_mobile_enum; - /* Platform dependant MBC configuration */ + /* Platform dependent MBC configuration */ int mbc_cfg; const char **mbc_texts; struct soc_enum mbc_enum; diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index 55cdf2982020..91c6b39de50c 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c @@ -305,7 +305,7 @@ static int speaker_mode_get(struct snd_kcontrol *kcontrol, /* * Stop any attempts to change speaker mode while the speaker is enabled. * - * We also have some special anti-pop controls dependant on speaker + * We also have some special anti-pop controls dependent on speaker * mode which must be changed along with the mode. */ static int speaker_mode_put(struct snd_kcontrol *kcontrol, @@ -456,7 +456,7 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref, pr_debug("Fvco=%dHz\n", target); - /* Find an appropraite FLL_FRATIO and factor it out of the target */ + /* Find an appropriate FLL_FRATIO and factor it out of the target */ for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) { if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) { fll_div->fll_fratio = fll_fratios[i].fll_fratio; diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c index bc92ec620004..ac2ded969253 100644 --- a/sound/soc/imx/imx-ssi.c +++ b/sound/soc/imx/imx-ssi.c @@ -16,7 +16,7 @@ * sane processor vendors have a FIFO per AC97 slot, the i.MX has only * one FIFO which combines all valid receive slots. We cannot even select * which slots we want to receive. The WM9712 with which this driver - * was developped with always sends GPIO status data in slot 12 which + * was developed with always sends GPIO status data in slot 12 which * we receive in our (PCM-) data stream. The only chance we have is to * manually skip this data in the FIQ handler. With sampling rates different * from 48000Hz not every frame has valid receive data, so the ratio diff --git a/sound/soc/kirkwood/kirkwood-dma.c b/sound/soc/kirkwood/kirkwood-dma.c index 0fd6a630db01..e13c6ce46328 100644 --- a/sound/soc/kirkwood/kirkwood-dma.c +++ b/sound/soc/kirkwood/kirkwood-dma.c @@ -132,7 +132,7 @@ static int kirkwood_dma_open(struct snd_pcm_substream *substream) priv = snd_soc_dai_get_dma_data(cpu_dai, substream); snd_soc_set_runtime_hwparams(substream, &kirkwood_dma_snd_hw); - /* Ensure that all constraints linked to dma burst are fullfilled */ + /* Ensure that all constraints linked to dma burst are fulfilled */ err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, priv->burst * 2, @@ -170,7 +170,7 @@ static int kirkwood_dma_open(struct snd_pcm_substream *substream) /* * Enable Error interrupts. We're only ack'ing them but - * it's usefull for diagnostics + * it's useful for diagnostics */ writel((unsigned long)-1, priv->io + KIRKWOOD_ERR_MASK); } diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c index ee2c22475a76..b2e9198a983a 100644 --- a/sound/soc/mid-x86/sst_platform.c +++ b/sound/soc/mid-x86/sst_platform.c @@ -440,7 +440,7 @@ static int sst_platform_remove(struct platform_device *pdev) snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(sst_platform_dai)); snd_soc_unregister_platform(&pdev->dev); - pr_debug("sst_platform_remove sucess\n"); + pr_debug("sst_platform_remove success\n"); return 0; } @@ -463,7 +463,7 @@ module_init(sst_soc_platform_init); static void __exit sst_soc_platform_exit(void) { platform_driver_unregister(&sst_platform_driver); - pr_debug("sst_soc_platform_exit sucess\n"); + pr_debug("sst_soc_platform_exit success\n"); } module_exit(sst_soc_platform_exit); diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c index 3167be689621..462cbcbea74a 100644 --- a/sound/soc/omap/ams-delta.c +++ b/sound/soc/omap/ams-delta.c @@ -248,7 +248,7 @@ static struct snd_soc_jack_pin ams_delta_hook_switch_pins[] = { */ /* To actually apply any modem controlled configuration changes to the codec, - * we must connect codec DAI pins to the modem for a moment. Be carefull not + * we must connect codec DAI pins to the modem for a moment. Be careful not * to interfere with our digital mute function that shares the same hardware. */ static struct timer_list cx81801_timer; static bool cx81801_cmd_pending; @@ -402,9 +402,9 @@ static struct tty_ldisc_ops cx81801_ops = { /* - * Even if not very usefull, the sound card can still work without any of the + * Even if not very useful, the sound card can still work without any of the * above functonality activated. You can still control its audio input/output - * constellation and speakerphone gain from userspace by issueing AT commands + * constellation and speakerphone gain from userspace by issuing AT commands * over the modem port. */ diff --git a/sound/soc/samsung/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c index 78bfdb3f5d7e..452230975632 100644 --- a/sound/soc/samsung/neo1973_wm8753.c +++ b/sound/soc/samsung/neo1973_wm8753.c @@ -228,7 +228,7 @@ static const struct snd_kcontrol_new neo1973_wm8753_controls[] = { SOC_DAPM_PIN_SWITCH("Handset Mic"), }; -/* GTA02 specific routes and controlls */ +/* GTA02 specific routes and controls */ #ifdef CONFIG_MACH_NEO1973_GTA02 @@ -372,7 +372,7 @@ static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd) return 0; } -/* GTA01 specific controlls */ +/* GTA01 specific controls */ #ifdef CONFIG_MACH_NEO1973_GTA01 diff --git a/sound/usb/6fire/firmware.c b/sound/usb/6fire/firmware.c index 9081a54a9c6c..86c1a3103760 100644 --- a/sound/usb/6fire/firmware.c +++ b/sound/usb/6fire/firmware.c @@ -76,7 +76,7 @@ struct ihex_record { u16 address; u8 len; u8 data[256]; - char error; /* true if an error occured parsing this record */ + char error; /* true if an error occurred parsing this record */ u8 max_len; /* maximum record length in whole ihex */ @@ -107,7 +107,7 @@ static u8 usb6fire_fw_ihex_hex(const u8 *data, u8 *crc) /* * returns true if record is available, false otherwise. - * iff an error occured, false will be returned and record->error will be true. + * iff an error occurred, false will be returned and record->error will be true. */ static bool usb6fire_fw_ihex_next_record(struct ihex_record *record) { diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 5e4775716607..6ec33b62e6cf 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -1182,7 +1182,7 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, /* * parse a feature unit * - * most of controlls are defined here. + * most of controls are defined here. */ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void *_ftr) { diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 355759bad581..ec07e62e53f3 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -266,7 +266,7 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip, * audio-interface quirks * * returns zero if no standard audio/MIDI parsing is needed. - * returns a postive value if standard audio/midi interfaces are parsed + * returns a positive value if standard audio/midi interfaces are parsed * after this. * returns a negative value at error. */ diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c index 287ef73b1237..a51340f6f2db 100644 --- a/sound/usb/usx2y/usx2yhwdeppcm.c +++ b/sound/usb/usx2y/usx2yhwdeppcm.c @@ -20,7 +20,7 @@ at standard samplerates, what led to this part of the usx2y module: It provides the alsa kernel half of the usx2y-alsa-jack driver pair. - The pair uses a hardware dependant alsa-device for mmaped pcm transport. + The pair uses a hardware dependent alsa-device for mmaped pcm transport. Advantage achieved: The usb_hc moves pcm data from/into memory via DMA. That memory is mmaped by jack's usx2y driver. @@ -38,7 +38,7 @@ 2periods works but is useless cause of crackling). This is a first "proof of concept" implementation. - Later, functionalities should migrate to more apropriate places: + Later, functionalities should migrate to more appropriate places: Userland: - The jackd could mmap its float-pcm buffers directly from alsa-lib. - alsa-lib could provide power of 2 period sized shaping combined with int/float diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c index 8fc0bd3a3a4a..b9a985dadd08 100644 --- a/tools/perf/util/string.c +++ b/tools/perf/util/string.c @@ -85,7 +85,7 @@ out: /* * Helper function for splitting a string into an argv-like array. - * originaly copied from lib/argv_split.c + * originally copied from lib/argv_split.c */ static const char *skip_sep(const char *cp) { diff --git a/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c b/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c index d9678a34dd70..2618ef2ba31f 100644 --- a/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c +++ b/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c @@ -46,7 +46,7 @@ int cpu = -1; * * performance * Performance is paramount. - * Unwilling to sacrafice any performance + * Unwilling to sacrifice any performance * for the sake of energy saving. (hardware default) * * normal diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c index 3656849f78a0..36d8092dbb3f 100644 --- a/virt/kvm/eventfd.c +++ b/virt/kvm/eventfd.c @@ -578,7 +578,7 @@ kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args) mutex_lock(&kvm->slots_lock); - /* Verify that there isnt a match already */ + /* Verify that there isn't a match already */ if (ioeventfd_check_collision(kvm, p)) { ret = -EEXIST; goto unlock_fail; -- cgit From c0bb9e45f3a7f67fc358946727bc3d5f23d0f55d Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Wed, 25 Aug 2010 10:22:58 +1000 Subject: kdump: Allow shrinking of kdump region to be overridden On ppc64 the crashkernel region almost always overlaps an area of firmware. This works fine except when using the sysfs interface to reduce the kdump region. If we free the firmware area we are guaranteed to crash. Rename free_reserved_phys_range to crash_free_reserved_phys_range and make it a weak function so we can override it. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- include/linux/kexec.h | 1 + kernel/kexec.c | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/kexec.h b/include/linux/kexec.h index 03e8e8dbc577..c2478a342cd7 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -208,6 +208,7 @@ int __init parse_crashkernel(char *cmdline, unsigned long long system_ram, unsigned long long *crash_size, unsigned long long *crash_base); int crash_shrink_memory(unsigned long new_size); size_t crash_get_memory_size(void); +void crash_free_reserved_phys_range(unsigned long begin, unsigned long end); #else /* !CONFIG_KEXEC */ struct pt_regs; diff --git a/kernel/kexec.c b/kernel/kexec.c index ec19b92c7ebd..4e240a378df6 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c @@ -1099,7 +1099,8 @@ size_t crash_get_memory_size(void) return size; } -static void free_reserved_phys_range(unsigned long begin, unsigned long end) +void __weak crash_free_reserved_phys_range(unsigned long begin, + unsigned long end) { unsigned long addr; @@ -1135,7 +1136,7 @@ int crash_shrink_memory(unsigned long new_size) start = roundup(start, PAGE_SIZE); end = roundup(start + new_size, PAGE_SIZE); - free_reserved_phys_range(end, crashk_res.end); + crash_free_reserved_phys_range(end, crashk_res.end); if ((start == end) && (crashk_res.parent != NULL)) release_resource(&crashk_res); -- cgit From 1cb7b1e0de6a1f8f071f4a146e3d10f3a662f707 Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Thu, 31 Mar 2011 13:36:38 +0200 Subject: ACPI EC: remove dead code static void acpi_ec_gpe_query(void *ec_cxt); -> The function is right above this declaration -> not needed. poll_force is also not used, cleaned up in ec.c and its users: compal-laptop and msi-laptop. Signed-off-by: Thomas Renninger Signed-off-by: Len Brown --- drivers/acpi/ec.c | 6 +----- drivers/platform/x86/compal-laptop.c | 12 ++++++------ drivers/platform/x86/msi-laptop.c | 12 ++++++------ include/linux/acpi.h | 3 +-- 4 files changed, 14 insertions(+), 19 deletions(-) (limited to 'include/linux') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index fa848c4116a8..b3f1d6f52a89 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -69,7 +69,6 @@ enum ec_command { #define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ -#define ACPI_EC_CDELAY 10 /* Wait 10us before polling EC */ #define ACPI_EC_MSI_UDELAY 550 /* Wait 550us for MSI EC */ #define ACPI_EC_STORM_THRESHOLD 8 /* number of false interrupts @@ -433,8 +432,7 @@ EXPORT_SYMBOL(ec_write); int ec_transaction(u8 command, const u8 * wdata, unsigned wdata_len, - u8 * rdata, unsigned rdata_len, - int force_poll) + u8 * rdata, unsigned rdata_len) { struct transaction t = {.command = command, .wdata = wdata, .rdata = rdata, @@ -592,8 +590,6 @@ static void acpi_ec_gpe_query(void *ec_cxt) mutex_unlock(&ec->lock); } -static void acpi_ec_gpe_query(void *ec_cxt); - static int ec_check_sci(struct acpi_ec *ec, u8 state) { if (state & ACPI_EC_FLAG_SCI) { diff --git a/drivers/platform/x86/compal-laptop.c b/drivers/platform/x86/compal-laptop.c index 034572b980c9..f4f43e65475f 100644 --- a/drivers/platform/x86/compal-laptop.c +++ b/drivers/platform/x86/compal-laptop.c @@ -200,7 +200,7 @@ static bool extra_features; * watching the output of address 0x4F (do an ec_transaction writing 0x33 * into 0x4F and read a few bytes from the output, like so: * u8 writeData = 0x33; - * ec_transaction(0x4F, &writeData, 1, buffer, 32, 0); + * ec_transaction(0x4F, &writeData, 1, buffer, 32); * That address is labled "fan1 table information" in the service manual. * It should be clear which value in 'buffer' changes). This seems to be * related to fan speed. It isn't a proper 'realtime' fan speed value @@ -286,7 +286,7 @@ static int get_backlight_level(void) static void set_backlight_state(bool on) { u8 data = on ? BACKLIGHT_STATE_ON_DATA : BACKLIGHT_STATE_OFF_DATA; - ec_transaction(BACKLIGHT_STATE_ADDR, &data, 1, NULL, 0, 0); + ec_transaction(BACKLIGHT_STATE_ADDR, &data, 1, NULL, 0); } @@ -294,24 +294,24 @@ static void set_backlight_state(bool on) static void pwm_enable_control(void) { unsigned char writeData = PWM_ENABLE_DATA; - ec_transaction(PWM_ENABLE_ADDR, &writeData, 1, NULL, 0, 0); + ec_transaction(PWM_ENABLE_ADDR, &writeData, 1, NULL, 0); } static void pwm_disable_control(void) { unsigned char writeData = PWM_DISABLE_DATA; - ec_transaction(PWM_DISABLE_ADDR, &writeData, 1, NULL, 0, 0); + ec_transaction(PWM_DISABLE_ADDR, &writeData, 1, NULL, 0); } static void set_pwm(int pwm) { - ec_transaction(PWM_ADDRESS, &pwm_lookup_table[pwm], 1, NULL, 0, 0); + ec_transaction(PWM_ADDRESS, &pwm_lookup_table[pwm], 1, NULL, 0); } static int get_fan_rpm(void) { u8 value, data = FAN_DATA; - ec_transaction(FAN_ADDRESS, &data, 1, &value, 1, 0); + ec_transaction(FAN_ADDRESS, &data, 1, &value, 1); return 100 * (int)value; } diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c index 7e9bb6df9d39..918a65dd2ab3 100644 --- a/drivers/platform/x86/msi-laptop.c +++ b/drivers/platform/x86/msi-laptop.c @@ -120,7 +120,7 @@ static int set_lcd_level(int level) buf[1] = (u8) (level*31); return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, buf, sizeof(buf), - NULL, 0, 1); + NULL, 0); } static int get_lcd_level(void) @@ -129,7 +129,7 @@ static int get_lcd_level(void) int result; result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1, - &rdata, 1, 1); + &rdata, 1); if (result < 0) return result; @@ -142,7 +142,7 @@ static int get_auto_brightness(void) int result; result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1, - &rdata, 1, 1); + &rdata, 1); if (result < 0) return result; @@ -157,7 +157,7 @@ static int set_auto_brightness(int enable) wdata[0] = 4; result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 1, - &rdata, 1, 1); + &rdata, 1); if (result < 0) return result; @@ -165,7 +165,7 @@ static int set_auto_brightness(int enable) wdata[1] = (rdata & 0xF7) | (enable ? 8 : 0); return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 2, - NULL, 0, 1); + NULL, 0); } static ssize_t set_device_state(const char *buf, size_t count, u8 mask) @@ -202,7 +202,7 @@ static int get_wireless_state(int *wlan, int *bluetooth) u8 wdata = 0, rdata; int result; - result = ec_transaction(MSI_EC_COMMAND_WIRELESS, &wdata, 1, &rdata, 1, 1); + result = ec_transaction(MSI_EC_COMMAND_WIRELESS, &wdata, 1, &rdata, 1); if (result < 0) return -1; diff --git a/include/linux/acpi.h b/include/linux/acpi.h index a2e910e01293..1deb2a73c2da 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -150,8 +150,7 @@ extern int ec_read(u8 addr, u8 *val); extern int ec_write(u8 addr, u8 val); extern int ec_transaction(u8 command, const u8 *wdata, unsigned wdata_len, - u8 *rdata, unsigned rdata_len, - int force_poll); + u8 *rdata, unsigned rdata_len); #if defined(CONFIG_ACPI_WMI) || defined(CONFIG_ACPI_WMI_MODULE) -- cgit From a4dd99250dc49031e6a92a895dbcc230a4832083 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Fri, 1 Apr 2011 07:15:14 -0700 Subject: rcu: create new rcu_access_index() and use in mce The MCE subsystem needs to sample an RCU-protected index outside of any protection for that index. If this was a pointer, we would use rcu_access_pointer(), but there is no corresponding rcu_access_index(). This commit therefore creates an rcu_access_index() and applies it to MCE. Signed-off-by: Paul E. McKenney Tested-by: Zdenek Kabelac --- arch/x86/kernel/cpu/mcheck/mce.c | 2 +- include/linux/rcupdate.h | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 5a05ef63eb4a..3385ea26f684 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c @@ -1626,7 +1626,7 @@ out: static unsigned int mce_poll(struct file *file, poll_table *wait) { poll_wait(file, &mce_wait, wait); - if (rcu_dereference_check_mce(mcelog.next)) + if (rcu_access_index(mcelog.next)) return POLLIN | POLLRDNORM; if (!mce_apei_read_done && apei_check_mce()) return POLLIN | POLLRDNORM; diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index af5614856285..ff422d2b7f90 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -339,6 +339,12 @@ extern int rcu_my_thread_group_empty(void); ((typeof(*p) __force __kernel *)(p)); \ }) +#define __rcu_access_index(p, space) \ + ({ \ + typeof(p) _________p1 = ACCESS_ONCE(p); \ + rcu_dereference_sparse(p, space); \ + (_________p1); \ + }) #define __rcu_dereference_index_check(p, c) \ ({ \ typeof(p) _________p1 = ACCESS_ONCE(p); \ @@ -428,6 +434,20 @@ extern int rcu_my_thread_group_empty(void); #define rcu_dereference_raw(p) rcu_dereference_check(p, 1) /*@@@ needed? @@@*/ +/** + * rcu_access_index() - fetch RCU index with no dereferencing + * @p: The index to read + * + * Return the value of the specified RCU-protected index, but omit the + * smp_read_barrier_depends() and keep the ACCESS_ONCE(). This is useful + * when the value of this index is accessed, but the index is not + * dereferenced, for example, when testing an RCU-protected index against + * -1. Although rcu_access_index() may also be used in cases where + * update-side locks prevent the value of the index from changing, you + * should instead use rcu_dereference_index_protected() for this use case. + */ +#define rcu_access_index(p) __rcu_access_index((p), __rcu) + /** * rcu_dereference_index_check() - rcu_dereference for indices with debug checking * @p: The pointer to read, prior to dereferencing -- cgit From c261344d3ce3edac781f9d3c7eabe2e96d8e8fe8 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 1 Apr 2011 20:12:02 -0700 Subject: usbnet: use eth%d name for known ethernet devices The documentation for the USB ethernet devices suggests that only some devices are supposed to use usb0 as the network interface name instead of eth0. The logic used there, and documented in Kconfig for CDC is that eth0 will be used when the mac address is a globally assigned one, but usb0 is used for the locally managed range that is typically used on point-to-point links. Unfortunately, this has caused a lot of pain on the smsc95xx device that is used on the popular pandaboard without an EEPROM to store the MAC address, which causes the driver to call random_ether_address(). Obviously, there should be a proper MAC addressed assigned to the device, and discussions are ongoing about how to solve this, but this patch at least makes sure that the default interface naming gets a little saner and matches what the user can expect based on the documentation, including for new devices. The approach taken here is to flag whether a device might be a point-to-point link with the new FLAG_POINTTOPOINT setting in the usbnet driver_info. A driver can set both FLAG_POINTTOPOINT and FLAG_ETHER if it is not sure (e.g. cdc_ether), or just one of the two. The usbnet framework only looks at the MAC address for device naming if both flags are set, otherwise it trusts the flag. Signed-off-by: Arnd Bergmann Tested-by: Andy Green Signed-off-by: David S. Miller --- drivers/net/usb/cdc_eem.c | 2 +- drivers/net/usb/cdc_ether.c | 2 +- drivers/net/usb/cdc_ncm.c | 2 +- drivers/net/usb/cdc_subset.c | 8 ++++++++ drivers/net/usb/gl620a.c | 2 +- drivers/net/usb/net1080.c | 2 +- drivers/net/usb/plusb.c | 2 +- drivers/net/usb/rndis_host.c | 2 +- drivers/net/usb/usbnet.c | 3 ++- drivers/net/usb/zaurus.c | 8 ++++---- include/linux/usb/usbnet.h | 2 ++ 11 files changed, 23 insertions(+), 12 deletions(-) (limited to 'include/linux') diff --git a/drivers/net/usb/cdc_eem.c b/drivers/net/usb/cdc_eem.c index 5f3b97668e63..8f128541656d 100644 --- a/drivers/net/usb/cdc_eem.c +++ b/drivers/net/usb/cdc_eem.c @@ -340,7 +340,7 @@ next: static const struct driver_info eem_info = { .description = "CDC EEM Device", - .flags = FLAG_ETHER, + .flags = FLAG_ETHER | FLAG_POINTTOPOINT, .bind = eem_bind, .rx_fixup = eem_rx_fixup, .tx_fixup = eem_tx_fixup, diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 51c259b69278..341f7056a800 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -452,7 +452,7 @@ static int cdc_manage_power(struct usbnet *dev, int on) static const struct driver_info cdc_info = { .description = "CDC Ethernet Device", - .flags = FLAG_ETHER, + .flags = FLAG_ETHER | FLAG_POINTTOPOINT, // .check_connect = cdc_check_connect, .bind = usbnet_cdc_bind, .unbind = usbnet_cdc_unbind, diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index 7113168473cf..967371f04454 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c @@ -1237,7 +1237,7 @@ static int cdc_ncm_manage_power(struct usbnet *dev, int status) static const struct driver_info cdc_ncm_info = { .description = "CDC NCM", - .flags = FLAG_NO_SETINT | FLAG_MULTI_PACKET, + .flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT | FLAG_MULTI_PACKET, .bind = cdc_ncm_bind, .unbind = cdc_ncm_unbind, .check_connect = cdc_ncm_check_connect, diff --git a/drivers/net/usb/cdc_subset.c b/drivers/net/usb/cdc_subset.c index ca39ace0b0eb..fc5f13d47ad9 100644 --- a/drivers/net/usb/cdc_subset.c +++ b/drivers/net/usb/cdc_subset.c @@ -89,6 +89,7 @@ static int always_connected (struct usbnet *dev) static const struct driver_info ali_m5632_info = { .description = "ALi M5632", + .flags = FLAG_POINTTOPOINT, }; #endif @@ -110,6 +111,7 @@ static const struct driver_info ali_m5632_info = { static const struct driver_info an2720_info = { .description = "AnchorChips/Cypress 2720", + .flags = FLAG_POINTTOPOINT, // no reset available! // no check_connect available! @@ -132,6 +134,7 @@ static const struct driver_info an2720_info = { static const struct driver_info belkin_info = { .description = "Belkin, eTEK, or compatible", + .flags = FLAG_POINTTOPOINT, }; #endif /* CONFIG_USB_BELKIN */ @@ -157,6 +160,7 @@ static const struct driver_info belkin_info = { static const struct driver_info epson2888_info = { .description = "Epson USB Device", .check_connect = always_connected, + .flags = FLAG_POINTTOPOINT, .in = 4, .out = 3, }; @@ -173,6 +177,7 @@ static const struct driver_info epson2888_info = { #define HAVE_HARDWARE static const struct driver_info kc2190_info = { .description = "KC Technology KC-190", + .flags = FLAG_POINTTOPOINT, }; #endif /* CONFIG_USB_KC2190 */ @@ -200,16 +205,19 @@ static const struct driver_info kc2190_info = { static const struct driver_info linuxdev_info = { .description = "Linux Device", .check_connect = always_connected, + .flags = FLAG_POINTTOPOINT, }; static const struct driver_info yopy_info = { .description = "Yopy", .check_connect = always_connected, + .flags = FLAG_POINTTOPOINT, }; static const struct driver_info blob_info = { .description = "Boot Loader OBject", .check_connect = always_connected, + .flags = FLAG_POINTTOPOINT, }; #endif /* CONFIG_USB_ARMLINUX */ diff --git a/drivers/net/usb/gl620a.c b/drivers/net/usb/gl620a.c index dcd57c37ef73..c4cfd1dea881 100644 --- a/drivers/net/usb/gl620a.c +++ b/drivers/net/usb/gl620a.c @@ -193,7 +193,7 @@ static int genelink_bind(struct usbnet *dev, struct usb_interface *intf) static const struct driver_info genelink_info = { .description = "Genesys GeneLink", - .flags = FLAG_FRAMING_GL | FLAG_NO_SETINT, + .flags = FLAG_POINTTOPOINT | FLAG_FRAMING_GL | FLAG_NO_SETINT, .bind = genelink_bind, .rx_fixup = genelink_rx_fixup, .tx_fixup = genelink_tx_fixup, diff --git a/drivers/net/usb/net1080.c b/drivers/net/usb/net1080.c index ba72a7281cb0..01db4602a39e 100644 --- a/drivers/net/usb/net1080.c +++ b/drivers/net/usb/net1080.c @@ -560,7 +560,7 @@ static int net1080_bind(struct usbnet *dev, struct usb_interface *intf) static const struct driver_info net1080_info = { .description = "NetChip TurboCONNECT", - .flags = FLAG_FRAMING_NC, + .flags = FLAG_POINTTOPOINT | FLAG_FRAMING_NC, .bind = net1080_bind, .reset = net1080_reset, .check_connect = net1080_check_connect, diff --git a/drivers/net/usb/plusb.c b/drivers/net/usb/plusb.c index 08ad269f6b4e..823c53751307 100644 --- a/drivers/net/usb/plusb.c +++ b/drivers/net/usb/plusb.c @@ -96,7 +96,7 @@ static int pl_reset(struct usbnet *dev) static const struct driver_info prolific_info = { .description = "Prolific PL-2301/PL-2302", - .flags = FLAG_NO_SETINT, + .flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT, /* some PL-2302 versions seem to fail usb_set_interface() */ .reset = pl_reset, }; diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c index dd8a4adf48ca..5994a25c56ac 100644 --- a/drivers/net/usb/rndis_host.c +++ b/drivers/net/usb/rndis_host.c @@ -573,7 +573,7 @@ EXPORT_SYMBOL_GPL(rndis_tx_fixup); static const struct driver_info rndis_info = { .description = "RNDIS device", - .flags = FLAG_ETHER | FLAG_FRAMING_RN | FLAG_NO_SETINT, + .flags = FLAG_ETHER | FLAG_POINTTOPOINT | FLAG_FRAMING_RN | FLAG_NO_SETINT, .bind = rndis_bind, .unbind = rndis_unbind, .status = rndis_status, diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index cf58b7682565..069c1cf0fdf7 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1380,7 +1380,8 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) // else "eth%d" when there's reasonable doubt. userspace // can rename the link if it knows better. if ((dev->driver_info->flags & FLAG_ETHER) != 0 && - (net->dev_addr [0] & 0x02) == 0) + ((dev->driver_info->flags & FLAG_POINTTOPOINT) == 0 || + (net->dev_addr [0] & 0x02) == 0)) strcpy (net->name, "eth%d"); /* WLAN devices should always be named "wlan%d" */ if ((dev->driver_info->flags & FLAG_WLAN) != 0) diff --git a/drivers/net/usb/zaurus.c b/drivers/net/usb/zaurus.c index 3eb0b167b5b4..241756e0e86f 100644 --- a/drivers/net/usb/zaurus.c +++ b/drivers/net/usb/zaurus.c @@ -102,7 +102,7 @@ static int always_connected (struct usbnet *dev) static const struct driver_info zaurus_sl5x00_info = { .description = "Sharp Zaurus SL-5x00", - .flags = FLAG_FRAMING_Z, + .flags = FLAG_POINTTOPOINT | FLAG_FRAMING_Z, .check_connect = always_connected, .bind = zaurus_bind, .unbind = usbnet_cdc_unbind, @@ -112,7 +112,7 @@ static const struct driver_info zaurus_sl5x00_info = { static const struct driver_info zaurus_pxa_info = { .description = "Sharp Zaurus, PXA-2xx based", - .flags = FLAG_FRAMING_Z, + .flags = FLAG_POINTTOPOINT | FLAG_FRAMING_Z, .check_connect = always_connected, .bind = zaurus_bind, .unbind = usbnet_cdc_unbind, @@ -122,7 +122,7 @@ static const struct driver_info zaurus_pxa_info = { static const struct driver_info olympus_mxl_info = { .description = "Olympus R1000", - .flags = FLAG_FRAMING_Z, + .flags = FLAG_POINTTOPOINT | FLAG_FRAMING_Z, .check_connect = always_connected, .bind = zaurus_bind, .unbind = usbnet_cdc_unbind, @@ -258,7 +258,7 @@ bad_desc: static const struct driver_info bogus_mdlm_info = { .description = "pseudo-MDLM (BLAN) device", - .flags = FLAG_FRAMING_Z, + .flags = FLAG_POINTTOPOINT | FLAG_FRAMING_Z, .check_connect = always_connected, .tx_fixup = zaurus_tx_fixup, .bind = blan_mdlm_bind, diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h index 201f2228f731..3c7329b8ea0e 100644 --- a/include/linux/usb/usbnet.h +++ b/include/linux/usb/usbnet.h @@ -97,6 +97,8 @@ struct driver_info { #define FLAG_LINK_INTR 0x0800 /* updates link (carrier) status */ +#define FLAG_POINTTOPOINT 0x1000 /* possibly use "usb%d" names */ + /* * Indicates to usbnet, that USB driver accumulates multiple IP packets. * Affects statistic (counters) and short packet handling. -- cgit From 4dd5ffe4fc36128dc86568ddeaeae359e6037762 Mon Sep 17 00:00:00 2001 From: MichaÅ‚ MirosÅ‚aw Date: Wed, 30 Mar 2011 23:58:08 +0000 Subject: net: Fix dev dev_ethtool_get_rx_csum() for forced NETIF_F_RXCSUM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dev_ethtool_get_rx_csum() won't report rx checksumming when it's not changeable and driver is converted to hw_features and friends. Fix this. (dev->hw_features & NETIF_F_RXCSUM) check is dropped - if the ethtool_ops->get_rx_csum is set, then driver is not coverted, yet. Signed-off-by: MichaÅ‚ MirosÅ‚aw Signed-off-by: David S. Miller --- include/linux/netdevice.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 5eeb2cd3631c..0249fe7e3872 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2598,8 +2598,8 @@ static inline int dev_ethtool_get_settings(struct net_device *dev, static inline u32 dev_ethtool_get_rx_csum(struct net_device *dev) { - if (dev->hw_features & NETIF_F_RXCSUM) - return !!(dev->features & NETIF_F_RXCSUM); + if (dev->features & NETIF_F_RXCSUM) + return 1; if (!dev->ethtool_ops || !dev->ethtool_ops->get_rx_csum) return 0; return dev->ethtool_ops->get_rx_csum(dev); -- cgit From 6cb6a27c45cec9184302c2e350b3593c64bc7f6c Mon Sep 17 00:00:00 2001 From: MichaÅ‚ MirosÅ‚aw Date: Sat, 2 Apr 2011 22:48:47 -0700 Subject: net: Call netdev_features_change() from netdev_update_features() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue FEAT_CHANGE notification when features are changed by netdev_update_features(). This will allow changes made by extra constraints on e.g. MTU change to be properly propagated like changes via ethtool. Signed-off-by: MichaÅ‚ MirosÅ‚aw Signed-off-by: David S. Miller --- include/linux/netdevice.h | 1 + net/core/dev.c | 23 +++++++++++++++++------ net/core/ethtool.c | 6 +++--- 3 files changed, 21 insertions(+), 9 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 5eeb2cd3631c..423a5447d2ed 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2550,6 +2550,7 @@ static inline u32 netdev_get_wanted_features(struct net_device *dev) } u32 netdev_increment_features(u32 all, u32 one, u32 mask); u32 netdev_fix_features(struct net_device *dev, u32 features); +int __netdev_update_features(struct net_device *dev); void netdev_update_features(struct net_device *dev); void netif_stacked_transfer_operstate(const struct net_device *rootdev, diff --git a/net/core/dev.c b/net/core/dev.c index 3da9fb06d47a..02f56376fe99 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -5236,7 +5236,7 @@ u32 netdev_fix_features(struct net_device *dev, u32 features) } EXPORT_SYMBOL(netdev_fix_features); -void netdev_update_features(struct net_device *dev) +int __netdev_update_features(struct net_device *dev) { u32 features; int err = 0; @@ -5250,7 +5250,7 @@ void netdev_update_features(struct net_device *dev) features = netdev_fix_features(dev, features); if (dev->features == features) - return; + return 0; netdev_info(dev, "Features changed: 0x%08x -> 0x%08x\n", dev->features, features); @@ -5258,12 +5258,23 @@ void netdev_update_features(struct net_device *dev) if (dev->netdev_ops->ndo_set_features) err = dev->netdev_ops->ndo_set_features(dev, features); - if (!err) - dev->features = features; - else if (err < 0) + if (unlikely(err < 0)) { netdev_err(dev, "set_features() failed (%d); wanted 0x%08x, left 0x%08x\n", err, features, dev->features); + return -1; + } + + if (!err) + dev->features = features; + + return 1; +} + +void netdev_update_features(struct net_device *dev) +{ + if (__netdev_update_features(dev)) + netdev_features_change(dev); } EXPORT_SYMBOL(netdev_update_features); @@ -5430,7 +5441,7 @@ int register_netdevice(struct net_device *dev) goto err_uninit; dev->reg_state = NETREG_REGISTERED; - netdev_update_features(dev); + __netdev_update_features(dev); /* * Default initial state at registry is that the diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 74ead9eca126..439e4b0e1312 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -317,7 +317,7 @@ static int ethtool_set_features(struct net_device *dev, void __user *useraddr) dev->wanted_features &= ~features[0].valid; dev->wanted_features |= features[0].valid & features[0].requested; - netdev_update_features(dev); + __netdev_update_features(dev); if ((dev->wanted_features ^ dev->features) & features[0].valid) ret |= ETHTOOL_F_WISH; @@ -499,7 +499,7 @@ static int ethtool_set_one_feature(struct net_device *dev, else dev->wanted_features &= ~mask; - netdev_update_features(dev); + __netdev_update_features(dev); return 0; } @@ -551,7 +551,7 @@ int __ethtool_set_flags(struct net_device *dev, u32 data) dev->wanted_features = (dev->wanted_features & ~changed) | data; - netdev_update_features(dev); + __netdev_update_features(dev); return 0; } -- cgit From ee77f075921730b2b465880f9fd4367003bdab39 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Fri, 1 Apr 2011 20:12:38 +0200 Subject: signal: Turn SIGNAL_STOP_DEQUEUED into GROUP_STOP_DEQUEUED This patch moves SIGNAL_STOP_DEQUEUED from signal_struct->flags to task_struct->group_stop, and thus makes it per-thread. Like SIGNAL_STOP_DEQUEUED, GROUP_STOP_DEQUEUED can be false-positive after return from get_signal_to_deliver(), this is fine. The only purpose of this bit is: we can drop ->siglock after __dequeue_signal() returns the sig_kernel_stop() signal and before we call do_signal_stop(), in this case we must not miss SIGCONT if it comes in between. But, unlike SIGNAL_STOP_DEQUEUED, GROUP_STOP_DEQUEUED can not be false-positive in do_signal_stop() if multiple threads dequeue the sig_kernel_stop() signal at the same time. Consider two threads T1 and T2, SIGTTIN has a hanlder. - T1 dequeues SIGTSTP and sets SIGNAL_STOP_DEQUEUED, then it drops ->siglock - SIGCONT comes and clears SIGNAL_STOP_DEQUEUED, SIGTSTP should be cancelled. - T2 dequeues SIGTTIN and sets SIGNAL_STOP_DEQUEUED again. Since we have a handler we should not stop, T2 returns to usermode to run the handler. - T1 continues, calls do_signal_stop() and wrongly starts the group stop because SIGNAL_STOP_DEQUEUED was restored in between. With or without this change: - we need to do something with ptrace_signal() which can return SIGSTOP, but this needs another discussion - SIGSTOP can be lost if it races with the mt exec, will be fixed later. Signed-off-by: Oleg Nesterov Signed-off-by: Tejun Heo --- include/linux/sched.h | 6 +++--- kernel/signal.c | 14 ++++---------- 2 files changed, 7 insertions(+), 13 deletions(-) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index 456d80ed3b78..8cef82d4cf77 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -652,9 +652,8 @@ struct signal_struct { * Bits in flags field of signal_struct. */ #define SIGNAL_STOP_STOPPED 0x00000001 /* job control stop in effect */ -#define SIGNAL_STOP_DEQUEUED 0x00000002 /* stop signal dequeued */ -#define SIGNAL_STOP_CONTINUED 0x00000004 /* SIGCONT since WCONTINUED reap */ -#define SIGNAL_GROUP_EXIT 0x00000008 /* group exit in progress */ +#define SIGNAL_STOP_CONTINUED 0x00000002 /* SIGCONT since WCONTINUED reap */ +#define SIGNAL_GROUP_EXIT 0x00000004 /* group exit in progress */ /* * Pending notifications to parent. */ @@ -1779,6 +1778,7 @@ extern void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t * #define GROUP_STOP_PENDING (1 << 16) /* task should stop for group stop */ #define GROUP_STOP_CONSUME (1 << 17) /* consume group stop count */ #define GROUP_STOP_TRAPPING (1 << 18) /* switching from STOPPED to TRACED */ +#define GROUP_STOP_DEQUEUED (1 << 19) /* stop signal dequeued */ extern void task_clear_group_stop_pending(struct task_struct *task); diff --git a/kernel/signal.c b/kernel/signal.c index e9abc69dc0d8..4f7312b49b2d 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -254,7 +254,8 @@ static void task_clear_group_stop_trapping(struct task_struct *task) */ void task_clear_group_stop_pending(struct task_struct *task) { - task->group_stop &= ~(GROUP_STOP_PENDING | GROUP_STOP_CONSUME); + task->group_stop &= ~(GROUP_STOP_PENDING | GROUP_STOP_CONSUME | + GROUP_STOP_DEQUEUED); } /** @@ -602,7 +603,7 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) * is to alert stop-signal processing code when another * processor has come along and cleared the flag. */ - tsk->signal->flags |= SIGNAL_STOP_DEQUEUED; + current->group_stop |= GROUP_STOP_DEQUEUED; } if ((info->si_code & __SI_MASK) == __SI_TIMER && info->si_sys_private) { /* @@ -821,13 +822,6 @@ static int prepare_signal(int sig, struct task_struct *p, int from_ancestor_ns) signal->flags = why | SIGNAL_STOP_CONTINUED; signal->group_stop_count = 0; signal->group_exit_code = 0; - } else { - /* - * We are not stopped, but there could be a stop - * signal in the middle of being processed after - * being removed from the queue. Clear that too. - */ - signal->flags &= ~SIGNAL_STOP_DEQUEUED; } } @@ -1855,7 +1849,7 @@ static int do_signal_stop(int signr) /* signr will be recorded in task->group_stop for retries */ WARN_ON_ONCE(signr & ~GROUP_STOP_SIGMASK); - if (!likely(sig->flags & SIGNAL_STOP_DEQUEUED) || + if (!likely(current->group_stop & GROUP_STOP_DEQUEUED) || unlikely(signal_group_exit(sig))) return 0; /* -- cgit From 17f60a7da150fdd0cfb9756f86a262daa72c835f Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Fri, 1 Apr 2011 17:07:50 -0400 Subject: capabilites: allow the application of capability limits to usermode helpers There is no way to limit the capabilities of usermodehelpers. This problem reared its head recently when someone complained that any user with cap_net_admin was able to load arbitrary kernel modules, even though the user didn't have cap_sys_module. The reason is because the actual load is done by a usermode helper and those always have the full cap set. This patch addes new sysctls which allow us to bound the permissions of usermode helpers. /proc/sys/kernel/usermodehelper/bset /proc/sys/kernel/usermodehelper/inheritable You must have CAP_SYS_MODULE and CAP_SETPCAP to change these (changes are &= ONLY). When the kernel launches a usermodehelper it will do so with these as the bset and pI. -v2: make globals static create spinlock to protect globals -v3: require both CAP_SETPCAP and CAP_SYS_MODULE -v4: fix the typo s/CAP_SET_PCAP/CAP_SETPCAP/ because I didn't commit Signed-off-by: Eric Paris No-objection-from: Serge E. Hallyn Acked-by: David Howells Acked-by: Serge E. Hallyn Acked-by: Andrew G. Morgan Signed-off-by: James Morris --- include/linux/kmod.h | 3 ++ kernel/kmod.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++ kernel/sysctl.c | 6 ++++ 3 files changed, 109 insertions(+) (limited to 'include/linux') diff --git a/include/linux/kmod.h b/include/linux/kmod.h index 6efd7a78de6a..79bb98d71858 100644 --- a/include/linux/kmod.h +++ b/include/linux/kmod.h @@ -24,6 +24,7 @@ #include #include #include +#include #define KMOD_PATH_LEN 256 @@ -109,6 +110,8 @@ call_usermodehelper(char *path, char **argv, char **envp, enum umh_wait wait) NULL, NULL, NULL); } +extern struct ctl_table usermodehelper_table[]; + extern void usermodehelper_init(void); extern int usermodehelper_disable(void); diff --git a/kernel/kmod.c b/kernel/kmod.c index 9cd0591c96a2..06fdea2819b6 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -43,6 +44,13 @@ extern int max_threads; static struct workqueue_struct *khelper_wq; +#define CAP_BSET (void *)1 +#define CAP_PI (void *)2 + +static kernel_cap_t usermodehelper_bset = CAP_FULL_SET; +static kernel_cap_t usermodehelper_inheritable = CAP_FULL_SET; +static DEFINE_SPINLOCK(umh_sysctl_lock); + #ifdef CONFIG_MODULES /* @@ -132,6 +140,7 @@ EXPORT_SYMBOL(__request_module); static int ____call_usermodehelper(void *data) { struct subprocess_info *sub_info = data; + struct cred *new; int retval; spin_lock_irq(¤t->sighand->siglock); @@ -153,6 +162,19 @@ static int ____call_usermodehelper(void *data) goto fail; } + retval = -ENOMEM; + new = prepare_kernel_cred(current); + if (!new) + goto fail; + + spin_lock(&umh_sysctl_lock); + new->cap_bset = cap_intersect(usermodehelper_bset, new->cap_bset); + new->cap_inheritable = cap_intersect(usermodehelper_inheritable, + new->cap_inheritable); + spin_unlock(&umh_sysctl_lock); + + commit_creds(new); + retval = kernel_execve(sub_info->path, (const char *const *)sub_info->argv, (const char *const *)sub_info->envp); @@ -418,6 +440,84 @@ unlock: } EXPORT_SYMBOL(call_usermodehelper_exec); +static int proc_cap_handler(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + struct ctl_table t; + unsigned long cap_array[_KERNEL_CAPABILITY_U32S]; + kernel_cap_t new_cap; + int err, i; + + if (write && (!capable(CAP_SETPCAP) || + !capable(CAP_SYS_MODULE))) + return -EPERM; + + /* + * convert from the global kernel_cap_t to the ulong array to print to + * userspace if this is a read. + */ + spin_lock(&umh_sysctl_lock); + for (i = 0; i < _KERNEL_CAPABILITY_U32S; i++) { + if (table->data == CAP_BSET) + cap_array[i] = usermodehelper_bset.cap[i]; + else if (table->data == CAP_PI) + cap_array[i] = usermodehelper_inheritable.cap[i]; + else + BUG(); + } + spin_unlock(&umh_sysctl_lock); + + t = *table; + t.data = &cap_array; + + /* + * actually read or write and array of ulongs from userspace. Remember + * these are least significant 32 bits first + */ + err = proc_doulongvec_minmax(&t, write, buffer, lenp, ppos); + if (err < 0) + return err; + + /* + * convert from the sysctl array of ulongs to the kernel_cap_t + * internal representation + */ + for (i = 0; i < _KERNEL_CAPABILITY_U32S; i++) + new_cap.cap[i] = cap_array[i]; + + /* + * Drop everything not in the new_cap (but don't add things) + */ + spin_lock(&umh_sysctl_lock); + if (write) { + if (table->data == CAP_BSET) + usermodehelper_bset = cap_intersect(usermodehelper_bset, new_cap); + if (table->data == CAP_PI) + usermodehelper_inheritable = cap_intersect(usermodehelper_inheritable, new_cap); + } + spin_unlock(&umh_sysctl_lock); + + return 0; +} + +struct ctl_table usermodehelper_table[] = { + { + .procname = "bset", + .data = CAP_BSET, + .maxlen = _KERNEL_CAPABILITY_U32S * sizeof(unsigned long), + .mode = 0600, + .proc_handler = proc_cap_handler, + }, + { + .procname = "inheritable", + .data = CAP_PI, + .maxlen = _KERNEL_CAPABILITY_U32S * sizeof(unsigned long), + .mode = 0600, + .proc_handler = proc_cap_handler, + }, + { } +}; + void __init usermodehelper_init(void) { khelper_wq = create_singlethread_workqueue("khelper"); diff --git a/kernel/sysctl.c b/kernel/sysctl.c index c0bb32414b17..965134bed6cd 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -56,6 +56,7 @@ #include #include #include +#include #include #include @@ -615,6 +616,11 @@ static struct ctl_table kern_table[] = { .mode = 0555, .child = random_table, }, + { + .procname = "usermodehelper", + .mode = 0555, + .child = usermodehelper_table, + }, { .procname = "overflowuid", .data = &overflowuid, -- cgit From ffa8e59df047d57e812a04f7d6baf6a25c652c0c Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Fri, 1 Apr 2011 17:08:34 -0400 Subject: capabilities: do not drop CAP_SETPCAP from the initial task In olden' days of yore CAP_SETPCAP had special meaning for the init task. We actually have code to make sure that CAP_SETPCAP wasn't in pE of things using the init_cred. But CAP_SETPCAP isn't so special any more and we don't have a reason to special case dropping it for init or kthreads.... Signed-off-by: Eric Paris Acked-by: Andrew G. Morgan Signed-off-by: James Morris --- include/linux/capability.h | 6 ++++-- kernel/capability.c | 2 -- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/capability.h b/include/linux/capability.h index 16ee8b49a200..11d562863e49 100644 --- a/include/linux/capability.h +++ b/include/linux/capability.h @@ -412,7 +412,6 @@ extern const kernel_cap_t __cap_init_eff_set; # define CAP_EMPTY_SET ((kernel_cap_t){{ 0, 0 }}) # define CAP_FULL_SET ((kernel_cap_t){{ ~0, ~0 }}) -# define CAP_INIT_EFF_SET ((kernel_cap_t){{ ~CAP_TO_MASK(CAP_SETPCAP), ~0 }}) # define CAP_FS_SET ((kernel_cap_t){{ CAP_FS_MASK_B0 \ | CAP_TO_MASK(CAP_LINUX_IMMUTABLE), \ CAP_FS_MASK_B1 } }) @@ -423,10 +422,10 @@ extern const kernel_cap_t __cap_init_eff_set; #endif /* _KERNEL_CAPABILITY_U32S != 2 */ #define CAP_INIT_INH_SET CAP_EMPTY_SET +#define CAP_INIT_EFF_SET CAP_FULL_SET # define cap_clear(c) do { (c) = __cap_empty_set; } while (0) # define cap_set_full(c) do { (c) = __cap_full_set; } while (0) -# define cap_set_init_eff(c) do { (c) = __cap_init_eff_set; } while (0) #define cap_raise(c, flag) ((c).cap[CAP_TO_INDEX(flag)] |= CAP_TO_MASK(flag)) #define cap_lower(c, flag) ((c).cap[CAP_TO_INDEX(flag)] &= ~CAP_TO_MASK(flag)) @@ -547,6 +546,9 @@ extern bool capable(int cap); extern bool ns_capable(struct user_namespace *ns, int cap); extern bool task_ns_capable(struct task_struct *t, int cap); +extern const kernel_cap_t __cap_empty_set; +extern const kernel_cap_t __cap_full_set; + /** * nsown_capable - Check superior capability to one's own user_ns * @cap: The capability in question diff --git a/kernel/capability.c b/kernel/capability.c index bf0c734d0c12..2a374d512ead 100644 --- a/kernel/capability.c +++ b/kernel/capability.c @@ -23,11 +23,9 @@ const kernel_cap_t __cap_empty_set = CAP_EMPTY_SET; const kernel_cap_t __cap_full_set = CAP_FULL_SET; -const kernel_cap_t __cap_init_eff_set = CAP_INIT_EFF_SET; EXPORT_SYMBOL(__cap_empty_set); EXPORT_SYMBOL(__cap_full_set); -EXPORT_SYMBOL(__cap_init_eff_set); int file_caps_enabled = 1; -- cgit From 5163b583a036b103c3cec7171d6731c125773ed6 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Fri, 1 Apr 2011 17:08:39 -0400 Subject: capabilities: delete unused cap_set_full unused code. Clean it up. Signed-off-by: Eric Paris Acked-by: David Howells Acked-by: Andrew G. Morgan Signed-off-by: James Morris --- include/linux/capability.h | 2 -- kernel/capability.c | 2 -- 2 files changed, 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/capability.h b/include/linux/capability.h index 11d562863e49..8d0da30dad23 100644 --- a/include/linux/capability.h +++ b/include/linux/capability.h @@ -425,7 +425,6 @@ extern const kernel_cap_t __cap_init_eff_set; #define CAP_INIT_EFF_SET CAP_FULL_SET # define cap_clear(c) do { (c) = __cap_empty_set; } while (0) -# define cap_set_full(c) do { (c) = __cap_full_set; } while (0) #define cap_raise(c, flag) ((c).cap[CAP_TO_INDEX(flag)] |= CAP_TO_MASK(flag)) #define cap_lower(c, flag) ((c).cap[CAP_TO_INDEX(flag)] &= ~CAP_TO_MASK(flag)) @@ -547,7 +546,6 @@ extern bool ns_capable(struct user_namespace *ns, int cap); extern bool task_ns_capable(struct task_struct *t, int cap); extern const kernel_cap_t __cap_empty_set; -extern const kernel_cap_t __cap_full_set; /** * nsown_capable - Check superior capability to one's own user_ns diff --git a/kernel/capability.c b/kernel/capability.c index 2a374d512ead..14ea4210a530 100644 --- a/kernel/capability.c +++ b/kernel/capability.c @@ -22,10 +22,8 @@ */ const kernel_cap_t __cap_empty_set = CAP_EMPTY_SET; -const kernel_cap_t __cap_full_set = CAP_FULL_SET; EXPORT_SYMBOL(__cap_empty_set); -EXPORT_SYMBOL(__cap_full_set); int file_caps_enabled = 1; -- cgit From a3232d2fa2e3cbab3e76d91cdae5890fee8a4034 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Fri, 1 Apr 2011 17:08:45 -0400 Subject: capabilities: delete all CAP_INIT macros The CAP_INIT macros of INH, BSET, and EFF made sense at one point in time, but now days they aren't helping. Just open code the logic in the init_cred. Signed-off-by: Eric Paris Acked-by: David Howells Signed-off-by: James Morris --- include/linux/capability.h | 3 --- include/linux/init_task.h | 7 ------- kernel/cred.c | 6 +++--- 3 files changed, 3 insertions(+), 13 deletions(-) (limited to 'include/linux') diff --git a/include/linux/capability.h b/include/linux/capability.h index 8d0da30dad23..04fed72809de 100644 --- a/include/linux/capability.h +++ b/include/linux/capability.h @@ -421,9 +421,6 @@ extern const kernel_cap_t __cap_init_eff_set; #endif /* _KERNEL_CAPABILITY_U32S != 2 */ -#define CAP_INIT_INH_SET CAP_EMPTY_SET -#define CAP_INIT_EFF_SET CAP_FULL_SET - # define cap_clear(c) do { (c) = __cap_empty_set; } while (0) #define cap_raise(c, flag) ((c).cap[CAP_TO_INDEX(flag)] |= CAP_TO_MASK(flag)) diff --git a/include/linux/init_task.h b/include/linux/init_task.h index caa151fbebb7..1f277204de34 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h @@ -83,13 +83,6 @@ extern struct group_info init_groups; #define INIT_IDS #endif -/* - * Because of the reduced scope of CAP_SETPCAP when filesystem - * capabilities are in effect, it is safe to allow CAP_SETPCAP to - * be available in the default configuration. - */ -# define CAP_INIT_BSET CAP_FULL_SET - #ifdef CONFIG_RCU_BOOST #define INIT_TASK_RCU_BOOST() \ .rcu_boost_mutex = NULL, diff --git a/kernel/cred.c b/kernel/cred.c index 5557b55048df..b982f0863ae9 100644 --- a/kernel/cred.c +++ b/kernel/cred.c @@ -49,10 +49,10 @@ struct cred init_cred = { .magic = CRED_MAGIC, #endif .securebits = SECUREBITS_DEFAULT, - .cap_inheritable = CAP_INIT_INH_SET, + .cap_inheritable = CAP_EMPTY_SET, .cap_permitted = CAP_FULL_SET, - .cap_effective = CAP_INIT_EFF_SET, - .cap_bset = CAP_INIT_BSET, + .cap_effective = CAP_FULL_SET, + .cap_bset = CAP_FULL_SET, .user = INIT_USER, .group_info = &init_groups, #ifdef CONFIG_KEYS -- cgit From 2f9f28b212a2bd4948c8ceaaec33ce0123632129 Mon Sep 17 00:00:00 2001 From: Jozsef Kadlecsik Date: Mon, 4 Apr 2011 15:19:25 +0200 Subject: netfilter: ipset: references are protected by rwlock instead of mutex The timeout variant of the list:set type must reference the member sets. However, its garbage collector runs at timer interrupt so the mutex protection of the references is a no go. Therefore the reference protection is converted to rwlock. Signed-off-by: Jozsef Kadlecsik Signed-off-by: Patrick McHardy --- include/linux/netfilter/ipset/ip_set.h | 2 +- include/linux/netfilter/ipset/ip_set_ahash.h | 3 +- net/netfilter/ipset/ip_set_bitmap_ip.c | 3 +- net/netfilter/ipset/ip_set_bitmap_ipmac.c | 3 +- net/netfilter/ipset/ip_set_bitmap_port.c | 3 +- net/netfilter/ipset/ip_set_core.c | 109 ++++++++++++++++----------- net/netfilter/ipset/ip_set_list_set.c | 6 +- 7 files changed, 73 insertions(+), 56 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netfilter/ipset/ip_set.h b/include/linux/netfilter/ipset/ip_set.h index ec333d83f3b4..5a262e3ae715 100644 --- a/include/linux/netfilter/ipset/ip_set.h +++ b/include/linux/netfilter/ipset/ip_set.h @@ -293,7 +293,7 @@ struct ip_set { /* Lock protecting the set data */ rwlock_t lock; /* References to the set */ - atomic_t ref; + u32 ref; /* The core set type */ struct ip_set_type *type; /* The type variant doing the real job */ diff --git a/include/linux/netfilter/ipset/ip_set_ahash.h b/include/linux/netfilter/ipset/ip_set_ahash.h index ec9d9bea1e37..a0196ac79051 100644 --- a/include/linux/netfilter/ipset/ip_set_ahash.h +++ b/include/linux/netfilter/ipset/ip_set_ahash.h @@ -515,8 +515,7 @@ type_pf_head(struct ip_set *set, struct sk_buff *skb) if (h->netmask != HOST_MASK) NLA_PUT_U8(skb, IPSET_ATTR_NETMASK, h->netmask); #endif - NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, - htonl(atomic_read(&set->ref) - 1)); + NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)); NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize)); if (with_timeout(h->timeout)) NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, htonl(h->timeout)); diff --git a/net/netfilter/ipset/ip_set_bitmap_ip.c b/net/netfilter/ipset/ip_set_bitmap_ip.c index bca96990218d..a113ff066928 100644 --- a/net/netfilter/ipset/ip_set_bitmap_ip.c +++ b/net/netfilter/ipset/ip_set_bitmap_ip.c @@ -338,8 +338,7 @@ bitmap_ip_head(struct ip_set *set, struct sk_buff *skb) NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP_TO, htonl(map->last_ip)); if (map->netmask != 32) NLA_PUT_U8(skb, IPSET_ATTR_NETMASK, map->netmask); - NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, - htonl(atomic_read(&set->ref) - 1)); + NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)); NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE, htonl(sizeof(*map) + map->memsize)); if (with_timeout(map->timeout)) diff --git a/net/netfilter/ipset/ip_set_bitmap_ipmac.c b/net/netfilter/ipset/ip_set_bitmap_ipmac.c index 5e790172deff..00a33242e90c 100644 --- a/net/netfilter/ipset/ip_set_bitmap_ipmac.c +++ b/net/netfilter/ipset/ip_set_bitmap_ipmac.c @@ -434,8 +434,7 @@ bitmap_ipmac_head(struct ip_set *set, struct sk_buff *skb) goto nla_put_failure; NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, htonl(map->first_ip)); NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP_TO, htonl(map->last_ip)); - NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, - htonl(atomic_read(&set->ref) - 1)); + NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)); NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE, htonl(sizeof(*map) + (map->last_ip - map->first_ip + 1) * map->dsize)); diff --git a/net/netfilter/ipset/ip_set_bitmap_port.c b/net/netfilter/ipset/ip_set_bitmap_port.c index 165f09b1a9cb..6b38eb8f6ed8 100644 --- a/net/netfilter/ipset/ip_set_bitmap_port.c +++ b/net/netfilter/ipset/ip_set_bitmap_port.c @@ -320,8 +320,7 @@ bitmap_port_head(struct ip_set *set, struct sk_buff *skb) goto nla_put_failure; NLA_PUT_NET16(skb, IPSET_ATTR_PORT, htons(map->first_port)); NLA_PUT_NET16(skb, IPSET_ATTR_PORT_TO, htons(map->last_port)); - NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, - htonl(atomic_read(&set->ref) - 1)); + NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)); NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE, htonl(sizeof(*map) + map->memsize)); if (with_timeout(map->timeout)) diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c index d6b48230a540..e88ac3c3ed07 100644 --- a/net/netfilter/ipset/ip_set_core.c +++ b/net/netfilter/ipset/ip_set_core.c @@ -26,6 +26,7 @@ static LIST_HEAD(ip_set_type_list); /* all registered set types */ static DEFINE_MUTEX(ip_set_type_mutex); /* protects ip_set_type_list */ +static DEFINE_RWLOCK(ip_set_ref_lock); /* protects the set refs */ static struct ip_set **ip_set_list; /* all individual sets */ static ip_set_id_t ip_set_max = CONFIG_IP_SET_MAX; /* max number of sets */ @@ -301,13 +302,18 @@ EXPORT_SYMBOL_GPL(ip_set_get_ipaddr6); static inline void __ip_set_get(ip_set_id_t index) { - atomic_inc(&ip_set_list[index]->ref); + write_lock_bh(&ip_set_ref_lock); + ip_set_list[index]->ref++; + write_unlock_bh(&ip_set_ref_lock); } static inline void __ip_set_put(ip_set_id_t index) { - atomic_dec(&ip_set_list[index]->ref); + write_lock_bh(&ip_set_ref_lock); + BUG_ON(ip_set_list[index]->ref == 0); + ip_set_list[index]->ref--; + write_unlock_bh(&ip_set_ref_lock); } /* @@ -324,7 +330,7 @@ ip_set_test(ip_set_id_t index, const struct sk_buff *skb, struct ip_set *set = ip_set_list[index]; int ret = 0; - BUG_ON(set == NULL || atomic_read(&set->ref) == 0); + BUG_ON(set == NULL); pr_debug("set %s, index %u\n", set->name, index); if (dim < set->type->dimension || @@ -356,7 +362,7 @@ ip_set_add(ip_set_id_t index, const struct sk_buff *skb, struct ip_set *set = ip_set_list[index]; int ret; - BUG_ON(set == NULL || atomic_read(&set->ref) == 0); + BUG_ON(set == NULL); pr_debug("set %s, index %u\n", set->name, index); if (dim < set->type->dimension || @@ -378,7 +384,7 @@ ip_set_del(ip_set_id_t index, const struct sk_buff *skb, struct ip_set *set = ip_set_list[index]; int ret = 0; - BUG_ON(set == NULL || atomic_read(&set->ref) == 0); + BUG_ON(set == NULL); pr_debug("set %s, index %u\n", set->name, index); if (dim < set->type->dimension || @@ -397,7 +403,6 @@ EXPORT_SYMBOL_GPL(ip_set_del); * Find set by name, reference it once. The reference makes sure the * thing pointed to, does not go away under our feet. * - * The nfnl mutex must already be activated. */ ip_set_id_t ip_set_get_byname(const char *name, struct ip_set **set) @@ -423,15 +428,12 @@ EXPORT_SYMBOL_GPL(ip_set_get_byname); * reference count by 1. The caller shall not assume the index * to be valid, after calling this function. * - * The nfnl mutex must already be activated. */ void ip_set_put_byindex(ip_set_id_t index) { - if (ip_set_list[index] != NULL) { - BUG_ON(atomic_read(&ip_set_list[index]->ref) == 0); + if (ip_set_list[index] != NULL) __ip_set_put(index); - } } EXPORT_SYMBOL_GPL(ip_set_put_byindex); @@ -441,7 +443,6 @@ EXPORT_SYMBOL_GPL(ip_set_put_byindex); * can't be destroyed. The set cannot be renamed due to * the referencing either. * - * The nfnl mutex must already be activated. */ const char * ip_set_name_byindex(ip_set_id_t index) @@ -449,7 +450,7 @@ ip_set_name_byindex(ip_set_id_t index) const struct ip_set *set = ip_set_list[index]; BUG_ON(set == NULL); - BUG_ON(atomic_read(&set->ref) == 0); + BUG_ON(set->ref == 0); /* Referenced, so it's safe */ return set->name; @@ -515,10 +516,7 @@ void ip_set_nfnl_put(ip_set_id_t index) { nfnl_lock(); - if (ip_set_list[index] != NULL) { - BUG_ON(atomic_read(&ip_set_list[index]->ref) == 0); - __ip_set_put(index); - } + ip_set_put_byindex(index); nfnl_unlock(); } EXPORT_SYMBOL_GPL(ip_set_nfnl_put); @@ -526,7 +524,7 @@ EXPORT_SYMBOL_GPL(ip_set_nfnl_put); /* * Communication protocol with userspace over netlink. * - * We already locked by nfnl_lock. + * The commands are serialized by the nfnl mutex. */ static inline bool @@ -657,7 +655,6 @@ ip_set_create(struct sock *ctnl, struct sk_buff *skb, return -ENOMEM; rwlock_init(&set->lock); strlcpy(set->name, name, IPSET_MAXNAMELEN); - atomic_set(&set->ref, 0); set->family = family; /* @@ -690,8 +687,8 @@ ip_set_create(struct sock *ctnl, struct sk_buff *skb, /* * Here, we have a valid, constructed set and we are protected - * by nfnl_lock. Find the first free index in ip_set_list and - * check clashing. + * by the nfnl mutex. Find the first free index in ip_set_list + * and check clashing. */ if ((ret = find_free_id(set->name, &index, &clash)) != 0) { /* If this is the same set and requested, ignore error */ @@ -751,31 +748,51 @@ ip_set_destroy(struct sock *ctnl, struct sk_buff *skb, const struct nlattr * const attr[]) { ip_set_id_t i; + int ret = 0; if (unlikely(protocol_failed(attr))) return -IPSET_ERR_PROTOCOL; - /* References are protected by the nfnl mutex */ + /* Commands are serialized and references are + * protected by the ip_set_ref_lock. + * External systems (i.e. xt_set) must call + * ip_set_put|get_nfnl_* functions, that way we + * can safely check references here. + * + * list:set timer can only decrement the reference + * counter, so if it's already zero, we can proceed + * without holding the lock. + */ + read_lock_bh(&ip_set_ref_lock); if (!attr[IPSET_ATTR_SETNAME]) { for (i = 0; i < ip_set_max; i++) { - if (ip_set_list[i] != NULL && - (atomic_read(&ip_set_list[i]->ref))) - return -IPSET_ERR_BUSY; + if (ip_set_list[i] != NULL && ip_set_list[i]->ref) { + ret = IPSET_ERR_BUSY; + goto out; + } } + read_unlock_bh(&ip_set_ref_lock); for (i = 0; i < ip_set_max; i++) { if (ip_set_list[i] != NULL) ip_set_destroy_set(i); } } else { i = find_set_id(nla_data(attr[IPSET_ATTR_SETNAME])); - if (i == IPSET_INVALID_ID) - return -ENOENT; - else if (atomic_read(&ip_set_list[i]->ref)) - return -IPSET_ERR_BUSY; + if (i == IPSET_INVALID_ID) { + ret = -ENOENT; + goto out; + } else if (ip_set_list[i]->ref) { + ret = -IPSET_ERR_BUSY; + goto out; + } + read_unlock_bh(&ip_set_ref_lock); ip_set_destroy_set(i); } return 0; +out: + read_unlock_bh(&ip_set_ref_lock); + return ret; } /* Flush sets */ @@ -834,6 +851,7 @@ ip_set_rename(struct sock *ctnl, struct sk_buff *skb, struct ip_set *set; const char *name2; ip_set_id_t i; + int ret = 0; if (unlikely(protocol_failed(attr) || attr[IPSET_ATTR_SETNAME] == NULL || @@ -843,25 +861,33 @@ ip_set_rename(struct sock *ctnl, struct sk_buff *skb, set = find_set(nla_data(attr[IPSET_ATTR_SETNAME])); if (set == NULL) return -ENOENT; - if (atomic_read(&set->ref) != 0) - return -IPSET_ERR_REFERENCED; + + read_lock_bh(&ip_set_ref_lock); + if (set->ref != 0) { + ret = -IPSET_ERR_REFERENCED; + goto out; + } name2 = nla_data(attr[IPSET_ATTR_SETNAME2]); for (i = 0; i < ip_set_max; i++) { if (ip_set_list[i] != NULL && - STREQ(ip_set_list[i]->name, name2)) - return -IPSET_ERR_EXIST_SETNAME2; + STREQ(ip_set_list[i]->name, name2)) { + ret = -IPSET_ERR_EXIST_SETNAME2; + goto out; + } } strncpy(set->name, name2, IPSET_MAXNAMELEN); - return 0; +out: + read_unlock_bh(&ip_set_ref_lock); + return ret; } /* Swap two sets so that name/index points to the other. * References and set names are also swapped. * - * We are protected by the nfnl mutex and references are - * manipulated only by holding the mutex. The kernel interfaces + * The commands are serialized by the nfnl mutex and references are + * protected by the ip_set_ref_lock. The kernel interfaces * do not hold the mutex but the pointer settings are atomic * so the ip_set_list always contains valid pointers to the sets. */ @@ -874,7 +900,6 @@ ip_set_swap(struct sock *ctnl, struct sk_buff *skb, struct ip_set *from, *to; ip_set_id_t from_id, to_id; char from_name[IPSET_MAXNAMELEN]; - u32 from_ref; if (unlikely(protocol_failed(attr) || attr[IPSET_ATTR_SETNAME] == NULL || @@ -899,17 +924,15 @@ ip_set_swap(struct sock *ctnl, struct sk_buff *skb, from->type->family == to->type->family)) return -IPSET_ERR_TYPE_MISMATCH; - /* No magic here: ref munging protected by the nfnl_lock */ strncpy(from_name, from->name, IPSET_MAXNAMELEN); - from_ref = atomic_read(&from->ref); - strncpy(from->name, to->name, IPSET_MAXNAMELEN); - atomic_set(&from->ref, atomic_read(&to->ref)); strncpy(to->name, from_name, IPSET_MAXNAMELEN); - atomic_set(&to->ref, from_ref); + write_lock_bh(&ip_set_ref_lock); + swap(from->ref, to->ref); ip_set_list[from_id] = to; ip_set_list[to_id] = from; + write_unlock_bh(&ip_set_ref_lock); return 0; } @@ -926,7 +949,7 @@ ip_set_dump_done(struct netlink_callback *cb) { if (cb->args[2]) { pr_debug("release set %s\n", ip_set_list[cb->args[1]]->name); - __ip_set_put((ip_set_id_t) cb->args[1]); + ip_set_put_byindex((ip_set_id_t) cb->args[1]); } return 0; } @@ -1068,7 +1091,7 @@ release_refcount: /* If there was an error or set is done, release set */ if (ret || !cb->args[2]) { pr_debug("release set %s\n", ip_set_list[index]->name); - __ip_set_put(index); + ip_set_put_byindex(index); } /* If we dump all sets, continue with dumping last ones */ diff --git a/net/netfilter/ipset/ip_set_list_set.c b/net/netfilter/ipset/ip_set_list_set.c index f4a46c0d25f3..e9159e99fc4b 100644 --- a/net/netfilter/ipset/ip_set_list_set.c +++ b/net/netfilter/ipset/ip_set_list_set.c @@ -366,8 +366,7 @@ list_set_head(struct ip_set *set, struct sk_buff *skb) NLA_PUT_NET32(skb, IPSET_ATTR_SIZE, htonl(map->size)); if (with_timeout(map->timeout)) NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, htonl(map->timeout)); - NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, - htonl(atomic_read(&set->ref) - 1)); + NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)); NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE, htonl(sizeof(*map) + map->size * map->dsize)); ipset_nest_end(skb, nested); @@ -457,8 +456,7 @@ list_set_gc(unsigned long ul_set) struct list_set *map = set->data; struct set_telem *e; u32 i; - - /* nfnl_lock should be called */ + write_lock_bh(&set->lock); for (i = 0; i < map->size; i++) { e = list_set_telem(map, i); -- cgit From 31ad3dd64e689bc79dd819f8f134b9b025240eb8 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Mon, 4 Apr 2011 16:56:29 +0200 Subject: netfilter: af_info: add network namespace parameter to route hook This is required to eventually replace the rt6_lookup call in xt_addrtype.c with nf_afinfo->route(). Signed-off-by: Florian Westphal Acked-by: David S. Miller Signed-off-by: Patrick McHardy --- include/linux/netfilter.h | 3 ++- net/ipv4/netfilter.c | 5 +++-- net/ipv6/netfilter.c | 5 +++-- net/netfilter/nf_conntrack_h323_main.c | 8 ++++---- net/netfilter/xt_TCPMSS.c | 2 +- 5 files changed, 13 insertions(+), 10 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h index eeec00abb664..20ed4528e850 100644 --- a/include/linux/netfilter.h +++ b/include/linux/netfilter.h @@ -270,7 +270,8 @@ struct nf_afinfo { unsigned int dataoff, unsigned int len, u_int8_t protocol); - int (*route)(struct dst_entry **dst, struct flowi *fl); + int (*route)(struct net *net, struct dst_entry **dst, + struct flowi *fl); void (*saveroute)(const struct sk_buff *skb, struct nf_queue_entry *entry); int (*reroute)(struct sk_buff *skb, diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c index f3c0b549b8e1..f1035f056503 100644 --- a/net/ipv4/netfilter.c +++ b/net/ipv4/netfilter.c @@ -221,9 +221,10 @@ static __sum16 nf_ip_checksum_partial(struct sk_buff *skb, unsigned int hook, return csum; } -static int nf_ip_route(struct dst_entry **dst, struct flowi *fl) +static int nf_ip_route(struct net *net, struct dst_entry **dst, + struct flowi *fl) { - struct rtable *rt = ip_route_output_key(&init_net, &fl->u.ip4); + struct rtable *rt = ip_route_output_key(net, &fl->u.ip4); if (IS_ERR(rt)) return PTR_ERR(rt); *dst = &rt->dst; diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c index 39aaca2b4fd2..e008b9b4a779 100644 --- a/net/ipv6/netfilter.c +++ b/net/ipv6/netfilter.c @@ -90,9 +90,10 @@ static int nf_ip6_reroute(struct sk_buff *skb, return 0; } -static int nf_ip6_route(struct dst_entry **dst, struct flowi *fl) +static int nf_ip6_route(struct net *net, struct dst_entry **dst, + struct flowi *fl) { - *dst = ip6_route_output(&init_net, NULL, &fl->u.ip6); + *dst = ip6_route_output(net, NULL, &fl->u.ip6); return (*dst)->error; } diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c index 533a183e6661..39a453895b4d 100644 --- a/net/netfilter/nf_conntrack_h323_main.c +++ b/net/netfilter/nf_conntrack_h323_main.c @@ -731,9 +731,9 @@ static int callforward_do_filter(const union nf_inet_addr *src, memset(&fl2, 0, sizeof(fl2)); fl2.daddr = dst->ip; - if (!afinfo->route((struct dst_entry **)&rt1, + if (!afinfo->route(&init_net, (struct dst_entry **)&rt1, flowi4_to_flowi(&fl1))) { - if (!afinfo->route((struct dst_entry **)&rt2, + if (!afinfo->route(&init_net, (struct dst_entry **)&rt2, flowi4_to_flowi(&fl2))) { if (rt1->rt_gateway == rt2->rt_gateway && rt1->dst.dev == rt2->dst.dev) @@ -755,9 +755,9 @@ static int callforward_do_filter(const union nf_inet_addr *src, memset(&fl2, 0, sizeof(fl2)); ipv6_addr_copy(&fl2.daddr, &dst->in6); - if (!afinfo->route((struct dst_entry **)&rt1, + if (!afinfo->route(&init_net, (struct dst_entry **)&rt1, flowi6_to_flowi(&fl1))) { - if (!afinfo->route((struct dst_entry **)&rt2, + if (!afinfo->route(&init_net, (struct dst_entry **)&rt2, flowi6_to_flowi(&fl2))) { if (!memcmp(&rt1->rt6i_gateway, &rt2->rt6i_gateway, sizeof(rt1->rt6i_gateway)) && diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c index 6e6b46cb1db9..8690125e3b18 100644 --- a/net/netfilter/xt_TCPMSS.c +++ b/net/netfilter/xt_TCPMSS.c @@ -166,7 +166,7 @@ static u_int32_t tcpmss_reverse_mtu(const struct sk_buff *skb, rcu_read_lock(); ai = nf_get_afinfo(family); if (ai != NULL) - ai->route((struct dst_entry **)&rt, &fl); + ai->route(&init_net, (struct dst_entry **)&rt, &fl); rcu_read_unlock(); if (rt != NULL) { -- cgit From 0fae2e7740aca7e384c5f337f458897e7e337d58 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Mon, 4 Apr 2011 17:00:54 +0200 Subject: netfilter: af_info: add 'strict' parameter to limit lookup to .oif ipv6 fib lookup can set RT6_LOOKUP_F_IFACE flag to restrict search to an interface, but this flag cannot be set via struct flowi. Also, it cannot be set via ip6_route_output: this function uses the passed sock struct to determine if this flag is required (by testing for nonzero sk_bound_dev_if). Work around this by passing in an artificial struct sk in case 'strict' argument is true. This is required to replace the rt6_lookup call in xt_addrtype.c with nf_afinfo->route(). Signed-off-by: Florian Westphal Acked-by: David S. Miller Signed-off-by: Patrick McHardy --- include/linux/netfilter.h | 2 +- net/ipv4/netfilter.c | 2 +- net/ipv6/netfilter.c | 12 ++++++++++-- net/netfilter/nf_conntrack_h323_main.c | 8 ++++---- net/netfilter/xt_TCPMSS.c | 2 +- 5 files changed, 17 insertions(+), 9 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h index 20ed4528e850..7fa95df60146 100644 --- a/include/linux/netfilter.h +++ b/include/linux/netfilter.h @@ -271,7 +271,7 @@ struct nf_afinfo { unsigned int len, u_int8_t protocol); int (*route)(struct net *net, struct dst_entry **dst, - struct flowi *fl); + struct flowi *fl, bool strict); void (*saveroute)(const struct sk_buff *skb, struct nf_queue_entry *entry); int (*reroute)(struct sk_buff *skb, diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c index f1035f056503..4614babdc45f 100644 --- a/net/ipv4/netfilter.c +++ b/net/ipv4/netfilter.c @@ -222,7 +222,7 @@ static __sum16 nf_ip_checksum_partial(struct sk_buff *skb, unsigned int hook, } static int nf_ip_route(struct net *net, struct dst_entry **dst, - struct flowi *fl) + struct flowi *fl, bool strict __always_unused) { struct rtable *rt = ip_route_output_key(net, &fl->u.ip4); if (IS_ERR(rt)) diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c index e008b9b4a779..28bc1f644b7b 100644 --- a/net/ipv6/netfilter.c +++ b/net/ipv6/netfilter.c @@ -91,9 +91,17 @@ static int nf_ip6_reroute(struct sk_buff *skb, } static int nf_ip6_route(struct net *net, struct dst_entry **dst, - struct flowi *fl) + struct flowi *fl, bool strict) { - *dst = ip6_route_output(net, NULL, &fl->u.ip6); + static const struct ipv6_pinfo fake_pinfo; + static const struct inet_sock fake_sk = { + /* makes ip6_route_output set RT6_LOOKUP_F_IFACE: */ + .sk.sk_bound_dev_if = 1, + .pinet6 = (struct ipv6_pinfo *) &fake_pinfo, + }; + const void *sk = strict ? &fake_sk : NULL; + + *dst = ip6_route_output(net, sk, &fl->u.ip6); return (*dst)->error; } diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c index 39a453895b4d..18b2ce5c8ced 100644 --- a/net/netfilter/nf_conntrack_h323_main.c +++ b/net/netfilter/nf_conntrack_h323_main.c @@ -732,9 +732,9 @@ static int callforward_do_filter(const union nf_inet_addr *src, memset(&fl2, 0, sizeof(fl2)); fl2.daddr = dst->ip; if (!afinfo->route(&init_net, (struct dst_entry **)&rt1, - flowi4_to_flowi(&fl1))) { + flowi4_to_flowi(&fl1), false)) { if (!afinfo->route(&init_net, (struct dst_entry **)&rt2, - flowi4_to_flowi(&fl2))) { + flowi4_to_flowi(&fl2), false)) { if (rt1->rt_gateway == rt2->rt_gateway && rt1->dst.dev == rt2->dst.dev) ret = 1; @@ -756,9 +756,9 @@ static int callforward_do_filter(const union nf_inet_addr *src, memset(&fl2, 0, sizeof(fl2)); ipv6_addr_copy(&fl2.daddr, &dst->in6); if (!afinfo->route(&init_net, (struct dst_entry **)&rt1, - flowi6_to_flowi(&fl1))) { + flowi6_to_flowi(&fl1), false)) { if (!afinfo->route(&init_net, (struct dst_entry **)&rt2, - flowi6_to_flowi(&fl2))) { + flowi6_to_flowi(&fl2), false)) { if (!memcmp(&rt1->rt6i_gateway, &rt2->rt6i_gateway, sizeof(rt1->rt6i_gateway)) && rt1->dst.dev == rt2->dst.dev) diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c index 8690125e3b18..9e63b43faeed 100644 --- a/net/netfilter/xt_TCPMSS.c +++ b/net/netfilter/xt_TCPMSS.c @@ -166,7 +166,7 @@ static u_int32_t tcpmss_reverse_mtu(const struct sk_buff *skb, rcu_read_lock(); ai = nf_get_afinfo(family); if (ai != NULL) - ai->route(&init_net, (struct dst_entry **)&rt, &fl); + ai->route(&init_net, (struct dst_entry **)&rt, &fl, false); rcu_read_unlock(); if (rt != NULL) { -- cgit From 7f5c6d4f665bb57a19a34ce1fb16cc708c04f219 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 4 Apr 2011 17:04:03 +0200 Subject: netfilter: get rid of atomic ops in fast path We currently use a percpu spinlock to 'protect' rule bytes/packets counters, after various attempts to use RCU instead. Lately we added a seqlock so that get_counters() can run without blocking BH or 'writers'. But we really only need the seqcount in it. Spinlock itself is only locked by the current/owner cpu, so we can remove it completely. This cleanups api, using correct 'writer' vs 'reader' semantic. At replace time, the get_counters() call makes sure all cpus are done using the old table. Signed-off-by: Eric Dumazet Cc: Jan Engelhardt Signed-off-by: Patrick McHardy --- include/linux/netfilter/x_tables.h | 96 +++++++++++++++++--------------------- net/ipv4/netfilter/arp_tables.c | 18 ++++--- net/ipv4/netfilter/ip_tables.c | 28 +++++------ net/ipv6/netfilter/ip6_tables.c | 19 +++++--- net/netfilter/x_tables.c | 9 ++-- 5 files changed, 80 insertions(+), 90 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index 37219525ff6f..32cddf78b13e 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h @@ -456,72 +456,60 @@ extern void xt_proto_fini(struct net *net, u_int8_t af); extern struct xt_table_info *xt_alloc_table_info(unsigned int size); extern void xt_free_table_info(struct xt_table_info *info); -/* - * Per-CPU spinlock associated with per-cpu table entries, and - * with a counter for the "reading" side that allows a recursive - * reader to avoid taking the lock and deadlocking. - * - * "reading" is used by ip/arp/ip6 tables rule processing which runs per-cpu. - * It needs to ensure that the rules are not being changed while the packet - * is being processed. In some cases, the read lock will be acquired - * twice on the same CPU; this is okay because of the count. - * - * "writing" is used when reading counters. - * During replace any readers that are using the old tables have to complete - * before freeing the old table. This is handled by the write locking - * necessary for reading the counters. +/** + * xt_recseq - recursive seqcount for netfilter use + * + * Packet processing changes the seqcount only if no recursion happened + * get_counters() can use read_seqcount_begin()/read_seqcount_retry(), + * because we use the normal seqcount convention : + * Low order bit set to 1 if a writer is active. */ -struct xt_info_lock { - seqlock_t lock; - unsigned char readers; -}; -DECLARE_PER_CPU(struct xt_info_lock, xt_info_locks); +DECLARE_PER_CPU(seqcount_t, xt_recseq); -/* - * Note: we need to ensure that preemption is disabled before acquiring - * the per-cpu-variable, so we do it as a two step process rather than - * using "spin_lock_bh()". - * - * We _also_ need to disable bottom half processing before updating our - * nesting count, to make sure that the only kind of re-entrancy is this - * code being called by itself: since the count+lock is not an atomic - * operation, we can allow no races. +/** + * xt_write_recseq_begin - start of a write section * - * _Only_ that special combination of being per-cpu and never getting - * re-entered asynchronously means that the count is safe. + * Begin packet processing : all readers must wait the end + * 1) Must be called with preemption disabled + * 2) softirqs must be disabled too (or we should use irqsafe_cpu_add()) + * Returns : + * 1 if no recursion on this cpu + * 0 if recursion detected */ -static inline void xt_info_rdlock_bh(void) +static inline unsigned int xt_write_recseq_begin(void) { - struct xt_info_lock *lock; + unsigned int addend; - local_bh_disable(); - lock = &__get_cpu_var(xt_info_locks); - if (likely(!lock->readers++)) - write_seqlock(&lock->lock); -} + /* + * Low order bit of sequence is set if we already + * called xt_write_recseq_begin(). + */ + addend = (__this_cpu_read(xt_recseq.sequence) + 1) & 1; -static inline void xt_info_rdunlock_bh(void) -{ - struct xt_info_lock *lock = &__get_cpu_var(xt_info_locks); + /* + * This is kind of a write_seqcount_begin(), but addend is 0 or 1 + * We dont check addend value to avoid a test and conditional jump, + * since addend is most likely 1 + */ + __this_cpu_add(xt_recseq.sequence, addend); + smp_wmb(); - if (likely(!--lock->readers)) - write_sequnlock(&lock->lock); - local_bh_enable(); + return addend; } -/* - * The "writer" side needs to get exclusive access to the lock, - * regardless of readers. This must be called with bottom half - * processing (and thus also preemption) disabled. +/** + * xt_write_recseq_end - end of a write section + * @addend: return value from previous xt_write_recseq_begin() + * + * End packet processing : all readers can proceed + * 1) Must be called with preemption disabled + * 2) softirqs must be disabled too (or we should use irqsafe_cpu_add()) */ -static inline void xt_info_wrlock(unsigned int cpu) -{ - write_seqlock(&per_cpu(xt_info_locks, cpu).lock); -} - -static inline void xt_info_wrunlock(unsigned int cpu) +static inline void xt_write_recseq_end(unsigned int addend) { - write_sequnlock(&per_cpu(xt_info_locks, cpu).lock); + /* this is kind of a write_seqcount_end(), but addend is 0 or 1 */ + smp_wmb(); + __this_cpu_add(xt_recseq.sequence, addend); } /* diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 4b5d457c2d76..2ea743336836 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -260,6 +260,7 @@ unsigned int arpt_do_table(struct sk_buff *skb, void *table_base; const struct xt_table_info *private; struct xt_action_param acpar; + unsigned int addend; if (!pskb_may_pull(skb, arp_hdr_len(skb->dev))) return NF_DROP; @@ -267,7 +268,8 @@ unsigned int arpt_do_table(struct sk_buff *skb, indev = in ? in->name : nulldevname; outdev = out ? out->name : nulldevname; - xt_info_rdlock_bh(); + local_bh_disable(); + addend = xt_write_recseq_begin(); private = table->private; table_base = private->entries[smp_processor_id()]; @@ -338,7 +340,8 @@ unsigned int arpt_do_table(struct sk_buff *skb, /* Verdict */ break; } while (!acpar.hotdrop); - xt_info_rdunlock_bh(); + xt_write_recseq_end(addend); + local_bh_enable(); if (acpar.hotdrop) return NF_DROP; @@ -712,7 +715,7 @@ static void get_counters(const struct xt_table_info *t, unsigned int i; for_each_possible_cpu(cpu) { - seqlock_t *lock = &per_cpu(xt_info_locks, cpu).lock; + seqcount_t *s = &per_cpu(xt_recseq, cpu); i = 0; xt_entry_foreach(iter, t->entries[cpu], t->size) { @@ -720,10 +723,10 @@ static void get_counters(const struct xt_table_info *t, unsigned int start; do { - start = read_seqbegin(lock); + start = read_seqcount_begin(s); bcnt = iter->counters.bcnt; pcnt = iter->counters.pcnt; - } while (read_seqretry(lock, start)); + } while (read_seqcount_retry(s, start)); ADD_COUNTER(counters[i], bcnt, pcnt); ++i; @@ -1115,6 +1118,7 @@ static int do_add_counters(struct net *net, const void __user *user, int ret = 0; void *loc_cpu_entry; struct arpt_entry *iter; + unsigned int addend; #ifdef CONFIG_COMPAT struct compat_xt_counters_info compat_tmp; @@ -1171,12 +1175,12 @@ static int do_add_counters(struct net *net, const void __user *user, /* Choose the copy that is on our node */ curcpu = smp_processor_id(); loc_cpu_entry = private->entries[curcpu]; - xt_info_wrlock(curcpu); + addend = xt_write_recseq_begin(); xt_entry_foreach(iter, loc_cpu_entry, private->size) { ADD_COUNTER(iter->counters, paddc[i].bcnt, paddc[i].pcnt); ++i; } - xt_info_wrunlock(curcpu); + xt_write_recseq_end(addend); unlock_up_free: local_bh_enable(); xt_table_unlock(t); diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index ffcea0d1678e..2b6b700949eb 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -68,15 +68,6 @@ void *ipt_alloc_initial_table(const struct xt_table *info) } EXPORT_SYMBOL_GPL(ipt_alloc_initial_table); -/* - We keep a set of rules for each CPU, so we can avoid write-locking - them in the softirq when updating the counters and therefore - only need to read-lock in the softirq; doing a write_lock_bh() in user - context stops packets coming through and allows user context to read - the counters or update the rules. - - Hence the start of any table is given by get_table() below. */ - /* Returns whether matches rule or not. */ /* Performance critical - called for every packet */ static inline bool @@ -311,6 +302,7 @@ ipt_do_table(struct sk_buff *skb, unsigned int *stackptr, origptr, cpu; const struct xt_table_info *private; struct xt_action_param acpar; + unsigned int addend; /* Initialization */ ip = ip_hdr(skb); @@ -331,7 +323,8 @@ ipt_do_table(struct sk_buff *skb, acpar.hooknum = hook; IP_NF_ASSERT(table->valid_hooks & (1 << hook)); - xt_info_rdlock_bh(); + local_bh_disable(); + addend = xt_write_recseq_begin(); private = table->private; cpu = smp_processor_id(); table_base = private->entries[cpu]; @@ -430,7 +423,9 @@ ipt_do_table(struct sk_buff *skb, pr_debug("Exiting %s; resetting sp from %u to %u\n", __func__, *stackptr, origptr); *stackptr = origptr; - xt_info_rdunlock_bh(); + xt_write_recseq_end(addend); + local_bh_enable(); + #ifdef DEBUG_ALLOW_ALL return NF_ACCEPT; #else @@ -886,7 +881,7 @@ get_counters(const struct xt_table_info *t, unsigned int i; for_each_possible_cpu(cpu) { - seqlock_t *lock = &per_cpu(xt_info_locks, cpu).lock; + seqcount_t *s = &per_cpu(xt_recseq, cpu); i = 0; xt_entry_foreach(iter, t->entries[cpu], t->size) { @@ -894,10 +889,10 @@ get_counters(const struct xt_table_info *t, unsigned int start; do { - start = read_seqbegin(lock); + start = read_seqcount_begin(s); bcnt = iter->counters.bcnt; pcnt = iter->counters.pcnt; - } while (read_seqretry(lock, start)); + } while (read_seqcount_retry(s, start)); ADD_COUNTER(counters[i], bcnt, pcnt); ++i; /* macro does multi eval of i */ @@ -1312,6 +1307,7 @@ do_add_counters(struct net *net, const void __user *user, int ret = 0; void *loc_cpu_entry; struct ipt_entry *iter; + unsigned int addend; #ifdef CONFIG_COMPAT struct compat_xt_counters_info compat_tmp; @@ -1368,12 +1364,12 @@ do_add_counters(struct net *net, const void __user *user, /* Choose the copy that is on our node */ curcpu = smp_processor_id(); loc_cpu_entry = private->entries[curcpu]; - xt_info_wrlock(curcpu); + addend = xt_write_recseq_begin(); xt_entry_foreach(iter, loc_cpu_entry, private->size) { ADD_COUNTER(iter->counters, paddc[i].bcnt, paddc[i].pcnt); ++i; } - xt_info_wrunlock(curcpu); + xt_write_recseq_end(addend); unlock_up_free: local_bh_enable(); xt_table_unlock(t); diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 0b2af9b85cec..ec7cf579cdd4 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -340,6 +340,7 @@ ip6t_do_table(struct sk_buff *skb, unsigned int *stackptr, origptr, cpu; const struct xt_table_info *private; struct xt_action_param acpar; + unsigned int addend; /* Initialization */ indev = in ? in->name : nulldevname; @@ -358,7 +359,8 @@ ip6t_do_table(struct sk_buff *skb, IP_NF_ASSERT(table->valid_hooks & (1 << hook)); - xt_info_rdlock_bh(); + local_bh_disable(); + addend = xt_write_recseq_begin(); private = table->private; cpu = smp_processor_id(); table_base = private->entries[cpu]; @@ -442,7 +444,9 @@ ip6t_do_table(struct sk_buff *skb, } while (!acpar.hotdrop); *stackptr = origptr; - xt_info_rdunlock_bh(); + + xt_write_recseq_end(addend); + local_bh_enable(); #ifdef DEBUG_ALLOW_ALL return NF_ACCEPT; @@ -899,7 +903,7 @@ get_counters(const struct xt_table_info *t, unsigned int i; for_each_possible_cpu(cpu) { - seqlock_t *lock = &per_cpu(xt_info_locks, cpu).lock; + seqcount_t *s = &per_cpu(xt_recseq, cpu); i = 0; xt_entry_foreach(iter, t->entries[cpu], t->size) { @@ -907,10 +911,10 @@ get_counters(const struct xt_table_info *t, unsigned int start; do { - start = read_seqbegin(lock); + start = read_seqcount_begin(s); bcnt = iter->counters.bcnt; pcnt = iter->counters.pcnt; - } while (read_seqretry(lock, start)); + } while (read_seqcount_retry(s, start)); ADD_COUNTER(counters[i], bcnt, pcnt); ++i; @@ -1325,6 +1329,7 @@ do_add_counters(struct net *net, const void __user *user, unsigned int len, int ret = 0; const void *loc_cpu_entry; struct ip6t_entry *iter; + unsigned int addend; #ifdef CONFIG_COMPAT struct compat_xt_counters_info compat_tmp; @@ -1381,13 +1386,13 @@ do_add_counters(struct net *net, const void __user *user, unsigned int len, i = 0; /* Choose the copy that is on our node */ curcpu = smp_processor_id(); - xt_info_wrlock(curcpu); + addend = xt_write_recseq_begin(); loc_cpu_entry = private->entries[curcpu]; xt_entry_foreach(iter, loc_cpu_entry, private->size) { ADD_COUNTER(iter->counters, paddc[i].bcnt, paddc[i].pcnt); ++i; } - xt_info_wrunlock(curcpu); + xt_write_recseq_end(addend); unlock_up_free: local_bh_enable(); diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index a9adf4c6b299..52959efca858 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c @@ -762,8 +762,8 @@ void xt_compat_unlock(u_int8_t af) EXPORT_SYMBOL_GPL(xt_compat_unlock); #endif -DEFINE_PER_CPU(struct xt_info_lock, xt_info_locks); -EXPORT_PER_CPU_SYMBOL_GPL(xt_info_locks); +DEFINE_PER_CPU(seqcount_t, xt_recseq); +EXPORT_PER_CPU_SYMBOL_GPL(xt_recseq); static int xt_jumpstack_alloc(struct xt_table_info *i) { @@ -1362,10 +1362,7 @@ static int __init xt_init(void) int rv; for_each_possible_cpu(i) { - struct xt_info_lock *lock = &per_cpu(xt_info_locks, i); - - seqlock_init(&lock->lock); - lock->readers = 0; + seqcount_init(&per_cpu(xt_recseq, i)); } xt = kmalloc(sizeof(struct xt_af) * NFPROTO_NUMPROTO, GFP_KERNEL); -- cgit From d430d3d7e646eb1eac2bb4aa244a644312e67c76 Mon Sep 17 00:00:00 2001 From: Jason Baron Date: Wed, 16 Mar 2011 17:29:47 -0400 Subject: jump label: Introduce static_branch() interface Introduce: static __always_inline bool static_branch(struct jump_label_key *key); instead of the old JUMP_LABEL(key, label) macro. In this way, jump labels become really easy to use: Define: struct jump_label_key jump_key; Can be used as: if (static_branch(&jump_key)) do unlikely code enable/disale via: jump_label_inc(&jump_key); jump_label_dec(&jump_key); that's it! For the jump labels disabled case, the static_branch() becomes an atomic_read(), and jump_label_inc()/dec() are simply atomic_inc(), atomic_dec() operations. We show testing results for this change below. Thanks to H. Peter Anvin for suggesting the 'static_branch()' construct. Since we now require a 'struct jump_label_key *key', we can store a pointer into the jump table addresses. In this way, we can enable/disable jump labels, in basically constant time. This change allows us to completely remove the previous hashtable scheme. Thanks to Peter Zijlstra for this re-write. Testing: I ran a series of 'tbench 20' runs 5 times (with reboots) for 3 configurations, where tracepoints were disabled. jump label configured in avg: 815.6 jump label *not* configured in (using atomic reads) avg: 800.1 jump label *not* configured in (regular reads) avg: 803.4 Signed-off-by: Peter Zijlstra LKML-Reference: <20110316212947.GA8792@redhat.com> Signed-off-by: Jason Baron Suggested-by: H. Peter Anvin Tested-by: David Daney Acked-by: Ralf Baechle Acked-by: David S. Miller Acked-by: Mathieu Desnoyers Signed-off-by: Steven Rostedt --- arch/mips/include/asm/jump_label.h | 22 +- arch/sparc/include/asm/jump_label.h | 25 +- arch/x86/include/asm/alternative.h | 3 +- arch/x86/include/asm/jump_label.h | 26 +- arch/x86/kernel/alternative.c | 2 +- arch/x86/kernel/module.c | 1 + include/asm-generic/vmlinux.lds.h | 14 +- include/linux/dynamic_debug.h | 2 - include/linux/jump_label.h | 89 +++--- include/linux/jump_label_ref.h | 44 --- include/linux/perf_event.h | 26 +- include/linux/tracepoint.h | 22 +- kernel/jump_label.c | 539 +++++++++++++++--------------------- kernel/perf_event.c | 4 +- kernel/tracepoint.c | 23 +- 15 files changed, 356 insertions(+), 486 deletions(-) delete mode 100644 include/linux/jump_label_ref.h (limited to 'include/linux') diff --git a/arch/mips/include/asm/jump_label.h b/arch/mips/include/asm/jump_label.h index 7622ccf75076..1881b316ca45 100644 --- a/arch/mips/include/asm/jump_label.h +++ b/arch/mips/include/asm/jump_label.h @@ -20,16 +20,18 @@ #define WORD_INSN ".word" #endif -#define JUMP_LABEL(key, label) \ - do { \ - asm goto("1:\tnop\n\t" \ - "nop\n\t" \ - ".pushsection __jump_table, \"a\"\n\t" \ - WORD_INSN " 1b, %l[" #label "], %0\n\t" \ - ".popsection\n\t" \ - : : "i" (key) : : label); \ - } while (0) - +static __always_inline bool arch_static_branch(struct jump_label_key *key) +{ + asm goto("1:\tnop\n\t" + "nop\n\t" + ".pushsection __jump_table, \"aw\"\n\t" + WORD_INSN " 1b, %l[l_yes], %0\n\t" + ".popsection\n\t" + : : "i" (key) : : l_yes); + return false; +l_yes: + return true; +} #endif /* __KERNEL__ */ diff --git a/arch/sparc/include/asm/jump_label.h b/arch/sparc/include/asm/jump_label.h index 427d4684e0d2..fc73a82366f8 100644 --- a/arch/sparc/include/asm/jump_label.h +++ b/arch/sparc/include/asm/jump_label.h @@ -7,17 +7,20 @@ #define JUMP_LABEL_NOP_SIZE 4 -#define JUMP_LABEL(key, label) \ - do { \ - asm goto("1:\n\t" \ - "nop\n\t" \ - "nop\n\t" \ - ".pushsection __jump_table, \"a\"\n\t"\ - ".align 4\n\t" \ - ".word 1b, %l[" #label "], %c0\n\t" \ - ".popsection \n\t" \ - : : "i" (key) : : label);\ - } while (0) +static __always_inline bool arch_static_branch(struct jump_label_key *key) +{ + asm goto("1:\n\t" + "nop\n\t" + "nop\n\t" + ".pushsection __jump_table, \"aw\"\n\t" + ".align 4\n\t" + ".word 1b, %l[l_yes], %c0\n\t" + ".popsection \n\t" + : : "i" (key) : : l_yes); + return false; +l_yes: + return true; +} #endif /* __KERNEL__ */ diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h index 13009d1af99a..8cdd1e247975 100644 --- a/arch/x86/include/asm/alternative.h +++ b/arch/x86/include/asm/alternative.h @@ -4,7 +4,6 @@ #include #include #include -#include #include /* @@ -191,7 +190,7 @@ extern void *text_poke(void *addr, const void *opcode, size_t len); extern void *text_poke_smp(void *addr, const void *opcode, size_t len); extern void text_poke_smp_batch(struct text_poke_param *params, int n); -#if defined(CONFIG_DYNAMIC_FTRACE) || defined(HAVE_JUMP_LABEL) +#if defined(CONFIG_DYNAMIC_FTRACE) || defined(CONFIG_JUMP_LABEL) #define IDEAL_NOP_SIZE_5 5 extern unsigned char ideal_nop5[IDEAL_NOP_SIZE_5]; extern void arch_init_ideal_nop5(void); diff --git a/arch/x86/include/asm/jump_label.h b/arch/x86/include/asm/jump_label.h index 574dbc22893a..f217cee86533 100644 --- a/arch/x86/include/asm/jump_label.h +++ b/arch/x86/include/asm/jump_label.h @@ -5,20 +5,24 @@ #include #include +#include #define JUMP_LABEL_NOP_SIZE 5 -# define JUMP_LABEL_INITIAL_NOP ".byte 0xe9 \n\t .long 0\n\t" - -# define JUMP_LABEL(key, label) \ - do { \ - asm goto("1:" \ - JUMP_LABEL_INITIAL_NOP \ - ".pushsection __jump_table, \"aw\" \n\t"\ - _ASM_PTR "1b, %l[" #label "], %c0 \n\t" \ - ".popsection \n\t" \ - : : "i" (key) : : label); \ - } while (0) +#define JUMP_LABEL_INITIAL_NOP ".byte 0xe9 \n\t .long 0\n\t" + +static __always_inline bool arch_static_branch(struct jump_label_key *key) +{ + asm goto("1:" + JUMP_LABEL_INITIAL_NOP + ".pushsection __jump_table, \"aw\" \n\t" + _ASM_PTR "1b, %l[l_yes], %c0 \n\t" + ".popsection \n\t" + : : "i" (key) : : l_yes); + return false; +l_yes: + return true; +} #endif /* __KERNEL__ */ diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index 4a234677e213..651454b0c811 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -679,7 +679,7 @@ void __kprobes text_poke_smp_batch(struct text_poke_param *params, int n) __stop_machine(stop_machine_text_poke, (void *)&tpp, NULL); } -#if defined(CONFIG_DYNAMIC_FTRACE) || defined(HAVE_JUMP_LABEL) +#if defined(CONFIG_DYNAMIC_FTRACE) || defined(CONFIG_JUMP_LABEL) #ifdef CONFIG_X86_64 unsigned char ideal_nop5[5] = { 0x66, 0x66, 0x66, 0x66, 0x90 }; diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c index ab23f1ad4bf1..52f256f2cc81 100644 --- a/arch/x86/kernel/module.c +++ b/arch/x86/kernel/module.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 32c45e5fe0ab..79522166d7f1 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -170,6 +170,10 @@ STRUCT_ALIGN(); \ *(__tracepoints) \ /* implement dynamic printk debug */ \ + . = ALIGN(8); \ + VMLINUX_SYMBOL(__start___jump_table) = .; \ + *(__jump_table) \ + VMLINUX_SYMBOL(__stop___jump_table) = .; \ . = ALIGN(8); \ VMLINUX_SYMBOL(__start___verbose) = .; \ *(__verbose) \ @@ -228,8 +232,6 @@ \ BUG_TABLE \ \ - JUMP_TABLE \ - \ /* PCI quirks */ \ .pci_fixup : AT(ADDR(.pci_fixup) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__start_pci_fixups_early) = .; \ @@ -589,14 +591,6 @@ #define BUG_TABLE #endif -#define JUMP_TABLE \ - . = ALIGN(8); \ - __jump_table : AT(ADDR(__jump_table) - LOAD_OFFSET) { \ - VMLINUX_SYMBOL(__start___jump_table) = .; \ - *(__jump_table) \ - VMLINUX_SYMBOL(__stop___jump_table) = .; \ - } - #ifdef CONFIG_PM_TRACE #define TRACEDATA \ . = ALIGN(4); \ diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h index 0c9653f11c18..e747ecd48e1c 100644 --- a/include/linux/dynamic_debug.h +++ b/include/linux/dynamic_debug.h @@ -1,8 +1,6 @@ #ifndef _DYNAMIC_DEBUG_H #define _DYNAMIC_DEBUG_H -#include - /* dynamic_printk_enabled, and dynamic_printk_enabled2 are bitmasks in which * bit n is set to 1 if any modname hashes into the bucket n, 0 otherwise. They * use independent hash functions, to reduce the chance of false positives. diff --git a/include/linux/jump_label.h b/include/linux/jump_label.h index 7880f18e4b86..83e745f3ead7 100644 --- a/include/linux/jump_label.h +++ b/include/linux/jump_label.h @@ -1,20 +1,43 @@ #ifndef _LINUX_JUMP_LABEL_H #define _LINUX_JUMP_LABEL_H +#include +#include + #if defined(CC_HAVE_ASM_GOTO) && defined(CONFIG_JUMP_LABEL) + +struct jump_label_key { + atomic_t enabled; + struct jump_entry *entries; +#ifdef CONFIG_MODULES + struct jump_label_mod *next; +#endif +}; + # include # define HAVE_JUMP_LABEL #endif enum jump_label_type { + JUMP_LABEL_DISABLE = 0, JUMP_LABEL_ENABLE, - JUMP_LABEL_DISABLE }; struct module; #ifdef HAVE_JUMP_LABEL +#ifdef CONFIG_MODULES +#define JUMP_LABEL_INIT {{ 0 }, NULL, NULL} +#else +#define JUMP_LABEL_INIT {{ 0 }, NULL} +#endif + +static __always_inline bool static_branch(struct jump_label_key *key) +{ + return arch_static_branch(key); +} + extern struct jump_entry __start___jump_table[]; extern struct jump_entry __stop___jump_table[]; @@ -23,37 +46,37 @@ extern void jump_label_unlock(void); extern void arch_jump_label_transform(struct jump_entry *entry, enum jump_label_type type); extern void arch_jump_label_text_poke_early(jump_label_t addr); -extern void jump_label_update(unsigned long key, enum jump_label_type type); -extern void jump_label_apply_nops(struct module *mod); extern int jump_label_text_reserved(void *start, void *end); +extern void jump_label_inc(struct jump_label_key *key); +extern void jump_label_dec(struct jump_label_key *key); +extern bool jump_label_enabled(struct jump_label_key *key); +extern void jump_label_apply_nops(struct module *mod); -#define jump_label_enable(key) \ - jump_label_update((unsigned long)key, JUMP_LABEL_ENABLE); +#else -#define jump_label_disable(key) \ - jump_label_update((unsigned long)key, JUMP_LABEL_DISABLE); +#include -#else +#define JUMP_LABEL_INIT {ATOMIC_INIT(0)} -#define JUMP_LABEL(key, label) \ -do { \ - if (unlikely(*key)) \ - goto label; \ -} while (0) +struct jump_label_key { + atomic_t enabled; +}; -#define jump_label_enable(cond_var) \ -do { \ - *(cond_var) = 1; \ -} while (0) +static __always_inline bool static_branch(struct jump_label_key *key) +{ + if (unlikely(atomic_read(&key->enabled))) + return true; + return false; +} -#define jump_label_disable(cond_var) \ -do { \ - *(cond_var) = 0; \ -} while (0) +static inline void jump_label_inc(struct jump_label_key *key) +{ + atomic_inc(&key->enabled); +} -static inline int jump_label_apply_nops(struct module *mod) +static inline void jump_label_dec(struct jump_label_key *key) { - return 0; + atomic_dec(&key->enabled); } static inline int jump_label_text_reserved(void *start, void *end) @@ -64,16 +87,16 @@ static inline int jump_label_text_reserved(void *start, void *end) static inline void jump_label_lock(void) {} static inline void jump_label_unlock(void) {} -#endif +static inline bool jump_label_enabled(struct jump_label_key *key) +{ + return !!atomic_read(&key->enabled); +} -#define COND_STMT(key, stmt) \ -do { \ - __label__ jl_enabled; \ - JUMP_LABEL(key, jl_enabled); \ - if (0) { \ -jl_enabled: \ - stmt; \ - } \ -} while (0) +static inline int jump_label_apply_nops(struct module *mod) +{ + return 0; +} + +#endif #endif diff --git a/include/linux/jump_label_ref.h b/include/linux/jump_label_ref.h deleted file mode 100644 index e5d012ad92c6..000000000000 --- a/include/linux/jump_label_ref.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef _LINUX_JUMP_LABEL_REF_H -#define _LINUX_JUMP_LABEL_REF_H - -#include -#include - -#ifdef HAVE_JUMP_LABEL - -static inline void jump_label_inc(atomic_t *key) -{ - if (atomic_add_return(1, key) == 1) - jump_label_enable(key); -} - -static inline void jump_label_dec(atomic_t *key) -{ - if (atomic_dec_and_test(key)) - jump_label_disable(key); -} - -#else /* !HAVE_JUMP_LABEL */ - -static inline void jump_label_inc(atomic_t *key) -{ - atomic_inc(key); -} - -static inline void jump_label_dec(atomic_t *key) -{ - atomic_dec(key); -} - -#undef JUMP_LABEL -#define JUMP_LABEL(key, label) \ -do { \ - if (unlikely(__builtin_choose_expr( \ - __builtin_types_compatible_p(typeof(key), atomic_t *), \ - atomic_read((atomic_t *)(key)), *(key)))) \ - goto label; \ -} while (0) - -#endif /* HAVE_JUMP_LABEL */ - -#endif /* _LINUX_JUMP_LABEL_REF_H */ diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 311b4dc785a1..730b7821690f 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -505,7 +505,7 @@ struct perf_guest_info_callbacks { #include #include #include -#include +#include #include #include @@ -1034,7 +1034,7 @@ static inline int is_software_event(struct perf_event *event) return event->pmu->task_ctx_nr == perf_sw_context; } -extern atomic_t perf_swevent_enabled[PERF_COUNT_SW_MAX]; +extern struct jump_label_key perf_swevent_enabled[PERF_COUNT_SW_MAX]; extern void __perf_sw_event(u32, u64, int, struct pt_regs *, u64); @@ -1063,22 +1063,21 @@ perf_sw_event(u32 event_id, u64 nr, int nmi, struct pt_regs *regs, u64 addr) { struct pt_regs hot_regs; - JUMP_LABEL(&perf_swevent_enabled[event_id], have_event); - return; - -have_event: - if (!regs) { - perf_fetch_caller_regs(&hot_regs); - regs = &hot_regs; + if (static_branch(&perf_swevent_enabled[event_id])) { + if (!regs) { + perf_fetch_caller_regs(&hot_regs); + regs = &hot_regs; + } + __perf_sw_event(event_id, nr, nmi, regs, addr); } - __perf_sw_event(event_id, nr, nmi, regs, addr); } -extern atomic_t perf_sched_events; +extern struct jump_label_key perf_sched_events; static inline void perf_event_task_sched_in(struct task_struct *task) { - COND_STMT(&perf_sched_events, __perf_event_task_sched_in(task)); + if (static_branch(&perf_sched_events)) + __perf_event_task_sched_in(task); } static inline @@ -1086,7 +1085,8 @@ void perf_event_task_sched_out(struct task_struct *task, struct task_struct *nex { perf_sw_event(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, 1, NULL, 0); - COND_STMT(&perf_sched_events, __perf_event_task_sched_out(task, next)); + if (static_branch(&perf_sched_events)) + __perf_event_task_sched_out(task, next); } extern void perf_event_mmap(struct vm_area_struct *vma); diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index 97c84a58efb8..d530a4460a0b 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h @@ -29,7 +29,7 @@ struct tracepoint_func { struct tracepoint { const char *name; /* Tracepoint name */ - int state; /* State. */ + struct jump_label_key key; void (*regfunc)(void); void (*unregfunc)(void); struct tracepoint_func __rcu *funcs; @@ -146,9 +146,7 @@ void tracepoint_update_probe_range(struct tracepoint * const *begin, extern struct tracepoint __tracepoint_##name; \ static inline void trace_##name(proto) \ { \ - JUMP_LABEL(&__tracepoint_##name.state, do_trace); \ - return; \ -do_trace: \ + if (static_branch(&__tracepoint_##name.key)) \ __DO_TRACE(&__tracepoint_##name, \ TP_PROTO(data_proto), \ TP_ARGS(data_args), \ @@ -176,14 +174,14 @@ do_trace: \ * structures, so we create an array of pointers that will be used for iteration * on the tracepoints. */ -#define DEFINE_TRACE_FN(name, reg, unreg) \ - static const char __tpstrtab_##name[] \ - __attribute__((section("__tracepoints_strings"))) = #name; \ - struct tracepoint __tracepoint_##name \ - __attribute__((section("__tracepoints"))) = \ - { __tpstrtab_##name, 0, reg, unreg, NULL }; \ - static struct tracepoint * const __tracepoint_ptr_##name __used \ - __attribute__((section("__tracepoints_ptrs"))) = \ +#define DEFINE_TRACE_FN(name, reg, unreg) \ + static const char __tpstrtab_##name[] \ + __attribute__((section("__tracepoints_strings"))) = #name; \ + struct tracepoint __tracepoint_##name \ + __attribute__((section("__tracepoints"))) = \ + { __tpstrtab_##name, JUMP_LABEL_INIT, reg, unreg, NULL };\ + static struct tracepoint * const __tracepoint_ptr_##name __used \ + __attribute__((section("__tracepoints_ptrs"))) = \ &__tracepoint_##name; #define DEFINE_TRACE(name) \ diff --git a/kernel/jump_label.c b/kernel/jump_label.c index 3b79bd938330..74d1c099fbd1 100644 --- a/kernel/jump_label.c +++ b/kernel/jump_label.c @@ -2,43 +2,23 @@ * jump label support * * Copyright (C) 2009 Jason Baron + * Copyright (C) 2011 Peter Zijlstra * */ -#include #include #include #include #include -#include #include #include #include +#include #ifdef HAVE_JUMP_LABEL -#define JUMP_LABEL_HASH_BITS 6 -#define JUMP_LABEL_TABLE_SIZE (1 << JUMP_LABEL_HASH_BITS) -static struct hlist_head jump_label_table[JUMP_LABEL_TABLE_SIZE]; - /* mutex to protect coming/going of the the jump_label table */ static DEFINE_MUTEX(jump_label_mutex); -struct jump_label_entry { - struct hlist_node hlist; - struct jump_entry *table; - int nr_entries; - /* hang modules off here */ - struct hlist_head modules; - unsigned long key; -}; - -struct jump_label_module_entry { - struct hlist_node hlist; - struct jump_entry *table; - int nr_entries; - struct module *mod; -}; - void jump_label_lock(void) { mutex_lock(&jump_label_mutex); @@ -49,6 +29,11 @@ void jump_label_unlock(void) mutex_unlock(&jump_label_mutex); } +bool jump_label_enabled(struct jump_label_key *key) +{ + return !!atomic_read(&key->enabled); +} + static int jump_label_cmp(const void *a, const void *b) { const struct jump_entry *jea = a; @@ -64,7 +49,7 @@ static int jump_label_cmp(const void *a, const void *b) } static void -sort_jump_label_entries(struct jump_entry *start, struct jump_entry *stop) +jump_label_sort_entries(struct jump_entry *start, struct jump_entry *stop) { unsigned long size; @@ -73,118 +58,25 @@ sort_jump_label_entries(struct jump_entry *start, struct jump_entry *stop) sort(start, size, sizeof(struct jump_entry), jump_label_cmp, NULL); } -static struct jump_label_entry *get_jump_label_entry(jump_label_t key) -{ - struct hlist_head *head; - struct hlist_node *node; - struct jump_label_entry *e; - u32 hash = jhash((void *)&key, sizeof(jump_label_t), 0); - - head = &jump_label_table[hash & (JUMP_LABEL_TABLE_SIZE - 1)]; - hlist_for_each_entry(e, node, head, hlist) { - if (key == e->key) - return e; - } - return NULL; -} +static void jump_label_update(struct jump_label_key *key, int enable); -static struct jump_label_entry * -add_jump_label_entry(jump_label_t key, int nr_entries, struct jump_entry *table) +void jump_label_inc(struct jump_label_key *key) { - struct hlist_head *head; - struct jump_label_entry *e; - u32 hash; - - e = get_jump_label_entry(key); - if (e) - return ERR_PTR(-EEXIST); - - e = kmalloc(sizeof(struct jump_label_entry), GFP_KERNEL); - if (!e) - return ERR_PTR(-ENOMEM); - - hash = jhash((void *)&key, sizeof(jump_label_t), 0); - head = &jump_label_table[hash & (JUMP_LABEL_TABLE_SIZE - 1)]; - e->key = key; - e->table = table; - e->nr_entries = nr_entries; - INIT_HLIST_HEAD(&(e->modules)); - hlist_add_head(&e->hlist, head); - return e; -} + if (atomic_inc_not_zero(&key->enabled)) + return; -static int -build_jump_label_hashtable(struct jump_entry *start, struct jump_entry *stop) -{ - struct jump_entry *iter, *iter_begin; - struct jump_label_entry *entry; - int count; - - sort_jump_label_entries(start, stop); - iter = start; - while (iter < stop) { - entry = get_jump_label_entry(iter->key); - if (!entry) { - iter_begin = iter; - count = 0; - while ((iter < stop) && - (iter->key == iter_begin->key)) { - iter++; - count++; - } - entry = add_jump_label_entry(iter_begin->key, - count, iter_begin); - if (IS_ERR(entry)) - return PTR_ERR(entry); - } else { - WARN_ONCE(1, KERN_ERR "build_jump_hashtable: unexpected entry!\n"); - return -1; - } - } - return 0; + jump_label_lock(); + if (atomic_add_return(1, &key->enabled) == 1) + jump_label_update(key, JUMP_LABEL_ENABLE); + jump_label_unlock(); } -/*** - * jump_label_update - update jump label text - * @key - key value associated with a a jump label - * @type - enum set to JUMP_LABEL_ENABLE or JUMP_LABEL_DISABLE - * - * Will enable/disable the jump for jump label @key, depending on the - * value of @type. - * - */ - -void jump_label_update(unsigned long key, enum jump_label_type type) +void jump_label_dec(struct jump_label_key *key) { - struct jump_entry *iter; - struct jump_label_entry *entry; - struct hlist_node *module_node; - struct jump_label_module_entry *e_module; - int count; + if (!atomic_dec_and_mutex_lock(&key->enabled, &jump_label_mutex)) + return; - jump_label_lock(); - entry = get_jump_label_entry((jump_label_t)key); - if (entry) { - count = entry->nr_entries; - iter = entry->table; - while (count--) { - if (kernel_text_address(iter->code)) - arch_jump_label_transform(iter, type); - iter++; - } - /* eanble/disable jump labels in modules */ - hlist_for_each_entry(e_module, module_node, &(entry->modules), - hlist) { - count = e_module->nr_entries; - iter = e_module->table; - while (count--) { - if (iter->key && - kernel_text_address(iter->code)) - arch_jump_label_transform(iter, type); - iter++; - } - } - } + jump_label_update(key, JUMP_LABEL_DISABLE); jump_label_unlock(); } @@ -197,77 +89,33 @@ static int addr_conflict(struct jump_entry *entry, void *start, void *end) return 0; } -#ifdef CONFIG_MODULES - -static int module_conflict(void *start, void *end) +static int __jump_label_text_reserved(struct jump_entry *iter_start, + struct jump_entry *iter_stop, void *start, void *end) { - struct hlist_head *head; - struct hlist_node *node, *node_next, *module_node, *module_node_next; - struct jump_label_entry *e; - struct jump_label_module_entry *e_module; struct jump_entry *iter; - int i, count; - int conflict = 0; - - for (i = 0; i < JUMP_LABEL_TABLE_SIZE; i++) { - head = &jump_label_table[i]; - hlist_for_each_entry_safe(e, node, node_next, head, hlist) { - hlist_for_each_entry_safe(e_module, module_node, - module_node_next, - &(e->modules), hlist) { - count = e_module->nr_entries; - iter = e_module->table; - while (count--) { - if (addr_conflict(iter, start, end)) { - conflict = 1; - goto out; - } - iter++; - } - } - } - } -out: - return conflict; -} - -#endif - -/*** - * jump_label_text_reserved - check if addr range is reserved - * @start: start text addr - * @end: end text addr - * - * checks if the text addr located between @start and @end - * overlaps with any of the jump label patch addresses. Code - * that wants to modify kernel text should first verify that - * it does not overlap with any of the jump label addresses. - * Caller must hold jump_label_mutex. - * - * returns 1 if there is an overlap, 0 otherwise - */ -int jump_label_text_reserved(void *start, void *end) -{ - struct jump_entry *iter; - struct jump_entry *iter_start = __start___jump_table; - struct jump_entry *iter_stop = __start___jump_table; - int conflict = 0; iter = iter_start; while (iter < iter_stop) { - if (addr_conflict(iter, start, end)) { - conflict = 1; - goto out; - } + if (addr_conflict(iter, start, end)) + return 1; iter++; } - /* now check modules */ -#ifdef CONFIG_MODULES - conflict = module_conflict(start, end); -#endif -out: - return conflict; + return 0; +} + +static void __jump_label_update(struct jump_label_key *key, + struct jump_entry *entry, int enable) +{ + for (; entry->key == (jump_label_t)(unsigned long)key; entry++) { + /* + * entry->code set to 0 invalidates module init text sections + * kernel_text_address() verifies we are not in core kernel + * init code, see jump_label_invalidate_module_init(). + */ + if (entry->code && kernel_text_address(entry->code)) + arch_jump_label_transform(entry, enable); + } } /* @@ -277,142 +125,173 @@ void __weak arch_jump_label_text_poke_early(jump_label_t addr) { } -static __init int init_jump_label(void) +static __init int jump_label_init(void) { - int ret; struct jump_entry *iter_start = __start___jump_table; struct jump_entry *iter_stop = __stop___jump_table; + struct jump_label_key *key = NULL; struct jump_entry *iter; jump_label_lock(); - ret = build_jump_label_hashtable(__start___jump_table, - __stop___jump_table); - iter = iter_start; - while (iter < iter_stop) { + jump_label_sort_entries(iter_start, iter_stop); + + for (iter = iter_start; iter < iter_stop; iter++) { arch_jump_label_text_poke_early(iter->code); - iter++; + if (iter->key == (jump_label_t)(unsigned long)key) + continue; + + key = (struct jump_label_key *)(unsigned long)iter->key; + atomic_set(&key->enabled, 0); + key->entries = iter; +#ifdef CONFIG_MODULES + key->next = NULL; +#endif } jump_label_unlock(); - return ret; + + return 0; } -early_initcall(init_jump_label); +early_initcall(jump_label_init); #ifdef CONFIG_MODULES -static struct jump_label_module_entry * -add_jump_label_module_entry(struct jump_label_entry *entry, - struct jump_entry *iter_begin, - int count, struct module *mod) +struct jump_label_mod { + struct jump_label_mod *next; + struct jump_entry *entries; + struct module *mod; +}; + +static int __jump_label_mod_text_reserved(void *start, void *end) +{ + struct module *mod; + + mod = __module_text_address((unsigned long)start); + if (!mod) + return 0; + + WARN_ON_ONCE(__module_text_address((unsigned long)end) != mod); + + return __jump_label_text_reserved(mod->jump_entries, + mod->jump_entries + mod->num_jump_entries, + start, end); +} + +static void __jump_label_mod_update(struct jump_label_key *key, int enable) +{ + struct jump_label_mod *mod = key->next; + + while (mod) { + __jump_label_update(key, mod->entries, enable); + mod = mod->next; + } +} + +/*** + * apply_jump_label_nops - patch module jump labels with arch_get_jump_label_nop() + * @mod: module to patch + * + * Allow for run-time selection of the optimal nops. Before the module + * loads patch these with arch_get_jump_label_nop(), which is specified by + * the arch specific jump label code. + */ +void jump_label_apply_nops(struct module *mod) { - struct jump_label_module_entry *e; - - e = kmalloc(sizeof(struct jump_label_module_entry), GFP_KERNEL); - if (!e) - return ERR_PTR(-ENOMEM); - e->mod = mod; - e->nr_entries = count; - e->table = iter_begin; - hlist_add_head(&e->hlist, &entry->modules); - return e; + struct jump_entry *iter_start = mod->jump_entries; + struct jump_entry *iter_stop = iter_start + mod->num_jump_entries; + struct jump_entry *iter; + + /* if the module doesn't have jump label entries, just return */ + if (iter_start == iter_stop) + return; + + for (iter = iter_start; iter < iter_stop; iter++) + arch_jump_label_text_poke_early(iter->code); } -static int add_jump_label_module(struct module *mod) +static int jump_label_add_module(struct module *mod) { - struct jump_entry *iter, *iter_begin; - struct jump_label_entry *entry; - struct jump_label_module_entry *module_entry; - int count; + struct jump_entry *iter_start = mod->jump_entries; + struct jump_entry *iter_stop = iter_start + mod->num_jump_entries; + struct jump_entry *iter; + struct jump_label_key *key = NULL; + struct jump_label_mod *jlm; /* if the module doesn't have jump label entries, just return */ - if (!mod->num_jump_entries) + if (iter_start == iter_stop) return 0; - sort_jump_label_entries(mod->jump_entries, - mod->jump_entries + mod->num_jump_entries); - iter = mod->jump_entries; - while (iter < mod->jump_entries + mod->num_jump_entries) { - entry = get_jump_label_entry(iter->key); - iter_begin = iter; - count = 0; - while ((iter < mod->jump_entries + mod->num_jump_entries) && - (iter->key == iter_begin->key)) { - iter++; - count++; - } - if (!entry) { - entry = add_jump_label_entry(iter_begin->key, 0, NULL); - if (IS_ERR(entry)) - return PTR_ERR(entry); + jump_label_sort_entries(iter_start, iter_stop); + + for (iter = iter_start; iter < iter_stop; iter++) { + if (iter->key == (jump_label_t)(unsigned long)key) + continue; + + key = (struct jump_label_key *)(unsigned long)iter->key; + + if (__module_address(iter->key) == mod) { + atomic_set(&key->enabled, 0); + key->entries = iter; + key->next = NULL; + continue; } - module_entry = add_jump_label_module_entry(entry, iter_begin, - count, mod); - if (IS_ERR(module_entry)) - return PTR_ERR(module_entry); + + jlm = kzalloc(sizeof(struct jump_label_mod), GFP_KERNEL); + if (!jlm) + return -ENOMEM; + + jlm->mod = mod; + jlm->entries = iter; + jlm->next = key->next; + key->next = jlm; + + if (jump_label_enabled(key)) + __jump_label_update(key, iter, JUMP_LABEL_ENABLE); } + return 0; } -static void remove_jump_label_module(struct module *mod) +static void jump_label_del_module(struct module *mod) { - struct hlist_head *head; - struct hlist_node *node, *node_next, *module_node, *module_node_next; - struct jump_label_entry *e; - struct jump_label_module_entry *e_module; - int i; + struct jump_entry *iter_start = mod->jump_entries; + struct jump_entry *iter_stop = iter_start + mod->num_jump_entries; + struct jump_entry *iter; + struct jump_label_key *key = NULL; + struct jump_label_mod *jlm, **prev; - /* if the module doesn't have jump label entries, just return */ - if (!mod->num_jump_entries) - return; + for (iter = iter_start; iter < iter_stop; iter++) { + if (iter->key == (jump_label_t)(unsigned long)key) + continue; + + key = (struct jump_label_key *)(unsigned long)iter->key; + + if (__module_address(iter->key) == mod) + continue; + + prev = &key->next; + jlm = key->next; - for (i = 0; i < JUMP_LABEL_TABLE_SIZE; i++) { - head = &jump_label_table[i]; - hlist_for_each_entry_safe(e, node, node_next, head, hlist) { - hlist_for_each_entry_safe(e_module, module_node, - module_node_next, - &(e->modules), hlist) { - if (e_module->mod == mod) { - hlist_del(&e_module->hlist); - kfree(e_module); - } - } - if (hlist_empty(&e->modules) && (e->nr_entries == 0)) { - hlist_del(&e->hlist); - kfree(e); - } + while (jlm && jlm->mod != mod) { + prev = &jlm->next; + jlm = jlm->next; + } + + if (jlm) { + *prev = jlm->next; + kfree(jlm); } } } -static void remove_jump_label_module_init(struct module *mod) +static void jump_label_invalidate_module_init(struct module *mod) { - struct hlist_head *head; - struct hlist_node *node, *node_next, *module_node, *module_node_next; - struct jump_label_entry *e; - struct jump_label_module_entry *e_module; + struct jump_entry *iter_start = mod->jump_entries; + struct jump_entry *iter_stop = iter_start + mod->num_jump_entries; struct jump_entry *iter; - int i, count; - - /* if the module doesn't have jump label entries, just return */ - if (!mod->num_jump_entries) - return; - for (i = 0; i < JUMP_LABEL_TABLE_SIZE; i++) { - head = &jump_label_table[i]; - hlist_for_each_entry_safe(e, node, node_next, head, hlist) { - hlist_for_each_entry_safe(e_module, module_node, - module_node_next, - &(e->modules), hlist) { - if (e_module->mod != mod) - continue; - count = e_module->nr_entries; - iter = e_module->table; - while (count--) { - if (within_module_init(iter->code, mod)) - iter->key = 0; - iter++; - } - } - } + for (iter = iter_start; iter < iter_stop; iter++) { + if (within_module_init(iter->code, mod)) + iter->code = 0; } } @@ -426,59 +305,77 @@ jump_label_module_notify(struct notifier_block *self, unsigned long val, switch (val) { case MODULE_STATE_COMING: jump_label_lock(); - ret = add_jump_label_module(mod); + ret = jump_label_add_module(mod); if (ret) - remove_jump_label_module(mod); + jump_label_del_module(mod); jump_label_unlock(); break; case MODULE_STATE_GOING: jump_label_lock(); - remove_jump_label_module(mod); + jump_label_del_module(mod); jump_label_unlock(); break; case MODULE_STATE_LIVE: jump_label_lock(); - remove_jump_label_module_init(mod); + jump_label_invalidate_module_init(mod); jump_label_unlock(); break; } - return ret; -} -/*** - * apply_jump_label_nops - patch module jump labels with arch_get_jump_label_nop() - * @mod: module to patch - * - * Allow for run-time selection of the optimal nops. Before the module - * loads patch these with arch_get_jump_label_nop(), which is specified by - * the arch specific jump label code. - */ -void jump_label_apply_nops(struct module *mod) -{ - struct jump_entry *iter; - - /* if the module doesn't have jump label entries, just return */ - if (!mod->num_jump_entries) - return; - - iter = mod->jump_entries; - while (iter < mod->jump_entries + mod->num_jump_entries) { - arch_jump_label_text_poke_early(iter->code); - iter++; - } + return notifier_from_errno(ret); } struct notifier_block jump_label_module_nb = { .notifier_call = jump_label_module_notify, - .priority = 0, + .priority = 1, /* higher than tracepoints */ }; -static __init int init_jump_label_module(void) +static __init int jump_label_init_module(void) { return register_module_notifier(&jump_label_module_nb); } -early_initcall(init_jump_label_module); +early_initcall(jump_label_init_module); #endif /* CONFIG_MODULES */ +/*** + * jump_label_text_reserved - check if addr range is reserved + * @start: start text addr + * @end: end text addr + * + * checks if the text addr located between @start and @end + * overlaps with any of the jump label patch addresses. Code + * that wants to modify kernel text should first verify that + * it does not overlap with any of the jump label addresses. + * Caller must hold jump_label_mutex. + * + * returns 1 if there is an overlap, 0 otherwise + */ +int jump_label_text_reserved(void *start, void *end) +{ + int ret = __jump_label_text_reserved(__start___jump_table, + __stop___jump_table, start, end); + + if (ret) + return ret; + +#ifdef CONFIG_MODULES + ret = __jump_label_mod_text_reserved(start, end); +#endif + return ret; +} + +static void jump_label_update(struct jump_label_key *key, int enable) +{ + struct jump_entry *entry = key->entries; + + /* if there are no users, entry can be NULL */ + if (entry) + __jump_label_update(key, entry, enable); + +#ifdef CONFIG_MODULES + __jump_label_mod_update(key, enable); +#endif +} + #endif diff --git a/kernel/perf_event.c b/kernel/perf_event.c index c75925c4d1e2..d665e92fbd44 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c @@ -125,7 +125,7 @@ enum event_type_t { * perf_sched_events : >0 events exist * perf_cgroup_events: >0 per-cpu cgroup events exist on this cpu */ -atomic_t perf_sched_events __read_mostly; +struct jump_label_key perf_sched_events __read_mostly; static DEFINE_PER_CPU(atomic_t, perf_cgroup_events); static atomic_t nr_mmap_events __read_mostly; @@ -5417,7 +5417,7 @@ fail: return err; } -atomic_t perf_swevent_enabled[PERF_COUNT_SW_MAX]; +struct jump_label_key perf_swevent_enabled[PERF_COUNT_SW_MAX]; static void sw_perf_event_destroy(struct perf_event *event) { diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c index 68187af4889e..b219f1449c54 100644 --- a/kernel/tracepoint.c +++ b/kernel/tracepoint.c @@ -251,9 +251,9 @@ static void set_tracepoint(struct tracepoint_entry **entry, { WARN_ON(strcmp((*entry)->name, elem->name) != 0); - if (elem->regfunc && !elem->state && active) + if (elem->regfunc && !jump_label_enabled(&elem->key) && active) elem->regfunc(); - else if (elem->unregfunc && elem->state && !active) + else if (elem->unregfunc && jump_label_enabled(&elem->key) && !active) elem->unregfunc(); /* @@ -264,13 +264,10 @@ static void set_tracepoint(struct tracepoint_entry **entry, * is used. */ rcu_assign_pointer(elem->funcs, (*entry)->funcs); - if (!elem->state && active) { - jump_label_enable(&elem->state); - elem->state = active; - } else if (elem->state && !active) { - jump_label_disable(&elem->state); - elem->state = active; - } + if (active && !jump_label_enabled(&elem->key)) + jump_label_inc(&elem->key); + else if (!active && jump_label_enabled(&elem->key)) + jump_label_dec(&elem->key); } /* @@ -281,13 +278,11 @@ static void set_tracepoint(struct tracepoint_entry **entry, */ static void disable_tracepoint(struct tracepoint *elem) { - if (elem->unregfunc && elem->state) + if (elem->unregfunc && jump_label_enabled(&elem->key)) elem->unregfunc(); - if (elem->state) { - jump_label_disable(&elem->state); - elem->state = 0; - } + if (jump_label_enabled(&elem->key)) + jump_label_dec(&elem->key); rcu_assign_pointer(elem->funcs, NULL); } -- cgit From 0545a3037773512d3448557ba048cebb73b3e4af Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 4 Apr 2011 05:30:58 +0000 Subject: pkt_sched: QFQ - quick fair queue scheduler This is an implementation of the Quick Fair Queue scheduler developed by Fabio Checconi. The same algorithm is already implemented in ipfw in FreeBSD. Fabio had an earlier version developed on Linux, I just cleaned it up. Thanks to Eric Dumazet for testing this under load. Signed-off-by: Stephen Hemminger Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/pkt_sched.h | 15 + net/sched/Kconfig | 11 + net/sched/Makefile | 1 + net/sched/sch_qfq.c | 1137 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 1164 insertions(+) create mode 100644 net/sched/sch_qfq.c (limited to 'include/linux') diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h index b1032a3fafdc..8062e0a68dda 100644 --- a/include/linux/pkt_sched.h +++ b/include/linux/pkt_sched.h @@ -588,4 +588,19 @@ struct tc_sfb_xstats { #define SFB_MAX_PROB 0xFFFF +/* QFQ */ +enum { + TCA_QFQ_UNSPEC, + TCA_QFQ_WEIGHT, + TCA_QFQ_LMAX, + __TCA_QFQ_MAX +}; + +#define TCA_QFQ_MAX (__TCA_QFQ_MAX - 1) + +struct tc_qfq_stats { + __u32 weight; + __u32 lmax; +}; + #endif diff --git a/net/sched/Kconfig b/net/sched/Kconfig index a7a5583d4f68..aeaa2110b699 100644 --- a/net/sched/Kconfig +++ b/net/sched/Kconfig @@ -239,6 +239,17 @@ config NET_SCH_CHOKE To compile this code as a module, choose M here: the module will be called sch_choke. +config NET_SCH_QFQ + tristate "Quick Fair Queueing scheduler (QFQ)" + help + Say Y here if you want to use the Quick Fair Queueing Scheduler (QFQ) + packet scheduling algorithm. + + To compile this driver as a module, choose M here: the module + will be called sch_qfq. + + If unsure, say N. + config NET_SCH_INGRESS tristate "Ingress Qdisc" depends on NET_CLS_ACT diff --git a/net/sched/Makefile b/net/sched/Makefile index 2e77b8dba22e..dc5889c0a15a 100644 --- a/net/sched/Makefile +++ b/net/sched/Makefile @@ -35,6 +35,7 @@ obj-$(CONFIG_NET_SCH_NETEM) += sch_netem.o obj-$(CONFIG_NET_SCH_DRR) += sch_drr.o obj-$(CONFIG_NET_SCH_MQPRIO) += sch_mqprio.o obj-$(CONFIG_NET_SCH_CHOKE) += sch_choke.o +obj-$(CONFIG_NET_SCH_QFQ) += sch_qfq.o obj-$(CONFIG_NET_CLS_U32) += cls_u32.o obj-$(CONFIG_NET_CLS_ROUTE4) += cls_route.o diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c new file mode 100644 index 000000000000..103343408593 --- /dev/null +++ b/net/sched/sch_qfq.c @@ -0,0 +1,1137 @@ +/* + * net/sched/sch_qfq.c Quick Fair Queueing Scheduler. + * + * Copyright (c) 2009 Fabio Checconi, Luigi Rizzo, and Paolo Valente. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* Quick Fair Queueing + =================== + + Sources: + + Fabio Checconi, Luigi Rizzo, and Paolo Valente: "QFQ: Efficient + Packet Scheduling with Tight Bandwidth Distribution Guarantees." + + See also: + http://retis.sssup.it/~fabio/linux/qfq/ + */ + +/* + + Virtual time computations. + + S, F and V are all computed in fixed point arithmetic with + FRAC_BITS decimal bits. + + QFQ_MAX_INDEX is the maximum index allowed for a group. We need + one bit per index. + QFQ_MAX_WSHIFT is the maximum power of two supported as a weight. + + The layout of the bits is as below: + + [ MTU_SHIFT ][ FRAC_BITS ] + [ MAX_INDEX ][ MIN_SLOT_SHIFT ] + ^.__grp->index = 0 + *.__grp->slot_shift + + where MIN_SLOT_SHIFT is derived by difference from the others. + + The max group index corresponds to Lmax/w_min, where + Lmax=1<group mapping. We allow class weights that are + * in the range [1, 2^MAX_WSHIFT], and we try to map each class i to the + * group with the smallest index that can support the L_i / r_i configured + * for the class. + * + * grp->index is the index of the group; and grp->slot_shift + * is the shift for the corresponding (scaled) sigma_i. + */ +#define QFQ_MAX_INDEX 19 +#define QFQ_MAX_WSHIFT 16 + +#define QFQ_MAX_WEIGHT (1<clhash, classid); + if (clc == NULL) + return NULL; + return container_of(clc, struct qfq_class, common); +} + +static void qfq_purge_queue(struct qfq_class *cl) +{ + unsigned int len = cl->qdisc->q.qlen; + + qdisc_reset(cl->qdisc); + qdisc_tree_decrease_qlen(cl->qdisc, len); +} + +static const struct nla_policy qfq_policy[TCA_QFQ_MAX + 1] = { + [TCA_QFQ_WEIGHT] = { .type = NLA_U32 }, + [TCA_QFQ_LMAX] = { .type = NLA_U32 }, +}; + +/* + * Calculate a flow index, given its weight and maximum packet length. + * index = log_2(maxlen/weight) but we need to apply the scaling. + * This is used only once at flow creation. + */ +static int qfq_calc_index(u32 inv_w, unsigned int maxlen) +{ + u64 slot_size = (u64)maxlen * inv_w; + unsigned long size_map; + int index = 0; + + size_map = slot_size >> QFQ_MIN_SLOT_SHIFT; + if (!size_map) + goto out; + + index = __fls(size_map) + 1; /* basically a log_2 */ + index -= !(slot_size - (1ULL << (index + QFQ_MIN_SLOT_SHIFT - 1))); + + if (index < 0) + index = 0; +out: + pr_debug("qfq calc_index: W = %lu, L = %u, I = %d\n", + (unsigned long) ONE_FP/inv_w, maxlen, index); + + return index; +} + +static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, + struct nlattr **tca, unsigned long *arg) +{ + struct qfq_sched *q = qdisc_priv(sch); + struct qfq_class *cl = (struct qfq_class *)*arg; + struct nlattr *tb[TCA_QFQ_MAX + 1]; + u32 weight, lmax, inv_w; + int i, err; + + if (tca[TCA_OPTIONS] == NULL) { + pr_notice("qfq: no options\n"); + return -EINVAL; + } + + err = nla_parse_nested(tb, TCA_QFQ_MAX, tca[TCA_OPTIONS], qfq_policy); + if (err < 0) + return err; + + if (tb[TCA_QFQ_WEIGHT]) { + weight = nla_get_u32(tb[TCA_QFQ_WEIGHT]); + if (!weight || weight > (1UL << QFQ_MAX_WSHIFT)) { + pr_notice("qfq: invalid weight %u\n", weight); + return -EINVAL; + } + } else + weight = 1; + + inv_w = ONE_FP / weight; + weight = ONE_FP / inv_w; + if (q->wsum + weight > QFQ_MAX_WSUM) { + pr_notice("qfq: total weight out of range (%u + %u)\n", + weight, q->wsum); + return -EINVAL; + } + + if (tb[TCA_QFQ_LMAX]) { + lmax = nla_get_u32(tb[TCA_QFQ_LMAX]); + if (!lmax || lmax > (1UL << QFQ_MTU_SHIFT)) { + pr_notice("qfq: invalid max length %u\n", lmax); + return -EINVAL; + } + } else + lmax = 1UL << QFQ_MTU_SHIFT; + + if (cl != NULL) { + if (tca[TCA_RATE]) { + err = gen_replace_estimator(&cl->bstats, &cl->rate_est, + qdisc_root_sleeping_lock(sch), + tca[TCA_RATE]); + if (err) + return err; + } + + sch_tree_lock(sch); + if (tb[TCA_QFQ_WEIGHT]) { + q->wsum = weight - ONE_FP / cl->inv_w; + cl->inv_w = inv_w; + } + sch_tree_unlock(sch); + + return 0; + } + + cl = kzalloc(sizeof(struct qfq_class), GFP_KERNEL); + if (cl == NULL) + return -ENOBUFS; + + cl->refcnt = 1; + cl->common.classid = classid; + cl->lmax = lmax; + cl->inv_w = inv_w; + i = qfq_calc_index(cl->inv_w, cl->lmax); + + cl->grp = &q->groups[i]; + q->wsum += weight; + + cl->qdisc = qdisc_create_dflt(sch->dev_queue, + &pfifo_qdisc_ops, classid); + if (cl->qdisc == NULL) + cl->qdisc = &noop_qdisc; + + if (tca[TCA_RATE]) { + err = gen_new_estimator(&cl->bstats, &cl->rate_est, + qdisc_root_sleeping_lock(sch), + tca[TCA_RATE]); + if (err) { + qdisc_destroy(cl->qdisc); + kfree(cl); + return err; + } + } + + sch_tree_lock(sch); + qdisc_class_hash_insert(&q->clhash, &cl->common); + sch_tree_unlock(sch); + + qdisc_class_hash_grow(sch, &q->clhash); + + *arg = (unsigned long)cl; + return 0; +} + +static void qfq_destroy_class(struct Qdisc *sch, struct qfq_class *cl) +{ + struct qfq_sched *q = qdisc_priv(sch); + + if (cl->inv_w) { + q->wsum -= ONE_FP / cl->inv_w; + cl->inv_w = 0; + } + + gen_kill_estimator(&cl->bstats, &cl->rate_est); + qdisc_destroy(cl->qdisc); + kfree(cl); +} + +static int qfq_delete_class(struct Qdisc *sch, unsigned long arg) +{ + struct qfq_sched *q = qdisc_priv(sch); + struct qfq_class *cl = (struct qfq_class *)arg; + + if (cl->filter_cnt > 0) + return -EBUSY; + + sch_tree_lock(sch); + + qfq_purge_queue(cl); + qdisc_class_hash_remove(&q->clhash, &cl->common); + + BUG_ON(--cl->refcnt == 0); + /* + * This shouldn't happen: we "hold" one cops->get() when called + * from tc_ctl_tclass; the destroy method is done from cops->put(). + */ + + sch_tree_unlock(sch); + return 0; +} + +static unsigned long qfq_get_class(struct Qdisc *sch, u32 classid) +{ + struct qfq_class *cl = qfq_find_class(sch, classid); + + if (cl != NULL) + cl->refcnt++; + + return (unsigned long)cl; +} + +static void qfq_put_class(struct Qdisc *sch, unsigned long arg) +{ + struct qfq_class *cl = (struct qfq_class *)arg; + + if (--cl->refcnt == 0) + qfq_destroy_class(sch, cl); +} + +static struct tcf_proto **qfq_tcf_chain(struct Qdisc *sch, unsigned long cl) +{ + struct qfq_sched *q = qdisc_priv(sch); + + if (cl) + return NULL; + + return &q->filter_list; +} + +static unsigned long qfq_bind_tcf(struct Qdisc *sch, unsigned long parent, + u32 classid) +{ + struct qfq_class *cl = qfq_find_class(sch, classid); + + if (cl != NULL) + cl->filter_cnt++; + + return (unsigned long)cl; +} + +static void qfq_unbind_tcf(struct Qdisc *sch, unsigned long arg) +{ + struct qfq_class *cl = (struct qfq_class *)arg; + + cl->filter_cnt--; +} + +static int qfq_graft_class(struct Qdisc *sch, unsigned long arg, + struct Qdisc *new, struct Qdisc **old) +{ + struct qfq_class *cl = (struct qfq_class *)arg; + + if (new == NULL) { + new = qdisc_create_dflt(sch->dev_queue, + &pfifo_qdisc_ops, cl->common.classid); + if (new == NULL) + new = &noop_qdisc; + } + + sch_tree_lock(sch); + qfq_purge_queue(cl); + *old = cl->qdisc; + cl->qdisc = new; + sch_tree_unlock(sch); + return 0; +} + +static struct Qdisc *qfq_class_leaf(struct Qdisc *sch, unsigned long arg) +{ + struct qfq_class *cl = (struct qfq_class *)arg; + + return cl->qdisc; +} + +static int qfq_dump_class(struct Qdisc *sch, unsigned long arg, + struct sk_buff *skb, struct tcmsg *tcm) +{ + struct qfq_class *cl = (struct qfq_class *)arg; + struct nlattr *nest; + + tcm->tcm_parent = TC_H_ROOT; + tcm->tcm_handle = cl->common.classid; + tcm->tcm_info = cl->qdisc->handle; + + nest = nla_nest_start(skb, TCA_OPTIONS); + if (nest == NULL) + goto nla_put_failure; + NLA_PUT_U32(skb, TCA_QFQ_WEIGHT, ONE_FP/cl->inv_w); + NLA_PUT_U32(skb, TCA_QFQ_LMAX, cl->lmax); + return nla_nest_end(skb, nest); + +nla_put_failure: + nla_nest_cancel(skb, nest); + return -EMSGSIZE; +} + +static int qfq_dump_class_stats(struct Qdisc *sch, unsigned long arg, + struct gnet_dump *d) +{ + struct qfq_class *cl = (struct qfq_class *)arg; + struct tc_qfq_stats xstats; + + memset(&xstats, 0, sizeof(xstats)); + cl->qdisc->qstats.qlen = cl->qdisc->q.qlen; + + xstats.weight = ONE_FP/cl->inv_w; + xstats.lmax = cl->lmax; + + if (gnet_stats_copy_basic(d, &cl->bstats) < 0 || + gnet_stats_copy_rate_est(d, &cl->bstats, &cl->rate_est) < 0 || + gnet_stats_copy_queue(d, &cl->qdisc->qstats) < 0) + return -1; + + return gnet_stats_copy_app(d, &xstats, sizeof(xstats)); +} + +static void qfq_walk(struct Qdisc *sch, struct qdisc_walker *arg) +{ + struct qfq_sched *q = qdisc_priv(sch); + struct qfq_class *cl; + struct hlist_node *n; + unsigned int i; + + if (arg->stop) + return; + + for (i = 0; i < q->clhash.hashsize; i++) { + hlist_for_each_entry(cl, n, &q->clhash.hash[i], common.hnode) { + if (arg->count < arg->skip) { + arg->count++; + continue; + } + if (arg->fn(sch, (unsigned long)cl, arg) < 0) { + arg->stop = 1; + return; + } + arg->count++; + } + } +} + +static struct qfq_class *qfq_classify(struct sk_buff *skb, struct Qdisc *sch, + int *qerr) +{ + struct qfq_sched *q = qdisc_priv(sch); + struct qfq_class *cl; + struct tcf_result res; + int result; + + if (TC_H_MAJ(skb->priority ^ sch->handle) == 0) { + pr_debug("qfq_classify: found %d\n", skb->priority); + cl = qfq_find_class(sch, skb->priority); + if (cl != NULL) + return cl; + } + + *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; + result = tc_classify(skb, q->filter_list, &res); + if (result >= 0) { +#ifdef CONFIG_NET_CLS_ACT + switch (result) { + case TC_ACT_QUEUED: + case TC_ACT_STOLEN: + *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN; + case TC_ACT_SHOT: + return NULL; + } +#endif + cl = (struct qfq_class *)res.class; + if (cl == NULL) + cl = qfq_find_class(sch, res.classid); + return cl; + } + + return NULL; +} + +/* Generic comparison function, handling wraparound. */ +static inline int qfq_gt(u64 a, u64 b) +{ + return (s64)(a - b) > 0; +} + +/* Round a precise timestamp to its slotted value. */ +static inline u64 qfq_round_down(u64 ts, unsigned int shift) +{ + return ts & ~((1ULL << shift) - 1); +} + +/* return the pointer to the group with lowest index in the bitmap */ +static inline struct qfq_group *qfq_ffs(struct qfq_sched *q, + unsigned long bitmap) +{ + int index = __ffs(bitmap); + return &q->groups[index]; +} +/* Calculate a mask to mimic what would be ffs_from(). */ +static inline unsigned long mask_from(unsigned long bitmap, int from) +{ + return bitmap & ~((1UL << from) - 1); +} + +/* + * The state computation relies on ER=0, IR=1, EB=2, IB=3 + * First compute eligibility comparing grp->S, q->V, + * then check if someone is blocking us and possibly add EB + */ +static int qfq_calc_state(struct qfq_sched *q, const struct qfq_group *grp) +{ + /* if S > V we are not eligible */ + unsigned int state = qfq_gt(grp->S, q->V); + unsigned long mask = mask_from(q->bitmaps[ER], grp->index); + struct qfq_group *next; + + if (mask) { + next = qfq_ffs(q, mask); + if (qfq_gt(grp->F, next->F)) + state |= EB; + } + + return state; +} + + +/* + * In principle + * q->bitmaps[dst] |= q->bitmaps[src] & mask; + * q->bitmaps[src] &= ~mask; + * but we should make sure that src != dst + */ +static inline void qfq_move_groups(struct qfq_sched *q, unsigned long mask, + int src, int dst) +{ + q->bitmaps[dst] |= q->bitmaps[src] & mask; + q->bitmaps[src] &= ~mask; +} + +static void qfq_unblock_groups(struct qfq_sched *q, int index, u64 old_F) +{ + unsigned long mask = mask_from(q->bitmaps[ER], index + 1); + struct qfq_group *next; + + if (mask) { + next = qfq_ffs(q, mask); + if (!qfq_gt(next->F, old_F)) + return; + } + + mask = (1UL << index) - 1; + qfq_move_groups(q, mask, EB, ER); + qfq_move_groups(q, mask, IB, IR); +} + +/* + * perhaps + * + old_V ^= q->V; + old_V >>= QFQ_MIN_SLOT_SHIFT; + if (old_V) { + ... + } + * + */ +static void qfq_make_eligible(struct qfq_sched *q, u64 old_V) +{ + unsigned long vslot = q->V >> QFQ_MIN_SLOT_SHIFT; + unsigned long old_vslot = old_V >> QFQ_MIN_SLOT_SHIFT; + + if (vslot != old_vslot) { + unsigned long mask = (1UL << fls(vslot ^ old_vslot)) - 1; + qfq_move_groups(q, mask, IR, ER); + qfq_move_groups(q, mask, IB, EB); + } +} + + +/* + * XXX we should make sure that slot becomes less than 32. + * This is guaranteed by the input values. + * roundedS is always cl->S rounded on grp->slot_shift bits. + */ +static void qfq_slot_insert(struct qfq_group *grp, struct qfq_class *cl, + u64 roundedS) +{ + u64 slot = (roundedS - grp->S) >> grp->slot_shift; + unsigned int i = (grp->front + slot) % QFQ_MAX_SLOTS; + + hlist_add_head(&cl->next, &grp->slots[i]); + __set_bit(slot, &grp->full_slots); +} + +/* Maybe introduce hlist_first_entry?? */ +static struct qfq_class *qfq_slot_head(struct qfq_group *grp) +{ + return hlist_entry(grp->slots[grp->front].first, + struct qfq_class, next); +} + +/* + * remove the entry from the slot + */ +static void qfq_front_slot_remove(struct qfq_group *grp) +{ + struct qfq_class *cl = qfq_slot_head(grp); + + BUG_ON(!cl); + hlist_del(&cl->next); + if (hlist_empty(&grp->slots[grp->front])) + __clear_bit(0, &grp->full_slots); +} + +/* + * Returns the first full queue in a group. As a side effect, + * adjust the bucket list so the first non-empty bucket is at + * position 0 in full_slots. + */ +static struct qfq_class *qfq_slot_scan(struct qfq_group *grp) +{ + unsigned int i; + + pr_debug("qfq slot_scan: grp %u full %#lx\n", + grp->index, grp->full_slots); + + if (grp->full_slots == 0) + return NULL; + + i = __ffs(grp->full_slots); /* zero based */ + if (i > 0) { + grp->front = (grp->front + i) % QFQ_MAX_SLOTS; + grp->full_slots >>= i; + } + + return qfq_slot_head(grp); +} + +/* + * adjust the bucket list. When the start time of a group decreases, + * we move the index down (modulo QFQ_MAX_SLOTS) so we don't need to + * move the objects. The mask of occupied slots must be shifted + * because we use ffs() to find the first non-empty slot. + * This covers decreases in the group's start time, but what about + * increases of the start time ? + * Here too we should make sure that i is less than 32 + */ +static void qfq_slot_rotate(struct qfq_group *grp, u64 roundedS) +{ + unsigned int i = (grp->S - roundedS) >> grp->slot_shift; + + grp->full_slots <<= i; + grp->front = (grp->front - i) % QFQ_MAX_SLOTS; +} + +static void qfq_update_eligible(struct qfq_sched *q, u64 old_V) +{ + struct qfq_group *grp; + unsigned long ineligible; + + ineligible = q->bitmaps[IR] | q->bitmaps[IB]; + if (ineligible) { + if (!q->bitmaps[ER]) { + grp = qfq_ffs(q, ineligible); + if (qfq_gt(grp->S, q->V)) + q->V = grp->S; + } + qfq_make_eligible(q, old_V); + } +} + +/* What is length of next packet in queue (0 if queue is empty) */ +static unsigned int qdisc_peek_len(struct Qdisc *sch) +{ + struct sk_buff *skb; + + skb = sch->ops->peek(sch); + return skb ? qdisc_pkt_len(skb) : 0; +} + +/* + * Updates the class, returns true if also the group needs to be updated. + */ +static bool qfq_update_class(struct qfq_group *grp, struct qfq_class *cl) +{ + unsigned int len = qdisc_peek_len(cl->qdisc); + + cl->S = cl->F; + if (!len) + qfq_front_slot_remove(grp); /* queue is empty */ + else { + u64 roundedS; + + cl->F = cl->S + (u64)len * cl->inv_w; + roundedS = qfq_round_down(cl->S, grp->slot_shift); + if (roundedS == grp->S) + return false; + + qfq_front_slot_remove(grp); + qfq_slot_insert(grp, cl, roundedS); + } + + return true; +} + +static struct sk_buff *qfq_dequeue(struct Qdisc *sch) +{ + struct qfq_sched *q = qdisc_priv(sch); + struct qfq_group *grp; + struct qfq_class *cl; + struct sk_buff *skb; + unsigned int len; + u64 old_V; + + if (!q->bitmaps[ER]) + return NULL; + + grp = qfq_ffs(q, q->bitmaps[ER]); + + cl = qfq_slot_head(grp); + skb = qdisc_dequeue_peeked(cl->qdisc); + if (!skb) { + WARN_ONCE(1, "qfq_dequeue: non-workconserving leaf\n"); + return NULL; + } + + sch->q.qlen--; + qdisc_bstats_update(sch, skb); + + old_V = q->V; + len = qdisc_pkt_len(skb); + q->V += (u64)len * IWSUM; + pr_debug("qfq dequeue: len %u F %lld now %lld\n", + len, (unsigned long long) cl->F, (unsigned long long) q->V); + + if (qfq_update_class(grp, cl)) { + u64 old_F = grp->F; + + cl = qfq_slot_scan(grp); + if (!cl) + __clear_bit(grp->index, &q->bitmaps[ER]); + else { + u64 roundedS = qfq_round_down(cl->S, grp->slot_shift); + unsigned int s; + + if (grp->S == roundedS) + goto skip_unblock; + grp->S = roundedS; + grp->F = roundedS + (2ULL << grp->slot_shift); + __clear_bit(grp->index, &q->bitmaps[ER]); + s = qfq_calc_state(q, grp); + __set_bit(grp->index, &q->bitmaps[s]); + } + + qfq_unblock_groups(q, grp->index, old_F); + } + +skip_unblock: + qfq_update_eligible(q, old_V); + + return skb; +} + +/* + * Assign a reasonable start time for a new flow k in group i. + * Admissible values for \hat(F) are multiples of \sigma_i + * no greater than V+\sigma_i . Larger values mean that + * we had a wraparound so we consider the timestamp to be stale. + * + * If F is not stale and F >= V then we set S = F. + * Otherwise we should assign S = V, but this may violate + * the ordering in ER. So, if we have groups in ER, set S to + * the F_j of the first group j which would be blocking us. + * We are guaranteed not to move S backward because + * otherwise our group i would still be blocked. + */ +static void qfq_update_start(struct qfq_sched *q, struct qfq_class *cl) +{ + unsigned long mask; + uint32_t limit, roundedF; + int slot_shift = cl->grp->slot_shift; + + roundedF = qfq_round_down(cl->F, slot_shift); + limit = qfq_round_down(q->V, slot_shift) + (1UL << slot_shift); + + if (!qfq_gt(cl->F, q->V) || qfq_gt(roundedF, limit)) { + /* timestamp was stale */ + mask = mask_from(q->bitmaps[ER], cl->grp->index); + if (mask) { + struct qfq_group *next = qfq_ffs(q, mask); + if (qfq_gt(roundedF, next->F)) { + cl->S = next->F; + return; + } + } + cl->S = q->V; + } else /* timestamp is not stale */ + cl->S = cl->F; +} + +static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch) +{ + struct qfq_sched *q = qdisc_priv(sch); + struct qfq_group *grp; + struct qfq_class *cl; + int err; + u64 roundedS; + int s; + + cl = qfq_classify(skb, sch, &err); + if (cl == NULL) { + if (err & __NET_XMIT_BYPASS) + sch->qstats.drops++; + kfree_skb(skb); + return err; + } + pr_debug("qfq_enqueue: cl = %x\n", cl->common.classid); + + err = qdisc_enqueue(skb, cl->qdisc); + if (unlikely(err != NET_XMIT_SUCCESS)) { + pr_debug("qfq_enqueue: enqueue failed %d\n", err); + if (net_xmit_drop_count(err)) { + cl->qstats.drops++; + sch->qstats.drops++; + } + return err; + } + + bstats_update(&cl->bstats, skb); + ++sch->q.qlen; + + /* If the new skb is not the head of queue, then done here. */ + if (cl->qdisc->q.qlen != 1) + return err; + + /* If reach this point, queue q was idle */ + grp = cl->grp; + qfq_update_start(q, cl); + + /* compute new finish time and rounded start. */ + cl->F = cl->S + (u64)qdisc_pkt_len(skb) * cl->inv_w; + roundedS = qfq_round_down(cl->S, grp->slot_shift); + + /* + * insert cl in the correct bucket. + * If cl->S >= grp->S we don't need to adjust the + * bucket list and simply go to the insertion phase. + * Otherwise grp->S is decreasing, we must make room + * in the bucket list, and also recompute the group state. + * Finally, if there were no flows in this group and nobody + * was in ER make sure to adjust V. + */ + if (grp->full_slots) { + if (!qfq_gt(grp->S, cl->S)) + goto skip_update; + + /* create a slot for this cl->S */ + qfq_slot_rotate(grp, roundedS); + /* group was surely ineligible, remove */ + __clear_bit(grp->index, &q->bitmaps[IR]); + __clear_bit(grp->index, &q->bitmaps[IB]); + } else if (!q->bitmaps[ER] && qfq_gt(roundedS, q->V)) + q->V = roundedS; + + grp->S = roundedS; + grp->F = roundedS + (2ULL << grp->slot_shift); + s = qfq_calc_state(q, grp); + __set_bit(grp->index, &q->bitmaps[s]); + + pr_debug("qfq enqueue: new state %d %#lx S %lld F %lld V %lld\n", + s, q->bitmaps[s], + (unsigned long long) cl->S, + (unsigned long long) cl->F, + (unsigned long long) q->V); + +skip_update: + qfq_slot_insert(grp, cl, roundedS); + + return err; +} + + +static void qfq_slot_remove(struct qfq_sched *q, struct qfq_group *grp, + struct qfq_class *cl) +{ + unsigned int i, offset; + u64 roundedS; + + roundedS = qfq_round_down(cl->S, grp->slot_shift); + offset = (roundedS - grp->S) >> grp->slot_shift; + i = (grp->front + offset) % QFQ_MAX_SLOTS; + + hlist_del(&cl->next); + if (hlist_empty(&grp->slots[i])) + __clear_bit(offset, &grp->full_slots); +} + +/* + * called to forcibly destroy a queue. + * If the queue is not in the front bucket, or if it has + * other queues in the front bucket, we can simply remove + * the queue with no other side effects. + * Otherwise we must propagate the event up. + */ +static void qfq_deactivate_class(struct qfq_sched *q, struct qfq_class *cl) +{ + struct qfq_group *grp = cl->grp; + unsigned long mask; + u64 roundedS; + int s; + + cl->F = cl->S; + qfq_slot_remove(q, grp, cl); + + if (!grp->full_slots) { + __clear_bit(grp->index, &q->bitmaps[IR]); + __clear_bit(grp->index, &q->bitmaps[EB]); + __clear_bit(grp->index, &q->bitmaps[IB]); + + if (test_bit(grp->index, &q->bitmaps[ER]) && + !(q->bitmaps[ER] & ~((1UL << grp->index) - 1))) { + mask = q->bitmaps[ER] & ((1UL << grp->index) - 1); + if (mask) + mask = ~((1UL << __fls(mask)) - 1); + else + mask = ~0UL; + qfq_move_groups(q, mask, EB, ER); + qfq_move_groups(q, mask, IB, IR); + } + __clear_bit(grp->index, &q->bitmaps[ER]); + } else if (hlist_empty(&grp->slots[grp->front])) { + cl = qfq_slot_scan(grp); + roundedS = qfq_round_down(cl->S, grp->slot_shift); + if (grp->S != roundedS) { + __clear_bit(grp->index, &q->bitmaps[ER]); + __clear_bit(grp->index, &q->bitmaps[IR]); + __clear_bit(grp->index, &q->bitmaps[EB]); + __clear_bit(grp->index, &q->bitmaps[IB]); + grp->S = roundedS; + grp->F = roundedS + (2ULL << grp->slot_shift); + s = qfq_calc_state(q, grp); + __set_bit(grp->index, &q->bitmaps[s]); + } + } + + qfq_update_eligible(q, q->V); +} + +static void qfq_qlen_notify(struct Qdisc *sch, unsigned long arg) +{ + struct qfq_sched *q = qdisc_priv(sch); + struct qfq_class *cl = (struct qfq_class *)arg; + + if (cl->qdisc->q.qlen == 0) + qfq_deactivate_class(q, cl); +} + +static unsigned int qfq_drop(struct Qdisc *sch) +{ + struct qfq_sched *q = qdisc_priv(sch); + struct qfq_group *grp; + unsigned int i, j, len; + + for (i = 0; i <= QFQ_MAX_INDEX; i++) { + grp = &q->groups[i]; + for (j = 0; j < QFQ_MAX_SLOTS; j++) { + struct qfq_class *cl; + struct hlist_node *n; + + hlist_for_each_entry(cl, n, &grp->slots[j], next) { + + if (!cl->qdisc->ops->drop) + continue; + + len = cl->qdisc->ops->drop(cl->qdisc); + if (len > 0) { + sch->q.qlen--; + if (!cl->qdisc->q.qlen) + qfq_deactivate_class(q, cl); + + return len; + } + } + } + } + + return 0; +} + +static int qfq_init_qdisc(struct Qdisc *sch, struct nlattr *opt) +{ + struct qfq_sched *q = qdisc_priv(sch); + struct qfq_group *grp; + int i, j, err; + + err = qdisc_class_hash_init(&q->clhash); + if (err < 0) + return err; + + for (i = 0; i <= QFQ_MAX_INDEX; i++) { + grp = &q->groups[i]; + grp->index = i; + grp->slot_shift = QFQ_MTU_SHIFT + FRAC_BITS + - (QFQ_MAX_INDEX - i); + for (j = 0; j < QFQ_MAX_SLOTS; j++) + INIT_HLIST_HEAD(&grp->slots[j]); + } + + return 0; +} + +static void qfq_reset_qdisc(struct Qdisc *sch) +{ + struct qfq_sched *q = qdisc_priv(sch); + struct qfq_group *grp; + struct qfq_class *cl; + struct hlist_node *n, *tmp; + unsigned int i, j; + + for (i = 0; i <= QFQ_MAX_INDEX; i++) { + grp = &q->groups[i]; + for (j = 0; j < QFQ_MAX_SLOTS; j++) { + hlist_for_each_entry_safe(cl, n, tmp, + &grp->slots[j], next) { + qfq_deactivate_class(q, cl); + } + } + } + + for (i = 0; i < q->clhash.hashsize; i++) { + hlist_for_each_entry(cl, n, &q->clhash.hash[i], common.hnode) + qdisc_reset(cl->qdisc); + } + sch->q.qlen = 0; +} + +static void qfq_destroy_qdisc(struct Qdisc *sch) +{ + struct qfq_sched *q = qdisc_priv(sch); + struct qfq_class *cl; + struct hlist_node *n, *next; + unsigned int i; + + tcf_destroy_chain(&q->filter_list); + + for (i = 0; i < q->clhash.hashsize; i++) { + hlist_for_each_entry_safe(cl, n, next, &q->clhash.hash[i], + common.hnode) { + qfq_destroy_class(sch, cl); + } + } + qdisc_class_hash_destroy(&q->clhash); +} + +static const struct Qdisc_class_ops qfq_class_ops = { + .change = qfq_change_class, + .delete = qfq_delete_class, + .get = qfq_get_class, + .put = qfq_put_class, + .tcf_chain = qfq_tcf_chain, + .bind_tcf = qfq_bind_tcf, + .unbind_tcf = qfq_unbind_tcf, + .graft = qfq_graft_class, + .leaf = qfq_class_leaf, + .qlen_notify = qfq_qlen_notify, + .dump = qfq_dump_class, + .dump_stats = qfq_dump_class_stats, + .walk = qfq_walk, +}; + +static struct Qdisc_ops qfq_qdisc_ops __read_mostly = { + .cl_ops = &qfq_class_ops, + .id = "qfq", + .priv_size = sizeof(struct qfq_sched), + .enqueue = qfq_enqueue, + .dequeue = qfq_dequeue, + .peek = qdisc_peek_dequeued, + .drop = qfq_drop, + .init = qfq_init_qdisc, + .reset = qfq_reset_qdisc, + .destroy = qfq_destroy_qdisc, + .owner = THIS_MODULE, +}; + +static int __init qfq_init(void) +{ + return register_qdisc(&qfq_qdisc_ops); +} + +static void __exit qfq_exit(void) +{ + unregister_qdisc(&qfq_qdisc_ops); +} + +module_init(qfq_init); +module_exit(qfq_exit); +MODULE_LICENSE("GPL"); -- cgit From 4dd365fd55991b4e54a1d1c255081e6370b9da29 Mon Sep 17 00:00:00 2001 From: Bing Zhao Date: Wed, 30 Mar 2011 18:01:15 -0700 Subject: ieee80211: add HT extended capabilities masks IEEE Std 802.11n, Oct. 29, 2009: 7.3.2.56.5 HT Extended Capabilities field Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- include/linux/ieee80211.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 2d1c6117d92c..79690b710665 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -884,6 +884,15 @@ struct ieee80211_ht_cap { #define IEEE80211_HT_CAP_40MHZ_INTOLERANT 0x4000 #define IEEE80211_HT_CAP_LSIG_TXOP_PROT 0x8000 +/* 802.11n HT extended capabilities masks (for extended_ht_cap_info) */ +#define IEEE80211_HT_EXT_CAP_PCO 0x0001 +#define IEEE80211_HT_EXT_CAP_PCO_TIME 0x0006 +#define IEEE80211_HT_EXT_CAP_PCO_TIME_SHIFT 1 +#define IEEE80211_HT_EXT_CAP_MCS_FB 0x0300 +#define IEEE80211_HT_EXT_CAP_MCS_FB_SHIFT 8 +#define IEEE80211_HT_EXT_CAP_HTC_SUP 0x0400 +#define IEEE80211_HT_EXT_CAP_RD_RESPONDER 0x0800 + /* 802.11n HT capability AMPDU settings (for ampdu_params_info) */ #define IEEE80211_HT_AMPDU_PARM_FACTOR 0x03 #define IEEE80211_HT_AMPDU_PARM_DENSITY 0x1C -- cgit From ce57d9e694d98e421e329fbac5d6f5dc5e9e101e Mon Sep 17 00:00:00 2001 From: RafaÅ‚ MiÅ‚ecki Date: Fri, 1 Apr 2011 12:06:48 +0200 Subject: ssb: trivial: use u8 for chip_rev (it's mask is 0xF) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/ssb/scan.c | 2 +- include/linux/ssb/ssb.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/drivers/ssb/scan.c b/drivers/ssb/scan.c index 29884c00c4d5..7dca719fbcfb 100644 --- a/drivers/ssb/scan.c +++ b/drivers/ssb/scan.c @@ -307,7 +307,7 @@ int ssb_bus_scan(struct ssb_bus *bus, } else { if (bus->bustype == SSB_BUSTYPE_PCI) { bus->chip_id = pcidev_to_chipid(bus->host_pci); - pci_read_config_word(bus->host_pci, PCI_REVISION_ID, + pci_read_config_byte(bus->host_pci, PCI_REVISION_ID, &bus->chip_rev); bus->chip_package = 0; } else { diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h index 9659eff52ca2..7e99b348834c 100644 --- a/include/linux/ssb/ssb.h +++ b/include/linux/ssb/ssb.h @@ -308,7 +308,7 @@ struct ssb_bus { /* ID information about the Chip. */ u16 chip_id; - u16 chip_rev; + u8 chip_rev; u16 sprom_offset; u16 sprom_size; /* number of words in sprom */ u8 chip_package; -- cgit From c6e1a0d12ca7b4f22c58e55a16beacfb7d3d8462 Mon Sep 17 00:00:00 2001 From: Tom Herbert Date: Mon, 4 Apr 2011 22:30:30 -0700 Subject: net: Allow no-cache copy from user on transmit This patch uses __copy_from_user_nocache on transmit to bypass data cache for a performance improvement. skb_add_data_nocache and skb_copy_to_page_nocache can be called by sendmsg functions to use this feature, initial support is in tcp_sendmsg. This functionality is configurable per device using ethtool. Presumably, this feature would only be useful when the driver does not touch the data. The feature is turned on by default if a device indicates that it does some form of checksum offload; it is off by default for devices that do no checksum offload or indicate no checksum is necessary. For the former case copy-checksum is probably done anyway, in the latter case the device is likely loopback in which case the no cache copy is probably not beneficial. This patch was tested using 200 instances of netperf TCP_RR with 1400 byte request and one byte reply. Platform is 16 core AMD x86. No-cache copy disabled: 672703 tps, 97.13% utilization 50/90/99% latency:244.31 484.205 1028.41 No-cache copy enabled: 702113 tps, 96.16% utilization, 50/90/99% latency 238.56 467.56 956.955 Using 14000 byte request and response sizes demonstrate the effects more dramatically: No-cache copy disabled: 79571 tps, 34.34 %utlization 50/90/95% latency 1584.46 2319.59 5001.76 No-cache copy enabled: 83856 tps, 34.81% utilization 50/90/95% latency 2508.42 2622.62 2735.88 Note especially the effect on latency tail (95th percentile). This seems to provide a nice performance improvement and is consistent in the tests I ran. Presumably, this would provide the greatest benfits in the presence of an application workload stressing the cache and a lot of transmit data happening. Signed-off-by: Tom Herbert Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 2 +- include/linux/netdevice.h | 3 ++- include/net/sock.h | 53 +++++++++++++++++++++++++++++++++++++++++ net/core/dev.c | 12 ++++++++++ net/core/ethtool.c | 2 +- net/ipv4/tcp.c | 7 +++--- 6 files changed, 73 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 16d6fe954695..b51e021354b5 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1407,7 +1407,7 @@ static int bond_compute_features(struct bonding *bond) int i; features &= ~(NETIF_F_ALL_CSUM | BOND_VLAN_FEATURES); - features |= NETIF_F_GSO_MASK | NETIF_F_NO_CSUM; + features |= NETIF_F_GSO_MASK | NETIF_F_NO_CSUM | NETIF_F_NOCACHE_COPY; if (!bond->first_slave) goto done; diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index a4664cc68e2b..09d262415769 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1066,6 +1066,7 @@ struct net_device { #define NETIF_F_NTUPLE (1 << 27) /* N-tuple filters supported */ #define NETIF_F_RXHASH (1 << 28) /* Receive hashing offload */ #define NETIF_F_RXCSUM (1 << 29) /* Receive checksumming offload */ +#define NETIF_F_NOCACHE_COPY (1 << 30) /* Use no-cache copyfromuser */ /* Segmentation offload features */ #define NETIF_F_GSO_SHIFT 16 @@ -1081,7 +1082,7 @@ struct net_device { /* = all defined minus driver/device-class-related */ #define NETIF_F_NEVER_CHANGE (NETIF_F_HIGHDMA | NETIF_F_VLAN_CHALLENGED | \ NETIF_F_LLTX | NETIF_F_NETNS_LOCAL) -#define NETIF_F_ETHTOOL_BITS (0x3f3fffff & ~NETIF_F_NEVER_CHANGE) +#define NETIF_F_ETHTOOL_BITS (0x7f3fffff & ~NETIF_F_NEVER_CHANGE) /* List of features with software fallbacks. */ #define NETIF_F_GSO_SOFTWARE (NETIF_F_TSO | NETIF_F_TSO_ECN | \ diff --git a/include/net/sock.h b/include/net/sock.h index da0534d3401c..43bd515e92fd 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -52,6 +52,7 @@ #include #include #include +#include #include #include @@ -1389,6 +1390,58 @@ static inline void sk_nocaps_add(struct sock *sk, int flags) sk->sk_route_caps &= ~flags; } +static inline int skb_do_copy_data_nocache(struct sock *sk, struct sk_buff *skb, + char __user *from, char *to, + int copy) +{ + if (skb->ip_summed == CHECKSUM_NONE) { + int err = 0; + __wsum csum = csum_and_copy_from_user(from, to, copy, 0, &err); + if (err) + return err; + skb->csum = csum_block_add(skb->csum, csum, skb->len); + } else if (sk->sk_route_caps & NETIF_F_NOCACHE_COPY) { + if (!access_ok(VERIFY_READ, from, copy) || + __copy_from_user_nocache(to, from, copy)) + return -EFAULT; + } else if (copy_from_user(to, from, copy)) + return -EFAULT; + + return 0; +} + +static inline int skb_add_data_nocache(struct sock *sk, struct sk_buff *skb, + char __user *from, int copy) +{ + int err; + + err = skb_do_copy_data_nocache(sk, skb, from, skb_put(skb, copy), copy); + if (err) + __skb_trim(skb, skb->len); + + return err; +} + +static inline int skb_copy_to_page_nocache(struct sock *sk, char __user *from, + struct sk_buff *skb, + struct page *page, + int off, int copy) +{ + int err; + + err = skb_do_copy_data_nocache(sk, skb, from, + page_address(page) + off, copy); + if (err) + return err; + + skb->len += copy; + skb->data_len += copy; + skb->truesize += copy; + sk->sk_wmem_queued += copy; + sk_mem_charge(sk, copy); + return 0; +} + static inline int skb_copy_to_page(struct sock *sk, char __user *from, struct sk_buff *skb, struct page *page, int off, int copy) diff --git a/net/core/dev.c b/net/core/dev.c index 02f56376fe99..5d0b4f6f1a72 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -5425,6 +5425,14 @@ int register_netdevice(struct net_device *dev) dev->features &= ~NETIF_F_GSO; } + /* Turn on no cache copy if HW is doing checksum */ + dev->hw_features |= NETIF_F_NOCACHE_COPY; + if ((dev->features & NETIF_F_ALL_CSUM) && + !(dev->features & NETIF_F_NO_CSUM)) { + dev->wanted_features |= NETIF_F_NOCACHE_COPY; + dev->features |= NETIF_F_NOCACHE_COPY; + } + /* Enable GRO and NETIF_F_HIGHDMA for vlans by default, * vlan_dev_init() will do the dev->features check, so these features * are enabled only if supported by underlying device. @@ -6182,6 +6190,10 @@ u32 netdev_increment_features(u32 all, u32 one, u32 mask) } } + /* If device can't no cache copy, don't do for all */ + if (!(one & NETIF_F_NOCACHE_COPY)) + all &= ~NETIF_F_NOCACHE_COPY; + one |= NETIF_F_ALL_CSUM; one |= all & NETIF_F_ONE_FOR_ALL; diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 439e4b0e1312..719670ae199c 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -359,7 +359,7 @@ static const char netdev_features_strings[ETHTOOL_DEV_FEATURE_WORDS * 32][ETH_GS /* NETIF_F_NTUPLE */ "rx-ntuple-filter", /* NETIF_F_RXHASH */ "rx-hashing", /* NETIF_F_RXCSUM */ "rx-checksum", - "", + /* NETIF_F_NOCACHE_COPY */ "tx-nocache-copy" "", }; diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index b22d45010545..054a59d21eb0 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -999,7 +999,8 @@ new_segment: /* We have some space in skb head. Superb! */ if (copy > skb_tailroom(skb)) copy = skb_tailroom(skb); - if ((err = skb_add_data(skb, from, copy)) != 0) + err = skb_add_data_nocache(sk, skb, from, copy); + if (err) goto do_fault; } else { int merge = 0; @@ -1042,8 +1043,8 @@ new_segment: /* Time to copy data. We are close to * the end! */ - err = skb_copy_to_page(sk, from, skb, page, - off, copy); + err = skb_copy_to_page_nocache(sk, from, skb, + page, off, copy); if (err) { /* If this page was new, give it to the * socket so it does not get leaked. -- cgit From e20b5b61a36bd5b80eea064c0f2e73285dbe0d3b Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 1 Apr 2011 22:52:34 +0100 Subject: ethtool: Convert struct ethtool_ops comment to kernel-doc format Signed-off-by: Ben Hutchings --- include/linux/ethtool.h | 80 ++++++++++++++++++++++--------------------------- 1 file changed, 35 insertions(+), 45 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index c8fcbdd2b0e7..ab12f84c17bd 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -683,63 +683,53 @@ void ethtool_ntuple_flush(struct net_device *dev); bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported); /** - * ðtool_ops - Alter and report network device settings - * get_settings: Get device-specific settings - * set_settings: Set device-specific settings - * get_drvinfo: Report driver information - * get_regs: Get device registers - * get_wol: Report whether Wake-on-Lan is enabled - * set_wol: Turn Wake-on-Lan on or off - * get_msglevel: Report driver message level - * set_msglevel: Set driver message level - * nway_reset: Restart autonegotiation - * get_link: Get link status - * get_eeprom: Read data from the device EEPROM - * set_eeprom: Write data to the device EEPROM - * get_coalesce: Get interrupt coalescing parameters - * set_coalesce: Set interrupt coalescing parameters - * get_ringparam: Report ring sizes - * set_ringparam: Set ring sizes - * get_pauseparam: Report pause parameters - * set_pauseparam: Set pause parameters - * get_rx_csum: Report whether receive checksums are turned on or off - * set_rx_csum: Turn receive checksum on or off - * get_tx_csum: Report whether transmit checksums are turned on or off - * set_tx_csum: Turn transmit checksums on or off - * get_sg: Report whether scatter-gather is enabled - * set_sg: Turn scatter-gather on or off - * get_tso: Report whether TCP segmentation offload is enabled - * set_tso: Turn TCP segmentation offload on or off - * get_ufo: Report whether UDP fragmentation offload is enabled - * set_ufo: Turn UDP fragmentation offload on or off - * self_test: Run specified self-tests - * get_strings: Return a set of strings that describe the requested objects - * phys_id: Identify the device - * get_stats: Return statistics about the device - * get_flags: get 32-bit flags bitmap - * set_flags: set 32-bit flags bitmap - * - * Description: - * - * get_settings: + * struct ethtool_ops - Alter and report network device settings + * @get_settings: Get device-specific settings. * @get_settings is passed an ðtool_cmd to fill in. It returns * an negative errno or zero. - * - * set_settings: + * @set_settings: Set device-specific settings. * @set_settings is passed an ðtool_cmd and should attempt to set * all the settings this device supports. It may return an error value * if something goes wrong (otherwise 0). - * - * get_eeprom: + * @get_drvinfo: Report driver information + * @get_regs: Get device registers + * @get_wol: Report whether Wake-on-Lan is enabled + * @set_wol: Turn Wake-on-Lan on or off + * @get_msglevel: Report driver message level + * @set_msglevel: Set driver message level + * @nway_reset: Restart autonegotiation + * @get_link: Get link status + * @get_eeprom: Read data from the device EEPROM. * Should fill in the magic field. Don't need to check len for zero * or wraparound. Fill in the data argument with the eeprom values * from offset to offset + len. Update len to the amount read. * Returns an error or zero. - * - * set_eeprom: + * @set_eeprom: Write data to the device EEPROM. * Should validate the magic field. Don't need to check len for zero * or wraparound. Update len to the amount written. Returns an error * or zero. + * @get_coalesce: Get interrupt coalescing parameters + * @set_coalesce: Set interrupt coalescing parameters + * @get_ringparam: Report ring sizes + * @set_ringparam: Set ring sizes + * @get_pauseparam: Report pause parameters + * @set_pauseparam: Set pause parameters + * @get_rx_csum: Report whether receive checksums are turned on or off + * @set_rx_csum: Turn receive checksum on or off + * @get_tx_csum: Report whether transmit checksums are turned on or off + * @set_tx_csum: Turn transmit checksums on or off + * @get_sg: Report whether scatter-gather is enabled + * @set_sg: Turn scatter-gather on or off + * @get_tso: Report whether TCP segmentation offload is enabled + * @set_tso: Turn TCP segmentation offload on or off + * @get_ufo: Report whether UDP fragmentation offload is enabled + * @set_ufo: Turn UDP fragmentation offload on or off + * @self_test: Run specified self-tests + * @get_strings: Return a set of strings that describe the requested objects + * @phys_id: Identify the device + * @get_stats: Return statistics about the device + * @get_flags: get 32-bit flags bitmap + * @set_flags: set 32-bit flags bitmap */ struct ethtool_ops { int (*get_settings)(struct net_device *, struct ethtool_cmd *); -- cgit From 8717d07b1143e0f150921f5bd7cfe7af579a995a Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 1 Apr 2011 23:57:41 +0100 Subject: ethtool: Fill out and update comment for struct ethtool_ops Briefly document all operations (except get_rx_ntuple), including whether they may return an error code and whether they are deprecated. Also mention some things that should be handled by the ethtool core rather than by drivers. Briefly document general requirements for callers. Signed-off-by: Ben Hutchings --- include/linux/ethtool.h | 124 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 93 insertions(+), 31 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index ab12f84c17bd..ead7dcb1bf1e 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -683,22 +683,28 @@ void ethtool_ntuple_flush(struct net_device *dev); bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported); /** - * struct ethtool_ops - Alter and report network device settings - * @get_settings: Get device-specific settings. - * @get_settings is passed an ðtool_cmd to fill in. It returns - * an negative errno or zero. - * @set_settings: Set device-specific settings. - * @set_settings is passed an ðtool_cmd and should attempt to set - * all the settings this device supports. It may return an error value - * if something goes wrong (otherwise 0). - * @get_drvinfo: Report driver information + * struct ethtool_ops - optional netdev operations + * @get_settings: Get various device settings including Ethernet link + * settings. Returns a negative error code or zero. + * @set_settings: Set various device settings including Ethernet link + * settings. Returns a negative error code or zero. + * @get_drvinfo: Report driver/device information. Should only set the + * @driver, @version, @fw_version and @bus_info fields. If not + * implemented, the @driver and @bus_info fields will be filled in + * according to the netdev's parent device. + * @get_regs_len: Get buffer length required for @get_regs * @get_regs: Get device registers * @get_wol: Report whether Wake-on-Lan is enabled - * @set_wol: Turn Wake-on-Lan on or off - * @get_msglevel: Report driver message level + * @set_wol: Turn Wake-on-Lan on or off. Returns a negative error code + * or zero. + * @get_msglevel: Report driver message level. This should be the value + * of the @msg_enable field used by netif logging functions. * @set_msglevel: Set driver message level - * @nway_reset: Restart autonegotiation - * @get_link: Get link status + * @nway_reset: Restart autonegotiation. Returns a negative error code + * or zero. + * @get_link: Report whether physical link is up. Will only be called if + * the netdev is up. Should usually be set to ethtool_op_get_link(), + * which uses netif_carrier_ok(). * @get_eeprom: Read data from the device EEPROM. * Should fill in the magic field. Don't need to check len for zero * or wraparound. Fill in the data argument with the eeprom values @@ -708,28 +714,84 @@ bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported); * Should validate the magic field. Don't need to check len for zero * or wraparound. Update len to the amount written. Returns an error * or zero. - * @get_coalesce: Get interrupt coalescing parameters - * @set_coalesce: Set interrupt coalescing parameters + * @get_coalesce: Get interrupt coalescing parameters. Returns a negative + * error code or zero. + * @set_coalesce: Set interrupt coalescing parameters. Returns a negative + * error code or zero. * @get_ringparam: Report ring sizes - * @set_ringparam: Set ring sizes + * @set_ringparam: Set ring sizes. Returns a negative error code or zero. * @get_pauseparam: Report pause parameters - * @set_pauseparam: Set pause parameters - * @get_rx_csum: Report whether receive checksums are turned on or off - * @set_rx_csum: Turn receive checksum on or off - * @get_tx_csum: Report whether transmit checksums are turned on or off - * @set_tx_csum: Turn transmit checksums on or off - * @get_sg: Report whether scatter-gather is enabled - * @set_sg: Turn scatter-gather on or off - * @get_tso: Report whether TCP segmentation offload is enabled - * @set_tso: Turn TCP segmentation offload on or off - * @get_ufo: Report whether UDP fragmentation offload is enabled - * @set_ufo: Turn UDP fragmentation offload on or off + * @set_pauseparam: Set pause parameters. Returns a negative error code + * or zero. + * @get_rx_csum: Deprecated in favour of the netdev feature %NETIF_F_RXCSUM. + * Report whether receive checksums are turned on or off. + * @set_rx_csum: Deprecated in favour of generic netdev features. Turn + * receive checksum on or off. Returns a negative error code or zero. + * @get_tx_csum: Deprecated as redundant. Report whether transmit checksums + * are turned on or off. + * @set_tx_csum: Deprecated in favour of generic netdev features. Turn + * transmit checksums on or off. Returns a egative error code or zero. + * @get_sg: Deprecated as redundant. Report whether scatter-gather is + * enabled. + * @set_sg: Deprecated in favour of generic netdev features. Turn + * scatter-gather on or off. Returns a negative error code or zero. + * @get_tso: Deprecated as redundant. Report whether TCP segmentation + * offload is enabled. + * @set_tso: Deprecated in favour of generic netdev features. Turn TCP + * segmentation offload on or off. Returns a negative error code or zero. * @self_test: Run specified self-tests * @get_strings: Return a set of strings that describe the requested objects - * @phys_id: Identify the device - * @get_stats: Return statistics about the device - * @get_flags: get 32-bit flags bitmap - * @set_flags: set 32-bit flags bitmap + * @phys_id: Identify the physical device, e.g. by flashing an LED + * attached to it until interrupted by a signal or the given time + * (in seconds) elapses. If the given time is zero, use a default + * time limit. Returns a negative error code or zero. Being + * interrupted by a signal is not an error. + * @get_ethtool_stats: Return extended statistics about the device. + * This is only useful if the device maintains statistics not + * included in &struct rtnl_link_stats64. + * @begin: Function to be called before any other operation. Returns a + * negative error code or zero. + * @complete: Function to be called after any other operation except + * @begin. Will be called even if the other operation failed. + * @get_ufo: Deprecated as redundant. Report whether UDP fragmentation + * offload is enabled. + * @set_ufo: Deprecated in favour of generic netdev features. Turn UDP + * fragmentation offload on or off. Returns a negative error code or zero. + * @get_flags: Deprecated as redundant. Report features included in + * &enum ethtool_flags that are enabled. + * @set_flags: Deprecated in favour of generic netdev features. Turn + * features included in &enum ethtool_flags on or off. Returns a + * negative error code or zero. + * @get_priv_flags: Report driver-specific feature flags. + * @set_priv_flags: Set driver-specific feature flags. Returns a negative + * error code or zero. + * @get_sset_count: Get number of strings that @get_strings will write. + * @get_rxnfc: Get RX flow classification rules. Returns a negative + * error code or zero. + * @set_rxnfc: Set RX flow classification rules. Returns a negative + * error code or zero. + * @flash_device: Write a firmware image to device's flash memory. + * Returns a negative error code or zero. + * @reset: Reset (part of) the device, as specified by a bitmask of + * flags from &enum ethtool_reset_flags. Returns a negative + * error code or zero. + * @set_rx_ntuple: Set an RX n-tuple rule. Returns a negative error code + * or zero. + * @get_rx_ntuple: Deprecated. + * @get_rxfh_indir: Get the contents of the RX flow hash indirection table. + * Returns a negative error code or zero. + * @set_rxfh_indir: Set the contents of the RX flow hash indirection table. + * Returns a negative error code or zero. + * + * All operations are optional (i.e. the function pointer may be set + * to %NULL) and callers must take this into account. Callers must + * hold the RTNL, except that for @get_drvinfo the caller may or may + * not hold the RTNL. + * + * See the structures used by these operations for further documentation. + * + * See &struct net_device and &struct net_device_ops for documentation + * of the generic netdev features interface. */ struct ethtool_ops { int (*get_settings)(struct net_device *, struct ethtool_cmd *); -- cgit From 68f512f21a64c9b264df6c61a9333e7890faf74b Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sat, 2 Apr 2011 00:35:15 +0100 Subject: ethtool: Change ETHTOOL_PHYS_ID implementation to allow dropping RTNL The ethtool ETHTOOL_PHYS_ID command runs for an arbitrarily long period of time, holding the RTNL lock. This blocks routing updates, device enumeration, and various important operations that one might want to keep running while hunting for the flashing LED. We need to drop the RTNL lock during this operation, but currently the core implementation is a thin wrapper around a driver operation and drivers may well depend upon holding the lock. Define a new driver operation 'set_phys_id' with an argument that sets the ID indicator on/off/inactive/active (the last optional, for any driver or firmware that prefers to handle blinking asynchronously). When this is defined, the ethtool core drops the lock while waiting and only acquires it around calls to this operation. Deprecate the 'phys_id' operation in favour of this. It can be removed once all in-tree drivers are converted. Signed-off-by: Ben Hutchings --- include/linux/ethtool.h | 30 ++++++++++++++++++++++++++- net/core/ethtool.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 82 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index ead7dcb1bf1e..c04d1316d221 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -663,6 +663,22 @@ struct ethtool_rx_ntuple_list { unsigned int count; }; +/** + * enum ethtool_phys_id_state - indicator state for physical identification + * @ETHTOOL_ID_INACTIVE: Physical ID indicator should be deactivated + * @ETHTOOL_ID_ACTIVE: Physical ID indicator should be activated + * @ETHTOOL_ID_ON: LED should be turned on (used iff %ETHTOOL_ID_ACTIVE + * is not supported) + * @ETHTOOL_ID_OFF: LED should be turned off (used iff %ETHTOOL_ID_ACTIVE + * is not supported) + */ +enum ethtool_phys_id_state { + ETHTOOL_ID_INACTIVE, + ETHTOOL_ID_ACTIVE, + ETHTOOL_ID_ON, + ETHTOOL_ID_OFF +}; + struct net_device; /* Some generic methods drivers may use in their ethtool_ops */ @@ -741,7 +757,18 @@ bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported); * segmentation offload on or off. Returns a negative error code or zero. * @self_test: Run specified self-tests * @get_strings: Return a set of strings that describe the requested objects - * @phys_id: Identify the physical device, e.g. by flashing an LED + * @set_phys_id: Identify the physical devices, e.g. by flashing an LED + * attached to it. The implementation may update the indicator + * asynchronously or synchronously, but in either case it must return + * quickly. It is initially called with the argument %ETHTOOL_ID_ACTIVE, + * and must either activate asynchronous updates or return -%EINVAL. + * If it returns -%EINVAL then it will be called again at intervals with + * argument %ETHTOOL_ID_ON or %ETHTOOL_ID_OFF and should set the state of + * the indicator accordingly. Finally, it is called with the argument + * %ETHTOOL_ID_INACTIVE and must deactivate the indicator. Returns a + * negative error code or zero. + * @phys_id: Deprecated in favour of @set_phys_id. + * Identify the physical device, e.g. by flashing an LED * attached to it until interrupted by a signal or the given time * (in seconds) elapses. If the given time is zero, use a default * time limit. Returns a negative error code or zero. Being @@ -830,6 +857,7 @@ struct ethtool_ops { int (*set_tso)(struct net_device *, u32); void (*self_test)(struct net_device *, struct ethtool_test *, u64 *); void (*get_strings)(struct net_device *, u32 stringset, u8 *); + int (*set_phys_id)(struct net_device *, enum ethtool_phys_id_state); int (*phys_id)(struct net_device *, u32); void (*get_ethtool_stats)(struct net_device *, struct ethtool_stats *, u64 *); diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 74ead9eca126..1c95f0fb8b3a 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include /* * Some useful ethtool_ops methods that're device independent. @@ -1618,14 +1620,63 @@ out: static int ethtool_phys_id(struct net_device *dev, void __user *useraddr) { struct ethtool_value id; + static bool busy; + int rc; - if (!dev->ethtool_ops->phys_id) + if (!dev->ethtool_ops->set_phys_id && !dev->ethtool_ops->phys_id) return -EOPNOTSUPP; + if (busy) + return -EBUSY; + if (copy_from_user(&id, useraddr, sizeof(id))) return -EFAULT; - return dev->ethtool_ops->phys_id(dev, id.data); + if (!dev->ethtool_ops->set_phys_id) + /* Do it the old way */ + return dev->ethtool_ops->phys_id(dev, id.data); + + rc = dev->ethtool_ops->set_phys_id(dev, ETHTOOL_ID_ACTIVE); + if (rc && rc != -EINVAL) + return rc; + + /* Drop the RTNL lock while waiting, but prevent reentry or + * removal of the device. + */ + busy = true; + dev_hold(dev); + rtnl_unlock(); + + if (rc == 0) { + /* Driver will handle this itself */ + schedule_timeout_interruptible( + id.data ? id.data : MAX_SCHEDULE_TIMEOUT); + } else { + /* Driver expects to be called periodically */ + do { + rtnl_lock(); + rc = dev->ethtool_ops->set_phys_id(dev, ETHTOOL_ID_ON); + rtnl_unlock(); + if (rc) + break; + schedule_timeout_interruptible(HZ / 2); + + rtnl_lock(); + rc = dev->ethtool_ops->set_phys_id(dev, ETHTOOL_ID_OFF); + rtnl_unlock(); + if (rc) + break; + schedule_timeout_interruptible(HZ / 2); + } while (!signal_pending(current) && + (id.data == 0 || --id.data != 0)); + } + + rtnl_lock(); + dev_put(dev); + busy = false; + + (void)dev->ethtool_ops->set_phys_id(dev, ETHTOOL_ID_INACTIVE); + return rc; } static int ethtool_get_stats(struct net_device *dev, void __user *useraddr) -- cgit From b710a480554f2be682bac3cb59b0e085ba3d644b Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Wed, 30 Mar 2011 09:52:30 +0200 Subject: block: get rid of elv_insert() interface Merge it with __elv_add_request(), it's pretty pointless to have a function with only two callers. The main interface is elv_add_request()/__elv_add_request(). Signed-off-by: Jens Axboe --- block/blk-flush.c | 4 ++-- block/elevator.c | 35 +++++++++++++++-------------------- include/linux/elevator.h | 1 - 3 files changed, 17 insertions(+), 23 deletions(-) (limited to 'include/linux') diff --git a/block/blk-flush.c b/block/blk-flush.c index 93d5fd8e51eb..d6275cbbaf35 100644 --- a/block/blk-flush.c +++ b/block/blk-flush.c @@ -261,7 +261,7 @@ static bool blk_kick_flush(struct request_queue *q) q->flush_rq.end_io = flush_end_io; q->flush_pending_idx ^= 1; - elv_insert(q, &q->flush_rq, ELEVATOR_INSERT_REQUEUE); + __elv_add_request(q, &q->flush_rq, ELEVATOR_INSERT_REQUEUE); return true; } @@ -281,7 +281,7 @@ static void flush_data_end_io(struct request *rq, int error) * blk_insert_flush - insert a new FLUSH/FUA request * @rq: request to insert * - * To be called from elv_insert() for %ELEVATOR_INSERT_FLUSH insertions. + * To be called from __elv_add_request() for %ELEVATOR_INSERT_FLUSH insertions. * @rq is being submitted. Analyze what needs to be done and put it on the * right queue. * diff --git a/block/elevator.c b/block/elevator.c index c387d3168734..0cdb4e7ebab4 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -610,7 +610,7 @@ void elv_requeue_request(struct request_queue *q, struct request *rq) rq->cmd_flags &= ~REQ_STARTED; - elv_insert(q, rq, ELEVATOR_INSERT_REQUEUE); + __elv_add_request(q, rq, ELEVATOR_INSERT_REQUEUE); } void elv_drain_elevator(struct request_queue *q) @@ -655,12 +655,25 @@ void elv_quiesce_end(struct request_queue *q) queue_flag_clear(QUEUE_FLAG_ELVSWITCH, q); } -void elv_insert(struct request_queue *q, struct request *rq, int where) +void __elv_add_request(struct request_queue *q, struct request *rq, int where) { trace_block_rq_insert(q, rq); rq->q = q; + BUG_ON(rq->cmd_flags & REQ_ON_PLUG); + + if (rq->cmd_flags & REQ_SOFTBARRIER) { + /* barriers are scheduling boundary, update end_sector */ + if (rq->cmd_type == REQ_TYPE_FS || + (rq->cmd_flags & REQ_DISCARD)) { + q->end_sector = rq_end_sector(rq); + q->boundary_rq = rq; + } + } else if (!(rq->cmd_flags & REQ_ELVPRIV) && + where == ELEVATOR_INSERT_SORT) + where = ELEVATOR_INSERT_BACK; + switch (where) { case ELEVATOR_INSERT_REQUEUE: case ELEVATOR_INSERT_FRONT: @@ -722,24 +735,6 @@ void elv_insert(struct request_queue *q, struct request *rq, int where) BUG(); } } - -void __elv_add_request(struct request_queue *q, struct request *rq, int where) -{ - BUG_ON(rq->cmd_flags & REQ_ON_PLUG); - - if (rq->cmd_flags & REQ_SOFTBARRIER) { - /* barriers are scheduling boundary, update end_sector */ - if (rq->cmd_type == REQ_TYPE_FS || - (rq->cmd_flags & REQ_DISCARD)) { - q->end_sector = rq_end_sector(rq); - q->boundary_rq = rq; - } - } else if (!(rq->cmd_flags & REQ_ELVPRIV) && - where == ELEVATOR_INSERT_SORT) - where = ELEVATOR_INSERT_BACK; - - elv_insert(q, rq, where); -} EXPORT_SYMBOL(__elv_add_request); void elv_add_request(struct request_queue *q, struct request *rq, int where) diff --git a/include/linux/elevator.h b/include/linux/elevator.h index d93efcc44570..21a8ebf2dc3a 100644 --- a/include/linux/elevator.h +++ b/include/linux/elevator.h @@ -101,7 +101,6 @@ extern void elv_dispatch_sort(struct request_queue *, struct request *); extern void elv_dispatch_add_tail(struct request_queue *, struct request *); extern void elv_add_request(struct request_queue *, struct request *, int); extern void __elv_add_request(struct request_queue *, struct request *, int); -extern void elv_insert(struct request_queue *, struct request *, int); extern int elv_merge(struct request_queue *, struct request **, struct bio *); extern int elv_try_merge(struct request *, struct bio *); extern void elv_merge_requests(struct request_queue *, struct request *, -- cgit From 7dcda1c96d7c643101d4a05579ef4512a4baa7ef Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 5 Apr 2011 23:51:48 +0200 Subject: fs: export empty_aops With the ->sync_page() hook gone, we have a few users that add their own static address_space_operations without any functions defined. fs/inode.c already has an empty_aops that it uses for init purposes. Lets export that and use it in the places where an otherwise empty aops was defined. Signed-off-by: Jens Axboe --- fs/inode.c | 9 ++++++++- fs/nilfs2/page.c | 2 -- fs/ubifs/xattr.c | 4 ++-- include/linux/fs.h | 2 ++ 4 files changed, 12 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/fs/inode.c b/fs/inode.c index 5f4e11aaeb5c..33c963d08ab4 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -124,6 +124,14 @@ __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_wb_list_lock); */ static DECLARE_RWSEM(iprune_sem); +/* + * Empty aops. Can be used for the cases where the user does not + * define any of the address_space operations. + */ +const struct address_space_operations empty_aops = { +}; +EXPORT_SYMBOL(empty_aops); + /* * Statistics gathering.. */ @@ -176,7 +184,6 @@ int proc_nr_inodes(ctl_table *table, int write, */ int inode_init_always(struct super_block *sb, struct inode *inode) { - static const struct address_space_operations empty_aops; static const struct inode_operations empty_iops; static const struct file_operations empty_fops; struct address_space *const mapping = &inode->i_data; diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c index 9d2dc6b4348e..1168059c7efd 100644 --- a/fs/nilfs2/page.c +++ b/fs/nilfs2/page.c @@ -495,8 +495,6 @@ unsigned nilfs_page_count_clean_buffers(struct page *page, void nilfs_mapping_init(struct address_space *mapping, struct backing_dev_info *bdi) { - static const struct address_space_operations empty_aops; - mapping->host = NULL; mapping->flags = 0; mapping_set_gfp_mask(mapping, GFP_NOFS); diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c index c74400f88fe0..3299f469e712 100644 --- a/fs/ubifs/xattr.c +++ b/fs/ubifs/xattr.c @@ -56,6 +56,7 @@ */ #include "ubifs.h" +#include #include #include #include @@ -80,7 +81,6 @@ enum { }; static const struct inode_operations none_inode_operations; -static const struct address_space_operations none_address_operations; static const struct file_operations none_file_operations; /** @@ -130,7 +130,7 @@ static int create_xattr(struct ubifs_info *c, struct inode *host, } /* Re-define all operations to be "nothing" */ - inode->i_mapping->a_ops = &none_address_operations; + inode->i_mapping->a_ops = &empty_aops; inode->i_op = &none_inode_operations; inode->i_fop = &none_file_operations; diff --git a/include/linux/fs.h b/include/linux/fs.h index 52f283c1edb2..1b95af37e3b3 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -613,6 +613,8 @@ struct address_space_operations { int (*error_remove_page)(struct address_space *, struct page *); }; +extern const struct address_space_operations empty_aops; + /* * pagecache_write_begin/pagecache_write_end must be used by general code * to write into the pagecache. -- cgit From a63a5cf84dac7a23a57c800eea5734701e7d3c04 Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Fri, 1 Apr 2011 21:02:31 +0200 Subject: dm: improve block integrity support The current block integrity (DIF/DIX) support in DM is verifying that all devices' integrity profiles match during DM device resume (which is past the point of no return). To some degree that is unavoidable (stacked DM devices force this late checking). But for most DM devices (which aren't stacking on other DM devices) the ideal time to verify all integrity profiles match is during table load. Introduce the notion of an "initialized" integrity profile: a profile that was blk_integrity_register()'d with a non-NULL 'blk_integrity' template. Add blk_integrity_is_initialized() to allow checking if a profile was initialized. Update DM integrity support to: - check all devices with _initialized_ integrity profiles match during table load; uninitialized profiles (e.g. for underlying DM device(s) of a stacked DM device) are ignored. - disallow a table load that would result in an integrity profile that conflicts with a DM device's existing (in-use) integrity profile - avoid clearing an existing integrity profile - validate all integrity profiles match during resume; but if they don't all we can do is report the mismatch (during resume we're past the point of no return) Signed-off-by: Mike Snitzer Cc: Martin K. Petersen Signed-off-by: Jens Axboe --- block/blk-integrity.c | 12 +++++- drivers/md/dm-table.c | 114 ++++++++++++++++++++++++++++++++++--------------- include/linux/blkdev.h | 2 + 3 files changed, 93 insertions(+), 35 deletions(-) (limited to 'include/linux') diff --git a/block/blk-integrity.c b/block/blk-integrity.c index 54bcba6c02a7..129b9e209a3b 100644 --- a/block/blk-integrity.c +++ b/block/blk-integrity.c @@ -30,6 +30,8 @@ static struct kmem_cache *integrity_cachep; +static const char *bi_unsupported_name = "unsupported"; + /** * blk_rq_count_integrity_sg - Count number of integrity scatterlist elements * @q: request queue @@ -358,6 +360,14 @@ static struct kobj_type integrity_ktype = { .release = blk_integrity_release, }; +bool blk_integrity_is_initialized(struct gendisk *disk) +{ + struct blk_integrity *bi = blk_get_integrity(disk); + + return (bi && bi->name && strcmp(bi->name, bi_unsupported_name) != 0); +} +EXPORT_SYMBOL(blk_integrity_is_initialized); + /** * blk_integrity_register - Register a gendisk as being integrity-capable * @disk: struct gendisk pointer to make integrity-aware @@ -407,7 +417,7 @@ int blk_integrity_register(struct gendisk *disk, struct blk_integrity *template) bi->get_tag_fn = template->get_tag_fn; bi->tag_size = template->tag_size; } else - bi->name = "unsupported"; + bi->name = bi_unsupported_name; return 0; } diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 416d4e258df6..cb8380c9767f 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -926,21 +926,81 @@ static int dm_table_build_index(struct dm_table *t) return r; } +/* + * Get a disk whose integrity profile reflects the table's profile. + * If %match_all is true, all devices' profiles must match. + * If %match_all is false, all devices must at least have an + * allocated integrity profile; but uninitialized is ok. + * Returns NULL if integrity support was inconsistent or unavailable. + */ +static struct gendisk * dm_table_get_integrity_disk(struct dm_table *t, + bool match_all) +{ + struct list_head *devices = dm_table_get_devices(t); + struct dm_dev_internal *dd = NULL; + struct gendisk *prev_disk = NULL, *template_disk = NULL; + + list_for_each_entry(dd, devices, list) { + template_disk = dd->dm_dev.bdev->bd_disk; + if (!blk_get_integrity(template_disk)) + goto no_integrity; + if (!match_all && !blk_integrity_is_initialized(template_disk)) + continue; /* skip uninitialized profiles */ + else if (prev_disk && + blk_integrity_compare(prev_disk, template_disk) < 0) + goto no_integrity; + prev_disk = template_disk; + } + + return template_disk; + +no_integrity: + if (prev_disk) + DMWARN("%s: integrity not set: %s and %s profile mismatch", + dm_device_name(t->md), + prev_disk->disk_name, + template_disk->disk_name); + return NULL; +} + /* * Register the mapped device for blk_integrity support if - * the underlying devices support it. + * the underlying devices have an integrity profile. But all devices + * may not have matching profiles (checking all devices isn't reliable + * during table load because this table may use other DM device(s) which + * must be resumed before they will have an initialized integity profile). + * Stacked DM devices force a 2 stage integrity profile validation: + * 1 - during load, validate all initialized integrity profiles match + * 2 - during resume, validate all integrity profiles match */ static int dm_table_prealloc_integrity(struct dm_table *t, struct mapped_device *md) { - struct list_head *devices = dm_table_get_devices(t); - struct dm_dev_internal *dd; + struct gendisk *template_disk = NULL; - list_for_each_entry(dd, devices, list) - if (bdev_get_integrity(dd->dm_dev.bdev)) { - t->integrity_supported = 1; - return blk_integrity_register(dm_disk(md), NULL); - } + template_disk = dm_table_get_integrity_disk(t, false); + if (!template_disk) + return 0; + if (!blk_integrity_is_initialized(dm_disk(md))) { + t->integrity_supported = 1; + return blk_integrity_register(dm_disk(md), NULL); + } + + /* + * If DM device already has an initalized integrity + * profile the new profile should not conflict. + */ + if (blk_integrity_is_initialized(template_disk) && + blk_integrity_compare(dm_disk(md), template_disk) < 0) { + DMWARN("%s: conflict with existing integrity profile: " + "%s profile mismatch", + dm_device_name(t->md), + template_disk->disk_name); + return 1; + } + + /* Preserve existing initialized integrity profile */ + t->integrity_supported = 1; return 0; } @@ -1094,41 +1154,27 @@ combine_limits: /* * Set the integrity profile for this device if all devices used have - * matching profiles. + * matching profiles. We're quite deep in the resume path but still + * don't know if all devices (particularly DM devices this device + * may be stacked on) have matching profiles. Even if the profiles + * don't match we have no way to fail (to resume) at this point. */ static void dm_table_set_integrity(struct dm_table *t) { - struct list_head *devices = dm_table_get_devices(t); - struct dm_dev_internal *prev = NULL, *dd = NULL; + struct gendisk *template_disk = NULL; if (!blk_get_integrity(dm_disk(t->md))) return; - list_for_each_entry(dd, devices, list) { - if (prev && - blk_integrity_compare(prev->dm_dev.bdev->bd_disk, - dd->dm_dev.bdev->bd_disk) < 0) { - DMWARN("%s: integrity not set: %s and %s mismatch", - dm_device_name(t->md), - prev->dm_dev.bdev->bd_disk->disk_name, - dd->dm_dev.bdev->bd_disk->disk_name); - goto no_integrity; - } - prev = dd; + template_disk = dm_table_get_integrity_disk(t, true); + if (!template_disk && + blk_integrity_is_initialized(dm_disk(t->md))) { + DMWARN("%s: device no longer has a valid integrity profile", + dm_device_name(t->md)); + return; } - - if (!prev || !bdev_get_integrity(prev->dm_dev.bdev)) - goto no_integrity; - blk_integrity_register(dm_disk(t->md), - bdev_get_integrity(prev->dm_dev.bdev)); - - return; - -no_integrity: - blk_integrity_register(dm_disk(t->md), NULL); - - return; + blk_get_integrity(template_disk)); } void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 16a902f099ac..32176cc8e715 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1206,6 +1206,7 @@ struct blk_integrity { struct kobject kobj; }; +extern bool blk_integrity_is_initialized(struct gendisk *); extern int blk_integrity_register(struct gendisk *, struct blk_integrity *); extern void blk_integrity_unregister(struct gendisk *); extern int blk_integrity_compare(struct gendisk *, struct gendisk *); @@ -1262,6 +1263,7 @@ queue_max_integrity_segments(struct request_queue *q) #define queue_max_integrity_segments(a) (0) #define blk_integrity_merge_rq(a, b, c) (0) #define blk_integrity_merge_bio(a, b, c) (0) +#define blk_integrity_is_initialized(a) (0) #endif /* CONFIG_BLK_DEV_INTEGRITY */ -- cgit From 34206f267120c839a479d0237db907fa062e7b0f Mon Sep 17 00:00:00 2001 From: Enric Balletbo i Serra Date: Tue, 5 Apr 2011 07:08:41 +0000 Subject: can: mcp251x: Allow pass IRQ flags through platform data. When an interrupt occurs, the INT pin is driven low by the MCP251x controller (falling edge) but in some cases the INT pin can be connected to the MPU through a transistor or level translator which inverts this signal. In this case interrupt should be configured in rising edge. This patch adds support to pass the IRQ flags via mcp251x_platform_data. Signed-off-by: Enric Balletbo i Serra Acked-by: Wolfgang Grandegger Acked-by: Marc Kleine-Budde Signed-off-by: David S. Miller --- drivers/net/can/mcp251x.c | 3 ++- include/linux/can/platform/mcp251x.h | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index 7513c4523ac4..330140ee266d 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c @@ -931,7 +931,8 @@ static int mcp251x_open(struct net_device *net) priv->tx_len = 0; ret = request_threaded_irq(spi->irq, NULL, mcp251x_can_ist, - IRQF_TRIGGER_FALLING, DEVICE_NAME, priv); + pdata->irq_flags ? pdata->irq_flags : IRQF_TRIGGER_FALLING, + DEVICE_NAME, priv); if (ret) { dev_err(&spi->dev, "failed to acquire irq %d\n", spi->irq); if (pdata->transceiver_enable) diff --git a/include/linux/can/platform/mcp251x.h b/include/linux/can/platform/mcp251x.h index 8e20540043f5..089fe43211a4 100644 --- a/include/linux/can/platform/mcp251x.h +++ b/include/linux/can/platform/mcp251x.h @@ -12,6 +12,7 @@ /** * struct mcp251x_platform_data - MCP251X SPI CAN controller platform data * @oscillator_frequency: - oscillator frequency in Hz + * @irq_flags: - IRQF configuration flags * @board_specific_setup: - called before probing the chip (power,reset) * @transceiver_enable: - called to power on/off the transceiver * @power_enable: - called to power on/off the mcp *and* the @@ -24,6 +25,7 @@ struct mcp251x_platform_data { unsigned long oscillator_frequency; + unsigned long irq_flags; int (*board_specific_setup)(struct spi_device *spi); int (*transceiver_enable)(int enable); int (*power_enable) (int enable); -- cgit From 31d68ef65c7d49def19c1bae4e01b87d66cf5a56 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Thu, 24 Feb 2011 11:25:33 -0800 Subject: SUNRPC: Don't wait for full record to receive tcp data Ensure that we immediately read and buffer data from the incoming TCP stream so that we grow the receive window quickly, and don't deadlock on large READ or WRITE requests. Also do some minor exit cleanup. Signed-off-by: Trond Myklebust Signed-off-by: J. Bruce Fields --- include/linux/sunrpc/svcsock.h | 1 + net/sunrpc/svcsock.c | 144 ++++++++++++++++++++++++++++++++--------- 2 files changed, 113 insertions(+), 32 deletions(-) (limited to 'include/linux') diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h index 04dba23c59f2..85c50b40759d 100644 --- a/include/linux/sunrpc/svcsock.h +++ b/include/linux/sunrpc/svcsock.h @@ -28,6 +28,7 @@ struct svc_sock { /* private TCP part */ u32 sk_reclen; /* length of record */ u32 sk_tcplen; /* current read length */ + struct page * sk_pages[RPCSVC_MAXPAGES]; /* received data */ }; /* diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 40b502b11442..a4fafcbc6ea0 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -387,6 +387,33 @@ static int svc_recvfrom(struct svc_rqst *rqstp, struct kvec *iov, int nr, return len; } +static int svc_partial_recvfrom(struct svc_rqst *rqstp, + struct kvec *iov, int nr, + int buflen, unsigned int base) +{ + size_t save_iovlen; + void __user *save_iovbase; + unsigned int i; + int ret; + + if (base == 0) + return svc_recvfrom(rqstp, iov, nr, buflen); + + for (i = 0; i < nr; i++) { + if (iov[i].iov_len > base) + break; + base -= iov[i].iov_len; + } + save_iovlen = iov[i].iov_len; + save_iovbase = iov[i].iov_base; + iov[i].iov_len -= base; + iov[i].iov_base += base; + ret = svc_recvfrom(rqstp, &iov[i], nr - i, buflen); + iov[i].iov_len = save_iovlen; + iov[i].iov_base = save_iovbase; + return ret; +} + /* * Set socket snd and rcv buffer lengths */ @@ -884,6 +911,56 @@ failed: return NULL; } +static unsigned int svc_tcp_restore_pages(struct svc_sock *svsk, struct svc_rqst *rqstp) +{ + unsigned int i, len, npages; + + if (svsk->sk_tcplen <= sizeof(rpc_fraghdr)) + return 0; + len = svsk->sk_tcplen - sizeof(rpc_fraghdr); + npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; + for (i = 0; i < npages; i++) { + if (rqstp->rq_pages[i] != NULL) + put_page(rqstp->rq_pages[i]); + BUG_ON(svsk->sk_pages[i] == NULL); + rqstp->rq_pages[i] = svsk->sk_pages[i]; + svsk->sk_pages[i] = NULL; + } + rqstp->rq_arg.head[0].iov_base = page_address(rqstp->rq_pages[0]); + return len; +} + +static void svc_tcp_save_pages(struct svc_sock *svsk, struct svc_rqst *rqstp) +{ + unsigned int i, len, npages; + + if (svsk->sk_tcplen <= sizeof(rpc_fraghdr)) + return; + len = svsk->sk_tcplen - sizeof(rpc_fraghdr); + npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; + for (i = 0; i < npages; i++) { + svsk->sk_pages[i] = rqstp->rq_pages[i]; + rqstp->rq_pages[i] = NULL; + } +} + +static void svc_tcp_clear_pages(struct svc_sock *svsk) +{ + unsigned int i, len, npages; + + if (svsk->sk_tcplen <= sizeof(rpc_fraghdr)) + goto out; + len = svsk->sk_tcplen - sizeof(rpc_fraghdr); + npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; + for (i = 0; i < npages; i++) { + BUG_ON(svsk->sk_pages[i] == NULL); + put_page(svsk->sk_pages[i]); + svsk->sk_pages[i] = NULL; + } +out: + svsk->sk_tcplen = 0; +} + /* * Receive data. * If we haven't gotten the record length yet, get the next four bytes. @@ -928,7 +1005,7 @@ static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp) if (len < want) { dprintk("svc: short recvfrom while reading record " "length (%d of %d)\n", len, want); - goto err_again; /* record header not complete */ + return -EAGAIN; } svsk->sk_reclen = ntohl(svsk->sk_reclen); @@ -958,26 +1035,14 @@ static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp) if (svsk->sk_reclen < 8) goto err_delete; /* client is nuts. */ - /* Check whether enough data is available */ - len = svc_recv_available(svsk); - if (len < 0) - goto error; - - if (len < svsk->sk_reclen) { - dprintk("svc: incomplete TCP record (%d of %d)\n", - len, svsk->sk_reclen); - goto err_again; /* record not complete */ - } len = svsk->sk_reclen; return len; - error: - if (len == -EAGAIN) - dprintk("RPC: TCP recv_record got EAGAIN\n"); +error: + dprintk("RPC: TCP recv_record got %d\n", len); return len; - err_delete: +err_delete: set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); - err_again: return -EAGAIN; } @@ -1035,6 +1100,7 @@ static int copy_pages_to_kvecs(struct kvec *vec, struct page **pages, int len) return i; } + /* * Receive data from a TCP socket. */ @@ -1045,6 +1111,7 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp) struct svc_serv *serv = svsk->sk_xprt.xpt_server; int len; struct kvec *vec; + unsigned int want, base; __be32 *p; __be32 calldir; int pnum; @@ -1058,6 +1125,9 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp) if (len < 0) goto error; + base = svc_tcp_restore_pages(svsk, rqstp); + want = svsk->sk_reclen - base; + vec = rqstp->rq_vec; pnum = copy_pages_to_kvecs(&vec[0], &rqstp->rq_pages[0], @@ -1066,11 +1136,18 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp) rqstp->rq_respages = &rqstp->rq_pages[pnum]; /* Now receive data */ - len = svc_recvfrom(rqstp, vec, pnum, svsk->sk_reclen); - if (len < 0) - goto err_again; + len = svc_partial_recvfrom(rqstp, vec, pnum, want, base); + if (len >= 0) + svsk->sk_tcplen += len; + if (len != want) { + if (len < 0 && len != -EAGAIN) + goto err_other; + svc_tcp_save_pages(svsk, rqstp); + dprintk("svc: incomplete TCP record (%d of %d)\n", + svsk->sk_tcplen, svsk->sk_reclen); + goto err_noclose; + } - dprintk("svc: TCP complete record (%d bytes)\n", svsk->sk_reclen); rqstp->rq_arg.len = svsk->sk_reclen; rqstp->rq_arg.page_base = 0; if (rqstp->rq_arg.len <= rqstp->rq_arg.head[0].iov_len) { @@ -1087,7 +1164,7 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp) if (calldir) { len = receive_cb_reply(svsk, rqstp); if (len < 0) - goto err_again; + goto error; } /* Reset TCP read info */ @@ -1102,20 +1179,20 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp) if (serv->sv_stats) serv->sv_stats->nettcpcnt++; + dprintk("svc: TCP complete record (%d bytes)\n", rqstp->rq_arg.len); return rqstp->rq_arg.len; -err_again: - if (len == -EAGAIN) { - dprintk("RPC: TCP recvfrom got EAGAIN\n"); - return len; - } error: - if (len != -EAGAIN) { - printk(KERN_NOTICE "%s: recvfrom returned errno %d\n", - svsk->sk_xprt.xpt_server->sv_name, -len); - set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); - } + if (len != -EAGAIN) + goto err_other; + dprintk("RPC: TCP recvfrom got EAGAIN\n"); return -EAGAIN; +err_other: + printk(KERN_NOTICE "%s: recvfrom returned errno %d\n", + svsk->sk_xprt.xpt_server->sv_name, -len); + set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); +err_noclose: + return -EAGAIN; /* record not complete */ } /* @@ -1286,6 +1363,7 @@ static void svc_tcp_init(struct svc_sock *svsk, struct svc_serv *serv) svsk->sk_reclen = 0; svsk->sk_tcplen = 0; + memset(&svsk->sk_pages[0], 0, sizeof(svsk->sk_pages)); tcp_sk(sk)->nonagle |= TCP_NAGLE_OFF; @@ -1544,8 +1622,10 @@ static void svc_tcp_sock_detach(struct svc_xprt *xprt) svc_sock_detach(xprt); - if (!test_bit(XPT_LISTENER, &xprt->xpt_flags)) + if (!test_bit(XPT_LISTENER, &xprt->xpt_flags)) { + svc_tcp_clear_pages(svsk); kernel_sock_shutdown(svsk->sk_sock, SHUT_RDWR); + } } /* -- cgit From f4263c9857e6411ef2388868cc6c79a1602a654e Mon Sep 17 00:00:00 2001 From: Paul Stewart Date: Thu, 31 Mar 2011 09:25:41 -0700 Subject: nl80211: Add BSS parameters to station This allows user-space monitoring of BSS parameters for the associated station. This is useful for debugging and verifying that the paramaters are as expected. [Exactly the same as before but bundled into a single message] Signed-off-by: Paul Stewart Cc: Johannes Berg Signed-off-by: John W. Linville --- include/linux/nl80211.h | 35 ++++++++++++++++++++++++++++++++++- include/net/cfg80211.h | 34 ++++++++++++++++++++++++++++++++++ net/mac80211/cfg.c | 13 ++++++++++++- net/wireless/nl80211.c | 21 ++++++++++++++++++++- 4 files changed, 100 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 30022189104d..16eea7229e99 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -1221,6 +1221,36 @@ enum nl80211_rate_info { NL80211_RATE_INFO_MAX = __NL80211_RATE_INFO_AFTER_LAST - 1 }; +/** + * enum nl80211_sta_bss_param - BSS information collected by STA + * + * These attribute types are used with %NL80211_STA_INFO_BSS_PARAM + * when getting information about the bitrate of a station. + * + * @__NL80211_STA_BSS_PARAM_INVALID: attribute number 0 is reserved + * @NL80211_STA_BSS_PARAM_CTS_PROT: whether CTS protection is enabled (flag) + * @NL80211_STA_BSS_PARAM_SHORT_PREAMBLE: whether short preamble is enabled + * (flag) + * @NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME: whether short slot time is enabled + * (flag) + * @NL80211_STA_BSS_PARAM_DTIM_PERIOD: DTIM period for beaconing (u8) + * @NL80211_STA_BSS_PARAM_BEACON_INTERVAL: Beacon interval (u16) + * @NL80211_STA_BSS_PARAM_MAX: highest sta_bss_param number currently defined + * @__NL80211_STA_BSS_PARAM_AFTER_LAST: internal use + */ +enum nl80211_sta_bss_param { + __NL80211_STA_BSS_PARAM_INVALID, + NL80211_STA_BSS_PARAM_CTS_PROT, + NL80211_STA_BSS_PARAM_SHORT_PREAMBLE, + NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME, + NL80211_STA_BSS_PARAM_DTIM_PERIOD, + NL80211_STA_BSS_PARAM_BEACON_INTERVAL, + + /* keep last */ + __NL80211_STA_BSS_PARAM_AFTER_LAST, + NL80211_STA_BSS_PARAM_MAX = __NL80211_STA_BSS_PARAM_AFTER_LAST - 1 +}; + /** * enum nl80211_sta_info - station information * @@ -1233,7 +1263,7 @@ enum nl80211_rate_info { * @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station) * @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm) * @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute - * containing info as possible, see &enum nl80211_sta_info_txrate. + * containing info as possible, see &enum nl80211_rate_info * @NL80211_STA_INFO_RX_PACKETS: total received packet (u32, from this station) * @NL80211_STA_INFO_TX_PACKETS: total transmitted packets (u32, to this * station) @@ -1245,6 +1275,8 @@ enum nl80211_rate_info { * @NL80211_STA_INFO_PLINK_STATE: peer link state for the station * @NL80211_STA_INFO_RX_BITRATE: last unicast data frame rx rate, nested * attribute, like NL80211_STA_INFO_TX_BITRATE. + * @NL80211_STA_INFO_BSS_PARAM: current station's view of BSS, nested attribute + * containing info as possible, see &enum nl80211_sta_bss_param * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute */ @@ -1264,6 +1296,7 @@ enum nl80211_sta_info { NL80211_STA_INFO_TX_FAILED, NL80211_STA_INFO_SIGNAL_AVG, NL80211_STA_INFO_RX_BITRATE, + NL80211_STA_INFO_BSS_PARAM, /* keep last */ __NL80211_STA_INFO_AFTER_LAST, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 2c4530451721..ba7384acf4e0 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -422,6 +422,7 @@ struct station_parameters { * @STATION_INFO_RX_DROP_MISC: @rx_dropped_misc filled * @STATION_INFO_SIGNAL_AVG: @signal_avg filled * @STATION_INFO_RX_BITRATE: @rxrate fields are filled + * @STATION_INFO_BSS_PARAM: @bss_param filled */ enum station_info_flags { STATION_INFO_INACTIVE_TIME = 1<<0, @@ -439,6 +440,7 @@ enum station_info_flags { STATION_INFO_RX_DROP_MISC = 1<<12, STATION_INFO_SIGNAL_AVG = 1<<13, STATION_INFO_RX_BITRATE = 1<<14, + STATION_INFO_BSS_PARAM = 1<<15, }; /** @@ -472,6 +474,37 @@ struct rate_info { u16 legacy; }; +/** + * enum station_info_rate_flags - bitrate info flags + * + * Used by the driver to indicate the specific rate transmission + * type for 802.11n transmissions. + * + * @BSS_PARAM_FLAGS_CTS_PROT: whether CTS protection is enabled + * @BSS_PARAM_FLAGS_SHORT_PREAMBLE: whether short preamble is enabled + * @BSS_PARAM_FLAGS_SHORT_SLOT_TIME: whether short slot time is enabled + */ +enum bss_param_flags { + BSS_PARAM_FLAGS_CTS_PROT = 1<<0, + BSS_PARAM_FLAGS_SHORT_PREAMBLE = 1<<1, + BSS_PARAM_FLAGS_SHORT_SLOT_TIME = 1<<2, +}; + +/** + * struct sta_bss_parameters - BSS parameters for the attached station + * + * Information about the currently associated BSS + * + * @flags: bitflag of flags from &enum bss_param_flags + * @dtim_period: DTIM period for the BSS + * @beacon_interval: beacon interval + */ +struct sta_bss_parameters { + u8 flags; + u8 dtim_period; + u16 beacon_interval; +}; + /** * struct station_info - station information * @@ -515,6 +548,7 @@ struct station_info { u32 tx_retries; u32 tx_failed; u32 rx_dropped_misc; + struct sta_bss_parameters bss_param; int generation; }; diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 334213571ad0..bf5d28da46e6 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -342,7 +342,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) STATION_INFO_TX_FAILED | STATION_INFO_TX_BITRATE | STATION_INFO_RX_BITRATE | - STATION_INFO_RX_DROP_MISC; + STATION_INFO_RX_DROP_MISC | + STATION_INFO_BSS_PARAM; sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); sinfo->rx_bytes = sta->rx_bytes; @@ -389,6 +390,16 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) sinfo->plink_state = sta->plink_state; #endif } + + sinfo->bss_param.flags = 0; + if (sdata->vif.bss_conf.use_cts_prot) + sinfo->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT; + if (sdata->vif.bss_conf.use_short_preamble) + sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE; + if (sdata->vif.bss_conf.use_short_slot) + sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME; + sinfo->bss_param.dtim_period = sdata->local->hw.conf.ps_dtim_period; + sinfo->bss_param.beacon_interval = sdata->vif.bss_conf.beacon_int; } diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 40c90fb461c4..297d7ce4117b 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -2002,7 +2002,7 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, const u8 *mac_addr, struct station_info *sinfo) { void *hdr; - struct nlattr *sinfoattr; + struct nlattr *sinfoattr, *bss_param; hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION); if (!hdr) @@ -2062,6 +2062,25 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, if (sinfo->filled & STATION_INFO_TX_FAILED) NLA_PUT_U32(msg, NL80211_STA_INFO_TX_FAILED, sinfo->tx_failed); + if (sinfo->filled & STATION_INFO_BSS_PARAM) { + bss_param = nla_nest_start(msg, NL80211_STA_INFO_BSS_PARAM); + if (!bss_param) + goto nla_put_failure; + + if (sinfo->bss_param.flags & BSS_PARAM_FLAGS_CTS_PROT) + NLA_PUT_FLAG(msg, NL80211_STA_BSS_PARAM_CTS_PROT); + if (sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_PREAMBLE) + NLA_PUT_FLAG(msg, NL80211_STA_BSS_PARAM_SHORT_PREAMBLE); + if (sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_SLOT_TIME) + NLA_PUT_FLAG(msg, + NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME); + NLA_PUT_U8(msg, NL80211_STA_BSS_PARAM_DTIM_PERIOD, + sinfo->bss_param.dtim_period); + NLA_PUT_U16(msg, NL80211_STA_BSS_PARAM_BEACON_INTERVAL, + sinfo->bss_param.beacon_interval); + + nla_nest_end(msg, bss_param); + } nla_nest_end(msg, sinfoattr); return genlmsg_end(msg, hdr); -- cgit From 0e028465d18b7c6797fcbdea632299d16097c5cd Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Sun, 6 Mar 2011 18:02:54 +0100 Subject: exec: unify do_execve/compat_do_execve code Add the appropriate members into struct user_arg_ptr and teach get_user_arg_ptr() to handle is_compat = T case correctly. This allows us to remove the compat_do_execve() code from fs/compat.c and reimplement compat_do_execve() as the trivial wrapper on top of do_execve_common(is_compat => true). In fact, this fixes another (minor) bug. "compat_uptr_t str" can overflow after "str += len" in compat_copy_strings() if a 64bit application execs via sys32_execve(). Unexport acct_arg_size() and get_arg_page(), fs/compat.c doesn't need them any longer. Signed-off-by: Oleg Nesterov Reviewed-by: KOSAKI Motohiro Tested-by: KOSAKI Motohiro --- fs/compat.c | 235 ------------------------------------------------ fs/exec.c | 62 ++++++++++--- include/linux/binfmts.h | 4 - 3 files changed, 50 insertions(+), 251 deletions(-) (limited to 'include/linux') diff --git a/fs/compat.c b/fs/compat.c index 72fe6cda9108..0ea00832de23 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -1306,241 +1306,6 @@ compat_sys_openat(unsigned int dfd, const char __user *filename, int flags, int return do_sys_open(dfd, filename, flags, mode); } -/* - * compat_count() counts the number of arguments/envelopes. It is basically - * a copy of count() from fs/exec.c, except that it works with 32 bit argv - * and envp pointers. - */ -static int compat_count(compat_uptr_t __user *argv, int max) -{ - int i = 0; - - if (argv != NULL) { - for (;;) { - compat_uptr_t p; - - if (get_user(p, argv)) - return -EFAULT; - if (!p) - break; - argv++; - if (i++ >= max) - return -E2BIG; - - if (fatal_signal_pending(current)) - return -ERESTARTNOHAND; - cond_resched(); - } - } - return i; -} - -/* - * compat_copy_strings() is basically a copy of copy_strings() from fs/exec.c - * except that it works with 32 bit argv and envp pointers. - */ -static int compat_copy_strings(int argc, compat_uptr_t __user *argv, - struct linux_binprm *bprm) -{ - struct page *kmapped_page = NULL; - char *kaddr = NULL; - unsigned long kpos = 0; - int ret; - - while (argc-- > 0) { - compat_uptr_t str; - int len; - unsigned long pos; - - if (get_user(str, argv+argc) || - !(len = strnlen_user(compat_ptr(str), MAX_ARG_STRLEN))) { - ret = -EFAULT; - goto out; - } - - if (len > MAX_ARG_STRLEN) { - ret = -E2BIG; - goto out; - } - - /* We're going to work our way backwords. */ - pos = bprm->p; - str += len; - bprm->p -= len; - - while (len > 0) { - int offset, bytes_to_copy; - - if (fatal_signal_pending(current)) { - ret = -ERESTARTNOHAND; - goto out; - } - cond_resched(); - - offset = pos % PAGE_SIZE; - if (offset == 0) - offset = PAGE_SIZE; - - bytes_to_copy = offset; - if (bytes_to_copy > len) - bytes_to_copy = len; - - offset -= bytes_to_copy; - pos -= bytes_to_copy; - str -= bytes_to_copy; - len -= bytes_to_copy; - - if (!kmapped_page || kpos != (pos & PAGE_MASK)) { - struct page *page; - - page = get_arg_page(bprm, pos, 1); - if (!page) { - ret = -E2BIG; - goto out; - } - - if (kmapped_page) { - flush_kernel_dcache_page(kmapped_page); - kunmap(kmapped_page); - put_page(kmapped_page); - } - kmapped_page = page; - kaddr = kmap(kmapped_page); - kpos = pos & PAGE_MASK; - flush_cache_page(bprm->vma, kpos, - page_to_pfn(kmapped_page)); - } - if (copy_from_user(kaddr+offset, compat_ptr(str), - bytes_to_copy)) { - ret = -EFAULT; - goto out; - } - } - } - ret = 0; -out: - if (kmapped_page) { - flush_kernel_dcache_page(kmapped_page); - kunmap(kmapped_page); - put_page(kmapped_page); - } - return ret; -} - -/* - * compat_do_execve() is mostly a copy of do_execve(), with the exception - * that it processes 32 bit argv and envp pointers. - */ -int compat_do_execve(char * filename, - compat_uptr_t __user *argv, - compat_uptr_t __user *envp, - struct pt_regs * regs) -{ - struct linux_binprm *bprm; - struct file *file; - struct files_struct *displaced; - bool clear_in_exec; - int retval; - - retval = unshare_files(&displaced); - if (retval) - goto out_ret; - - retval = -ENOMEM; - bprm = kzalloc(sizeof(*bprm), GFP_KERNEL); - if (!bprm) - goto out_files; - - retval = prepare_bprm_creds(bprm); - if (retval) - goto out_free; - - retval = check_unsafe_exec(bprm); - if (retval < 0) - goto out_free; - clear_in_exec = retval; - current->in_execve = 1; - - file = open_exec(filename); - retval = PTR_ERR(file); - if (IS_ERR(file)) - goto out_unmark; - - sched_exec(); - - bprm->file = file; - bprm->filename = filename; - bprm->interp = filename; - - retval = bprm_mm_init(bprm); - if (retval) - goto out_file; - - bprm->argc = compat_count(argv, MAX_ARG_STRINGS); - if ((retval = bprm->argc) < 0) - goto out; - - bprm->envc = compat_count(envp, MAX_ARG_STRINGS); - if ((retval = bprm->envc) < 0) - goto out; - - retval = prepare_binprm(bprm); - if (retval < 0) - goto out; - - retval = copy_strings_kernel(1, &bprm->filename, bprm); - if (retval < 0) - goto out; - - bprm->exec = bprm->p; - retval = compat_copy_strings(bprm->envc, envp, bprm); - if (retval < 0) - goto out; - - retval = compat_copy_strings(bprm->argc, argv, bprm); - if (retval < 0) - goto out; - - retval = search_binary_handler(bprm, regs); - if (retval < 0) - goto out; - - /* execve succeeded */ - current->fs->in_exec = 0; - current->in_execve = 0; - acct_update_integrals(current); - free_bprm(bprm); - if (displaced) - put_files_struct(displaced); - return retval; - -out: - if (bprm->mm) { - acct_arg_size(bprm, 0); - mmput(bprm->mm); - } - -out_file: - if (bprm->file) { - allow_write_access(bprm->file); - fput(bprm->file); - } - -out_unmark: - if (clear_in_exec) - current->fs->in_exec = 0; - current->in_execve = 0; - -out_free: - free_bprm(bprm); - -out_files: - if (displaced) - reset_files_struct(displaced); -out_ret: - return retval; -} - #define __COMPAT_NFDBITS (8 * sizeof(compat_ulong_t)) static int poll_select_copy_remaining(struct timespec *end_time, void __user *p, diff --git a/fs/exec.c b/fs/exec.c index 526a0399d963..89d788ca7829 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -55,6 +55,7 @@ #include #include #include +#include #include #include @@ -167,7 +168,7 @@ out: #ifdef CONFIG_MMU -void acct_arg_size(struct linux_binprm *bprm, unsigned long pages) +static void acct_arg_size(struct linux_binprm *bprm, unsigned long pages) { struct mm_struct *mm = current->mm; long diff = (long)(pages - bprm->vma_pages); @@ -186,7 +187,7 @@ void acct_arg_size(struct linux_binprm *bprm, unsigned long pages) #endif } -struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, +static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, int write) { struct page *page; @@ -305,11 +306,11 @@ static bool valid_arg_len(struct linux_binprm *bprm, long len) #else -void acct_arg_size(struct linux_binprm *bprm, unsigned long pages) +static inline void acct_arg_size(struct linux_binprm *bprm, unsigned long pages) { } -struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, +static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, int write) { struct page *page; @@ -399,17 +400,36 @@ err: } struct user_arg_ptr { - const char __user *const __user *native; +#ifdef CONFIG_COMPAT + bool is_compat; +#endif + union { + const char __user *const __user *native; +#ifdef CONFIG_COMPAT + compat_uptr_t __user *compat; +#endif + } ptr; }; static const char __user *get_user_arg_ptr(struct user_arg_ptr argv, int nr) { - const char __user *ptr; + const char __user *native; + +#ifdef CONFIG_COMPAT + if (unlikely(argv.is_compat)) { + compat_uptr_t compat; + + if (get_user(compat, argv.ptr.compat + nr)) + return ERR_PTR(-EFAULT); - if (get_user(ptr, argv.native + nr)) + return compat_ptr(compat); + } +#endif + + if (get_user(native, argv.ptr.native + nr)) return ERR_PTR(-EFAULT); - return ptr; + return native; } /* @@ -419,7 +439,7 @@ static int count(struct user_arg_ptr argv, int max) { int i = 0; - if (argv.native != NULL) { + if (argv.ptr.native != NULL) { for (;;) { const char __user *p = get_user_arg_ptr(argv, i); @@ -542,7 +562,7 @@ int copy_strings_kernel(int argc, const char *const *__argv, int r; mm_segment_t oldfs = get_fs(); struct user_arg_ptr argv = { - .native = (const char __user *const __user *)__argv, + .ptr.native = (const char __user *const __user *)__argv, }; set_fs(KERNEL_DS); @@ -1516,10 +1536,28 @@ int do_execve(const char *filename, const char __user *const __user *__envp, struct pt_regs *regs) { - struct user_arg_ptr argv = { .native = __argv }; - struct user_arg_ptr envp = { .native = __envp }; + struct user_arg_ptr argv = { .ptr.native = __argv }; + struct user_arg_ptr envp = { .ptr.native = __envp }; + return do_execve_common(filename, argv, envp, regs); +} + +#ifdef CONFIG_COMPAT +int compat_do_execve(char *filename, + compat_uptr_t __user *__argv, + compat_uptr_t __user *__envp, + struct pt_regs *regs) +{ + struct user_arg_ptr argv = { + .is_compat = true, + .ptr.compat = __argv, + }; + struct user_arg_ptr envp = { + .is_compat = true, + .ptr.compat = __envp, + }; return do_execve_common(filename, argv, envp, regs); } +#endif void set_binfmt(struct linux_binfmt *new) { diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h index c3d6512eded1..8845613fd7e3 100644 --- a/include/linux/binfmts.h +++ b/include/linux/binfmts.h @@ -60,10 +60,6 @@ struct linux_binprm { unsigned long loader, exec; }; -extern void acct_arg_size(struct linux_binprm *bprm, unsigned long pages); -extern struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, - int write); - #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0 #define BINPRM_FLAGS_ENFORCE_NONDUMP (1 << BINPRM_FLAGS_ENFORCE_NONDUMP_BIT) -- cgit From 5cdede2408e80f190c5595e592c24e77c1bf44b2 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Mon, 4 Apr 2011 15:55:18 +0200 Subject: PCI: Move ATS declarations in seperate header file This patch moves the relevant declarations from the local header file in drivers/pci to a more accessible locations so that it can be used by the AMD IOMMU driver too. The file is named pci-ats.h because support for the PCI PRI capability will also be added there in a later patch-set. Signed-off-by: Joerg Roedel Acked-by: Jesse Barnes --- drivers/pci/intel-iommu.c | 1 + drivers/pci/iov.c | 1 + drivers/pci/pci.h | 37 --------------------------------- include/linux/pci-ats.h | 52 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 37 deletions(-) create mode 100644 include/linux/pci-ats.h (limited to 'include/linux') diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 7da3bef60d87..fdb2cef2b908 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include "pci.h" diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index 553d8ee55c1c..42fae4776515 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "pci.h" #define VIRTFN_ID_LEN 16 diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index a6ec200fe5ee..4020025f854e 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -250,15 +250,6 @@ struct pci_sriov { u8 __iomem *mstate; /* VF Migration State Array */ }; -/* Address Translation Service */ -struct pci_ats { - int pos; /* capability position */ - int stu; /* Smallest Translation Unit */ - int qdep; /* Invalidate Queue Depth */ - int ref_cnt; /* Physical Function reference count */ - unsigned int is_enabled:1; /* Enable bit is set */ -}; - #ifdef CONFIG_PCI_IOV extern int pci_iov_init(struct pci_dev *dev); extern void pci_iov_release(struct pci_dev *dev); @@ -269,19 +260,6 @@ extern resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, extern void pci_restore_iov_state(struct pci_dev *dev); extern int pci_iov_bus_range(struct pci_bus *bus); -extern int pci_enable_ats(struct pci_dev *dev, int ps); -extern void pci_disable_ats(struct pci_dev *dev); -extern int pci_ats_queue_depth(struct pci_dev *dev); -/** - * pci_ats_enabled - query the ATS status - * @dev: the PCI device - * - * Returns 1 if ATS capability is enabled, or 0 if not. - */ -static inline int pci_ats_enabled(struct pci_dev *dev) -{ - return dev->ats && dev->ats->is_enabled; -} #else static inline int pci_iov_init(struct pci_dev *dev) { @@ -304,21 +282,6 @@ static inline int pci_iov_bus_range(struct pci_bus *bus) return 0; } -static inline int pci_enable_ats(struct pci_dev *dev, int ps) -{ - return -ENODEV; -} -static inline void pci_disable_ats(struct pci_dev *dev) -{ -} -static inline int pci_ats_queue_depth(struct pci_dev *dev) -{ - return -ENODEV; -} -static inline int pci_ats_enabled(struct pci_dev *dev) -{ - return 0; -} #endif /* CONFIG_PCI_IOV */ static inline resource_size_t pci_resource_alignment(struct pci_dev *dev, diff --git a/include/linux/pci-ats.h b/include/linux/pci-ats.h new file mode 100644 index 000000000000..655824fa4c76 --- /dev/null +++ b/include/linux/pci-ats.h @@ -0,0 +1,52 @@ +#ifndef LINUX_PCI_ATS_H +#define LINUX_PCI_ATS_H + +/* Address Translation Service */ +struct pci_ats { + int pos; /* capability position */ + int stu; /* Smallest Translation Unit */ + int qdep; /* Invalidate Queue Depth */ + int ref_cnt; /* Physical Function reference count */ + unsigned int is_enabled:1; /* Enable bit is set */ +}; + +#ifdef CONFIG_PCI_IOV + +extern int pci_enable_ats(struct pci_dev *dev, int ps); +extern void pci_disable_ats(struct pci_dev *dev); +extern int pci_ats_queue_depth(struct pci_dev *dev); +/** + * pci_ats_enabled - query the ATS status + * @dev: the PCI device + * + * Returns 1 if ATS capability is enabled, or 0 if not. + */ +static inline int pci_ats_enabled(struct pci_dev *dev) +{ + return dev->ats && dev->ats->is_enabled; +} + +#else /* CONFIG_PCI_IOV */ + +static inline int pci_enable_ats(struct pci_dev *dev, int ps) +{ + return -ENODEV; +} + +static inline void pci_disable_ats(struct pci_dev *dev) +{ +} + +static inline int pci_ats_queue_depth(struct pci_dev *dev) +{ + return -ENODEV; +} + +static inline int pci_ats_enabled(struct pci_dev *dev) +{ + return 0; +} + +#endif /* CONFIG_PCI_IOV */ + +#endif /* LINUX_PCI_ATS_H*/ -- cgit From dce840a08702bd13a9a186e07e63d1ef82256b5e Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 7 Apr 2011 14:09:50 +0200 Subject: sched: Dynamically allocate sched_domain/sched_group data-structures Instead of relying on static allocations for the sched_domain and sched_group trees, dynamically allocate and RCU free them. Allocating this dynamically also allows for some build_sched_groups() simplification since we can now (like with other simplifications) rely on the sched_domain tree instead of hard-coded knowledge. One tricky to note is that detach_destroy_domains() needs to hold rcu_read_lock() over the entire tear-down, per-cpu is not sufficient since that can lead to partial sched_group existance (could possibly be solved by doing the tear-down backwards but this is much more robust). A concequence of the above is that we can no longer print the sched_domain debug stuff from cpu_attach_domain() since that might now run with preemption disabled (due to classic RCU etc.) and sched_domain_debug() does some GFP_KERNEL allocations. Another thing to note is that we now fully rely on normal RCU and not RCU-sched, this is because with the new and exiting RCU flavours we grew over the years BH doesn't necessarily hold off RCU-sched grace periods (-rt is known to break this). This would in fact already cause us grief since we do sched_domain/sched_group iterations from softirq context. This patch is somewhat larger than I would like it to be, but I didn't find any means of shrinking/splitting this. Signed-off-by: Peter Zijlstra Cc: Mike Galbraith Cc: Nick Piggin Cc: Linus Torvalds Cc: Andrew Morton Link: http://lkml.kernel.org/r/20110407122942.245307941@chello.nl Signed-off-by: Ingo Molnar --- include/linux/sched.h | 5 + kernel/sched.c | 479 ++++++++++++++++++++------------------------------ kernel/sched_fair.c | 30 +++- 3 files changed, 218 insertions(+), 296 deletions(-) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index 4ec2c027e92c..020b79d6c486 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -868,6 +868,7 @@ static inline int sd_power_saving_flags(void) struct sched_group { struct sched_group *next; /* Must be a circular list */ + atomic_t ref; /* * CPU power of this group, SCHED_LOAD_SCALE being max power for a @@ -973,6 +974,10 @@ struct sched_domain { #ifdef CONFIG_SCHED_DEBUG char *name; #endif + union { + void *private; /* used during construction */ + struct rcu_head rcu; /* used during destruction */ + }; unsigned int span_weight; /* diff --git a/kernel/sched.c b/kernel/sched.c index 1cca59ec4a49..65204845063e 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -417,6 +417,7 @@ struct rt_rq { */ struct root_domain { atomic_t refcount; + struct rcu_head rcu; cpumask_var_t span; cpumask_var_t online; @@ -571,7 +572,7 @@ static inline int cpu_of(struct rq *rq) #define rcu_dereference_check_sched_domain(p) \ rcu_dereference_check((p), \ - rcu_read_lock_sched_held() || \ + rcu_read_lock_held() || \ lockdep_is_held(&sched_domains_mutex)) /* @@ -6572,12 +6573,11 @@ sd_parent_degenerate(struct sched_domain *sd, struct sched_domain *parent) return 1; } -static void free_rootdomain(struct root_domain *rd) +static void free_rootdomain(struct rcu_head *rcu) { - synchronize_sched(); + struct root_domain *rd = container_of(rcu, struct root_domain, rcu); cpupri_cleanup(&rd->cpupri); - free_cpumask_var(rd->rto_mask); free_cpumask_var(rd->online); free_cpumask_var(rd->span); @@ -6618,7 +6618,7 @@ static void rq_attach_root(struct rq *rq, struct root_domain *rd) raw_spin_unlock_irqrestore(&rq->lock, flags); if (old_rd) - free_rootdomain(old_rd); + call_rcu_sched(&old_rd->rcu, free_rootdomain); } static int init_rootdomain(struct root_domain *rd) @@ -6669,6 +6669,25 @@ static struct root_domain *alloc_rootdomain(void) return rd; } +static void free_sched_domain(struct rcu_head *rcu) +{ + struct sched_domain *sd = container_of(rcu, struct sched_domain, rcu); + if (atomic_dec_and_test(&sd->groups->ref)) + kfree(sd->groups); + kfree(sd); +} + +static void destroy_sched_domain(struct sched_domain *sd, int cpu) +{ + call_rcu(&sd->rcu, free_sched_domain); +} + +static void destroy_sched_domains(struct sched_domain *sd, int cpu) +{ + for (; sd; sd = sd->parent) + destroy_sched_domain(sd, cpu); +} + /* * Attach the domain 'sd' to 'cpu' as its base domain. Callers must * hold the hotplug lock. @@ -6689,20 +6708,25 @@ cpu_attach_domain(struct sched_domain *sd, struct root_domain *rd, int cpu) tmp->parent = parent->parent; if (parent->parent) parent->parent->child = tmp; + destroy_sched_domain(parent, cpu); } else tmp = tmp->parent; } if (sd && sd_degenerate(sd)) { + tmp = sd; sd = sd->parent; + destroy_sched_domain(tmp, cpu); if (sd) sd->child = NULL; } - sched_domain_debug(sd, cpu); + /* sched_domain_debug(sd, cpu); */ rq_attach_root(rq, rd); + tmp = rq->sd; rcu_assign_pointer(rq->sd, sd); + destroy_sched_domains(tmp, cpu); } /* cpus with isolated domains */ @@ -6718,56 +6742,6 @@ static int __init isolated_cpu_setup(char *str) __setup("isolcpus=", isolated_cpu_setup); -/* - * init_sched_build_groups takes the cpumask we wish to span, and a pointer - * to a function which identifies what group(along with sched group) a CPU - * belongs to. The return value of group_fn must be a >= 0 and < nr_cpu_ids - * (due to the fact that we keep track of groups covered with a struct cpumask). - * - * init_sched_build_groups will build a circular linked list of the groups - * covered by the given span, and will set each group's ->cpumask correctly, - * and ->cpu_power to 0. - */ -static void -init_sched_build_groups(const struct cpumask *span, - const struct cpumask *cpu_map, - int (*group_fn)(int cpu, const struct cpumask *cpu_map, - struct sched_group **sg, - struct cpumask *tmpmask), - struct cpumask *covered, struct cpumask *tmpmask) -{ - struct sched_group *first = NULL, *last = NULL; - int i; - - cpumask_clear(covered); - - for_each_cpu(i, span) { - struct sched_group *sg; - int group = group_fn(i, cpu_map, &sg, tmpmask); - int j; - - if (cpumask_test_cpu(i, covered)) - continue; - - cpumask_clear(sched_group_cpus(sg)); - sg->cpu_power = 0; - - for_each_cpu(j, span) { - if (group_fn(j, cpu_map, NULL, tmpmask) != group) - continue; - - cpumask_set_cpu(j, covered); - cpumask_set_cpu(j, sched_group_cpus(sg)); - } - if (!first) - first = sg; - if (last) - last->next = sg; - last = sg; - } - last->next = first; -} - #define SD_NODES_PER_DOMAIN 16 #ifdef CONFIG_NUMA @@ -6858,154 +6832,96 @@ struct static_sched_domain { DECLARE_BITMAP(span, CONFIG_NR_CPUS); }; +struct sd_data { + struct sched_domain **__percpu sd; + struct sched_group **__percpu sg; +}; + struct s_data { #ifdef CONFIG_NUMA int sd_allnodes; #endif cpumask_var_t nodemask; cpumask_var_t send_covered; - cpumask_var_t tmpmask; struct sched_domain ** __percpu sd; + struct sd_data sdd[SD_LV_MAX]; struct root_domain *rd; }; enum s_alloc { sa_rootdomain, sa_sd, - sa_tmpmask, + sa_sd_storage, sa_send_covered, sa_nodemask, sa_none, }; /* - * SMT sched-domains: + * Assumes the sched_domain tree is fully constructed */ -#ifdef CONFIG_SCHED_SMT -static DEFINE_PER_CPU(struct static_sched_domain, cpu_domains); -static DEFINE_PER_CPU(struct static_sched_group, sched_groups); - -static int -cpu_to_cpu_group(int cpu, const struct cpumask *cpu_map, - struct sched_group **sg, struct cpumask *unused) +static int get_group(int cpu, struct sd_data *sdd, struct sched_group **sg) { - if (sg) - *sg = &per_cpu(sched_groups, cpu).sg; - return cpu; -} -#endif /* CONFIG_SCHED_SMT */ + struct sched_domain *sd = *per_cpu_ptr(sdd->sd, cpu); + struct sched_domain *child = sd->child; -/* - * multi-core sched-domains: - */ -#ifdef CONFIG_SCHED_MC -static DEFINE_PER_CPU(struct static_sched_domain, core_domains); -static DEFINE_PER_CPU(struct static_sched_group, sched_group_core); + if (child) + cpu = cpumask_first(sched_domain_span(child)); -static int -cpu_to_core_group(int cpu, const struct cpumask *cpu_map, - struct sched_group **sg, struct cpumask *mask) -{ - int group; -#ifdef CONFIG_SCHED_SMT - cpumask_and(mask, topology_thread_cpumask(cpu), cpu_map); - group = cpumask_first(mask); -#else - group = cpu; -#endif if (sg) - *sg = &per_cpu(sched_group_core, group).sg; - return group; + *sg = *per_cpu_ptr(sdd->sg, cpu); + + return cpu; } -#endif /* CONFIG_SCHED_MC */ /* - * book sched-domains: + * build_sched_groups takes the cpumask we wish to span, and a pointer + * to a function which identifies what group(along with sched group) a CPU + * belongs to. The return value of group_fn must be a >= 0 and < nr_cpu_ids + * (due to the fact that we keep track of groups covered with a struct cpumask). + * + * build_sched_groups will build a circular linked list of the groups + * covered by the given span, and will set each group's ->cpumask correctly, + * and ->cpu_power to 0. */ -#ifdef CONFIG_SCHED_BOOK -static DEFINE_PER_CPU(struct static_sched_domain, book_domains); -static DEFINE_PER_CPU(struct static_sched_group, sched_group_book); - -static int -cpu_to_book_group(int cpu, const struct cpumask *cpu_map, - struct sched_group **sg, struct cpumask *mask) -{ - int group = cpu; -#ifdef CONFIG_SCHED_MC - cpumask_and(mask, cpu_coregroup_mask(cpu), cpu_map); - group = cpumask_first(mask); -#elif defined(CONFIG_SCHED_SMT) - cpumask_and(mask, topology_thread_cpumask(cpu), cpu_map); - group = cpumask_first(mask); -#endif - if (sg) - *sg = &per_cpu(sched_group_book, group).sg; - return group; -} -#endif /* CONFIG_SCHED_BOOK */ - -static DEFINE_PER_CPU(struct static_sched_domain, phys_domains); -static DEFINE_PER_CPU(struct static_sched_group, sched_group_phys); - -static int -cpu_to_phys_group(int cpu, const struct cpumask *cpu_map, - struct sched_group **sg, struct cpumask *mask) +static void +build_sched_groups(struct sched_domain *sd, struct cpumask *covered) { - int group; -#ifdef CONFIG_SCHED_BOOK - cpumask_and(mask, cpu_book_mask(cpu), cpu_map); - group = cpumask_first(mask); -#elif defined(CONFIG_SCHED_MC) - cpumask_and(mask, cpu_coregroup_mask(cpu), cpu_map); - group = cpumask_first(mask); -#elif defined(CONFIG_SCHED_SMT) - cpumask_and(mask, topology_thread_cpumask(cpu), cpu_map); - group = cpumask_first(mask); -#else - group = cpu; -#endif - if (sg) - *sg = &per_cpu(sched_group_phys, group).sg; - return group; -} - -#ifdef CONFIG_NUMA -static DEFINE_PER_CPU(struct static_sched_domain, node_domains); -static DEFINE_PER_CPU(struct static_sched_group, sched_group_node); + struct sched_group *first = NULL, *last = NULL; + struct sd_data *sdd = sd->private; + const struct cpumask *span = sched_domain_span(sd); + int i; -static int cpu_to_node_group(int cpu, const struct cpumask *cpu_map, - struct sched_group **sg, - struct cpumask *nodemask) -{ - int group; + cpumask_clear(covered); - cpumask_and(nodemask, cpumask_of_node(cpu_to_node(cpu)), cpu_map); - group = cpumask_first(nodemask); + for_each_cpu(i, span) { + struct sched_group *sg; + int group = get_group(i, sdd, &sg); + int j; - if (sg) - *sg = &per_cpu(sched_group_node, group).sg; - return group; -} + if (cpumask_test_cpu(i, covered)) + continue; -static DEFINE_PER_CPU(struct static_sched_domain, allnodes_domains); -static DEFINE_PER_CPU(struct static_sched_group, sched_group_allnodes); + cpumask_clear(sched_group_cpus(sg)); + sg->cpu_power = 0; -static int cpu_to_allnodes_group(int cpu, const struct cpumask *cpu_map, - struct sched_group **sg, - struct cpumask *nodemask) -{ - int group; + for_each_cpu(j, span) { + if (get_group(j, sdd, NULL) != group) + continue; - cpumask_and(nodemask, cpumask_of_node(cpu_to_node(cpu)), cpu_map); - group = cpumask_first(nodemask); + cpumask_set_cpu(j, covered); + cpumask_set_cpu(j, sched_group_cpus(sg)); + } - if (sg) - *sg = &per_cpu(sched_group_allnodes, group).sg; - return group; + if (!first) + first = sg; + if (last) + last->next = sg; + last = sg; + } + last->next = first; } -#endif /* CONFIG_NUMA */ - /* * Initialize sched groups cpu_power. * @@ -7039,15 +6955,15 @@ static void init_sched_groups_power(int cpu, struct sched_domain *sd) # define SD_INIT_NAME(sd, type) do { } while (0) #endif -#define SD_INIT(sd, type) sd_init_##type(sd) - -#define SD_INIT_FUNC(type) \ -static noinline void sd_init_##type(struct sched_domain *sd) \ -{ \ - memset(sd, 0, sizeof(*sd)); \ - *sd = SD_##type##_INIT; \ - sd->level = SD_LV_##type; \ - SD_INIT_NAME(sd, type); \ +#define SD_INIT_FUNC(type) \ +static noinline struct sched_domain *sd_init_##type(struct s_data *d, int cpu) \ +{ \ + struct sched_domain *sd = *per_cpu_ptr(d->sdd[SD_LV_##type].sd, cpu); \ + *sd = SD_##type##_INIT; \ + sd->level = SD_LV_##type; \ + SD_INIT_NAME(sd, type); \ + sd->private = &d->sdd[SD_LV_##type]; \ + return sd; \ } SD_INIT_FUNC(CPU) @@ -7103,13 +7019,22 @@ static void set_domain_attribute(struct sched_domain *sd, static void __free_domain_allocs(struct s_data *d, enum s_alloc what, const struct cpumask *cpu_map) { + int i, j; + switch (what) { case sa_rootdomain: - free_rootdomain(d->rd); /* fall through */ + free_rootdomain(&d->rd->rcu); /* fall through */ case sa_sd: free_percpu(d->sd); /* fall through */ - case sa_tmpmask: - free_cpumask_var(d->tmpmask); /* fall through */ + case sa_sd_storage: + for (i = 0; i < SD_LV_MAX; i++) { + for_each_cpu(j, cpu_map) { + kfree(*per_cpu_ptr(d->sdd[i].sd, j)); + kfree(*per_cpu_ptr(d->sdd[i].sg, j)); + } + free_percpu(d->sdd[i].sd); + free_percpu(d->sdd[i].sg); + } /* fall through */ case sa_send_covered: free_cpumask_var(d->send_covered); /* fall through */ case sa_nodemask: @@ -7122,25 +7047,70 @@ static void __free_domain_allocs(struct s_data *d, enum s_alloc what, static enum s_alloc __visit_domain_allocation_hell(struct s_data *d, const struct cpumask *cpu_map) { + int i, j; + + memset(d, 0, sizeof(*d)); + if (!alloc_cpumask_var(&d->nodemask, GFP_KERNEL)) return sa_none; if (!alloc_cpumask_var(&d->send_covered, GFP_KERNEL)) return sa_nodemask; - if (!alloc_cpumask_var(&d->tmpmask, GFP_KERNEL)) - return sa_send_covered; - d->sd = alloc_percpu(struct sched_domain *); - if (!d->sd) { - printk(KERN_WARNING "Cannot alloc per-cpu pointers\n"); - return sa_tmpmask; + for (i = 0; i < SD_LV_MAX; i++) { + d->sdd[i].sd = alloc_percpu(struct sched_domain *); + if (!d->sdd[i].sd) + return sa_sd_storage; + + d->sdd[i].sg = alloc_percpu(struct sched_group *); + if (!d->sdd[i].sg) + return sa_sd_storage; + + for_each_cpu(j, cpu_map) { + struct sched_domain *sd; + struct sched_group *sg; + + sd = kzalloc_node(sizeof(struct sched_domain) + cpumask_size(), + GFP_KERNEL, cpu_to_node(j)); + if (!sd) + return sa_sd_storage; + + *per_cpu_ptr(d->sdd[i].sd, j) = sd; + + sg = kzalloc_node(sizeof(struct sched_group) + cpumask_size(), + GFP_KERNEL, cpu_to_node(j)); + if (!sg) + return sa_sd_storage; + + *per_cpu_ptr(d->sdd[i].sg, j) = sg; + } } + d->sd = alloc_percpu(struct sched_domain *); + if (!d->sd) + return sa_sd_storage; d->rd = alloc_rootdomain(); - if (!d->rd) { - printk(KERN_WARNING "Cannot alloc root domain\n"); + if (!d->rd) return sa_sd; - } return sa_rootdomain; } +/* + * NULL the sd_data elements we've used to build the sched_domain and + * sched_group structure so that the subsequent __free_domain_allocs() + * will not free the data we're using. + */ +static void claim_allocations(int cpu, struct sched_domain *sd) +{ + struct sd_data *sdd = sd->private; + struct sched_group *sg = sd->groups; + + WARN_ON_ONCE(*per_cpu_ptr(sdd->sd, cpu) != sd); + *per_cpu_ptr(sdd->sd, cpu) = NULL; + + if (cpu == cpumask_first(sched_group_cpus(sg))) { + WARN_ON_ONCE(*per_cpu_ptr(sdd->sg, cpu) != sg); + *per_cpu_ptr(sdd->sg, cpu) = NULL; + } +} + static struct sched_domain *__build_numa_sched_domains(struct s_data *d, const struct cpumask *cpu_map, struct sched_domain_attr *attr, int i) { @@ -7151,24 +7121,20 @@ static struct sched_domain *__build_numa_sched_domains(struct s_data *d, d->sd_allnodes = 0; if (cpumask_weight(cpu_map) > SD_NODES_PER_DOMAIN * cpumask_weight(d->nodemask)) { - sd = &per_cpu(allnodes_domains, i).sd; - SD_INIT(sd, ALLNODES); + sd = sd_init_ALLNODES(d, i); set_domain_attribute(sd, attr); cpumask_copy(sched_domain_span(sd), cpu_map); - cpu_to_allnodes_group(i, cpu_map, &sd->groups, d->tmpmask); d->sd_allnodes = 1; } parent = sd; - sd = &per_cpu(node_domains, i).sd; - SD_INIT(sd, NODE); + sd = sd_init_NODE(d, i); set_domain_attribute(sd, attr); sched_domain_node_span(cpu_to_node(i), sched_domain_span(sd)); sd->parent = parent; if (parent) parent->child = sd; cpumask_and(sched_domain_span(sd), sched_domain_span(sd), cpu_map); - cpu_to_node_group(i, cpu_map, &sd->groups, d->tmpmask); #endif return sd; } @@ -7178,14 +7144,12 @@ static struct sched_domain *__build_cpu_sched_domain(struct s_data *d, struct sched_domain *parent, int i) { struct sched_domain *sd; - sd = &per_cpu(phys_domains, i).sd; - SD_INIT(sd, CPU); + sd = sd_init_CPU(d, i); set_domain_attribute(sd, attr); cpumask_copy(sched_domain_span(sd), d->nodemask); sd->parent = parent; if (parent) parent->child = sd; - cpu_to_phys_group(i, cpu_map, &sd->groups, d->tmpmask); return sd; } @@ -7195,13 +7159,11 @@ static struct sched_domain *__build_book_sched_domain(struct s_data *d, { struct sched_domain *sd = parent; #ifdef CONFIG_SCHED_BOOK - sd = &per_cpu(book_domains, i).sd; - SD_INIT(sd, BOOK); + sd = sd_init_BOOK(d, i); set_domain_attribute(sd, attr); cpumask_and(sched_domain_span(sd), cpu_map, cpu_book_mask(i)); sd->parent = parent; parent->child = sd; - cpu_to_book_group(i, cpu_map, &sd->groups, d->tmpmask); #endif return sd; } @@ -7212,13 +7174,11 @@ static struct sched_domain *__build_mc_sched_domain(struct s_data *d, { struct sched_domain *sd = parent; #ifdef CONFIG_SCHED_MC - sd = &per_cpu(core_domains, i).sd; - SD_INIT(sd, MC); + sd = sd_init_MC(d, i); set_domain_attribute(sd, attr); cpumask_and(sched_domain_span(sd), cpu_map, cpu_coregroup_mask(i)); sd->parent = parent; parent->child = sd; - cpu_to_core_group(i, cpu_map, &sd->groups, d->tmpmask); #endif return sd; } @@ -7229,92 +7189,32 @@ static struct sched_domain *__build_smt_sched_domain(struct s_data *d, { struct sched_domain *sd = parent; #ifdef CONFIG_SCHED_SMT - sd = &per_cpu(cpu_domains, i).sd; - SD_INIT(sd, SIBLING); + sd = sd_init_SIBLING(d, i); set_domain_attribute(sd, attr); cpumask_and(sched_domain_span(sd), cpu_map, topology_thread_cpumask(i)); sd->parent = parent; parent->child = sd; - cpu_to_cpu_group(i, cpu_map, &sd->groups, d->tmpmask); #endif return sd; } -static void build_sched_groups(struct s_data *d, struct sched_domain *sd, - const struct cpumask *cpu_map, int cpu) -{ - switch (sd->level) { -#ifdef CONFIG_SCHED_SMT - case SD_LV_SIBLING: /* set up CPU (sibling) groups */ - if (cpu == cpumask_first(sched_domain_span(sd))) - init_sched_build_groups(sched_domain_span(sd), cpu_map, - &cpu_to_cpu_group, - d->send_covered, d->tmpmask); - break; -#endif -#ifdef CONFIG_SCHED_MC - case SD_LV_MC: /* set up multi-core groups */ - if (cpu == cpumask_first(sched_domain_span(sd))) - init_sched_build_groups(sched_domain_span(sd), cpu_map, - &cpu_to_core_group, - d->send_covered, d->tmpmask); - break; -#endif -#ifdef CONFIG_SCHED_BOOK - case SD_LV_BOOK: /* set up book groups */ - if (cpu == cpumask_first(sched_domain_span(sd))) - init_sched_build_groups(sched_domain_span(sd), cpu_map, - &cpu_to_book_group, - d->send_covered, d->tmpmask); - break; -#endif - case SD_LV_CPU: /* set up physical groups */ - if (cpu == cpumask_first(sched_domain_span(sd))) - init_sched_build_groups(sched_domain_span(sd), cpu_map, - &cpu_to_phys_group, - d->send_covered, d->tmpmask); - break; -#ifdef CONFIG_NUMA - case SD_LV_NODE: - if (cpu == cpumask_first(sched_domain_span(sd))) - init_sched_build_groups(sched_domain_span(sd), cpu_map, - &cpu_to_node_group, - d->send_covered, d->tmpmask); - - case SD_LV_ALLNODES: - if (cpu == cpumask_first(cpu_map)) - init_sched_build_groups(cpu_map, cpu_map, - &cpu_to_allnodes_group, - d->send_covered, d->tmpmask); - break; -#endif - default: - break; - } -} - /* * Build sched domains for a given set of cpus and attach the sched domains * to the individual cpus */ -static int __build_sched_domains(const struct cpumask *cpu_map, - struct sched_domain_attr *attr) +static int build_sched_domains(const struct cpumask *cpu_map, + struct sched_domain_attr *attr) { enum s_alloc alloc_state = sa_none; + struct sched_domain *sd; struct s_data d; - struct sched_domain *sd, *tmp; int i; -#ifdef CONFIG_NUMA - d.sd_allnodes = 0; -#endif alloc_state = __visit_domain_allocation_hell(&d, cpu_map); if (alloc_state != sa_rootdomain) goto error; - /* - * Set up domains for cpus specified by the cpu_map. - */ + /* Set up domains for cpus specified by the cpu_map. */ for_each_cpu(i, cpu_map) { cpumask_and(d.nodemask, cpumask_of_node(cpu_to_node(i)), cpu_map); @@ -7326,10 +7226,19 @@ static int __build_sched_domains(const struct cpumask *cpu_map, sd = __build_smt_sched_domain(&d, cpu_map, attr, sd, i); *per_cpu_ptr(d.sd, i) = sd; + } + + /* Build the groups for the domains */ + for_each_cpu(i, cpu_map) { + for (sd = *per_cpu_ptr(d.sd, i); sd; sd = sd->parent) { + sd->span_weight = cpumask_weight(sched_domain_span(sd)); + get_group(i, sd->private, &sd->groups); + atomic_inc(&sd->groups->ref); - for (tmp = sd; tmp; tmp = tmp->parent) { - tmp->span_weight = cpumask_weight(sched_domain_span(tmp)); - build_sched_groups(&d, tmp, cpu_map, i); + if (i != cpumask_first(sched_domain_span(sd))) + continue; + + build_sched_groups(sd, d.send_covered); } } @@ -7338,18 +7247,21 @@ static int __build_sched_domains(const struct cpumask *cpu_map, if (!cpumask_test_cpu(i, cpu_map)) continue; - sd = *per_cpu_ptr(d.sd, i); - for (; sd; sd = sd->parent) + for (sd = *per_cpu_ptr(d.sd, i); sd; sd = sd->parent) { + claim_allocations(i, sd); init_sched_groups_power(i, sd); + } } /* Attach the domains */ + rcu_read_lock(); for_each_cpu(i, cpu_map) { sd = *per_cpu_ptr(d.sd, i); cpu_attach_domain(sd, d.rd, i); } + rcu_read_unlock(); - __free_domain_allocs(&d, sa_tmpmask, cpu_map); + __free_domain_allocs(&d, sa_sd, cpu_map); return 0; error: @@ -7357,11 +7269,6 @@ error: return -ENOMEM; } -static int build_sched_domains(const struct cpumask *cpu_map) -{ - return __build_sched_domains(cpu_map, NULL); -} - static cpumask_var_t *doms_cur; /* current sched domains */ static int ndoms_cur; /* number of sched domains in 'doms_cur' */ static struct sched_domain_attr *dattr_cur; @@ -7425,31 +7332,24 @@ static int init_sched_domains(const struct cpumask *cpu_map) doms_cur = &fallback_doms; cpumask_andnot(doms_cur[0], cpu_map, cpu_isolated_map); dattr_cur = NULL; - err = build_sched_domains(doms_cur[0]); + err = build_sched_domains(doms_cur[0], NULL); register_sched_domain_sysctl(); return err; } -static void destroy_sched_domains(const struct cpumask *cpu_map, - struct cpumask *tmpmask) -{ -} - /* * Detach sched domains from a group of cpus specified in cpu_map * These cpus will now be attached to the NULL domain */ static void detach_destroy_domains(const struct cpumask *cpu_map) { - /* Save because hotplug lock held. */ - static DECLARE_BITMAP(tmpmask, CONFIG_NR_CPUS); int i; + rcu_read_lock(); for_each_cpu(i, cpu_map) cpu_attach_domain(NULL, &def_root_domain, i); - synchronize_sched(); - destroy_sched_domains(cpu_map, to_cpumask(tmpmask)); + rcu_read_unlock(); } /* handle null as "default" */ @@ -7538,8 +7438,7 @@ match1: goto match2; } /* no match - add a new doms_new */ - __build_sched_domains(doms_new[i], - dattr_new ? dattr_new + i : NULL); + build_sched_domains(doms_new[i], dattr_new ? dattr_new + i : NULL); match2: ; } diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 4ee50f0af8d1..4a8ac7c2a18e 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -1622,6 +1622,7 @@ static int select_idle_sibling(struct task_struct *p, int target) /* * Otherwise, iterate the domains and find an elegible idle cpu. */ + rcu_read_lock(); for_each_domain(target, sd) { if (!(sd->flags & SD_SHARE_PKG_RESOURCES)) break; @@ -1641,6 +1642,7 @@ static int select_idle_sibling(struct task_struct *p, int target) cpumask_test_cpu(prev_cpu, sched_domain_span(sd))) break; } + rcu_read_unlock(); return target; } @@ -1673,6 +1675,7 @@ select_task_rq_fair(struct rq *rq, struct task_struct *p, int sd_flag, int wake_ new_cpu = prev_cpu; } + rcu_read_lock(); for_each_domain(cpu, tmp) { if (!(tmp->flags & SD_LOAD_BALANCE)) continue; @@ -1723,9 +1726,10 @@ select_task_rq_fair(struct rq *rq, struct task_struct *p, int sd_flag, int wake_ if (affine_sd) { if (cpu == prev_cpu || wake_affine(affine_sd, p, sync)) - return select_idle_sibling(p, cpu); - else - return select_idle_sibling(p, prev_cpu); + prev_cpu = cpu; + + new_cpu = select_idle_sibling(p, prev_cpu); + goto unlock; } while (sd) { @@ -1766,6 +1770,8 @@ select_task_rq_fair(struct rq *rq, struct task_struct *p, int sd_flag, int wake_ } /* while loop will break here if sd == NULL */ } +unlock: + rcu_read_unlock(); return new_cpu; } @@ -3462,6 +3468,7 @@ static void idle_balance(int this_cpu, struct rq *this_rq) raw_spin_unlock(&this_rq->lock); update_shares(this_cpu); + rcu_read_lock(); for_each_domain(this_cpu, sd) { unsigned long interval; int balance = 1; @@ -3483,6 +3490,7 @@ static void idle_balance(int this_cpu, struct rq *this_rq) break; } } + rcu_read_unlock(); raw_spin_lock(&this_rq->lock); @@ -3531,6 +3539,7 @@ static int active_load_balance_cpu_stop(void *data) double_lock_balance(busiest_rq, target_rq); /* Search for an sd spanning us and the target CPU. */ + rcu_read_lock(); for_each_domain(target_cpu, sd) { if ((sd->flags & SD_LOAD_BALANCE) && cpumask_test_cpu(busiest_cpu, sched_domain_span(sd))) @@ -3546,6 +3555,7 @@ static int active_load_balance_cpu_stop(void *data) else schedstat_inc(sd, alb_failed); } + rcu_read_unlock(); double_unlock_balance(busiest_rq, target_rq); out_unlock: busiest_rq->active_balance = 0; @@ -3672,6 +3682,7 @@ static int find_new_ilb(int cpu) { struct sched_domain *sd; struct sched_group *ilb_group; + int ilb = nr_cpu_ids; /* * Have idle load balancer selection from semi-idle packages only @@ -3687,20 +3698,25 @@ static int find_new_ilb(int cpu) if (cpumask_weight(nohz.idle_cpus_mask) < 2) goto out_done; + rcu_read_lock(); for_each_flag_domain(cpu, sd, SD_POWERSAVINGS_BALANCE) { ilb_group = sd->groups; do { - if (is_semi_idle_group(ilb_group)) - return cpumask_first(nohz.grp_idle_mask); + if (is_semi_idle_group(ilb_group)) { + ilb = cpumask_first(nohz.grp_idle_mask); + goto unlock; + } ilb_group = ilb_group->next; } while (ilb_group != sd->groups); } +unlock: + rcu_read_unlock(); out_done: - return nr_cpu_ids; + return ilb; } #else /* (CONFIG_SCHED_MC || CONFIG_SCHED_SMT) */ static inline int find_new_ilb(int call_cpu) @@ -3845,6 +3861,7 @@ static void rebalance_domains(int cpu, enum cpu_idle_type idle) update_shares(cpu); + rcu_read_lock(); for_each_domain(cpu, sd) { if (!(sd->flags & SD_LOAD_BALANCE)) continue; @@ -3890,6 +3907,7 @@ out: if (!balance) break; } + rcu_read_unlock(); /* * next_balance will be updated only when there is a need. -- cgit From 3859173d43658d51a749bc0201b943922577d39c Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 7 Apr 2011 14:09:53 +0200 Subject: sched: Reduce some allocation pressure Since we now allocate SD_LV_MAX * nr_cpu_ids sched_domain/sched_group structures when rebuilding the scheduler toplogy it might make sense to shrink that depending on the CONFIG_ options. This is only needed until we get rid of SD_LV_* alltogether and provide a full dynamic topology interface. Signed-off-by: Peter Zijlstra Cc: Mike Galbraith Cc: Nick Piggin Cc: Linus Torvalds Cc: Andrew Morton Link: http://lkml.kernel.org/r/20110407122942.406226449@chello.nl Signed-off-by: Ingo Molnar --- include/linux/sched.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index 020b79d6c486..5a9168b01db8 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -897,12 +897,20 @@ static inline struct cpumask *sched_group_cpus(struct sched_group *sg) enum sched_domain_level { SD_LV_NONE = 0, +#ifdef CONFIG_SCHED_SMT SD_LV_SIBLING, +#endif +#ifdef CONFIG_SCHED_MC SD_LV_MC, +#endif +#ifdef CONFIG_SCHED_BOOK SD_LV_BOOK, +#endif SD_LV_CPU, +#ifdef CONFIG_NUMA SD_LV_NODE, SD_LV_ALLNODES, +#endif SD_LV_MAX }; -- cgit From 7dd04b730749f957c116f363524fd622b05e5141 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 7 Apr 2011 14:09:56 +0200 Subject: sched: Remove some dead code Signed-off-by: Peter Zijlstra Cc: Mike Galbraith Cc: Nick Piggin Cc: Linus Torvalds Cc: Andrew Morton Link: http://lkml.kernel.org/r/20110407122942.553814623@chello.nl Signed-off-by: Ingo Molnar --- include/linux/sched.h | 6 ------ kernel/sched.c | 16 ---------------- 2 files changed, 22 deletions(-) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index 5a9168b01db8..09d9e02f2b61 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -883,9 +883,6 @@ struct sched_group { * NOTE: this field is variable length. (Allocated dynamically * by attaching extra space to the end of the structure, * depending on how many CPUs the kernel has booted up with) - * - * It is also be embedded into static data structures at build - * time. (See 'struct static_sched_group' in kernel/sched.c) */ unsigned long cpumask[0]; }; @@ -994,9 +991,6 @@ struct sched_domain { * NOTE: this field is variable length. (Allocated dynamically * by attaching extra space to the end of the structure, * depending on how many CPUs the kernel has booted up with) - * - * It is also be embedded into static data structures at build - * time. (See 'struct static_sched_domain' in kernel/sched.c) */ unsigned long span[0]; }; diff --git a/kernel/sched.c b/kernel/sched.c index f4d3a624c50a..5ec685ce516a 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -6816,22 +6816,6 @@ static void sched_domain_node_span(int node, struct cpumask *span) int sched_smt_power_savings = 0, sched_mc_power_savings = 0; -/* - * The cpus mask in sched_group and sched_domain hangs off the end. - * - * ( See the the comments in include/linux/sched.h:struct sched_group - * and struct sched_domain. ) - */ -struct static_sched_group { - struct sched_group sg; - DECLARE_BITMAP(cpus, CONFIG_NR_CPUS); -}; - -struct static_sched_domain { - struct sched_domain sd; - DECLARE_BITMAP(span, CONFIG_NR_CPUS); -}; - struct sd_data { struct sched_domain **__percpu sd; struct sched_group **__percpu sg; -- cgit From 60495e7760d8ee364695006af37309b0755e0e17 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 7 Apr 2011 14:10:04 +0200 Subject: sched: Dynamic sched_domain::level Remove the SD_LV_ enum and use dynamic level assignments. Signed-off-by: Peter Zijlstra Cc: Mike Galbraith Cc: Nick Piggin Cc: Linus Torvalds Cc: Andrew Morton Link: http://lkml.kernel.org/r/20110407122942.969433965@chello.nl Signed-off-by: Ingo Molnar --- include/linux/sched.h | 23 +++-------------------- kernel/cpuset.c | 2 +- kernel/sched.c | 9 ++++++--- 3 files changed, 10 insertions(+), 24 deletions(-) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index 09d9e02f2b61..e43e5b0ab0b5 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -892,25 +892,6 @@ static inline struct cpumask *sched_group_cpus(struct sched_group *sg) return to_cpumask(sg->cpumask); } -enum sched_domain_level { - SD_LV_NONE = 0, -#ifdef CONFIG_SCHED_SMT - SD_LV_SIBLING, -#endif -#ifdef CONFIG_SCHED_MC - SD_LV_MC, -#endif -#ifdef CONFIG_SCHED_BOOK - SD_LV_BOOK, -#endif - SD_LV_CPU, -#ifdef CONFIG_NUMA - SD_LV_NODE, - SD_LV_ALLNODES, -#endif - SD_LV_MAX -}; - struct sched_domain_attr { int relax_domain_level; }; @@ -919,6 +900,8 @@ struct sched_domain_attr { .relax_domain_level = -1, \ } +extern int sched_domain_level_max; + struct sched_domain { /* These fields must be setup */ struct sched_domain *parent; /* top domain must be null terminated */ @@ -936,7 +919,7 @@ struct sched_domain { unsigned int forkexec_idx; unsigned int smt_gain; int flags; /* See SD_* */ - enum sched_domain_level level; + int level; /* Runtime fields. */ unsigned long last_balance; /* init to jiffies. units in jiffies */ diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 33eee16addb8..2bb8c2e98fff 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c @@ -1159,7 +1159,7 @@ int current_cpuset_is_being_rebound(void) static int update_relax_domain_level(struct cpuset *cs, s64 val) { #ifdef CONFIG_SMP - if (val < -1 || val >= SD_LV_MAX) + if (val < -1 || val >= sched_domain_level_max) return -EINVAL; #endif diff --git a/kernel/sched.c b/kernel/sched.c index 3231e1997426..506cb8147c70 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -6966,7 +6966,6 @@ sd_init_##type(struct sched_domain_topology_level *tl, int cpu) \ { \ struct sched_domain *sd = *per_cpu_ptr(tl->data.sd, cpu); \ *sd = SD_##type##_INIT; \ - sd->level = SD_LV_##type; \ SD_INIT_NAME(sd, type); \ sd->private = &tl->data; \ return sd; \ @@ -6988,13 +6987,14 @@ SD_INIT_FUNC(CPU) #endif static int default_relax_domain_level = -1; +int sched_domain_level_max; static int __init setup_relax_domain_level(char *str) { unsigned long val; val = simple_strtoul(str, NULL, 0); - if (val < SD_LV_MAX) + if (val < sched_domain_level_max) default_relax_domain_level = val; return 1; @@ -7173,8 +7173,11 @@ struct sched_domain *build_sched_domain(struct sched_domain_topology_level *tl, set_domain_attribute(sd, attr); cpumask_and(sched_domain_span(sd), cpu_map, tl->mask(cpu)); - if (child) + if (child) { + sd->level = child->level + 1; + sched_domain_level_max = max(sched_domain_level_max, sd->level); child->parent = sd; + } sd->child = child; return sd; -- cgit From 127fe533ae56d7f4e7b5011869870982eba25723 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Fri, 8 Apr 2011 18:01:59 +0000 Subject: v3 ethtool: add ntuple flow specifier data to network flow classifier This change is meant to add an ntuple data extensions to the rx network flow classification specifiers. The idea is to allow ntuple to be displayed via the network flow classification interface. The first patch had some left over stuff from the original flow extension flags I had added. That bit is removed in this patch. The second had some left over comments that stated we ignored bits in the masks when we actually match them. This work is based on input from Ben Hutchings. Signed-off-by: Alexander Duyck Reviewed-by: Ben Hutchings Signed-off-by: David S. Miller --- include/linux/ethtool.h | 53 +++++++++++++++++++++++++++++-------------------- net/socket.c | 14 ++++++------- 2 files changed, 39 insertions(+), 28 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index c04d1316d221..c7eff13d2f34 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -380,27 +380,42 @@ struct ethtool_usrip4_spec { __u8 proto; }; +union ethtool_flow_union { + struct ethtool_tcpip4_spec tcp_ip4_spec; + struct ethtool_tcpip4_spec udp_ip4_spec; + struct ethtool_tcpip4_spec sctp_ip4_spec; + struct ethtool_ah_espip4_spec ah_ip4_spec; + struct ethtool_ah_espip4_spec esp_ip4_spec; + struct ethtool_usrip4_spec usr_ip4_spec; + struct ethhdr ether_spec; + __u8 hdata[60]; +}; + +struct ethtool_flow_ext { + __be16 vlan_etype; + __be16 vlan_tci; + __be32 data[2]; +}; + /** * struct ethtool_rx_flow_spec - specification for RX flow filter * @flow_type: Type of match to perform, e.g. %TCP_V4_FLOW * @h_u: Flow fields to match (dependent on @flow_type) - * @m_u: Masks for flow field bits to be ignored + * @h_ext: Additional fields to match + * @m_u: Masks for flow field bits to be matched + * @m_ext: Masks for additional field bits to be matched + * Note, all additional fields must be ignored unless @flow_type + * includes the %FLOW_EXT flag. * @ring_cookie: RX ring/queue index to deliver to, or %RX_CLS_FLOW_DISC * if packets should be discarded * @location: Index of filter in hardware table */ struct ethtool_rx_flow_spec { __u32 flow_type; - union { - struct ethtool_tcpip4_spec tcp_ip4_spec; - struct ethtool_tcpip4_spec udp_ip4_spec; - struct ethtool_tcpip4_spec sctp_ip4_spec; - struct ethtool_ah_espip4_spec ah_ip4_spec; - struct ethtool_ah_espip4_spec esp_ip4_spec; - struct ethtool_usrip4_spec usr_ip4_spec; - struct ethhdr ether_spec; - __u8 hdata[72]; - } h_u, m_u; + union ethtool_flow_union h_u; + struct ethtool_flow_ext h_ext; + union ethtool_flow_union m_u; + struct ethtool_flow_ext m_ext; __u64 ring_cookie; __u32 location; }; @@ -458,16 +473,10 @@ struct ethtool_rxnfc { struct compat_ethtool_rx_flow_spec { u32 flow_type; - union { - struct ethtool_tcpip4_spec tcp_ip4_spec; - struct ethtool_tcpip4_spec udp_ip4_spec; - struct ethtool_tcpip4_spec sctp_ip4_spec; - struct ethtool_ah_espip4_spec ah_ip4_spec; - struct ethtool_ah_espip4_spec esp_ip4_spec; - struct ethtool_usrip4_spec usr_ip4_spec; - struct ethhdr ether_spec; - u8 hdata[72]; - } h_u, m_u; + union ethtool_flow_union h_u; + struct ethtool_flow_ext h_ext; + union ethtool_flow_union m_u; + struct ethtool_flow_ext m_ext; compat_u64 ring_cookie; u32 location; }; @@ -1072,6 +1081,8 @@ struct ethtool_ops { #define IPV4_FLOW 0x10 /* hash only */ #define IPV6_FLOW 0x11 /* hash only */ #define ETHER_FLOW 0x12 /* spec only (ether_spec) */ +/* Flag to enable additional fields in struct ethtool_rx_flow_spec */ +#define FLOW_EXT 0x80000000 /* L3-L4 network traffic flow hash options */ #define RXH_L2DA (1 << 1) diff --git a/net/socket.c b/net/socket.c index 5212447c86e7..575c84f2af19 100644 --- a/net/socket.c +++ b/net/socket.c @@ -2643,13 +2643,13 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32) return -EFAULT; if (convert_in) { - /* We expect there to be holes between fs.m_u and + /* We expect there to be holes between fs.m_ext and * fs.ring_cookie and at the end of fs, but nowhere else. */ - BUILD_BUG_ON(offsetof(struct compat_ethtool_rxnfc, fs.m_u) + - sizeof(compat_rxnfc->fs.m_u) != - offsetof(struct ethtool_rxnfc, fs.m_u) + - sizeof(rxnfc->fs.m_u)); + BUILD_BUG_ON(offsetof(struct compat_ethtool_rxnfc, fs.m_ext) + + sizeof(compat_rxnfc->fs.m_ext) != + offsetof(struct ethtool_rxnfc, fs.m_ext) + + sizeof(rxnfc->fs.m_ext)); BUILD_BUG_ON( offsetof(struct compat_ethtool_rxnfc, fs.location) - offsetof(struct compat_ethtool_rxnfc, fs.ring_cookie) != @@ -2657,7 +2657,7 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32) offsetof(struct ethtool_rxnfc, fs.ring_cookie)); if (copy_in_user(rxnfc, compat_rxnfc, - (void *)(&rxnfc->fs.m_u + 1) - + (void *)(&rxnfc->fs.m_ext + 1) - (void *)rxnfc) || copy_in_user(&rxnfc->fs.ring_cookie, &compat_rxnfc->fs.ring_cookie, @@ -2674,7 +2674,7 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32) if (convert_out) { if (copy_in_user(compat_rxnfc, rxnfc, - (const void *)(&rxnfc->fs.m_u + 1) - + (const void *)(&rxnfc->fs.m_ext + 1) - (const void *)rxnfc) || copy_in_user(&compat_rxnfc->fs.ring_cookie, &rxnfc->fs.ring_cookie, -- cgit From 1f112cee07b314e244ee9e71d9c1e6950dc13327 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 11 Apr 2011 22:54:42 +0200 Subject: PM / Hibernate: Introduce CONFIG_HIBERNATE_CALLBACKS Xen save/restore is going to use hibernate device callbacks for quiescing devices and putting them back to normal operations and it would need to select CONFIG_HIBERNATION for this purpose. However, that also would cause the hibernate interfaces for user space to be enabled, which might confuse user space, because the Xen kernels don't support hibernation. Moreover, it would be wasteful, as it would make the Xen kernels include a substantial amount of code that they would never use. To address this issue introduce new power management Kconfig option CONFIG_HIBERNATE_CALLBACKS, such that it will only select the code that is necessary for the hibernate device callbacks to work and make CONFIG_HIBERNATION select it. Then, Xen save/restore will be able to select CONFIG_HIBERNATE_CALLBACKS without dragging the entire hibernate code along with it. Signed-off-by: Rafael J. Wysocki Tested-by: Shriram Rajagopalan --- arch/powerpc/kernel/ibmebus.c | 6 +++--- drivers/amba/bus.c | 6 +++--- drivers/base/platform.c | 6 +++--- drivers/base/power/main.c | 8 ++++---- drivers/pci/pci-driver.c | 6 +++--- drivers/xen/manage.c | 6 +++--- include/linux/suspend.h | 11 +++-------- kernel/power/Kconfig | 6 +++++- 8 files changed, 27 insertions(+), 28 deletions(-) (limited to 'include/linux') diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index c00d4ca1ee15..28581f1ad2c0 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c @@ -527,7 +527,7 @@ static int ibmebus_bus_pm_resume_noirq(struct device *dev) #endif /* !CONFIG_SUSPEND */ -#ifdef CONFIG_HIBERNATION +#ifdef CONFIG_HIBERNATE_CALLBACKS static int ibmebus_bus_pm_freeze(struct device *dev) { @@ -665,7 +665,7 @@ static int ibmebus_bus_pm_restore_noirq(struct device *dev) return ret; } -#else /* !CONFIG_HIBERNATION */ +#else /* !CONFIG_HIBERNATE_CALLBACKS */ #define ibmebus_bus_pm_freeze NULL #define ibmebus_bus_pm_thaw NULL @@ -676,7 +676,7 @@ static int ibmebus_bus_pm_restore_noirq(struct device *dev) #define ibmebus_bus_pm_poweroff_noirq NULL #define ibmebus_bus_pm_restore_noirq NULL -#endif /* !CONFIG_HIBERNATION */ +#endif /* !CONFIG_HIBERNATE_CALLBACKS */ static struct dev_pm_ops ibmebus_bus_dev_pm_ops = { .prepare = ibmebus_bus_pm_prepare, diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index 821040503154..7025593a58c8 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c @@ -214,7 +214,7 @@ static int amba_pm_resume_noirq(struct device *dev) #endif /* !CONFIG_SUSPEND */ -#ifdef CONFIG_HIBERNATION +#ifdef CONFIG_HIBERNATE_CALLBACKS static int amba_pm_freeze(struct device *dev) { @@ -352,7 +352,7 @@ static int amba_pm_restore_noirq(struct device *dev) return ret; } -#else /* !CONFIG_HIBERNATION */ +#else /* !CONFIG_HIBERNATE_CALLBACKS */ #define amba_pm_freeze NULL #define amba_pm_thaw NULL @@ -363,7 +363,7 @@ static int amba_pm_restore_noirq(struct device *dev) #define amba_pm_poweroff_noirq NULL #define amba_pm_restore_noirq NULL -#endif /* !CONFIG_HIBERNATION */ +#endif /* !CONFIG_HIBERNATE_CALLBACKS */ #ifdef CONFIG_PM diff --git a/drivers/base/platform.c b/drivers/base/platform.c index f051cfff18af..92792313d24a 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -771,7 +771,7 @@ int __weak platform_pm_resume_noirq(struct device *dev) #endif /* !CONFIG_SUSPEND */ -#ifdef CONFIG_HIBERNATION +#ifdef CONFIG_HIBERNATE_CALLBACKS static int platform_pm_freeze(struct device *dev) { @@ -909,7 +909,7 @@ static int platform_pm_restore_noirq(struct device *dev) return ret; } -#else /* !CONFIG_HIBERNATION */ +#else /* !CONFIG_HIBERNATE_CALLBACKS */ #define platform_pm_freeze NULL #define platform_pm_thaw NULL @@ -920,7 +920,7 @@ static int platform_pm_restore_noirq(struct device *dev) #define platform_pm_poweroff_noirq NULL #define platform_pm_restore_noirq NULL -#endif /* !CONFIG_HIBERNATION */ +#endif /* !CONFIG_HIBERNATE_CALLBACKS */ #ifdef CONFIG_PM_RUNTIME diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 052dc53eef38..fbc5b6e7c591 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -233,7 +233,7 @@ static int pm_op(struct device *dev, } break; #endif /* CONFIG_SUSPEND */ -#ifdef CONFIG_HIBERNATION +#ifdef CONFIG_HIBERNATE_CALLBACKS case PM_EVENT_FREEZE: case PM_EVENT_QUIESCE: if (ops->freeze) { @@ -260,7 +260,7 @@ static int pm_op(struct device *dev, suspend_report_result(ops->restore, error); } break; -#endif /* CONFIG_HIBERNATION */ +#endif /* CONFIG_HIBERNATE_CALLBACKS */ default: error = -EINVAL; } @@ -308,7 +308,7 @@ static int pm_noirq_op(struct device *dev, } break; #endif /* CONFIG_SUSPEND */ -#ifdef CONFIG_HIBERNATION +#ifdef CONFIG_HIBERNATE_CALLBACKS case PM_EVENT_FREEZE: case PM_EVENT_QUIESCE: if (ops->freeze_noirq) { @@ -335,7 +335,7 @@ static int pm_noirq_op(struct device *dev, suspend_report_result(ops->restore_noirq, error); } break; -#endif /* CONFIG_HIBERNATION */ +#endif /* CONFIG_HIBERNATE_CALLBACKS */ default: error = -EINVAL; } diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index d86ea8b01137..135df164a4c1 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -781,7 +781,7 @@ static int pci_pm_resume(struct device *dev) #endif /* !CONFIG_SUSPEND */ -#ifdef CONFIG_HIBERNATION +#ifdef CONFIG_HIBERNATE_CALLBACKS static int pci_pm_freeze(struct device *dev) { @@ -970,7 +970,7 @@ static int pci_pm_restore(struct device *dev) return error; } -#else /* !CONFIG_HIBERNATION */ +#else /* !CONFIG_HIBERNATE_CALLBACKS */ #define pci_pm_freeze NULL #define pci_pm_freeze_noirq NULL @@ -981,7 +981,7 @@ static int pci_pm_restore(struct device *dev) #define pci_pm_restore NULL #define pci_pm_restore_noirq NULL -#endif /* !CONFIG_HIBERNATION */ +#endif /* !CONFIG_HIBERNATE_CALLBACKS */ #ifdef CONFIG_PM_RUNTIME diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index 95143dd6904d..1ac94125bf93 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c @@ -61,7 +61,7 @@ static void xen_post_suspend(int cancelled) xen_mm_unpin_all(); } -#ifdef CONFIG_HIBERNATION +#ifdef CONFIG_HIBERNATE_CALLBACKS static int xen_suspend(void *data) { struct suspend_info *si = data; @@ -173,7 +173,7 @@ out: #endif shutting_down = SHUTDOWN_INVALID; } -#endif /* CONFIG_HIBERNATION */ +#endif /* CONFIG_HIBERNATE_CALLBACKS */ struct shutdown_handler { const char *command; @@ -202,7 +202,7 @@ static void shutdown_handler(struct xenbus_watch *watch, { "poweroff", do_poweroff }, { "halt", do_poweroff }, { "reboot", do_reboot }, -#ifdef CONFIG_HIBERNATION +#ifdef CONFIG_HIBERNATE_CALLBACKS { "suspend", do_suspend }, #endif {NULL, NULL}, diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 5a89e3612875..083ffea7ba18 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -249,6 +249,8 @@ extern void hibernation_set_ops(const struct platform_hibernation_ops *ops); extern int hibernate(void); extern bool system_entering_hibernation(void); #else /* CONFIG_HIBERNATION */ +static inline void register_nosave_region(unsigned long b, unsigned long e) {} +static inline void register_nosave_region_late(unsigned long b, unsigned long e) {} static inline int swsusp_page_is_forbidden(struct page *p) { return 0; } static inline void swsusp_set_page_free(struct page *p) {} static inline void swsusp_unset_page_free(struct page *p) {} @@ -297,14 +299,7 @@ static inline bool pm_wakeup_pending(void) { return false; } extern struct mutex pm_mutex; -#ifndef CONFIG_HIBERNATION -static inline void register_nosave_region(unsigned long b, unsigned long e) -{ -} -static inline void register_nosave_region_late(unsigned long b, unsigned long e) -{ -} - +#ifndef CONFIG_HIBERNATE_CALLBACKS static inline void lock_system_sleep(void) {} static inline void unlock_system_sleep(void) {} diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig index 4603f08dc47b..049791468d37 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig @@ -18,9 +18,13 @@ config SUSPEND_FREEZER Turning OFF this setting is NOT recommended! If in doubt, say Y. +config HIBERNATE_CALLBACKS + bool + config HIBERNATION bool "Hibernation (aka 'suspend to disk')" depends on SWAP && ARCH_HIBERNATION_POSSIBLE + select HIBERNATE_CALLBACKS select LZO_COMPRESS select LZO_DECOMPRESS ---help--- @@ -85,7 +89,7 @@ config PM_STD_PARTITION config PM_SLEEP def_bool y - depends on SUSPEND || HIBERNATION || XEN_SAVE_RESTORE + depends on SUSPEND || HIBERNATE_CALLBACKS || XEN_SAVE_RESTORE config PM_SLEEP_SMP def_bool y -- cgit From 92a47674f57b4a84a43ce93b0dfdb596c0543749 Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Mon, 11 Apr 2011 23:34:37 -0700 Subject: Input: gpio_keys - add support for EV_ABS With this patch you can setup a group of GPIOs representing a specific position on an EV_ABS axis. Signed-off-by: Alexander Stein Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/gpio_keys.c | 9 +++++++-- include/linux/gpio_keys.h | 7 ++++--- 2 files changed, 11 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index eb3006361ee4..73e58a96ab99 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -324,7 +324,12 @@ static void gpio_keys_report_event(struct gpio_button_data *bdata) unsigned int type = button->type ?: EV_KEY; int state = (gpio_get_value_cansleep(button->gpio) ? 1 : 0) ^ button->active_low; - input_event(input, type, button->code, !!state); + if (type == EV_ABS) { + if (state) + input_event(input, type, button->code, button->value); + } else { + input_event(input, type, button->code, !!state); + } input_sync(input); } @@ -363,7 +368,7 @@ static int __devinit gpio_keys_setup_key(struct platform_device *pdev, struct gpio_button_data *bdata, struct gpio_keys_button *button) { - char *desc = button->desc ? button->desc : "gpio_keys"; + const char *desc = button->desc ? button->desc : "gpio_keys"; struct device *dev = &pdev->dev; unsigned long irqflags; int irq, error; diff --git a/include/linux/gpio_keys.h b/include/linux/gpio_keys.h index dd1a56fbe924..3204edfe6b19 100644 --- a/include/linux/gpio_keys.h +++ b/include/linux/gpio_keys.h @@ -3,14 +3,15 @@ struct gpio_keys_button { /* Configuration parameters */ - int code; /* input event code (KEY_*, SW_*) */ + unsigned int code; /* input event code (KEY_*, SW_*) */ int gpio; int active_low; - char *desc; - int type; /* input event type (EV_KEY, EV_SW) */ + const char *desc; + unsigned int type; /* input event type (EV_KEY, EV_SW, EV_ABS) */ int wakeup; /* configure the button as a wake-up source */ int debounce_interval; /* debounce ticks interval in msecs */ bool can_disable; + int value; /* axis value for EV_ABS */ }; struct gpio_keys_platform_data { -- cgit From 467112777c462a592c27338eeea5d1a320e82b5f Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Mon, 11 Apr 2011 23:34:48 -0700 Subject: Input: gpio-keys - add support for setting device name This patch allows to set a device name which helps distinguishing several gpio-keys devices. Signed-off-by: Alexander Stein Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/gpio_keys.c | 2 +- include/linux/gpio_keys.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 73e58a96ab99..6e6145b9a4c1 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -473,7 +473,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) platform_set_drvdata(pdev, ddata); input_set_drvdata(input, ddata); - input->name = pdev->name; + input->name = pdata->name ? : pdev->name; input->phys = "gpio-keys/input0"; input->dev.parent = &pdev->dev; input->open = gpio_keys_open; diff --git a/include/linux/gpio_keys.h b/include/linux/gpio_keys.h index 3204edfe6b19..b5ca4b2c08ec 100644 --- a/include/linux/gpio_keys.h +++ b/include/linux/gpio_keys.h @@ -22,6 +22,7 @@ struct gpio_keys_platform_data { unsigned int rep:1; /* enable input subsystem auto repeat */ int (*enable)(struct device *dev); void (*disable)(struct device *dev); + const char *name; /* input device name */ }; #endif -- cgit From f75664570d8b75469cc468f23c2b27220984983b Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 12 Apr 2011 10:17:31 +0200 Subject: block: add callback function for unplug notification MD would like to know when a queue is unplugged, so it can flush it's bitmap writes. Add such a callback. Signed-off-by: Jens Axboe --- block/blk-core.c | 3 +++ block/blk-settings.c | 16 ++++++++++++++++ include/linux/blkdev.h | 3 +++ 3 files changed, 22 insertions(+) (limited to 'include/linux') diff --git a/block/blk-core.c b/block/blk-core.c index 0c0ea10e61ea..76850fc9cf23 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -2672,6 +2672,9 @@ static void queue_unplugged(struct request_queue *q, unsigned int depth) { trace_block_unplug_io(q, depth); __blk_run_queue(q, false); + + if (q->unplugged_fn) + q->unplugged_fn(q); } static void flush_plug_list(struct blk_plug *plug) diff --git a/block/blk-settings.c b/block/blk-settings.c index 1fa769293597..eb949045bb12 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c @@ -790,6 +790,22 @@ void blk_queue_flush(struct request_queue *q, unsigned int flush) } EXPORT_SYMBOL_GPL(blk_queue_flush); +/** + * blk_queue_unplugged - register a callback for an unplug event + * @q: the request queue for the device + * @fn: the function to call + * + * Some stacked drivers may need to know when IO is dispatched on an + * unplug event. By registrering a callback here, they will be notified + * when someone flushes their on-stack queue plug. The function will be + * called with the queue lock held. + */ +void blk_queue_unplugged(struct request_queue *q, unplugged_fn *fn) +{ + q->unplugged_fn = fn; +} +EXPORT_SYMBOL(blk_queue_unplugged); + static int __init blk_settings_init(void) { blk_max_low_pfn = max_low_pfn - 1; diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 32176cc8e715..c07ffafac5d4 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -196,6 +196,7 @@ typedef void (request_fn_proc) (struct request_queue *q); typedef int (make_request_fn) (struct request_queue *q, struct bio *bio); typedef int (prep_rq_fn) (struct request_queue *, struct request *); typedef void (unprep_rq_fn) (struct request_queue *, struct request *); +typedef void (unplugged_fn) (struct request_queue *); struct bio_vec; struct bvec_merge_data { @@ -283,6 +284,7 @@ struct request_queue rq_timed_out_fn *rq_timed_out_fn; dma_drain_needed_fn *dma_drain_needed; lld_busy_fn *lld_busy_fn; + unplugged_fn *unplugged_fn; /* * Dispatch queue sorting @@ -841,6 +843,7 @@ extern void blk_queue_dma_alignment(struct request_queue *, int); extern void blk_queue_update_dma_alignment(struct request_queue *, int); extern void blk_queue_softirq_done(struct request_queue *, softirq_done_fn *); extern void blk_queue_rq_timed_out(struct request_queue *, rq_timed_out_fn *); +extern void blk_queue_unplugged(struct request_queue *, unplugged_fn *); extern void blk_queue_rq_timeout(struct request_queue *, unsigned int); extern void blk_queue_flush(struct request_queue *q, unsigned int flush); extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev); -- cgit From e710d7d5a9cab1041b7a3cf9e655b75d92786857 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Fri, 8 Apr 2011 00:43:01 +0200 Subject: mfd: Fetch cell pointer from platform_device->mfd_cell In order for MFD drivers to fetch their cell pointer but also their platform data one, an mfd cell pointer is added to the platform_device structure. That allows all MFD sub devices drivers to be MFD agnostic, unless they really need to access their MFD cell data. Most of them don't, especially the ones for IPs used by both MFD and non MFD SoCs. Cc: Grant Likely Acked-by: Greg KH Signed-off-by: Samuel Ortiz --- drivers/base/platform.c | 1 + drivers/mfd/mfd-core.c | 16 ++++++++++++++-- include/linux/mfd/core.h | 13 +++++++++++-- include/linux/platform_device.h | 5 +++++ 4 files changed, 31 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/drivers/base/platform.c b/drivers/base/platform.c index f051cfff18af..6c3a2bdc527a 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -149,6 +149,7 @@ static void platform_device_release(struct device *dev) of_device_node_put(&pa->pdev.dev); kfree(pa->pdev.dev.platform_data); + kfree(pa->pdev.mfd_cell); kfree(pa->pdev.resource); kfree(pa); } diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index d01574d98870..f4c8c844b913 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c @@ -55,6 +55,19 @@ int mfd_cell_disable(struct platform_device *pdev) } EXPORT_SYMBOL(mfd_cell_disable); +static int mfd_platform_add_cell(struct platform_device *pdev, + const struct mfd_cell *cell) +{ + if (!cell) + return 0; + + pdev->mfd_cell = kmemdup(cell, sizeof(*cell), GFP_KERNEL); + if (!pdev->mfd_cell) + return -ENOMEM; + + return 0; +} + static int mfd_add_device(struct device *parent, int id, const struct mfd_cell *cell, struct resource *mem_base, @@ -75,7 +88,7 @@ static int mfd_add_device(struct device *parent, int id, pdev->dev.parent = parent; - ret = platform_device_add_data(pdev, cell, sizeof(*cell)); + ret = mfd_platform_add_cell(pdev, cell); if (ret) goto fail_res; @@ -123,7 +136,6 @@ static int mfd_add_device(struct device *parent, int id, return 0; -/* platform_device_del(pdev); */ fail_res: kfree(res); fail_device: diff --git a/include/linux/mfd/core.h b/include/linux/mfd/core.h index ad1b19aa6508..aef23309a742 100644 --- a/include/linux/mfd/core.h +++ b/include/linux/mfd/core.h @@ -86,16 +86,25 @@ extern int mfd_clone_cell(const char *cell, const char **clones, */ static inline const struct mfd_cell *mfd_get_cell(struct platform_device *pdev) { - return pdev->dev.platform_data; + return pdev->mfd_cell; } /* * Given a platform device that's been created by mfd_add_devices(), fetch * the .mfd_data entry from the mfd_cell that created it. + * Otherwise just return the platform_data pointer. + * This maintains compatibility with platform drivers whose devices aren't + * created by the mfd layer, and expect platform_data to contain what would've + * otherwise been in mfd_data. */ static inline void *mfd_get_data(struct platform_device *pdev) { - return mfd_get_cell(pdev)->mfd_data; + const struct mfd_cell *cell = mfd_get_cell(pdev); + + if (cell) + return cell->mfd_data; + else + return pdev->dev.platform_data; } extern int mfd_add_devices(struct device *parent, int id, diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index d96db9825708..744942c95fec 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h @@ -14,6 +14,8 @@ #include #include +struct mfd_cell; + struct platform_device { const char * name; int id; @@ -23,6 +25,9 @@ struct platform_device { const struct platform_device_id *id_entry; + /* MFD cell pointer */ + struct mfd_cell *mfd_cell; + /* arch specific additions */ struct pdev_archdata archdata; }; -- cgit From be85bccaa5aa5a11dcaf85f9e945ffefd253f631 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 12 Apr 2011 13:35:56 -0700 Subject: Revert "vfs: Export file system uuid via /proc//mountinfo" This reverts commit 93f1c20bc8cdb757be50566eff88d65c3b26881f. It turns out that libmount misparses it because it adds a '-' character in the uuid string, which libmount then incorrectly confuses with the separator string (" - ") at the end of all the optional arguments. Upstream libmount (in the util-linux tree) has been fixed, but until that fix actually percolates up to users, we'd better not expose this change in the kernel. Let's revisit this later (possibly by exposing the UUID without any '-' characters in it, avoiding the user-space bug). Reported-by: Dave Jones Cc: Aneesh Kumar K.V Cc: Al Viro Cc: Karel Zak Cc: Ram Pai Cc: Miklos Szeredi Cc: Eric Sandeen Signed-off-by: Linus Torvalds --- fs/namespace.c | 16 ---------------- include/linux/fs.h | 1 - 2 files changed, 17 deletions(-) (limited to 'include/linux') diff --git a/fs/namespace.c b/fs/namespace.c index 7dba2ed03429..d99bcf59e4c2 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1030,18 +1030,6 @@ const struct seq_operations mounts_op = { .show = show_vfsmnt }; -static int uuid_is_nil(u8 *uuid) -{ - int i; - u8 *cp = (u8 *)uuid; - - for (i = 0; i < 16; i++) { - if (*cp++) - return 0; - } - return 1; -} - static int show_mountinfo(struct seq_file *m, void *v) { struct proc_mounts *p = m->private; @@ -1085,10 +1073,6 @@ static int show_mountinfo(struct seq_file *m, void *v) if (IS_MNT_UNBINDABLE(mnt)) seq_puts(m, " unbindable"); - if (!uuid_is_nil(mnt->mnt_sb->s_uuid)) - /* print the uuid */ - seq_printf(m, " uuid:%pU", mnt->mnt_sb->s_uuid); - /* Filesystem specific data */ seq_puts(m, " - "); show_type(m, sb); diff --git a/include/linux/fs.h b/include/linux/fs.h index dbd860af0804..5b14843af9f9 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1403,7 +1403,6 @@ struct super_block { wait_queue_head_t s_wait_unfrozen; char s_id[32]; /* Informational name */ - u8 s_uuid[16]; /* UUID */ void *s_fs_info; /* Filesystem private info */ fmode_t s_mode; -- cgit From 581a8b0feeed8877aab3a8ca4c972419790cd07f Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Thu, 7 Apr 2011 15:08:27 -0700 Subject: nl80211: rename NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE To NL80211_MESH_SETUP_IE. This reflects our ability to insert any ie into a mesh beacon, not simply path selection ies. Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- include/linux/nl80211.h | 9 +++++---- include/net/cfg80211.h | 8 ++++---- net/mac80211/cfg.c | 15 +++++++-------- net/mac80211/ieee80211_i.h | 4 ++-- net/mac80211/mesh.c | 6 +++--- net/mac80211/mesh_plink.c | 2 +- net/mac80211/tx.c | 2 +- net/wireless/mesh.c | 4 ++-- net/wireless/nl80211.c | 11 ++++++----- 9 files changed, 31 insertions(+), 30 deletions(-) (limited to 'include/linux') diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 16eea7229e99..ecf6b68a96da 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -545,6 +545,7 @@ enum nl80211_commands { /* source-level API compatibility */ #define NL80211_CMD_GET_MESH_PARAMS NL80211_CMD_GET_MESH_CONFIG #define NL80211_CMD_SET_MESH_PARAMS NL80211_CMD_SET_MESH_CONFIG +#define NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE NL80211_MESH_SETUP_IE /** * enum nl80211_attrs - nl80211 netlink attributes @@ -1719,9 +1720,9 @@ enum nl80211_meshconf_params { * vendor specific path metric or disable it to use the default Airtime * metric. * - * @NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE: A vendor specific information - * element that vendors will use to identify the path selection methods and - * metrics in use. + * @NL80211_MESH_SETUP_IE: Information elements for this mesh, for instance, a + * robust security network ie, or a vendor specific information element that + * vendors will use to identify the path selection methods and metrics in use. * * @NL80211_MESH_SETUP_ATTR_MAX: highest possible mesh setup attribute number * @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use @@ -1730,7 +1731,7 @@ enum nl80211_mesh_setup_params { __NL80211_MESH_SETUP_INVALID, NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL, NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC, - NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE, + NL80211_MESH_SETUP_IE, /* keep last */ __NL80211_MESH_SETUP_ATTR_AFTER_LAST, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index ba7384acf4e0..1d02ddf5a8a3 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -689,8 +689,8 @@ struct mesh_config { * @mesh_id_len: length of the mesh ID, at least 1 and at most 32 bytes * @path_sel_proto: which path selection protocol to use * @path_metric: which metric to use - * @vendor_ie: vendor information elements (optional) - * @vendor_ie_len: length of vendor information elements + * @ie: vendor information elements (optional) + * @ie_len: length of vendor information elements * * These parameters are fixed when the mesh is created. */ @@ -699,8 +699,8 @@ struct mesh_setup { u8 mesh_id_len; u8 path_sel_proto; u8 path_metric; - const u8 *vendor_ie; - u8 vendor_ie_len; + const u8 *ie; + u8 ie_len; }; /** diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index bf5d28da46e6..d9428afd8bf6 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1034,26 +1034,25 @@ static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh, u8 *new_ie; const u8 *old_ie; - /* first allocate the new vendor information element */ + /* allocate information elements */ new_ie = NULL; - old_ie = ifmsh->vendor_ie; + old_ie = ifmsh->ie; - ifmsh->vendor_ie_len = setup->vendor_ie_len; - if (setup->vendor_ie_len) { - new_ie = kmemdup(setup->vendor_ie, setup->vendor_ie_len, + if (setup->ie_len) { + new_ie = kmemdup(setup->ie, setup->ie_len, GFP_KERNEL); if (!new_ie) return -ENOMEM; } + ifmsh->ie_len = setup->ie_len; + ifmsh->ie = new_ie; + kfree(old_ie); /* now copy the rest of the setup parameters */ ifmsh->mesh_id_len = setup->mesh_id_len; memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len); ifmsh->mesh_pp_id = setup->path_sel_proto; ifmsh->mesh_pm_id = setup->path_metric; - ifmsh->vendor_ie = new_ie; - - kfree(old_ie); return 0; } diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 6eb2c8523eeb..6450100594ba 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -488,8 +488,8 @@ struct ieee80211_if_mesh { struct mesh_config mshcfg; u32 mesh_seqnum; bool accepting_plinks; - const u8 *vendor_ie; - u8 vendor_ie_len; + const u8 *ie; + u8 ie_len; }; #ifdef CONFIG_MAC80211_MESH diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 2a57cc02c618..1c244c0c7664 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -279,9 +279,9 @@ void mesh_mgmt_ies_add(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata) MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00; *pos++ = 0x00; - if (sdata->u.mesh.vendor_ie) { - int len = sdata->u.mesh.vendor_ie_len; - const u8 *data = sdata->u.mesh.vendor_ie; + if (sdata->u.mesh.ie) { + int len = sdata->u.mesh.ie_len; + const u8 *data = sdata->u.mesh.ie; if (skb_tailroom(skb) > len) memcpy(skb_put(skb, len), data, len); } diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 44b53931ba5e..c705b20e1acb 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -161,7 +161,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, __le16 reason) { struct ieee80211_local *local = sdata->local; struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400 + - sdata->u.mesh.vendor_ie_len); + sdata->u.mesh.ie_len); struct ieee80211_mgmt *mgmt; bool include_plid = false; static const u8 meshpeeringproto[] = { 0x00, 0x0F, 0xAC, 0x2A }; diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index ce4596ed1268..17b10be31f55 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -2262,7 +2262,7 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, /* headroom, head length, tail length and maximum TIM length */ skb = dev_alloc_skb(local->tx_headroom + 400 + - sdata->u.mesh.vendor_ie_len); + sdata->u.mesh.ie_len); if (!skb) goto out; diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c index 73e39c171ffb..0d4b2260f96f 100644 --- a/net/wireless/mesh.c +++ b/net/wireless/mesh.c @@ -53,8 +53,8 @@ const struct mesh_config default_mesh_config = { const struct mesh_setup default_mesh_setup = { .path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP, .path_metric = IEEE80211_PATH_METRIC_AIRTIME, - .vendor_ie = NULL, - .vendor_ie_len = 0, + .ie = NULL, + .ie_len = 0, }; int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 297d7ce4117b..ccd825a5857e 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -2823,7 +2823,7 @@ static const struct nla_policy nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = { [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 }, [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 }, - [NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE] = { .type = NLA_BINARY, + [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY, .len = IEEE80211_MAX_DATA_LEN }, }; @@ -2925,13 +2925,14 @@ static int nl80211_parse_mesh_setup(struct genl_info *info, IEEE80211_PATH_METRIC_VENDOR : IEEE80211_PATH_METRIC_AIRTIME; - if (tb[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE]) { + + if (tb[NL80211_MESH_SETUP_IE]) { struct nlattr *ieattr = - tb[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE]; + tb[NL80211_MESH_SETUP_IE]; if (!is_valid_ie_attr(ieattr)) return -EINVAL; - setup->vendor_ie = nla_data(ieattr); - setup->vendor_ie_len = nla_len(ieattr); + setup->ie = nla_data(ieattr); + setup->ie_len = nla_len(ieattr); } return 0; -- cgit From 15d5dda623139bbf6165030fc251bbd5798f4130 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Thu, 7 Apr 2011 15:08:28 -0700 Subject: cfg80211/nl80211: Add userspace authentication flag to mesh setup During mesh setup, use NL80211_MESH_SETUP_USERSPACE_AUTH flag to create a secure mesh and route management frames to userspace. Also, NL80211_CMD_GET_WIPHY now returns a flag NL80211_SUPPORT_MESH_AUTH if the wiphy's mesh implementation supports routing of mesh auth frames to userspace. This is useful for forward compatibility between old kernels and new userspace tools. Signed-off-by: Javier Cardona Signed-off-by: Thomas Pedersen Signed-off-by: John W. Linville --- include/linux/nl80211.h | 9 +++++++++ include/net/cfg80211.h | 5 +++++ net/wireless/mesh.c | 4 ++++ net/wireless/nl80211.c | 5 +++++ 4 files changed, 23 insertions(+) (limited to 'include/linux') diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index ecf6b68a96da..0e652d860819 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -887,6 +887,9 @@ enum nl80211_commands { * changed once the mesh is active. * @NL80211_ATTR_MESH_CONFIG: Mesh configuration parameters, a nested attribute * containing attributes from &enum nl80211_meshconf_params. + * @NL80211_ATTR_SUPPORT_MESH_AUTH: Currently, this means the underlying driver + * allows auth frames in a mesh to be passed to userspace for processing via + * the @NL80211_MESH_SETUP_USERSPACE_AUTH flag. * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use @@ -1075,6 +1078,8 @@ enum nl80211_attrs { NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX, + NL80211_ATTR_SUPPORT_MESH_AUTH, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, @@ -1724,6 +1729,9 @@ enum nl80211_meshconf_params { * robust security network ie, or a vendor specific information element that * vendors will use to identify the path selection methods and metrics in use. * + * @NL80211_MESH_SETUP_USERSPACE_AUTH: Enable this option if an authentication + * daemon will be authenticating mesh candidates. + * * @NL80211_MESH_SETUP_ATTR_MAX: highest possible mesh setup attribute number * @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use */ @@ -1732,6 +1740,7 @@ enum nl80211_mesh_setup_params { NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL, NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC, NL80211_MESH_SETUP_IE, + NL80211_MESH_SETUP_USERSPACE_AUTH, /* keep last */ __NL80211_MESH_SETUP_ATTR_AFTER_LAST, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 1d02ddf5a8a3..e77603bd1630 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -691,6 +691,7 @@ struct mesh_config { * @path_metric: which metric to use * @ie: vendor information elements (optional) * @ie_len: length of vendor information elements + * @is_secure: or not * * These parameters are fixed when the mesh is created. */ @@ -701,6 +702,7 @@ struct mesh_setup { u8 path_metric; const u8 *ie; u8 ie_len; + bool is_secure; }; /** @@ -1451,6 +1453,8 @@ struct cfg80211_ops { * @WIPHY_FLAG_IBSS_RSN: The device supports IBSS RSN. * @WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS: The device supports separate * unicast and multicast TX keys. + * @WIPHY_FLAG_MESH_AUTH: The device supports mesh authentication by routing + * auth frames to userspace. See @NL80211_MESH_SETUP_USERSPACE_AUTH. */ enum wiphy_flags { WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), @@ -1463,6 +1467,7 @@ enum wiphy_flags { WIPHY_FLAG_CONTROL_PORT_PROTOCOL = BIT(7), WIPHY_FLAG_IBSS_RSN = BIT(8), WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS= BIT(9), + WIPHY_FLAG_MESH_AUTH = BIT(10), }; struct mac_address { diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c index 0d4b2260f96f..0e5c122ce324 100644 --- a/net/wireless/mesh.c +++ b/net/wireless/mesh.c @@ -72,6 +72,10 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) return -EOPNOTSUPP; + if (!(rdev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) && + setup->is_secure) + return -EOPNOTSUPP; + if (wdev->mesh_id_len) return -EALREADY; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index ccd825a5857e..cbedfc2a42a2 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -124,6 +124,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 }, [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED }, + [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG }, [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY, .len = NL80211_HT_CAPABILITY_LEN }, @@ -594,6 +595,8 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, if (dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN); + if (dev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) + NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_MESH_AUTH); NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES, sizeof(u32) * dev->wiphy.n_cipher_suites, @@ -2823,6 +2826,7 @@ static const struct nla_policy nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = { [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 }, [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 }, + [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG }, [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY, .len = IEEE80211_MAX_DATA_LEN }, }; @@ -2934,6 +2938,7 @@ static int nl80211_parse_mesh_setup(struct genl_info *info, setup->ie = nla_data(ieattr); setup->ie_len = nla_len(ieattr); } + setup->is_secure = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AUTH]); return 0; } -- cgit From b39c48fac1fc915a5dcd024bf6e9aabc855ed591 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Thu, 7 Apr 2011 15:08:30 -0700 Subject: nl80211/mac80211: let userspace authenticate stations Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- include/linux/nl80211.h | 2 ++ net/mac80211/cfg.c | 6 ++++++ net/wireless/nl80211.c | 5 ++++- 3 files changed, 12 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 0e652d860819..5ec4ac3a0ef4 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -1174,6 +1174,7 @@ enum nl80211_iftype { * with short barker preamble * @NL80211_STA_FLAG_WME: station is WME/QoS capable * @NL80211_STA_FLAG_MFP: station uses management frame protection + * @NL80211_STA_FLAG_AUTHENTICATED: station is authenticated * @NL80211_STA_FLAG_MAX: highest station flag number currently defined * @__NL80211_STA_FLAG_AFTER_LAST: internal use */ @@ -1183,6 +1184,7 @@ enum nl80211_sta_flags { NL80211_STA_FLAG_SHORT_PREAMBLE, NL80211_STA_FLAG_WME, NL80211_STA_FLAG_MFP, + NL80211_STA_FLAG_AUTHENTICATED, /* keep last */ __NL80211_STA_FLAG_AFTER_LAST, diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index dc623d884d02..1c25723eacda 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -686,6 +686,12 @@ static void sta_apply_parameters(struct ieee80211_local *local, if (set & BIT(NL80211_STA_FLAG_MFP)) sta->flags |= WLAN_STA_MFP; } + + if (mask & BIT(NL80211_STA_FLAG_AUTHENTICATED)) { + sta->flags &= ~WLAN_STA_AUTH; + if (set & BIT(NL80211_STA_FLAG_AUTHENTICATED)) + sta->flags |= WLAN_STA_AUTH; + } spin_unlock_irqrestore(&sta->flaglock, flags); /* diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index cbedfc2a42a2..ce29a0d0e88e 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -1925,6 +1925,7 @@ static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = { [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG }, [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG }, [NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG }, + [NL80211_STA_FLAG_AUTHENTICATED] = { .type = NLA_FLAG }, }; static int parse_station_flags(struct genl_info *info, @@ -2284,7 +2285,9 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) err = -EINVAL; if (params.supported_rates) err = -EINVAL; - if (params.sta_flags_mask) + if (params.sta_flags_mask & + ~(BIT(NL80211_STA_FLAG_AUTHENTICATED) | + BIT(NL80211_STA_FLAG_AUTHORIZED))) err = -EINVAL; break; default: -- cgit From c93b5e717ec47b57abfe0229360bc11e77520984 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Thu, 7 Apr 2011 15:08:34 -0700 Subject: nl80211: New notification to discover mesh peer candidates. Notify userspace when a beacon/presp is received from a suitable mesh peer candidate for whom no sta information exists. Userspace can then decide to create a sta info for the candidate. If userspace is not ready to authenticate the peer right away, it can create the sta info with the authenticated flag unset and set it later. Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- include/linux/nl80211.h | 12 ++++++++++++ include/net/cfg80211.h | 16 ++++++++++++++++ net/wireless/mesh.c | 14 ++++++++++++++ net/wireless/nl80211.c | 38 ++++++++++++++++++++++++++++++++++++++ net/wireless/nl80211.h | 4 ++++ 5 files changed, 84 insertions(+) (limited to 'include/linux') diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 5ec4ac3a0ef4..b87481866dde 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -410,6 +410,16 @@ * notification. This event is used to indicate that an unprotected * disassociation frame was dropped when MFP is in use. * + * @NL80211_CMD_NEW_PEER_CANDIDATE: Notification on the reception of a + * beacon or probe response from a compatible mesh peer. This is only + * sent while no station information (sta_info) exists for the new peer + * candidate and when @NL80211_MESH_SETUP_USERSPACE_AUTH is set. On + * reception of this notification, userspace may decide to create a new + * station (@NL80211_CMD_NEW_STATION). To stop this notification from + * reoccurring, the userspace authentication daemon may want to create the + * new station with the AUTHENTICATED flag unset and maybe change it later + * depending on the authentication result. + * * @NL80211_CMD_MAX: highest used command number * @__NL80211_CMD_AFTER_LAST: internal use */ @@ -522,6 +532,8 @@ enum nl80211_commands { NL80211_CMD_UNPROT_DEAUTHENTICATE, NL80211_CMD_UNPROT_DISASSOCIATE, + NL80211_CMD_NEW_PEER_CANDIDATE, + /* add new commands above here */ /* used to define NL80211_CMD_MAX below */ diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index e77603bd1630..f40cd30847de 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2488,6 +2488,22 @@ void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr, */ void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp); +/** + * cfg80211_notify_new_candidate - notify cfg80211 of a new mesh peer candidate + * + * @dev: network device + * @macaddr: the MAC address of the new candidate + * @ie: information elements advertised by the peer candidate + * @ie_len: lenght of the information elements buffer + * @gfp: allocation flags + * + * This function notifies cfg80211 that the mesh peer candidate has been + * detected, most likely via a beacon or, less likely, via a probe response. + * cfg80211 then sends a notification to userspace. + */ +void cfg80211_notify_new_peer_candidate(struct net_device *dev, + const u8 *macaddr, const u8 *ie, u8 ie_len, gfp_t gfp); + /** * DOC: RFkill integration * diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c index e0226e8265a3..5c116083eeca 100644 --- a/net/wireless/mesh.c +++ b/net/wireless/mesh.c @@ -1,5 +1,6 @@ #include #include +#include "nl80211.h" #include "core.h" /* Default values, timeouts in ms */ @@ -110,6 +111,19 @@ int cfg80211_join_mesh(struct cfg80211_registered_device *rdev, return err; } +void cfg80211_notify_new_peer_candidate(struct net_device *dev, + const u8 *macaddr, const u8* ie, u8 ie_len, gfp_t gfp) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + + if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT)) + return; + + nl80211_send_new_peer_candidate(wiphy_to_dev(wdev->wiphy), dev, + macaddr, ie, ie_len, gfp); +} +EXPORT_SYMBOL(cfg80211_notify_new_peer_candidate); + static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, struct net_device *dev) { diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index f4cb8efe2e5f..58f501a35022 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -5818,6 +5818,44 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev, nlmsg_free(msg); } +void nl80211_send_new_peer_candidate(struct cfg80211_registered_device *rdev, + struct net_device *netdev, + const u8 *macaddr, const u8* ie, u8 ie_len, + gfp_t gfp) +{ + struct sk_buff *msg; + void *hdr; + + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); + if (!msg) + return; + + hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NEW_PEER_CANDIDATE); + if (!hdr) { + nlmsg_free(msg); + return; + } + + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); + NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); + NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, macaddr); + if (ie_len && ie) + NLA_PUT(msg, NL80211_ATTR_IE, ie_len , ie); + + if (genlmsg_end(msg, hdr) < 0) { + nlmsg_free(msg); + return; + } + + genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, + nl80211_mlme_mcgrp.id, gfp); + return; + + nla_put_failure: + genlmsg_cancel(msg, hdr); + nlmsg_free(msg); +} + void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, struct net_device *netdev, const u8 *addr, enum nl80211_key_type key_type, int key_id, diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index dcac5cd6f017..f2af6955a665 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h @@ -50,6 +50,10 @@ void nl80211_send_disconnected(struct cfg80211_registered_device *rdev, struct net_device *netdev, u16 reason, const u8 *ie, size_t ie_len, bool from_ap); +void nl80211_send_new_peer_candidate(struct cfg80211_registered_device *rdev, + struct net_device *netdev, + const u8 *macaddr, const u8* ie, u8 ie_len, + gfp_t gfp); void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, struct net_device *netdev, const u8 *addr, -- cgit From ebe27c91af8b7f4810ae906fbd3eeb2d87850026 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Fri, 8 Apr 2011 21:24:24 +0530 Subject: {mac|nl}80211: Add station connected time Add station connected time in debugfs. This will be helpful to get a measure of stability of the connection and for debugging stress issues Cc: Senthilkumar Balasubramanian Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- include/linux/nl80211.h | 2 ++ include/net/cfg80211.h | 4 ++++ net/mac80211/cfg.c | 7 ++++++- net/mac80211/debugfs_sta.c | 26 ++++++++++++++++++++++++++ net/mac80211/sta_info.c | 3 +++ net/mac80211/sta_info.h | 2 ++ net/wireless/nl80211.c | 3 +++ 7 files changed, 46 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index b87481866dde..be8df57b789d 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -1297,6 +1297,7 @@ enum nl80211_sta_bss_param { * attribute, like NL80211_STA_INFO_TX_BITRATE. * @NL80211_STA_INFO_BSS_PARAM: current station's view of BSS, nested attribute * containing info as possible, see &enum nl80211_sta_bss_param + * @NL80211_STA_INFO_CONNECTED_TIME: time since the station is last connected * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute */ @@ -1317,6 +1318,7 @@ enum nl80211_sta_info { NL80211_STA_INFO_SIGNAL_AVG, NL80211_STA_INFO_RX_BITRATE, NL80211_STA_INFO_BSS_PARAM, + NL80211_STA_INFO_CONNECTED_TIME, /* keep last */ __NL80211_STA_INFO_AFTER_LAST, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index f40cd30847de..d30eada7c6cd 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -423,6 +423,7 @@ struct station_parameters { * @STATION_INFO_SIGNAL_AVG: @signal_avg filled * @STATION_INFO_RX_BITRATE: @rxrate fields are filled * @STATION_INFO_BSS_PARAM: @bss_param filled + * @STATION_INFO_CONNECTED_TIME: @connected_time filled */ enum station_info_flags { STATION_INFO_INACTIVE_TIME = 1<<0, @@ -441,6 +442,7 @@ enum station_info_flags { STATION_INFO_SIGNAL_AVG = 1<<13, STATION_INFO_RX_BITRATE = 1<<14, STATION_INFO_BSS_PARAM = 1<<15, + STATION_INFO_CONNECTED_TIME = 1<<16 }; /** @@ -511,6 +513,7 @@ struct sta_bss_parameters { * Station information filled by driver for get_station() and dump_station. * * @filled: bitflag of flags from &enum station_info_flags + * @connected_time: time(in secs) since a station is last connected * @inactive_time: time since last station activity (tx/rx) in milliseconds * @rx_bytes: bytes received from this station * @tx_bytes: bytes transmitted to this station @@ -533,6 +536,7 @@ struct sta_bss_parameters { */ struct station_info { u32 filled; + u32 connected_time; u32 inactive_time; u32 rx_bytes; u32 tx_bytes; diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 1c25723eacda..a6d191f2a0fe 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -330,6 +330,7 @@ static void rate_idx_to_bitrate(struct rate_info *rate, struct sta_info *sta, in static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) { struct ieee80211_sub_if_data *sdata = sta->sdata; + struct timespec uptime; sinfo->generation = sdata->local->sta_generation; @@ -343,7 +344,11 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) STATION_INFO_TX_BITRATE | STATION_INFO_RX_BITRATE | STATION_INFO_RX_DROP_MISC | - STATION_INFO_BSS_PARAM; + STATION_INFO_BSS_PARAM | + STATION_INFO_CONNECTED_TIME; + + do_posix_clock_monotonic_gettime(&uptime); + sinfo->connected_time = uptime.tv_sec - sta->last_connected; sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); sinfo->rx_bytes = sta->rx_bytes; diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index c04a1396cf8d..c008232731eb 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c @@ -92,6 +92,31 @@ static ssize_t sta_inactive_ms_read(struct file *file, char __user *userbuf, } STA_OPS(inactive_ms); + +static ssize_t sta_connected_time_read(struct file *file, char __user *userbuf, + size_t count, loff_t *ppos) +{ + struct sta_info *sta = file->private_data; + struct timespec uptime; + struct tm result; + long connected_time_secs; + char buf[100]; + int res; + do_posix_clock_monotonic_gettime(&uptime); + connected_time_secs = uptime.tv_sec - sta->last_connected; + time_to_tm(connected_time_secs, 0, &result); + result.tm_year -= 70; + result.tm_mday -= 1; + res = scnprintf(buf, sizeof(buf), + "years - %d\nmonths - %d\ndays - %d\nclock - %d:%d:%d\n\n", + result.tm_year, result.tm_mon, result.tm_mday, + result.tm_hour, result.tm_min, result.tm_sec); + return simple_read_from_buffer(userbuf, count, ppos, buf, res); +} +STA_OPS(connected_time); + + + static ssize_t sta_last_seq_ctrl_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { @@ -324,6 +349,7 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta) DEBUGFS_ADD(flags); DEBUGFS_ADD(num_ps_buf_frames); DEBUGFS_ADD(inactive_ms); + DEBUGFS_ADD(connected_time); DEBUGFS_ADD(last_seq_ctrl); DEBUGFS_ADD(agg_status); DEBUGFS_ADD(dev); diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 999f8fbf0b4b..8a9068ac0673 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -228,6 +228,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, { struct ieee80211_local *local = sdata->local; struct sta_info *sta; + struct timespec uptime; int i; sta = kzalloc(sizeof(*sta) + local->hw.sta_data_size, gfp); @@ -245,6 +246,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, sta->sdata = sdata; sta->last_rx = jiffies; + do_posix_clock_monotonic_gettime(&uptime); + sta->last_connected = uptime.tv_sec; ewma_init(&sta->avg_signal, 1024, 8); if (sta_prepare_rate_control(local, sta, gfp)) { diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 43238e99cfb3..984a03db3553 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -226,6 +226,7 @@ enum plink_state { * @rx_bytes: Number of bytes received from this STA * @wep_weak_iv_count: number of weak WEP IVs received from this station * @last_rx: time (in jiffies) when last frame was received from this STA + * @last_connected: time (in seconds) when a station got connected * @num_duplicates: number of duplicate frames received from this STA * @rx_fragments: number of received MPDUs * @rx_dropped: number of dropped MPDUs from this STA @@ -295,6 +296,7 @@ struct sta_info { unsigned long rx_packets, rx_bytes; unsigned long wep_weak_iv_count; unsigned long last_rx; + long last_connected; unsigned long num_duplicates; unsigned long rx_fragments; unsigned long rx_dropped; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 58f501a35022..0efa7fd01150 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -2020,6 +2020,9 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO); if (!sinfoattr) goto nla_put_failure; + if (sinfo->filled & STATION_INFO_CONNECTED_TIME) + NLA_PUT_U32(msg, NL80211_STA_INFO_CONNECTED_TIME, + sinfo->connected_time); if (sinfo->filled & STATION_INFO_INACTIVE_TIME) NLA_PUT_U32(msg, NL80211_STA_INFO_INACTIVE_TIME, sinfo->inactive_time); -- cgit From bcc6d47903612c3861201cc3a866fb604f26b8b2 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Thu, 7 Apr 2011 19:48:33 +0000 Subject: net: vlan: make non-hw-accel rx path similar to hw-accel Now there are 2 paths for rx vlan frames. When rx-vlan-hw-accel is enabled, skb is untagged by NIC, vlan_tci is set and the skb gets into vlan code in __netif_receive_skb - vlan_hwaccel_do_receive. For non-rx-vlan-hw-accel however, tagged skb goes thru whole __netif_receive_skb, it's untagged in ptype_base hander and reinjected This incosistency is fixed by this patch. Vlan untagging happens early in __netif_receive_skb so the rest of code (ptype_all handlers, rx_handlers) see the skb like it was untagged by hw. Signed-off-by: Jiri Pirko v1->v2: remove "inline" from vlan_core.c functions Signed-off-by: David S. Miller --- include/linux/if_vlan.h | 10 ++- net/8021q/vlan.c | 8 --- net/8021q/vlan.h | 2 - net/8021q/vlan_core.c | 85 +++++++++++++++++++++++- net/8021q/vlan_dev.c | 173 ------------------------------------------------ net/core/dev.c | 8 ++- 6 files changed, 99 insertions(+), 187 deletions(-) (limited to 'include/linux') diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index 635e1faec412..998b29930b80 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -132,7 +132,8 @@ extern u16 vlan_dev_vlan_id(const struct net_device *dev); extern int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, u16 vlan_tci, int polling); -extern bool vlan_hwaccel_do_receive(struct sk_buff **skb); +extern bool vlan_do_receive(struct sk_buff **skb); +extern struct sk_buff *vlan_untag(struct sk_buff *skb); extern gro_result_t vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp, unsigned int vlan_tci, struct sk_buff *skb); @@ -166,13 +167,18 @@ static inline int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, return NET_XMIT_SUCCESS; } -static inline bool vlan_hwaccel_do_receive(struct sk_buff **skb) +static inline bool vlan_do_receive(struct sk_buff **skb) { if ((*skb)->vlan_tci & VLAN_VID_MASK) (*skb)->pkt_type = PACKET_OTHERHOST; return false; } +inline struct sk_buff *vlan_untag(struct sk_buff *skb) +{ + return skb; +} + static inline gro_result_t vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp, unsigned int vlan_tci, struct sk_buff *skb) diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index e47600b4e2e3..14ef5efbc653 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -49,11 +49,6 @@ const char vlan_version[] = DRV_VERSION; static const char vlan_copyright[] = "Ben Greear "; static const char vlan_buggyright[] = "David S. Miller "; -static struct packet_type vlan_packet_type __read_mostly = { - .type = cpu_to_be16(ETH_P_8021Q), - .func = vlan_skb_recv, /* VLAN receive method */ -}; - /* End of global variables definitions. */ static void vlan_group_free(struct vlan_group *grp) @@ -684,7 +679,6 @@ static int __init vlan_proto_init(void) if (err < 0) goto err4; - dev_add_pack(&vlan_packet_type); vlan_ioctl_set(vlan_ioctl_handler); return 0; @@ -705,8 +699,6 @@ static void __exit vlan_cleanup_module(void) unregister_netdevice_notifier(&vlan_notifier_block); - dev_remove_pack(&vlan_packet_type); - unregister_pernet_subsys(&vlan_net_ops); rcu_barrier(); /* Wait for completion of call_rcu()'s */ diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h index 5687c9b95f33..c3408def8a19 100644 --- a/net/8021q/vlan.h +++ b/net/8021q/vlan.h @@ -75,8 +75,6 @@ static inline struct vlan_dev_info *vlan_dev_info(const struct net_device *dev) } /* found in vlan_dev.c */ -int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, - struct packet_type *ptype, struct net_device *orig_dev); void vlan_dev_set_ingress_priority(const struct net_device *dev, u32 skb_prio, u16 vlan_prio); int vlan_dev_set_egress_priority(const struct net_device *dev, diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index ce8e3ab3e7a5..41495dc2a4c9 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c @@ -4,7 +4,7 @@ #include #include "vlan.h" -bool vlan_hwaccel_do_receive(struct sk_buff **skbp) +bool vlan_do_receive(struct sk_buff **skbp) { struct sk_buff *skb = *skbp; u16 vlan_id = skb->vlan_tci & VLAN_VID_MASK; @@ -88,3 +88,86 @@ gro_result_t vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp, return napi_gro_frags(napi); } EXPORT_SYMBOL(vlan_gro_frags); + +static struct sk_buff *vlan_check_reorder_header(struct sk_buff *skb) +{ + if (vlan_dev_info(skb->dev)->flags & VLAN_FLAG_REORDER_HDR) { + if (skb_cow(skb, skb_headroom(skb)) < 0) + skb = NULL; + if (skb) { + /* Lifted from Gleb's VLAN code... */ + memmove(skb->data - ETH_HLEN, + skb->data - VLAN_ETH_HLEN, 12); + skb->mac_header += VLAN_HLEN; + } + } + return skb; +} + +static void vlan_set_encap_proto(struct sk_buff *skb, struct vlan_hdr *vhdr) +{ + __be16 proto; + unsigned char *rawp; + + /* + * Was a VLAN packet, grab the encapsulated protocol, which the layer + * three protocols care about. + */ + + proto = vhdr->h_vlan_encapsulated_proto; + if (ntohs(proto) >= 1536) { + skb->protocol = proto; + return; + } + + rawp = skb->data; + if (*(unsigned short *) rawp == 0xFFFF) + /* + * This is a magic hack to spot IPX packets. Older Novell + * breaks the protocol design and runs IPX over 802.3 without + * an 802.2 LLC layer. We look for FFFF which isn't a used + * 802.2 SSAP/DSAP. This won't work for fault tolerant netware + * but does for the rest. + */ + skb->protocol = htons(ETH_P_802_3); + else + /* + * Real 802.2 LLC + */ + skb->protocol = htons(ETH_P_802_2); +} + +struct sk_buff *vlan_untag(struct sk_buff *skb) +{ + struct vlan_hdr *vhdr; + u16 vlan_tci; + + if (unlikely(vlan_tx_tag_present(skb))) { + /* vlan_tci is already set-up so leave this for another time */ + return skb; + } + + skb = skb_share_check(skb, GFP_ATOMIC); + if (unlikely(!skb)) + goto err_free; + + if (unlikely(!pskb_may_pull(skb, VLAN_HLEN))) + goto err_free; + + vhdr = (struct vlan_hdr *) skb->data; + vlan_tci = ntohs(vhdr->h_vlan_TCI); + __vlan_hwaccel_put_tag(skb, vlan_tci); + + skb_pull_rcsum(skb, VLAN_HLEN); + vlan_set_encap_proto(skb, vhdr); + + skb = vlan_check_reorder_header(skb); + if (unlikely(!skb)) + goto err_free; + + return skb; + +err_free: + kfree_skb(skb); + return NULL; +} diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index b84a46b30c0c..d174c312b7f1 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -65,179 +65,6 @@ static int vlan_dev_rebuild_header(struct sk_buff *skb) return 0; } -static inline struct sk_buff *vlan_check_reorder_header(struct sk_buff *skb) -{ - if (vlan_dev_info(skb->dev)->flags & VLAN_FLAG_REORDER_HDR) { - if (skb_cow(skb, skb_headroom(skb)) < 0) - skb = NULL; - if (skb) { - /* Lifted from Gleb's VLAN code... */ - memmove(skb->data - ETH_HLEN, - skb->data - VLAN_ETH_HLEN, 12); - skb->mac_header += VLAN_HLEN; - } - } - - return skb; -} - -static inline void vlan_set_encap_proto(struct sk_buff *skb, - struct vlan_hdr *vhdr) -{ - __be16 proto; - unsigned char *rawp; - - /* - * Was a VLAN packet, grab the encapsulated protocol, which the layer - * three protocols care about. - */ - - proto = vhdr->h_vlan_encapsulated_proto; - if (ntohs(proto) >= 1536) { - skb->protocol = proto; - return; - } - - rawp = skb->data; - if (*(unsigned short *)rawp == 0xFFFF) - /* - * This is a magic hack to spot IPX packets. Older Novell - * breaks the protocol design and runs IPX over 802.3 without - * an 802.2 LLC layer. We look for FFFF which isn't a used - * 802.2 SSAP/DSAP. This won't work for fault tolerant netware - * but does for the rest. - */ - skb->protocol = htons(ETH_P_802_3); - else - /* - * Real 802.2 LLC - */ - skb->protocol = htons(ETH_P_802_2); -} - -/* - * Determine the packet's protocol ID. The rule here is that we - * assume 802.3 if the type field is short enough to be a length. - * This is normal practice and works for any 'now in use' protocol. - * - * Also, at this point we assume that we ARE dealing exclusively with - * VLAN packets, or packets that should be made into VLAN packets based - * on a default VLAN ID. - * - * NOTE: Should be similar to ethernet/eth.c. - * - * SANITY NOTE: This method is called when a packet is moving up the stack - * towards userland. To get here, it would have already passed - * through the ethernet/eth.c eth_type_trans() method. - * SANITY NOTE 2: We are referencing to the VLAN_HDR frields, which MAY be - * stored UNALIGNED in the memory. RISC systems don't like - * such cases very much... - * SANITY NOTE 2a: According to Dave Miller & Alexey, it will always be - * aligned, so there doesn't need to be any of the unaligned - * stuff. It has been commented out now... --Ben - * - */ -int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, - struct packet_type *ptype, struct net_device *orig_dev) -{ - struct vlan_hdr *vhdr; - struct vlan_pcpu_stats *rx_stats; - struct net_device *vlan_dev; - u16 vlan_id; - u16 vlan_tci; - - skb = skb_share_check(skb, GFP_ATOMIC); - if (skb == NULL) - goto err_free; - - if (unlikely(!pskb_may_pull(skb, VLAN_HLEN))) - goto err_free; - - vhdr = (struct vlan_hdr *)skb->data; - vlan_tci = ntohs(vhdr->h_vlan_TCI); - vlan_id = vlan_tci & VLAN_VID_MASK; - - rcu_read_lock(); - vlan_dev = vlan_find_dev(dev, vlan_id); - - /* If the VLAN device is defined, we use it. - * If not, and the VID is 0, it is a 802.1p packet (not - * really a VLAN), so we will just netif_rx it later to the - * original interface, but with the skb->proto set to the - * wrapped proto: we do nothing here. - */ - - if (!vlan_dev) { - if (vlan_id) { - pr_debug("%s: ERROR: No net_device for VID: %u on dev: %s\n", - __func__, vlan_id, dev->name); - goto err_unlock; - } - rx_stats = NULL; - } else { - skb->dev = vlan_dev; - - rx_stats = this_cpu_ptr(vlan_dev_info(skb->dev)->vlan_pcpu_stats); - - u64_stats_update_begin(&rx_stats->syncp); - rx_stats->rx_packets++; - rx_stats->rx_bytes += skb->len; - - skb->priority = vlan_get_ingress_priority(skb->dev, vlan_tci); - - pr_debug("%s: priority: %u for TCI: %hu\n", - __func__, skb->priority, vlan_tci); - - switch (skb->pkt_type) { - case PACKET_BROADCAST: - /* Yeah, stats collect these together.. */ - /* stats->broadcast ++; // no such counter :-( */ - break; - - case PACKET_MULTICAST: - rx_stats->rx_multicast++; - break; - - case PACKET_OTHERHOST: - /* Our lower layer thinks this is not local, let's make - * sure. - * This allows the VLAN to have a different MAC than the - * underlying device, and still route correctly. - */ - if (!compare_ether_addr(eth_hdr(skb)->h_dest, - skb->dev->dev_addr)) - skb->pkt_type = PACKET_HOST; - break; - default: - break; - } - u64_stats_update_end(&rx_stats->syncp); - } - - skb_pull_rcsum(skb, VLAN_HLEN); - vlan_set_encap_proto(skb, vhdr); - - if (vlan_dev) { - skb = vlan_check_reorder_header(skb); - if (!skb) { - rx_stats->rx_errors++; - goto err_unlock; - } - } - - netif_rx(skb); - - rcu_read_unlock(); - return NET_RX_SUCCESS; - -err_unlock: - rcu_read_unlock(); -err_free: - atomic_long_inc(&dev->rx_dropped); - kfree_skb(skb); - return NET_RX_DROP; -} - static inline u16 vlan_dev_get_egress_qos_mask(struct net_device *dev, struct sk_buff *skb) { diff --git a/net/core/dev.c b/net/core/dev.c index 95897ff3a76f..d1aebf7c6494 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -3130,6 +3130,12 @@ another_round: __this_cpu_inc(softnet_data.processed); + if (skb->protocol == cpu_to_be16(ETH_P_8021Q)) { + skb = vlan_untag(skb); + if (unlikely(!skb)) + goto out; + } + #ifdef CONFIG_NET_CLS_ACT if (skb->tc_verd & TC_NCLS) { skb->tc_verd = CLR_TC_NCLS(skb->tc_verd); @@ -3177,7 +3183,7 @@ ncls: ret = deliver_skb(skb, pt_prev, orig_dev); pt_prev = NULL; } - if (vlan_hwaccel_do_receive(&skb)) { + if (vlan_do_receive(&skb)) { ret = __netif_receive_skb(skb); goto out; } else if (unlikely(!skb)) -- cgit From 1aac62671686e6234c91b5f6fc4caaa850419d5d Mon Sep 17 00:00:00 2001 From: MichaÅ‚ MirosÅ‚aw Date: Tue, 12 Apr 2011 04:07:39 +0000 Subject: net: vlan_features comment clarification MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: MichaÅ‚ MirosÅ‚aw Signed-off-by: David S. Miller --- include/linux/netdevice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 09d262415769..cb8178ab3c52 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1035,7 +1035,7 @@ struct net_device { u32 hw_features; /* user-requested features */ u32 wanted_features; - /* VLAN feature mask */ + /* mask of features inheritable by VLAN devices */ u32 vlan_features; /* Net device feature bits; if you change something, -- cgit From 0bba01695b74fdd2f9286243bb39f88544d81401 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 12 Apr 2011 15:21:04 -0700 Subject: vfs: Re-introduce s_uuid in the superblock Gaah. When commit be85bccaa5aa reverted the export of file system uuid via /proc//mountinfo, it also unintentionally removed the s_uuid field in struct super_block. I didn't mean to do that, since filesystems have been taught to fill it in (and we want to keep it for future re-introduction in the mountinfo file). Stupid of me. This adds it back in. Signed-off-by: Linus Torvalds --- include/linux/fs.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/fs.h b/include/linux/fs.h index 5b14843af9f9..dbd860af0804 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1403,6 +1403,7 @@ struct super_block { wait_queue_head_t s_wait_unfrozen; char s_id[32]; /* Informational name */ + u8 s_uuid[16]; /* UUID */ void *s_fs_info; /* Filesystem private info */ fmode_t s_mode; -- cgit From 6139e75f4a413bdc8f366fc11e437347be8abc59 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 12 Apr 2011 19:27:51 -0700 Subject: net: Missing 'inline' in vlan-disabled vlan_untag() Reported-by: Stephen Rothwell Signed-off-by: David S. Miller --- include/linux/if_vlan.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index 998b29930b80..546d9d35fbd4 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -174,7 +174,7 @@ static inline bool vlan_do_receive(struct sk_buff **skb) return false; } -inline struct sk_buff *vlan_untag(struct sk_buff *skb) +static inline struct sk_buff *vlan_untag(struct sk_buff *skb) { return skb; } -- cgit From ba6a078b77e0dc1309d7e6e2ee034b92ab91f88c Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Tue, 12 Apr 2011 23:13:08 -0700 Subject: Input: add KEY_IMAGES specifically for AL Image Browser Many media center remotes have buttons intended for jumping straight to one type of media browser or another -- commonly, images/photos/pictures, audio/music, television, and movies. At present, remotes with an images or photos or pictures button use any number of different keycodes which sort of maybe fit. I've seen at least KEY_MEDIA, KEY_CAMERA, KEY_GRAPHICSEDITOR and KEY_PRESENTATION. None of those seem quite right. In my mind, KEY_MEDIA should be something more like a media center application launcher (and I'd like to standardize on that for things like the windows media center button on the mce remotes). KEY_CAMERA is used in a lot of webcams, and typically means "take a picture now". KEY_GRAPHICSEDITOR implies an editor, not a browser. KEY_PRESENTATION might be the closest fit here, if you think "photo slide show", but it may well be more intended for "run application in full-screen presentation mode" or to launch something like magicpoint, I dunno. And thus, I'd like to have a KEY_IMAGES, which matches the HID Usage AL Image Browser, the meaning of which I think is crystal-clear. I believe AL Audio Browser is already covered by KEY_AUDIO, and AL Movie Browser by KEY_VIDEO, so I'm also adding appropriate comments next to those keys. Signed-off-by: Jarod Wilson Signed-off-by: Dmitry Torokhov --- include/linux/input.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/input.h b/include/linux/input.h index 056ae8a5bd9b..0cc25e4ce2ab 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -553,8 +553,8 @@ struct input_keymap_entry { #define KEY_DVD 0x185 /* Media Select DVD */ #define KEY_AUX 0x186 #define KEY_MP3 0x187 -#define KEY_AUDIO 0x188 -#define KEY_VIDEO 0x189 +#define KEY_AUDIO 0x188 /* AL Audio Browser */ +#define KEY_VIDEO 0x189 /* AL Movie Browser */ #define KEY_DIRECTORY 0x18a #define KEY_LIST 0x18b #define KEY_MEMO 0x18c /* Media Select Messages */ @@ -603,8 +603,9 @@ struct input_keymap_entry { #define KEY_FRAMEFORWARD 0x1b5 #define KEY_CONTEXT_MENU 0x1b6 /* GenDesc - system context menu */ #define KEY_MEDIA_REPEAT 0x1b7 /* Consumer - transport control */ -#define KEY_10CHANNELSUP 0x1b8 /* 10 channels up (10+) */ -#define KEY_10CHANNELSDOWN 0x1b9 /* 10 channels down (10-) */ +#define KEY_10CHANNELSUP 0x1b8 /* 10 channels up (10+) */ +#define KEY_10CHANNELSDOWN 0x1b9 /* 10 channels down (10-) */ +#define KEY_IMAGES 0x1ba /* AL Image Browser */ #define KEY_DEL_EOL 0x1c0 #define KEY_DEL_EOS 0x1c1 -- cgit From 9fb0f14e31b6101a0cc69a333b43541044f9b0a6 Mon Sep 17 00:00:00 2001 From: Jeff Brown Date: Tue, 12 Apr 2011 23:29:38 -0700 Subject: Input: evdev - indicate buffer overrun with SYN_DROPPED Add a new EV_SYN code, SYN_DROPPED, to inform the client when input events have been dropped from the evdev input buffer due to a buffer overrun. The client should use this event as a hint to reset its state or ignore all following events until the next packet begins. Signed-off-by: Jeff Brown [dtor@mail.ru: Implement Henrik's suggestion and drop old events in case of overflow.] Signed-off-by: Dmitry Torokhov --- Documentation/input/event-codes.txt | 6 ++++++ drivers/input/evdev.c | 33 +++++++++++++++++++++------------ include/linux/input.h | 1 + 3 files changed, 28 insertions(+), 12 deletions(-) (limited to 'include/linux') diff --git a/Documentation/input/event-codes.txt b/Documentation/input/event-codes.txt index f13aee550409..23fcb05175be 100644 --- a/Documentation/input/event-codes.txt +++ b/Documentation/input/event-codes.txt @@ -85,6 +85,12 @@ sent in the evdev event stream. - Used to synchronize and separate touch events. See the multi-touch-protocol.txt document for more information. +* SYN_DROPPED: + - Used to indicate buffer overrun in the evdev client's event queue. + Client should ignore all events up to and including next SYN_REPORT + event and query the device (using EVIOCG* ioctls) to obtain its + current state. + EV_KEY: ---------- EV_KEY events take the form KEY_ or BTN_. For example, KEY_A is used diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 7f42d3a454d2..88d8e4cb419a 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -39,13 +39,13 @@ struct evdev { }; struct evdev_client { - int head; - int tail; + unsigned int head; + unsigned int tail; spinlock_t buffer_lock; /* protects access to buffer, head and tail */ struct fasync_struct *fasync; struct evdev *evdev; struct list_head node; - int bufsize; + unsigned int bufsize; struct input_event buffer[]; }; @@ -55,16 +55,25 @@ static DEFINE_MUTEX(evdev_table_mutex); static void evdev_pass_event(struct evdev_client *client, struct input_event *event) { - /* - * Interrupts are disabled, just acquire the lock. - * Make sure we don't leave with the client buffer - * "empty" by having client->head == client->tail. - */ + /* Interrupts are disabled, just acquire the lock. */ spin_lock(&client->buffer_lock); - do { - client->buffer[client->head++] = *event; - client->head &= client->bufsize - 1; - } while (client->head == client->tail); + + client->buffer[client->head++] = *event; + client->head &= client->bufsize - 1; + + if (unlikely(client->head == client->tail)) { + /* + * This effectively "drops" all unconsumed events, leaving + * EV_SYN/SYN_DROPPED plus the newest event in the queue. + */ + client->tail = (client->head - 2) & (client->bufsize - 1); + + client->buffer[client->tail].time = event->time; + client->buffer[client->tail].type = EV_SYN; + client->buffer[client->tail].code = SYN_DROPPED; + client->buffer[client->tail].value = 0; + } + spin_unlock(&client->buffer_lock); if (event->type == EV_SYN) diff --git a/include/linux/input.h b/include/linux/input.h index 0cc25e4ce2ab..73a8c6ee595b 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -167,6 +167,7 @@ struct input_keymap_entry { #define SYN_REPORT 0 #define SYN_CONFIG 1 #define SYN_MT_REPORT 2 +#define SYN_DROPPED 3 /* * Keys and buttons -- cgit From edb2fd9524cc2a55fb5a2e878b6e4e83f9e63fd0 Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Wed, 13 Apr 2011 09:45:45 +0200 Subject: include/linux/leds-regulator.h: fix syntax in example code Fix struct field initializer syntax in some example code from a comment, this will make copying and pasting the code more straightforward. Signed-off-by: Antonio Ospite Signed-off-by: Jiri Kosina --- include/linux/leds-regulator.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/leds-regulator.h b/include/linux/leds-regulator.h index 5a8eb389aab8..e2337a8c90b0 100644 --- a/include/linux/leds-regulator.h +++ b/include/linux/leds-regulator.h @@ -16,7 +16,7 @@ * Use "vled" as supply id when declaring the regulator consumer: * * static struct regulator_consumer_supply pcap_regulator_VVIB_consumers [] = { - * { .dev_name = "leds-regulator.0", supply = "vled" }, + * { .dev_name = "leds-regulator.0", .supply = "vled" }, * }; * * If you have several regulator driven LEDs, you can append a numerical id to -- cgit From 91eb7c08c6cb3b8eeba1c61f5753c56dcb77f018 Mon Sep 17 00:00:00 2001 From: Jozsef Kadlecsik Date: Wed, 13 Apr 2011 13:51:38 +0200 Subject: netfilter: ipset: SCTP, UDPLITE support added SCTP and UDPLITE port support added to the hash:*port* set types. Signed-off-by: Jozsef Kadlecsik Signed-off-by: Patrick McHardy --- include/linux/netfilter/ipset/ip_set_getport.h | 2 ++ net/netfilter/ipset/ip_set_getport.c | 16 +++++++++++++++- net/netfilter/ipset/ip_set_hash_ipport.c | 2 +- net/netfilter/ipset/ip_set_hash_ipportip.c | 2 +- net/netfilter/ipset/ip_set_hash_ipportnet.c | 2 +- net/netfilter/ipset/ip_set_hash_netport.c | 2 +- 6 files changed, 21 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netfilter/ipset/ip_set_getport.h b/include/linux/netfilter/ipset/ip_set_getport.h index 5aebd170f899..90d09300e954 100644 --- a/include/linux/netfilter/ipset/ip_set_getport.h +++ b/include/linux/netfilter/ipset/ip_set_getport.h @@ -22,7 +22,9 @@ static inline bool ip_set_proto_with_ports(u8 proto) { switch (proto) { case IPPROTO_TCP: + case IPPROTO_SCTP: case IPPROTO_UDP: + case IPPROTO_UDPLITE: return true; } return false; diff --git a/net/netfilter/ipset/ip_set_getport.c b/net/netfilter/ipset/ip_set_getport.c index 8d5227212686..757143b2240a 100644 --- a/net/netfilter/ipset/ip_set_getport.c +++ b/net/netfilter/ipset/ip_set_getport.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -35,7 +36,20 @@ get_port(const struct sk_buff *skb, int protocol, unsigned int protooff, *port = src ? th->source : th->dest; break; } - case IPPROTO_UDP: { + case IPPROTO_SCTP: { + sctp_sctphdr_t _sh; + const sctp_sctphdr_t *sh; + + sh = skb_header_pointer(skb, protooff, sizeof(_sh), &_sh); + if (sh == NULL) + /* No choice either */ + return false; + + *port = src ? sh->source : sh->dest; + break; + } + case IPPROTO_UDP: + case IPPROTO_UDPLITE: { struct udphdr _udph; const struct udphdr *uh; diff --git a/net/netfilter/ipset/ip_set_hash_ipport.c b/net/netfilter/ipset/ip_set_hash_ipport.c index b9214145d357..14281b6b8074 100644 --- a/net/netfilter/ipset/ip_set_hash_ipport.c +++ b/net/netfilter/ipset/ip_set_hash_ipport.c @@ -491,7 +491,7 @@ static struct ip_set_type hash_ipport_type __read_mostly = { .features = IPSET_TYPE_IP | IPSET_TYPE_PORT, .dimension = IPSET_DIM_TWO, .family = AF_UNSPEC, - .revision = 0, + .revision = 1, .create = hash_ipport_create, .create_policy = { [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 }, diff --git a/net/netfilter/ipset/ip_set_hash_ipportip.c b/net/netfilter/ipset/ip_set_hash_ipportip.c index 4642872df6e1..401c8a2531db 100644 --- a/net/netfilter/ipset/ip_set_hash_ipportip.c +++ b/net/netfilter/ipset/ip_set_hash_ipportip.c @@ -509,7 +509,7 @@ static struct ip_set_type hash_ipportip_type __read_mostly = { .features = IPSET_TYPE_IP | IPSET_TYPE_PORT | IPSET_TYPE_IP2, .dimension = IPSET_DIM_THREE, .family = AF_UNSPEC, - .revision = 0, + .revision = 1, .create = hash_ipportip_create, .create_policy = { [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 }, diff --git a/net/netfilter/ipset/ip_set_hash_ipportnet.c b/net/netfilter/ipset/ip_set_hash_ipportnet.c index 2cb84a54b7ad..4743e5402522 100644 --- a/net/netfilter/ipset/ip_set_hash_ipportnet.c +++ b/net/netfilter/ipset/ip_set_hash_ipportnet.c @@ -574,7 +574,7 @@ static struct ip_set_type hash_ipportnet_type __read_mostly = { .features = IPSET_TYPE_IP | IPSET_TYPE_PORT | IPSET_TYPE_IP2, .dimension = IPSET_DIM_THREE, .family = AF_UNSPEC, - .revision = 0, + .revision = 1, .create = hash_ipportnet_create, .create_policy = { [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 }, diff --git a/net/netfilter/ipset/ip_set_hash_netport.c b/net/netfilter/ipset/ip_set_hash_netport.c index 8598676f2a05..d2a40362dd3a 100644 --- a/net/netfilter/ipset/ip_set_hash_netport.c +++ b/net/netfilter/ipset/ip_set_hash_netport.c @@ -526,7 +526,7 @@ static struct ip_set_type hash_netport_type __read_mostly = { .features = IPSET_TYPE_IP | IPSET_TYPE_PORT, .dimension = IPSET_DIM_TWO, .family = AF_UNSPEC, - .revision = 0, + .revision = 1, .create = hash_netport_create, .create_policy = { [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 }, -- cgit From 8b5933c380fc66a6311739f9b36a812383f82141 Mon Sep 17 00:00:00 2001 From: amit salecha Date: Thu, 7 Apr 2011 01:58:42 +0000 Subject: net: ethtool support to configure number of channels Ethtool support to configure RX, TX and other channels. combined field in struct ethtool_channels to reflect set of channel (RX, TX or other). Other channel can be link interrupts, SR-IOV coordination etc. ETHTOOL_GCHANNELS will report max and current number of RX channels, max and current number of TX channels, max and current number of other channel or max and current number of combined channel. Number of channel can be modify upto max number of channel through ETHTOOL_SCHANNELS command. Ben Hutchings: o define 'combined' and 'other' types. Most multiqueue drivers pair up RX and TX queues so that most channels combine RX and TX work. o Please could you use a kernel-doc comment to describe the structure. Signed-off-by: Amit Kumar Salecha Reviewed-by: Ben Hutchings Signed-off-by: David S. Miller --- include/linux/ethtool.h | 36 ++++++++++++++++++++++++++++++++++++ net/core/ethtool.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 12cfbd0be2ee..ad22a68c2e5d 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -229,6 +229,34 @@ struct ethtool_ringparam { __u32 tx_pending; }; +/** + * struct ethtool_channels - configuring number of network channel + * @cmd: ETHTOOL_{G,S}CHANNELS + * @max_rx: Read only. Maximum number of receive channel the driver support. + * @max_tx: Read only. Maximum number of transmit channel the driver support. + * @max_other: Read only. Maximum number of other channel the driver support. + * @max_combined: Read only. Maximum number of combined channel the driver + * support. Set of queues RX, TX or other. + * @rx_count: Valid values are in the range 1 to the max_rx. + * @tx_count: Valid values are in the range 1 to the max_tx. + * @other_count: Valid values are in the range 1 to the max_other. + * @combined_count: Valid values are in the range 1 to the max_combined. + * + * This can be used to configure RX, TX and other channels. + */ + +struct ethtool_channels { + __u32 cmd; + __u32 max_rx; + __u32 max_tx; + __u32 max_other; + __u32 max_combined; + __u32 rx_count; + __u32 tx_count; + __u32 other_count; + __u32 combined_count; +}; + /* for configuring link flow control parameters */ struct ethtool_pauseparam { __u32 cmd; /* ETHTOOL_{G,S}PAUSEPARAM */ @@ -818,6 +846,9 @@ bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported); * Returns a negative error code or zero. * @set_rxfh_indir: Set the contents of the RX flow hash indirection table. * Returns a negative error code or zero. + * @get_channels: Get number of channels. + * @set_channels: Set number of channels. Returns a negative error code or + * zero. * * All operations are optional (i.e. the function pointer may be set * to %NULL) and callers must take this into account. Callers must @@ -891,6 +922,9 @@ struct ethtool_ops { struct ethtool_rxfh_indir *); int (*set_rxfh_indir)(struct net_device *, const struct ethtool_rxfh_indir *); + void (*get_channels)(struct net_device *, struct ethtool_channels *); + int (*set_channels)(struct net_device *, struct ethtool_channels *); + }; #endif /* __KERNEL__ */ @@ -959,6 +993,8 @@ struct ethtool_ops { #define ETHTOOL_GFEATURES 0x0000003a /* Get device offload settings */ #define ETHTOOL_SFEATURES 0x0000003b /* Change device offload settings */ +#define ETHTOOL_GCHANNELS 0x0000003c /* Get no of channels */ +#define ETHTOOL_SCHANNELS 0x0000003d /* Set no of channels */ /* compatibility with older code */ #define SPARC_ETH_GSET ETHTOOL_GSET diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 43ef09fedd6e..41dee2de13ad 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -1446,6 +1446,35 @@ static int ethtool_set_ringparam(struct net_device *dev, void __user *useraddr) return dev->ethtool_ops->set_ringparam(dev, &ringparam); } +static noinline_for_stack int ethtool_get_channels(struct net_device *dev, + void __user *useraddr) +{ + struct ethtool_channels channels = { .cmd = ETHTOOL_GCHANNELS }; + + if (!dev->ethtool_ops->get_channels) + return -EOPNOTSUPP; + + dev->ethtool_ops->get_channels(dev, &channels); + + if (copy_to_user(useraddr, &channels, sizeof(channels))) + return -EFAULT; + return 0; +} + +static noinline_for_stack int ethtool_set_channels(struct net_device *dev, + void __user *useraddr) +{ + struct ethtool_channels channels; + + if (!dev->ethtool_ops->set_channels) + return -EOPNOTSUPP; + + if (copy_from_user(&channels, useraddr, sizeof(channels))) + return -EFAULT; + + return dev->ethtool_ops->set_channels(dev, &channels); +} + static int ethtool_get_pauseparam(struct net_device *dev, void __user *useraddr) { struct ethtool_pauseparam pauseparam = { ETHTOOL_GPAUSEPARAM }; @@ -2007,6 +2036,12 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) case ETHTOOL_SGRO: rc = ethtool_set_one_feature(dev, useraddr, ethcmd); break; + case ETHTOOL_GCHANNELS: + rc = ethtool_get_channels(dev, useraddr); + break; + case ETHTOOL_SCHANNELS: + rc = ethtool_set_channels(dev, useraddr); + break; default: rc = -EOPNOTSUPP; } -- cgit From 4d42d417be75d750b82798922b6e775915e11bce Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 13 Apr 2011 14:48:55 -0700 Subject: rndis_host: Poll status before control channel where necessary Some RNDIS devices don't respond on the control channel until polled on the status channel. In particular, this was reported to be the case for the 2Wire HomePortal 1000SW and for some Windows Mobile devices. This is roughly based on a patch by John Carr which is currently applied by Mandriva. Reported-by: Mark Glassberg Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/usb/rndis_host.c | 39 ++++++++++++++++++++++++++++++++------- include/linux/usb/rndis_host.h | 2 ++ 2 files changed, 34 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c index 5994a25c56ac..6d6c1da68a36 100644 --- a/drivers/net/usb/rndis_host.c +++ b/drivers/net/usb/rndis_host.c @@ -104,8 +104,10 @@ static void rndis_msg_indicate(struct usbnet *dev, struct rndis_indicate *msg, int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen) { struct cdc_state *info = (void *) &dev->data; + struct usb_cdc_notification notification; int master_ifnum; int retval; + int partial; unsigned count; __le32 rsp; u32 xid = 0, msg_len, request_id; @@ -133,13 +135,20 @@ int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen) if (unlikely(retval < 0 || xid == 0)) return retval; - // FIXME Seems like some devices discard responses when - // we time out and cancel our "get response" requests... - // so, this is fragile. Probably need to poll for status. + /* Some devices don't respond on the control channel until + * polled on the status channel, so do that first. */ + if (dev->driver_info->data & RNDIS_DRIVER_DATA_POLL_STATUS) { + retval = usb_interrupt_msg( + dev->udev, + usb_rcvintpipe(dev->udev, + dev->status->desc.bEndpointAddress), + ¬ification, sizeof(notification), &partial, + RNDIS_CONTROL_TIMEOUT_MS); + if (unlikely(retval < 0)) + return retval; + } - /* ignore status endpoint, just poll the control channel; - * the request probably completed immediately - */ + /* Poll the control channel; the request probably completed immediately */ rsp = buf->msg_type | RNDIS_MSG_COMPLETION; for (count = 0; count < 10; count++) { memset(buf, 0, CONTROL_BUFFER_SIZE); @@ -581,17 +590,33 @@ static const struct driver_info rndis_info = { .tx_fixup = rndis_tx_fixup, }; +static const struct driver_info rndis_poll_status_info = { + .description = "RNDIS device (poll status before control)", + .flags = FLAG_ETHER | FLAG_FRAMING_RN | FLAG_NO_SETINT, + .data = RNDIS_DRIVER_DATA_POLL_STATUS, + .bind = rndis_bind, + .unbind = rndis_unbind, + .status = rndis_status, + .rx_fixup = rndis_rx_fixup, + .tx_fixup = rndis_tx_fixup, +}; + /*-------------------------------------------------------------------------*/ static const struct usb_device_id products [] = { { + /* 2Wire HomePortal 1000SW */ + USB_DEVICE_AND_INTERFACE_INFO(0x1630, 0x0042, + USB_CLASS_COMM, 2 /* ACM */, 0x0ff), + .driver_info = (unsigned long) &rndis_poll_status_info, +}, { /* RNDIS is MSFT's un-official variant of CDC ACM */ USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff), .driver_info = (unsigned long) &rndis_info, }, { /* "ActiveSync" is an undocumented variant of RNDIS, used in WM5 */ USB_INTERFACE_INFO(USB_CLASS_MISC, 1, 1), - .driver_info = (unsigned long) &rndis_info, + .driver_info = (unsigned long) &rndis_poll_status_info, }, { /* RNDIS for tethering */ USB_INTERFACE_INFO(USB_CLASS_WIRELESS_CONTROLLER, 1, 3), diff --git a/include/linux/usb/rndis_host.h b/include/linux/usb/rndis_host.h index 05ef52861988..88fceb718c77 100644 --- a/include/linux/usb/rndis_host.h +++ b/include/linux/usb/rndis_host.h @@ -256,6 +256,8 @@ struct rndis_keepalive_c { /* IN (optionally OUT) */ #define FLAG_RNDIS_PHYM_NOT_WIRELESS 0x0001 #define FLAG_RNDIS_PHYM_WIRELESS 0x0002 +/* Flags for driver_info::data */ +#define RNDIS_DRIVER_DATA_POLL_STATUS 1 /* poll status before control */ extern void rndis_status(struct usbnet *dev, struct urb *urb); extern int -- cgit From f1407d5c66240b33d11a7f1a41d55ccf6a9d7647 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 4 Apr 2011 13:44:59 +0900 Subject: usb: renesas_usbhs: Add Renesas USBHS common code Renesas SuperH has USBHS IP which can switch Host / Function. This driver is designed so that Host / Function may dynamically change. This patch add usb/renesas_usbhs and common code for SuperH USBHS. Signed-off-by: Kuninori Morimoto Signed-off-by: Greg Kroah-Hartman --- drivers/Makefile | 1 + drivers/usb/Kconfig | 2 + drivers/usb/renesas_usbhs/Kconfig | 15 + drivers/usb/renesas_usbhs/Makefile | 7 + drivers/usb/renesas_usbhs/common.c | 394 +++++++++++++++++ drivers/usb/renesas_usbhs/common.h | 225 ++++++++++ drivers/usb/renesas_usbhs/mod.c | 261 +++++++++++ drivers/usb/renesas_usbhs/mod.h | 106 +++++ drivers/usb/renesas_usbhs/pipe.c | 880 +++++++++++++++++++++++++++++++++++++ drivers/usb/renesas_usbhs/pipe.h | 105 +++++ include/linux/usb/renesas_usbhs.h | 149 +++++++ 11 files changed, 2145 insertions(+) create mode 100644 drivers/usb/renesas_usbhs/Kconfig create mode 100644 drivers/usb/renesas_usbhs/Makefile create mode 100644 drivers/usb/renesas_usbhs/common.c create mode 100644 drivers/usb/renesas_usbhs/common.h create mode 100644 drivers/usb/renesas_usbhs/mod.c create mode 100644 drivers/usb/renesas_usbhs/mod.h create mode 100644 drivers/usb/renesas_usbhs/pipe.c create mode 100644 drivers/usb/renesas_usbhs/pipe.h create mode 100644 include/linux/usb/renesas_usbhs.h (limited to 'include/linux') diff --git a/drivers/Makefile b/drivers/Makefile index 3f135b6fb014..ad67b7d4c271 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -67,6 +67,7 @@ obj-$(CONFIG_UWB) += uwb/ obj-$(CONFIG_USB_OTG_UTILS) += usb/otg/ obj-$(CONFIG_USB) += usb/ obj-$(CONFIG_USB_MUSB_HDRC) += usb/musb/ +obj-$(CONFIG_USB_RENESAS_USBHS) += usb/renesas_usbhs/ obj-$(CONFIG_PCI) += usb/ obj-$(CONFIG_USB_GADGET) += usb/gadget/ obj-$(CONFIG_SERIO) += input/serio/ diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 41b6e51188e4..d299906e4f00 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -115,6 +115,8 @@ source "drivers/usb/host/Kconfig" source "drivers/usb/musb/Kconfig" +source "drivers/usb/renesas_usbhs/Kconfig" + source "drivers/usb/class/Kconfig" source "drivers/usb/storage/Kconfig" diff --git a/drivers/usb/renesas_usbhs/Kconfig b/drivers/usb/renesas_usbhs/Kconfig new file mode 100644 index 000000000000..481490e5500a --- /dev/null +++ b/drivers/usb/renesas_usbhs/Kconfig @@ -0,0 +1,15 @@ +# +# Renesas USB Controller Drivers +# + +config USB_RENESAS_USBHS + tristate 'Renesas USBHS controller' + default n + help + Renesas USBHS is a discrete USB host and peripheral controller chip + that supports both full and high speed USB 2.0 data transfers. + It has nine or more configurable endpoints, and endpoint zero. + + Say "y" to link the driver statically, or "m" to build a + dynamically linked module called "renesas_usbhs" and force all + gadget drivers to also be dynamically linked. diff --git a/drivers/usb/renesas_usbhs/Makefile b/drivers/usb/renesas_usbhs/Makefile new file mode 100644 index 000000000000..d76f3dd3b9d1 --- /dev/null +++ b/drivers/usb/renesas_usbhs/Makefile @@ -0,0 +1,7 @@ +# +# for Renesas USB +# + +obj-$(CONFIG_USB_RENESAS_USBHS) += renesas_usbhs.o + +renesas_usbhs-y := common.o mod.o pipe.o diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c new file mode 100644 index 000000000000..d9ad60d1c156 --- /dev/null +++ b/drivers/usb/renesas_usbhs/common.c @@ -0,0 +1,394 @@ +/* + * Renesas USB driver + * + * Copyright (C) 2011 Renesas Solutions Corp. + * Kuninori Morimoto + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#include +#include +#include +#include +#include +#include "./common.h" + +/* + * platform call back + * + * renesas usb support platform callback function. + * Below macro call it. + * if platform doesn't have callback, it return 0 (no error) + */ +#define usbhs_platform_call(priv, func, args...)\ + (!(priv) ? -ENODEV : \ + !((priv)->pfunc->func) ? 0 : \ + (priv)->pfunc->func(args)) + +/* + * common functions + */ +u16 usbhs_read(struct usbhs_priv *priv, u32 reg) +{ + return ioread16(priv->base + reg); +} + +void usbhs_write(struct usbhs_priv *priv, u32 reg, u16 data) +{ + iowrite16(data, priv->base + reg); +} + +void usbhs_bset(struct usbhs_priv *priv, u32 reg, u16 mask, u16 data) +{ + u16 val = usbhs_read(priv, reg); + + val &= ~mask; + val |= data & mask; + + usbhs_write(priv, reg, val); +} + +/* + * syscfg functions + */ +void usbhs_sys_clock_ctrl(struct usbhs_priv *priv, int enable) +{ + usbhs_bset(priv, SYSCFG, SCKE, enable ? SCKE : 0); +} + +void usbhs_sys_hispeed_ctrl(struct usbhs_priv *priv, int enable) +{ + usbhs_bset(priv, SYSCFG, HSE, enable ? HSE : 0); +} + +void usbhs_sys_usb_ctrl(struct usbhs_priv *priv, int enable) +{ + usbhs_bset(priv, SYSCFG, USBE, enable ? USBE : 0); +} + +void usbhs_sys_host_ctrl(struct usbhs_priv *priv, int enable) +{ + u16 mask = DCFM | DRPD | DPRPU; + u16 val = DCFM | DRPD; + + /* + * if enable + * + * - select Host mode + * - D+ Line/D- Line Pull-down + */ + usbhs_bset(priv, SYSCFG, mask, enable ? val : 0); +} + +void usbhs_sys_function_ctrl(struct usbhs_priv *priv, int enable) +{ + u16 mask = DCFM | DRPD | DPRPU; + u16 val = DPRPU; + + /* + * if enable + * + * - select Function mode + * - D+ Line Pull-up + */ + usbhs_bset(priv, SYSCFG, mask, enable ? val : 0); +} + +/* + * frame functions + */ +int usbhs_frame_get_num(struct usbhs_priv *priv) +{ + return usbhs_read(priv, FRMNUM) & FRNM_MASK; +} + +/* + * local functions + */ +static struct usbhs_priv *usbhsc_pdev_to_priv(struct platform_device *pdev) +{ + return dev_get_drvdata(&pdev->dev); +} + +static void usbhsc_bus_ctrl(struct usbhs_priv *priv, int enable) +{ + int wait = usbhs_get_dparam(priv, buswait_bwait); + u16 data = 0; + + if (enable) { + /* set bus wait if platform have */ + if (wait) + usbhs_bset(priv, BUSWAIT, 0x000F, wait); + } + usbhs_write(priv, DVSTCTR, data); +} + +/* + * platform default param + */ +static u32 usbhsc_default_pipe_type[] = { + USB_ENDPOINT_XFER_CONTROL, + USB_ENDPOINT_XFER_ISOC, + USB_ENDPOINT_XFER_ISOC, + USB_ENDPOINT_XFER_BULK, + USB_ENDPOINT_XFER_BULK, + USB_ENDPOINT_XFER_BULK, + USB_ENDPOINT_XFER_INT, + USB_ENDPOINT_XFER_INT, + USB_ENDPOINT_XFER_INT, + USB_ENDPOINT_XFER_INT, +}; + +/* + * driver callback functions + */ +static void usbhsc_notify_hotplug(struct work_struct *work) +{ + struct usbhs_priv *priv = container_of(work, + struct usbhs_priv, + notify_hotplug_work); + struct platform_device *pdev = usbhs_priv_to_pdev(priv); + struct usbhs_mod *mod = usbhs_mod_get_current(priv); + int id; + int enable; + int ret; + + /* + * get vbus status from platform + */ + enable = usbhs_platform_call(priv, get_vbus, pdev); + + /* + * get id from platform + */ + id = usbhs_platform_call(priv, get_id, pdev); + + if (enable && !mod) { + ret = usbhs_mod_change(priv, id); + if (ret < 0) + return; + + dev_dbg(&pdev->dev, "%s enable\n", __func__); + + /* enable PM */ + pm_runtime_get_sync(&pdev->dev); + + /* USB on */ + usbhs_sys_clock_ctrl(priv, enable); + usbhsc_bus_ctrl(priv, enable); + + /* module start */ + usbhs_mod_call(priv, start, priv); + + } else if (!enable && mod) { + dev_dbg(&pdev->dev, "%s disable\n", __func__); + + /* module stop */ + usbhs_mod_call(priv, stop, priv); + + /* USB off */ + usbhsc_bus_ctrl(priv, enable); + usbhs_sys_clock_ctrl(priv, enable); + + /* disable PM */ + pm_runtime_put_sync(&pdev->dev); + + usbhs_mod_change(priv, -1); + + /* reset phy for next connection */ + usbhs_platform_call(priv, phy_reset, pdev); + } +} + +static int usbhsc_drvcllbck_notify_hotplug(struct platform_device *pdev) +{ + struct usbhs_priv *priv = usbhsc_pdev_to_priv(pdev); + + /* + * This functions will be called in interrupt. + * To make sure safety context, + * use workqueue for usbhs_notify_hotplug + */ + schedule_work(&priv->notify_hotplug_work); + return 0; +} + +/* + * platform functions + */ +static int __devinit usbhs_probe(struct platform_device *pdev) +{ + struct renesas_usbhs_platform_info *info = pdev->dev.platform_data; + struct renesas_usbhs_driver_callback *dfunc; + struct usbhs_priv *priv; + struct resource *res; + unsigned int irq; + int ret; + + /* check platform information */ + if (!info || + !info->platform_callback.get_id || + !info->platform_callback.get_vbus) { + dev_err(&pdev->dev, "no platform information\n"); + return -EINVAL; + } + + /* platform data */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + irq = platform_get_irq(pdev, 0); + if (!res || (int)irq <= 0) { + dev_err(&pdev->dev, "Not enough Renesas USB platform resources.\n"); + return -ENODEV; + } + + /* usb private data */ + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) { + dev_err(&pdev->dev, "Could not allocate priv\n"); + return -ENOMEM; + } + + priv->base = ioremap_nocache(res->start, resource_size(res)); + if (!priv->base) { + dev_err(&pdev->dev, "ioremap error.\n"); + ret = -ENOMEM; + goto probe_end_kfree; + } + + /* + * care platform info + */ + priv->pfunc = &info->platform_callback; + priv->dparam = &info->driver_param; + + /* set driver callback functions for platform */ + dfunc = &info->driver_callback; + dfunc->notify_hotplug = usbhsc_drvcllbck_notify_hotplug; + + /* set default param if platform doesn't have */ + if (!priv->dparam->pipe_type) { + priv->dparam->pipe_type = usbhsc_default_pipe_type; + priv->dparam->pipe_size = ARRAY_SIZE(usbhsc_default_pipe_type); + } + + /* + * priv settings + */ + priv->irq = irq; + priv->pdev = pdev; + INIT_WORK(&priv->notify_hotplug_work, usbhsc_notify_hotplug); + spin_lock_init(usbhs_priv_to_lock(priv)); + + /* call pipe and module init */ + ret = usbhs_pipe_probe(priv); + if (ret < 0) + goto probe_end_mod_exit; + + ret = usbhs_mod_probe(priv); + if (ret < 0) + goto probe_end_iounmap; + + /* dev_set_drvdata should be called after usbhs_mod_init */ + dev_set_drvdata(&pdev->dev, priv); + + /* + * deviece reset here because + * USB device might be used in boot loader. + */ + usbhs_sys_clock_ctrl(priv, 0); + + /* + * platform call + * + * USB phy setup might depend on CPU/Board. + * If platform has its callback functions, + * call it here. + */ + ret = usbhs_platform_call(priv, hardware_init, pdev); + if (ret < 0) { + dev_err(&pdev->dev, "platform prove failed.\n"); + goto probe_end_pipe_exit; + } + + /* reset phy for connection */ + usbhs_platform_call(priv, phy_reset, pdev); + + /* + * manual call notify_hotplug for cold plug + */ + pm_runtime_enable(&pdev->dev); + ret = usbhsc_drvcllbck_notify_hotplug(pdev); + if (ret < 0) + goto probe_end_call_remove; + + dev_info(&pdev->dev, "probed\n"); + + return ret; + +probe_end_call_remove: + usbhs_platform_call(priv, hardware_exit, pdev); +probe_end_pipe_exit: + usbhs_pipe_remove(priv); +probe_end_mod_exit: + usbhs_mod_remove(priv); +probe_end_iounmap: + iounmap(priv->base); +probe_end_kfree: + kfree(priv); + + dev_info(&pdev->dev, "probe failed\n"); + + return ret; +} + +static int __devexit usbhs_remove(struct platform_device *pdev) +{ + struct usbhs_priv *priv = usbhsc_pdev_to_priv(pdev); + + dev_dbg(&pdev->dev, "usb remove\n"); + + pm_runtime_disable(&pdev->dev); + + usbhsc_bus_ctrl(priv, 0); + + usbhs_platform_call(priv, hardware_exit, pdev); + usbhs_pipe_remove(priv); + usbhs_mod_remove(priv); + iounmap(priv->base); + kfree(priv); + + return 0; +} + +static struct platform_driver renesas_usbhs_driver = { + .driver = { + .name = "renesas_usbhs", + }, + .probe = usbhs_probe, + .remove = __devexit_p(usbhs_remove), +}; + +static int __init usbhs_init(void) +{ + return platform_driver_register(&renesas_usbhs_driver); +} + +static void __exit usbhs_exit(void) +{ + platform_driver_unregister(&renesas_usbhs_driver); +} + +module_init(usbhs_init); +module_exit(usbhs_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Renesas USB driver"); +MODULE_AUTHOR("Kuninori Morimoto "); diff --git a/drivers/usb/renesas_usbhs/common.h b/drivers/usb/renesas_usbhs/common.h new file mode 100644 index 000000000000..f1a2b62f93f9 --- /dev/null +++ b/drivers/usb/renesas_usbhs/common.h @@ -0,0 +1,225 @@ +/* + * Renesas USB driver + * + * Copyright (C) 2011 Renesas Solutions Corp. + * Kuninori Morimoto + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#ifndef RENESAS_USB_DRIVER_H +#define RENESAS_USB_DRIVER_H + +#include +#include + +struct usbhs_priv; + +#include "./mod.h" +#include "./pipe.h" + +/* + * + * register define + * + */ +#define SYSCFG 0x0000 +#define BUSWAIT 0x0002 +#define DVSTCTR 0x0008 +#define CFIFO 0x0014 +#define CFIFOSEL 0x0020 +#define CFIFOCTR 0x0022 +#define INTENB0 0x0030 +#define INTENB1 0x0032 +#define BRDYENB 0x0036 +#define NRDYENB 0x0038 +#define BEMPENB 0x003A +#define INTSTS0 0x0040 +#define INTSTS1 0x0042 +#define BRDYSTS 0x0046 +#define NRDYSTS 0x0048 +#define BEMPSTS 0x004A +#define FRMNUM 0x004C +#define USBREQ 0x0054 /* USB request type register */ +#define USBVAL 0x0056 /* USB request value register */ +#define USBINDX 0x0058 /* USB request index register */ +#define USBLENG 0x005A /* USB request length register */ +#define DCPCFG 0x005C +#define DCPMAXP 0x005E +#define DCPCTR 0x0060 +#define PIPESEL 0x0064 +#define PIPECFG 0x0068 +#define PIPEBUF 0x006A +#define PIPEMAXP 0x006C +#define PIPEPERI 0x006E +#define PIPEnCTR 0x0070 + +/* SYSCFG */ +#define SCKE (1 << 10) /* USB Module Clock Enable */ +#define HSE (1 << 7) /* High-Speed Operation Enable */ +#define DCFM (1 << 6) /* Controller Function Select */ +#define DRPD (1 << 5) /* D+ Line/D- Line Resistance Control */ +#define DPRPU (1 << 4) /* D+ Line Resistance Control */ +#define USBE (1 << 0) /* USB Module Operation Enable */ + +/* DVSTCTR */ +#define EXTLP (1 << 10) /* Controls the EXTLP pin output state */ +#define PWEN (1 << 9) /* Controls the PWEN pin output state */ +#define RHST (0x7) /* Reset Handshake */ +#define RHST_LOW_SPEED 1 /* Low-speed connection */ +#define RHST_FULL_SPEED 2 /* Full-speed connection */ +#define RHST_HIGH_SPEED 3 /* High-speed connection */ + +/* CFIFOSEL */ +#define MBW_32 (0x2 << 10) /* CFIFO Port Access Bit Width */ + +/* CFIFOCTR */ +#define BVAL (1 << 15) /* Buffer Memory Enable Flag */ +#define BCLR (1 << 14) /* CPU buffer clear */ +#define FRDY (1 << 13) /* FIFO Port Ready */ +#define DTLN_MASK (0x0FFF) /* Receive Data Length */ + +/* INTENB0 */ +#define VBSE (1 << 15) /* Enable IRQ VBUS_0 and VBUSIN_0 */ +#define RSME (1 << 14) /* Enable IRQ Resume */ +#define SOFE (1 << 13) /* Enable IRQ Frame Number Update */ +#define DVSE (1 << 12) /* Enable IRQ Device State Transition */ +#define CTRE (1 << 11) /* Enable IRQ Control Stage Transition */ +#define BEMPE (1 << 10) /* Enable IRQ Buffer Empty */ +#define NRDYE (1 << 9) /* Enable IRQ Buffer Not Ready Response */ +#define BRDYE (1 << 8) /* Enable IRQ Buffer Ready */ + +/* INTENB1 */ +#define BCHGE (1 << 14) /* USB Bus Change Interrupt Enable */ +#define DTCHE (1 << 12) /* Disconnection Detect Interrupt Enable */ +#define ATTCHE (1 << 11) /* Connection Detect Interrupt Enable */ +#define EOFERRE (1 << 6) /* EOF Error Detect Interrupt Enable */ +#define SIGNE (1 << 5) /* Setup Transaction Error Interrupt Enable */ +#define SACKE (1 << 4) /* Setup Transaction ACK Interrupt Enable */ + +/* INTSTS0 */ +#define DVST (1 << 12) /* Device State Transition Interrupt Status */ +#define CTRT (1 << 11) /* Control Stage Interrupt Status */ +#define BEMP (1 << 10) /* Buffer Empty Interrupt Status */ +#define BRDY (1 << 8) /* Buffer Ready Interrupt Status */ +#define VBSTS (1 << 7) /* VBUS_0 and VBUSIN_0 Input Status */ +#define VALID (1 << 3) /* USB Request Receive */ + +#define DVSQ_MASK (0x3 << 4) /* Device State */ +#define POWER_STATE (0 << 4) +#define DEFAULT_STATE (1 << 4) +#define ADDRESS_STATE (2 << 4) +#define CONFIGURATION_STATE (3 << 4) + +#define CTSQ_MASK (0x7) /* Control Transfer Stage */ +#define IDLE_SETUP_STAGE 0 /* Idle stage or setup stage */ +#define READ_DATA_STAGE 1 /* Control read data stage */ +#define READ_STATUS_STAGE 2 /* Control read status stage */ +#define WRITE_DATA_STAGE 3 /* Control write data stage */ +#define WRITE_STATUS_STAGE 4 /* Control write status stage */ +#define NODATA_STATUS_STAGE 5 /* Control write NoData status stage */ +#define SEQUENCE_ERROR 6 /* Control transfer sequence error */ + +/* PIPECFG */ +/* DCPCFG */ +#define TYPE_NONE (0 << 14) /* Transfer Type */ +#define TYPE_BULK (1 << 14) +#define TYPE_INT (2 << 14) +#define TYPE_ISO (3 << 14) +#define DBLB (1 << 9) /* Double Buffer Mode */ +#define SHTNAK (1 << 7) /* Pipe Disable in Transfer End */ +#define DIR_OUT (1 << 4) /* Transfer Direction */ + +/* PIPEMAXP */ +/* DCPMAXP */ +#define DEVSEL_MASK (0xF << 12) /* Device Select */ +#define DCP_MAXP_MASK (0x7F) +#define PIPE_MAXP_MASK (0x7FF) + +/* PIPEBUF */ +#define BUFSIZE_SHIFT 10 +#define BUFSIZE_MASK (0x1F << BUFSIZE_SHIFT) +#define BUFNMB_MASK (0xFF) + +/* PIPEnCTR */ +/* DCPCTR */ +#define BSTS (1 << 15) /* Buffer Status */ +#define CSSTS (1 << 12) /* CSSTS Status */ +#define SQCLR (1 << 8) /* Toggle Bit Clear */ +#define ACLRM (1 << 9) /* Buffer Auto-Clear Mode */ +#define PBUSY (1 << 5) /* Pipe Busy */ +#define PID_MASK (0x3) /* Response PID */ +#define PID_NAK 0 +#define PID_BUF 1 +#define PID_STALL10 2 +#define PID_STALL11 3 + +#define CCPL (1 << 2) /* Control Transfer End Enable */ + +/* FRMNUM */ +#define FRNM_MASK (0x7FF) + +/* + * struct + */ +struct usbhs_priv { + + void __iomem *base; + unsigned int irq; + + struct renesas_usbhs_platform_callback *pfunc; + struct renesas_usbhs_driver_param *dparam; + + struct work_struct notify_hotplug_work; + struct platform_device *pdev; + + spinlock_t lock; + + /* + * module control + */ + struct usbhs_mod_info mod_info; + + /* + * pipe control + */ + struct usbhs_pipe_info pipe_info; +}; + +/* + * common + */ +u16 usbhs_read(struct usbhs_priv *priv, u32 reg); +void usbhs_write(struct usbhs_priv *priv, u32 reg, u16 data); +void usbhs_bset(struct usbhs_priv *priv, u32 reg, u16 mask, u16 data); + +/* + * sysconfig + */ +void usbhs_sys_clock_ctrl(struct usbhs_priv *priv, int enable); +void usbhs_sys_hispeed_ctrl(struct usbhs_priv *priv, int enable); +void usbhs_sys_usb_ctrl(struct usbhs_priv *priv, int enable); +void usbhs_sys_host_ctrl(struct usbhs_priv *priv, int enable); +void usbhs_sys_function_ctrl(struct usbhs_priv *priv, int enable); + +/* + * frame + */ +int usbhs_frame_get_num(struct usbhs_priv *priv); + +/* + * data + */ +#define usbhs_get_dparam(priv, param) (priv->dparam->param) +#define usbhs_priv_to_pdev(priv) (priv->pdev) +#define usbhs_priv_to_dev(priv) (&priv->pdev->dev) +#define usbhs_priv_to_lock(priv) (&priv->lock) + +#endif /* RENESAS_USB_DRIVER_H */ diff --git a/drivers/usb/renesas_usbhs/mod.c b/drivers/usb/renesas_usbhs/mod.c new file mode 100644 index 000000000000..4a3398484cd7 --- /dev/null +++ b/drivers/usb/renesas_usbhs/mod.c @@ -0,0 +1,261 @@ +/* + * Renesas USB driver + * + * Copyright (C) 2011 Renesas Solutions Corp. + * Kuninori Morimoto + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#include + +#include "./common.h" +#include "./mod.h" + +#define usbhs_priv_to_modinfo(priv) (&priv->mod_info) + +/* + * host / gadget functions + * + * renesas_usbhs host/gadget can register itself by below functions. + * these functions are called when probe + * + */ +void usbhs_mod_register(struct usbhs_priv *priv, struct usbhs_mod *mod, int id) +{ + struct usbhs_mod_info *info = usbhs_priv_to_modinfo(priv); + + info->mod[id] = mod; + mod->priv = priv; +} + +struct usbhs_mod *usbhs_mod_get(struct usbhs_priv *priv, int id) +{ + struct usbhs_mod_info *info = usbhs_priv_to_modinfo(priv); + struct usbhs_mod *ret = NULL; + + switch (id) { + case USBHS_HOST: + case USBHS_GADGET: + ret = info->mod[id]; + break; + } + + return ret; +} + +int usbhs_mod_is_host(struct usbhs_priv *priv, struct usbhs_mod *mod) +{ + struct usbhs_mod_info *info = usbhs_priv_to_modinfo(priv); + + if (!mod) + return -EINVAL; + + return info->mod[USBHS_HOST] == mod; +} + +struct usbhs_mod *usbhs_mod_get_current(struct usbhs_priv *priv) +{ + struct usbhs_mod_info *info = usbhs_priv_to_modinfo(priv); + + return info->curt; +} + +int usbhs_mod_change(struct usbhs_priv *priv, int id) +{ + struct usbhs_mod_info *info = usbhs_priv_to_modinfo(priv); + struct usbhs_mod *mod = NULL; + int ret = 0; + + /* id < 0 mean no current */ + switch (id) { + case USBHS_HOST: + case USBHS_GADGET: + mod = info->mod[id]; + break; + default: + ret = -EINVAL; + } + info->curt = mod; + + return ret; +} + +static irqreturn_t usbhs_interrupt(int irq, void *data); +int usbhs_mod_probe(struct usbhs_priv *priv) +{ + struct device *dev = usbhs_priv_to_dev(priv); + int ret; + + /* irq settings */ + ret = request_irq(priv->irq, usbhs_interrupt, + IRQF_DISABLED, dev_name(dev), priv); + if (ret) + dev_err(dev, "irq request err\n"); + + return ret; +} + +void usbhs_mod_remove(struct usbhs_priv *priv) +{ + free_irq(priv->irq, priv); +} + +/* + * status functions + */ +int usbhs_status_get_usb_speed(struct usbhs_irq_state *irq_state) +{ + switch (irq_state->dvstctr & RHST) { + case RHST_LOW_SPEED: + return USB_SPEED_LOW; + case RHST_FULL_SPEED: + return USB_SPEED_FULL; + case RHST_HIGH_SPEED: + return USB_SPEED_HIGH; + } + + return USB_SPEED_UNKNOWN; +} + +int usbhs_status_get_device_state(struct usbhs_irq_state *irq_state) +{ + int state = irq_state->intsts0 & DVSQ_MASK; + + switch (state) { + case POWER_STATE: + case DEFAULT_STATE: + case ADDRESS_STATE: + case CONFIGURATION_STATE: + return state; + } + + return -EIO; +} + +int usbhs_status_get_ctrl_stage(struct usbhs_irq_state *irq_state) +{ + /* + * return value + * + * IDLE_SETUP_STAGE + * READ_DATA_STAGE + * READ_STATUS_STAGE + * WRITE_DATA_STAGE + * WRITE_STATUS_STAGE + * NODATA_STATUS_STAGE + * SEQUENCE_ERROR + */ + return (int)irq_state->intsts0 & CTSQ_MASK; +} + +static void usbhs_status_get_each_irq(struct usbhs_priv *priv, + struct usbhs_irq_state *state) +{ + struct usbhs_mod *mod = usbhs_mod_get_current(priv); + + state->intsts0 = usbhs_read(priv, INTSTS0); + state->intsts1 = usbhs_read(priv, INTSTS1); + + state->brdysts = usbhs_read(priv, BRDYSTS); + state->nrdysts = usbhs_read(priv, NRDYSTS); + state->bempsts = usbhs_read(priv, BEMPSTS); + + state->dvstctr = usbhs_read(priv, DVSTCTR); + + /* mask */ + state->bempsts &= mod->irq_bempsts; + state->brdysts &= mod->irq_brdysts; +} + +/* + * interrupt + */ +#define INTSTS0_MAGIC 0xF800 /* acknowledge magical interrupt sources */ +#define INTSTS1_MAGIC 0xA870 /* acknowledge magical interrupt sources */ +static irqreturn_t usbhs_interrupt(int irq, void *data) +{ + struct usbhs_priv *priv = data; + struct usbhs_irq_state irq_state; + + usbhs_status_get_each_irq(priv, &irq_state); + + /* + * clear interrupt + * + * The hardware is _very_ picky to clear interrupt bit. + * Especially INTSTS0_MAGIC, INTSTS1_MAGIC value. + * + * see + * "Operation" + * - "Control Transfer (DCP)" + * - Function :: VALID bit should 0 + */ + usbhs_write(priv, INTSTS0, ~irq_state.intsts0 & INTSTS0_MAGIC); + usbhs_write(priv, INTSTS1, ~irq_state.intsts1 & INTSTS1_MAGIC); + + usbhs_write(priv, BRDYSTS, 0); + usbhs_write(priv, NRDYSTS, 0); + usbhs_write(priv, BEMPSTS, 0); + + /* + * call irq callback functions + * see also + * usbhs_irq_setting_update + */ + if (irq_state.intsts0 & DVST) + usbhs_mod_call(priv, irq_dev_state, priv, &irq_state); + + if (irq_state.intsts0 & CTRT) + usbhs_mod_call(priv, irq_ctrl_stage, priv, &irq_state); + + if (irq_state.intsts0 & BEMP) + usbhs_mod_call(priv, irq_empty, priv, &irq_state); + + if (irq_state.intsts0 & BRDY) + usbhs_mod_call(priv, irq_ready, priv, &irq_state); + + return IRQ_HANDLED; +} + +void usbhs_irq_callback_update(struct usbhs_priv *priv, struct usbhs_mod *mod) +{ + u16 intenb0 = 0; + + usbhs_write(priv, INTENB0, 0); + + usbhs_write(priv, BEMPENB, 0); + usbhs_write(priv, BRDYENB, 0); + + /* + * see also + * usbhs_interrupt + */ + + /* + * it don't enable DVSE (intenb0) here + * but "mod->irq_dev_state" will be called. + */ + + if (mod->irq_ctrl_stage) + intenb0 |= CTRE; + + if (mod->irq_empty && mod->irq_bempsts) { + usbhs_write(priv, BEMPENB, mod->irq_bempsts); + intenb0 |= BEMPE; + } + + if (mod->irq_ready && mod->irq_brdysts) { + usbhs_write(priv, BRDYENB, mod->irq_brdysts); + intenb0 |= BRDYE; + } + + usbhs_write(priv, INTENB0, intenb0); +} diff --git a/drivers/usb/renesas_usbhs/mod.h b/drivers/usb/renesas_usbhs/mod.h new file mode 100644 index 000000000000..bd873d5b432a --- /dev/null +++ b/drivers/usb/renesas_usbhs/mod.h @@ -0,0 +1,106 @@ +/* + * Renesas USB driver + * + * Copyright (C) 2011 Renesas Solutions Corp. + * Kuninori Morimoto + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#ifndef RENESAS_USB_MOD_H +#define RENESAS_USB_MOD_H + +#include +#include +#include "./common.h" + +/* + * struct + */ +struct usbhs_irq_state { + u16 intsts0; + u16 intsts1; + u16 brdysts; + u16 nrdysts; + u16 bempsts; + u16 dvstctr; +}; + +struct usbhs_mod { + char *name; + + /* + * entry point from common.c + */ + int (*start)(struct usbhs_priv *priv); + int (*stop)(struct usbhs_priv *priv); + + /* INTSTS0 :: DVST (DVSQ) */ + int (*irq_dev_state)(struct usbhs_priv *priv, + struct usbhs_irq_state *irq_state); + + /* INTSTS0 :: CTRT (CTSQ) */ + int (*irq_ctrl_stage)(struct usbhs_priv *priv, + struct usbhs_irq_state *irq_state); + + /* INTSTS0 :: BEMP */ + /* BEMPSTS */ + int (*irq_empty)(struct usbhs_priv *priv, + struct usbhs_irq_state *irq_state); + u16 irq_bempsts; + + /* INTSTS0 :: BRDY */ + /* BRDYSTS */ + int (*irq_ready)(struct usbhs_priv *priv, + struct usbhs_irq_state *irq_state); + u16 irq_brdysts; + + struct usbhs_priv *priv; +}; + +struct usbhs_mod_info { + struct usbhs_mod *mod[USBHS_MAX]; + struct usbhs_mod *curt; /* current mod */ +}; + +/* + * for host/gadget module + */ +struct usbhs_mod *usbhs_mod_get(struct usbhs_priv *priv, int id); +struct usbhs_mod *usbhs_mod_get_current(struct usbhs_priv *priv); +void usbhs_mod_register(struct usbhs_priv *priv, struct usbhs_mod *usb, int id); +int usbhs_mod_is_host(struct usbhs_priv *priv, struct usbhs_mod *mod); +int usbhs_mod_change(struct usbhs_priv *priv, int id); +int usbhs_mod_probe(struct usbhs_priv *priv); +void usbhs_mod_remove(struct usbhs_priv *priv); + +/* + * status functions + */ +int usbhs_status_get_usb_speed(struct usbhs_irq_state *irq_state); +int usbhs_status_get_device_state(struct usbhs_irq_state *irq_state); +int usbhs_status_get_ctrl_stage(struct usbhs_irq_state *irq_state); + +/* + * callback functions + */ +void usbhs_irq_callback_update(struct usbhs_priv *priv, struct usbhs_mod *mod); + + +#define usbhs_mod_call(priv, func, param...) \ + ({ \ + struct usbhs_mod *mod; \ + mod = usbhs_mod_get_current(priv); \ + !mod ? -ENODEV : \ + !mod->func ? 0 : \ + mod->func(param); \ + }) + +#endif /* RENESAS_USB_MOD_H */ diff --git a/drivers/usb/renesas_usbhs/pipe.c b/drivers/usb/renesas_usbhs/pipe.c new file mode 100644 index 000000000000..b7a9137f599b --- /dev/null +++ b/drivers/usb/renesas_usbhs/pipe.c @@ -0,0 +1,880 @@ +/* + * Renesas USB driver + * + * Copyright (C) 2011 Renesas Solutions Corp. + * Kuninori Morimoto + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#include +#include +#include +#include "./common.h" +#include "./pipe.h" + +/* + * macros + */ +#define usbhsp_priv_to_pipeinfo(pr) (&(pr)->pipe_info) +#define usbhsp_pipe_to_priv(p) ((p)->priv) + +#define usbhsp_addr_offset(p) ((usbhs_pipe_number(p) - 1) * 2) + +#define usbhsp_is_dcp(p) ((p)->priv->pipe_info.pipe == (p)) + +#define usbhsp_flags_set(p, f) ((p)->flags |= USBHS_PIPE_FLAGS_##f) +#define usbhsp_flags_clr(p, f) ((p)->flags &= ~USBHS_PIPE_FLAGS_##f) +#define usbhsp_flags_has(p, f) ((p)->flags & USBHS_PIPE_FLAGS_##f) +#define usbhsp_flags_init(p) do {(p)->flags = 0; } while (0) + +#define usbhsp_type(p) ((p)->pipe_type) +#define usbhsp_type_is(p, t) ((p)->pipe_type == t) + +/* + * for debug + */ +static char *usbhsp_pipe_name[] = { + [USB_ENDPOINT_XFER_CONTROL] = "DCP", + [USB_ENDPOINT_XFER_BULK] = "BULK", + [USB_ENDPOINT_XFER_INT] = "INT", + [USB_ENDPOINT_XFER_ISOC] = "ISO", +}; + +/* + * usb request functions + */ +void usbhs_usbreq_get_val(struct usbhs_priv *priv, struct usb_ctrlrequest *req) +{ + u16 val; + + val = usbhs_read(priv, USBREQ); + req->bRequest = (val >> 8) & 0xFF; + req->bRequestType = (val >> 0) & 0xFF; + + req->wValue = usbhs_read(priv, USBVAL); + req->wIndex = usbhs_read(priv, USBINDX); + req->wLength = usbhs_read(priv, USBLENG); +} + +void usbhs_usbreq_set_val(struct usbhs_priv *priv, struct usb_ctrlrequest *req) +{ + usbhs_write(priv, USBREQ, (req->bRequest << 8) | req->bRequestType); + usbhs_write(priv, USBVAL, req->wValue); + usbhs_write(priv, USBINDX, req->wIndex); + usbhs_write(priv, USBLENG, req->wLength); +} + +/* + * DCPCTR/PIPEnCTR functions + */ +static void usbhsp_pipectrl_set(struct usbhs_pipe *pipe, u16 mask, u16 val) +{ + struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); + int offset = usbhsp_addr_offset(pipe); + + if (usbhsp_is_dcp(pipe)) + usbhs_bset(priv, DCPCTR, mask, val); + else + usbhs_bset(priv, PIPEnCTR + offset, mask, val); +} + +static u16 usbhsp_pipectrl_get(struct usbhs_pipe *pipe) +{ + struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); + int offset = usbhsp_addr_offset(pipe); + + if (usbhsp_is_dcp(pipe)) + return usbhs_read(priv, DCPCTR); + else + return usbhs_read(priv, PIPEnCTR + offset); +} + +/* + * DCP/PIPE functions + */ +static void __usbhsp_pipe_xxx_set(struct usbhs_pipe *pipe, + u16 dcp_reg, u16 pipe_reg, + u16 mask, u16 val) +{ + struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); + + if (usbhsp_is_dcp(pipe)) + usbhs_bset(priv, dcp_reg, mask, val); + else + usbhs_bset(priv, pipe_reg, mask, val); +} + +static u16 __usbhsp_pipe_xxx_get(struct usbhs_pipe *pipe, + u16 dcp_reg, u16 pipe_reg) +{ + struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); + + if (usbhsp_is_dcp(pipe)) + return usbhs_read(priv, dcp_reg); + else + return usbhs_read(priv, pipe_reg); +} + +/* + * DCPCFG/PIPECFG functions + */ +static void usbhsp_pipe_cfg_set(struct usbhs_pipe *pipe, u16 mask, u16 val) +{ + __usbhsp_pipe_xxx_set(pipe, DCPCFG, PIPECFG, mask, val); +} + +/* + * PIPEBUF + */ +static void usbhsp_pipe_buf_set(struct usbhs_pipe *pipe, u16 mask, u16 val) +{ + if (usbhsp_is_dcp(pipe)) + return; + + __usbhsp_pipe_xxx_set(pipe, 0, PIPEBUF, mask, val); +} + +/* + * DCPMAXP/PIPEMAXP + */ +static void usbhsp_pipe_maxp_set(struct usbhs_pipe *pipe, u16 mask, u16 val) +{ + __usbhsp_pipe_xxx_set(pipe, DCPMAXP, PIPEMAXP, mask, val); +} + +static u16 usbhsp_pipe_maxp_get(struct usbhs_pipe *pipe) +{ + return __usbhsp_pipe_xxx_get(pipe, DCPMAXP, PIPEMAXP); +} + +/* + * pipe control functions + */ +static void usbhsp_pipe_select(struct usbhs_pipe *pipe) +{ + struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); + + /* + * On pipe, this is necessary before + * accesses to below registers. + * + * PIPESEL : usbhsp_pipe_select + * PIPECFG : usbhsp_pipe_cfg_xxx + * PIPEBUF : usbhsp_pipe_buf_xxx + * PIPEMAXP : usbhsp_pipe_maxp_xxx + * PIPEPERI + */ + + /* + * if pipe is dcp, no pipe is selected. + * it is no problem, because dcp have its register + */ + usbhs_write(priv, PIPESEL, 0xF & usbhs_pipe_number(pipe)); +} + +static int usbhsp_pipe_barrier(struct usbhs_pipe *pipe) +{ + struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); + struct device *dev = usbhs_priv_to_dev(priv); + int timeout = 1024; + u16 val; + + /* + * make sure.... + * + * Modify these bits when CSSTS = 0, PID = NAK, and no pipe number is + * specified by the CURPIPE bits. + * When changing the setting of this bit after changing + * the PID bits for the selected pipe from BUF to NAK, + * check that CSSTS = 0 and PBUSY = 0. + */ + + /* + * CURPIPE bit = 0 + * + * see also + * "Operation" + * - "Pipe Control" + * - "Pipe Control Registers Switching Procedure" + */ + usbhs_write(priv, CFIFOSEL, 0); + + do { + val = usbhsp_pipectrl_get(pipe); + val &= CSSTS | PID_MASK; + if (!val) + return 0; + + udelay(10); + + } while (timeout--); + + /* + * force NAK + */ + timeout = 1024; + usbhs_fifo_disable(pipe); + do { + val = usbhsp_pipectrl_get(pipe); + val &= PBUSY; + if (!val) + return 0; + + } while (timeout--); + + dev_err(dev, "pipe barrier failed\n"); + + return -EBUSY; +} + +static int usbhsp_pipe_is_accessible(struct usbhs_pipe *pipe) +{ + u16 val; + + val = usbhsp_pipectrl_get(pipe); + if (val & BSTS) + return 0; + + return -EBUSY; +} + +/* + * PID ctrl + */ +static void __usbhsp_pid_try_nak_if_stall(struct usbhs_pipe *pipe) +{ + u16 pid = usbhsp_pipectrl_get(pipe); + + pid &= PID_MASK; + + /* + * see + * "Pipe n Control Register" - "PID" + */ + switch (pid) { + case PID_STALL11: + usbhsp_pipectrl_set(pipe, PID_MASK, PID_STALL10); + /* fall-through */ + case PID_STALL10: + usbhsp_pipectrl_set(pipe, PID_MASK, PID_NAK); + } +} + +void usbhs_fifo_disable(struct usbhs_pipe *pipe) +{ + /* see "Pipe n Control Register" - "PID" */ + __usbhsp_pid_try_nak_if_stall(pipe); + + usbhsp_pipectrl_set(pipe, PID_MASK, PID_NAK); +} + +void usbhs_fifo_enable(struct usbhs_pipe *pipe) +{ + /* see "Pipe n Control Register" - "PID" */ + __usbhsp_pid_try_nak_if_stall(pipe); + + usbhsp_pipectrl_set(pipe, PID_MASK, PID_BUF); +} + +void usbhs_fifo_stall(struct usbhs_pipe *pipe) +{ + u16 pid = usbhsp_pipectrl_get(pipe); + + pid &= PID_MASK; + + /* + * see + * "Pipe n Control Register" - "PID" + */ + switch (pid) { + case PID_NAK: + usbhsp_pipectrl_set(pipe, PID_MASK, PID_STALL10); + break; + case PID_BUF: + usbhsp_pipectrl_set(pipe, PID_MASK, PID_STALL11); + break; + } +} + +/* + * CFIFO ctrl + */ +void usbhs_fifo_send_terminator(struct usbhs_pipe *pipe) +{ + struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); + + usbhs_bset(priv, CFIFOCTR, BVAL, BVAL); +} + +static void usbhsp_fifo_clear(struct usbhs_pipe *pipe) +{ + struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); + + usbhs_write(priv, CFIFOCTR, BCLR); +} + +static int usbhsp_fifo_barrier(struct usbhs_priv *priv) +{ + int timeout = 1024; + + do { + /* The FIFO port is accessible */ + if (usbhs_read(priv, CFIFOCTR) & FRDY) + return 0; + + udelay(10); + } while (timeout--); + + return -EBUSY; +} + +static int usbhsp_fifo_rcv_len(struct usbhs_priv *priv) +{ + return usbhs_read(priv, CFIFOCTR) & DTLN_MASK; +} + +static int usbhsp_fifo_select(struct usbhs_pipe *pipe, int write) +{ + struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); + struct device *dev = usbhs_priv_to_dev(priv); + int timeout = 1024; + u16 mask = ((1 << 5) | 0xF); /* mask of ISEL | CURPIPE */ + u16 base = usbhs_pipe_number(pipe); /* CURPIPE */ + + if (usbhsp_is_dcp(pipe)) + base |= (1 == write) << 5; /* ISEL */ + + /* "base" will be used below */ + usbhs_write(priv, CFIFOSEL, base | MBW_32); + + /* check ISEL and CURPIPE value */ + while (timeout--) { + if (base == (mask & usbhs_read(priv, CFIFOSEL))) + return 0; + udelay(10); + } + + dev_err(dev, "fifo select error\n"); + + return -EIO; +} + +int usbhs_fifo_prepare_write(struct usbhs_pipe *pipe) +{ + int ret; + + ret = usbhsp_fifo_select(pipe, 1); + if (ret < 0) + return ret; + + usbhsp_fifo_clear(pipe); + + return ret; +} + +int usbhs_fifo_write(struct usbhs_pipe *pipe, u8 *buf, int len) +{ + struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); + void __iomem *addr = priv->base + CFIFO; + int maxp = usbhs_pipe_get_maxpacket(pipe); + int total_len; + int i, ret; + + ret = usbhsp_pipe_is_accessible(pipe); + if (ret < 0) + return ret; + + ret = usbhs_fifo_prepare_write(pipe); + if (ret < 0) + return ret; + + ret = usbhsp_fifo_barrier(priv); + if (ret < 0) + return ret; + + len = min(len, maxp); + total_len = len; + + /* + * FIXME + * + * 32-bit access only + */ + if (len >= 4 && + !((unsigned long)buf & 0x03)) { + iowrite32_rep(addr, buf, len / 4); + len %= 4; + buf += total_len - len; + } + + /* the rest operation */ + for (i = 0; i < len; i++) + iowrite8(buf[i], addr + (0x03 - (i & 0x03))); + + if (total_len < maxp) + usbhs_fifo_send_terminator(pipe); + + return total_len; +} + +int usbhs_fifo_prepare_read(struct usbhs_pipe *pipe) +{ + int ret; + + /* + * select pipe and enable it to prepare packet receive + */ + ret = usbhsp_fifo_select(pipe, 0); + if (ret < 0) + return ret; + + usbhs_fifo_enable(pipe); + + return ret; +} + +int usbhs_fifo_read(struct usbhs_pipe *pipe, u8 *buf, int len) +{ + struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); + void __iomem *addr = priv->base + CFIFO; + int rcv_len; + int i, ret; + int total_len; + u32 data = 0; + + ret = usbhsp_fifo_select(pipe, 0); + if (ret < 0) + return ret; + + ret = usbhsp_fifo_barrier(priv); + if (ret < 0) + return ret; + + rcv_len = usbhsp_fifo_rcv_len(priv); + + /* + * Buffer clear if Zero-Length packet + * + * see + * "Operation" - "FIFO Buffer Memory" - "FIFO Port Function" + */ + if (0 == rcv_len) { + usbhsp_fifo_clear(pipe); + return 0; + } + + len = min(rcv_len, len); + total_len = len; + + /* + * FIXME + * + * 32-bit access only + */ + if (len >= 4 && + !((unsigned long)buf & 0x03)) { + ioread32_rep(addr, buf, len / 4); + len %= 4; + buf += rcv_len - len; + } + + /* the rest operation */ + for (i = 0; i < len; i++) { + if (!(i & 0x03)) + data = ioread32(addr); + + buf[i] = (data >> ((i & 0x03) * 8)) & 0xff; + } + + return total_len; +} + +/* + * pipe setup + */ +static int usbhsp_possible_double_buffer(struct usbhs_pipe *pipe) +{ + /* + * only ISO / BULK pipe can use double buffer + */ + if (usbhsp_type_is(pipe, USB_ENDPOINT_XFER_BULK) || + usbhsp_type_is(pipe, USB_ENDPOINT_XFER_ISOC)) + return 1; + + return 0; +} + +static u16 usbhsp_setup_pipecfg(struct usbhs_pipe *pipe, + const struct usb_endpoint_descriptor *desc, + int is_host) +{ + u16 type = 0; + u16 bfre = 0; + u16 dblb = 0; + u16 cntmd = 0; + u16 dir = 0; + u16 epnum = 0; + u16 shtnak = 0; + u16 type_array[] = { + [USB_ENDPOINT_XFER_BULK] = TYPE_BULK, + [USB_ENDPOINT_XFER_INT] = TYPE_INT, + [USB_ENDPOINT_XFER_ISOC] = TYPE_ISO, + }; + int is_double = usbhsp_possible_double_buffer(pipe); + + if (usbhsp_is_dcp(pipe)) + return -EINVAL; + + /* + * PIPECFG + * + * see + * - "Register Descriptions" - "PIPECFG" register + * - "Features" - "Pipe configuration" + * - "Operation" - "Pipe Control" + */ + + /* TYPE */ + type = type_array[usbhsp_type(pipe)]; + + /* BFRE */ + if (usbhsp_type_is(pipe, USB_ENDPOINT_XFER_ISOC) || + usbhsp_type_is(pipe, USB_ENDPOINT_XFER_BULK)) + bfre = 0; /* FIXME */ + + /* DBLB */ + if (usbhsp_type_is(pipe, USB_ENDPOINT_XFER_ISOC) || + usbhsp_type_is(pipe, USB_ENDPOINT_XFER_BULK)) + dblb = (is_double) ? DBLB : 0; + + /* CNTMD */ + if (usbhsp_type_is(pipe, USB_ENDPOINT_XFER_BULK)) + cntmd = 0; /* FIXME */ + + /* DIR */ + if (usb_endpoint_dir_in(desc)) + usbhsp_flags_set(pipe, IS_DIR_IN); + + if ((is_host && usb_endpoint_dir_out(desc)) || + (!is_host && usb_endpoint_dir_in(desc))) + dir |= DIR_OUT; + + /* SHTNAK */ + if (usbhsp_type_is(pipe, USB_ENDPOINT_XFER_BULK) && + !dir) + shtnak = SHTNAK; + + /* EPNUM */ + epnum = 0xF & usb_endpoint_num(desc); + + return type | + bfre | + dblb | + cntmd | + dir | + shtnak | + epnum; +} + +static u16 usbhsp_setup_pipemaxp(struct usbhs_pipe *pipe, + const struct usb_endpoint_descriptor *desc, + int is_host) +{ + /* host should set DEVSEL */ + + /* reutn MXPS */ + return PIPE_MAXP_MASK & le16_to_cpu(desc->wMaxPacketSize); +} + +static u16 usbhsp_setup_pipebuff(struct usbhs_pipe *pipe, + const struct usb_endpoint_descriptor *desc, + int is_host) +{ + struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); + struct usbhs_pipe_info *info = usbhsp_priv_to_pipeinfo(priv); + struct device *dev = usbhs_priv_to_dev(priv); + int pipe_num = usbhs_pipe_number(pipe); + int is_double = usbhsp_possible_double_buffer(pipe); + u16 buff_size; + u16 bufnmb; + u16 bufnmb_cnt; + + /* + * PIPEBUF + * + * see + * - "Register Descriptions" - "PIPEBUF" register + * - "Features" - "Pipe configuration" + * - "Operation" - "FIFO Buffer Memory" + * - "Operation" - "Pipe Control" + * + * ex) if pipe6 - pipe9 are USB_ENDPOINT_XFER_INT (SH7724) + * + * BUFNMB: PIPE + * 0: pipe0 (DCP 256byte) + * 1: - + * 2: - + * 3: - + * 4: pipe6 (INT 64byte) + * 5: pipe7 (INT 64byte) + * 6: pipe8 (INT 64byte) + * 7: pipe9 (INT 64byte) + * 8 - xx: free (for BULK, ISOC) + */ + + /* + * FIXME + * + * it doesn't have good buffer allocator + * + * DCP : 256 byte + * BULK: 512 byte + * INT : 64 byte + * ISOC: 512 byte + */ + if (usbhsp_type_is(pipe, USB_ENDPOINT_XFER_CONTROL)) + buff_size = 256; + else if (usbhsp_type_is(pipe, USB_ENDPOINT_XFER_INT)) + buff_size = 64; + else + buff_size = 512; + + /* change buff_size to register value */ + bufnmb_cnt = (buff_size / 64) - 1; + + /* BUFNMB has been reserved for INT pipe + * see above */ + if (usbhsp_type_is(pipe, USB_ENDPOINT_XFER_INT)) { + bufnmb = pipe_num - 2; + } else { + bufnmb = info->bufnmb_last; + info->bufnmb_last += bufnmb_cnt + 1; + + /* + * double buffer + */ + if (is_double) + info->bufnmb_last += bufnmb_cnt + 1; + } + + dev_dbg(dev, "pipe : %d : buff_size 0x%x: bufnmb 0x%x\n", + pipe_num, buff_size, bufnmb); + + return (0x1f & bufnmb_cnt) << 10 | + (0xff & bufnmb) << 0; +} + +/* + * pipe control + */ +int usbhs_pipe_get_maxpacket(struct usbhs_pipe *pipe) +{ + u16 mask = usbhsp_is_dcp(pipe) ? DCP_MAXP_MASK : PIPE_MAXP_MASK; + + usbhsp_pipe_select(pipe); + + return (int)(usbhsp_pipe_maxp_get(pipe) & mask); +} + +int usbhs_pipe_is_dir_in(struct usbhs_pipe *pipe) +{ + return usbhsp_flags_has(pipe, IS_DIR_IN); +} + +void usbhs_pipe_clear_sequence(struct usbhs_pipe *pipe) +{ + usbhsp_pipectrl_set(pipe, SQCLR, SQCLR); +} + +static struct usbhs_pipe *usbhsp_get_pipe(struct usbhs_priv *priv, u32 type) +{ + struct usbhs_pipe *pos, *pipe; + int i; + + /* + * find target pipe + */ + pipe = NULL; + usbhs_for_each_pipe_with_dcp(pos, priv, i) { + if (!usbhsp_type_is(pos, type)) + continue; + if (usbhsp_flags_has(pos, IS_USED)) + continue; + + pipe = pos; + break; + } + + if (!pipe) + return NULL; + + /* + * initialize pipe flags + */ + usbhsp_flags_init(pipe); + usbhsp_flags_set(pipe, IS_USED); + + return pipe; +} + +void usbhs_pipe_init(struct usbhs_priv *priv) +{ + struct usbhs_pipe_info *info = usbhsp_priv_to_pipeinfo(priv); + struct usbhs_pipe *pipe; + int i; + + /* + * FIXME + * + * driver needs good allocator. + * + * find first free buffer area (BULK, ISOC) + * (DCP, INT area is fixed) + * + * buffer number 0 - 3 have been reserved for DCP + * see + * usbhsp_to_bufnmb + */ + info->bufnmb_last = 4; + usbhs_for_each_pipe_with_dcp(pipe, priv, i) { + if (usbhsp_type_is(pipe, USB_ENDPOINT_XFER_INT)) + info->bufnmb_last++; + + usbhsp_flags_init(pipe); + pipe->mod_private = NULL; + } +} + +struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv, + const struct usb_endpoint_descriptor *desc) +{ + struct device *dev = usbhs_priv_to_dev(priv); + struct usbhs_mod *mod = usbhs_mod_get_current(priv); + struct usbhs_pipe *pipe; + int is_host = usbhs_mod_is_host(priv, mod); + int ret; + u16 pipecfg, pipebuf, pipemaxp; + + pipe = usbhsp_get_pipe(priv, usb_endpoint_type(desc)); + if (!pipe) + return NULL; + + usbhs_fifo_disable(pipe); + + /* make sure pipe is not busy */ + ret = usbhsp_pipe_barrier(pipe); + if (ret < 0) { + dev_err(dev, "pipe setup failed %d\n", usbhs_pipe_number(pipe)); + return NULL; + } + + pipecfg = usbhsp_setup_pipecfg(pipe, desc, is_host); + pipebuf = usbhsp_setup_pipebuff(pipe, desc, is_host); + pipemaxp = usbhsp_setup_pipemaxp(pipe, desc, is_host); + + /* buffer clear + * see PIPECFG :: BFRE */ + usbhsp_pipectrl_set(pipe, ACLRM, ACLRM); + usbhsp_pipectrl_set(pipe, ACLRM, 0); + + usbhsp_pipe_select(pipe); + usbhsp_pipe_cfg_set(pipe, 0xFFFF, pipecfg); + usbhsp_pipe_buf_set(pipe, 0xFFFF, pipebuf); + usbhsp_pipe_maxp_set(pipe, 0xFFFF, pipemaxp); + + usbhs_pipe_clear_sequence(pipe); + + dev_dbg(dev, "enable pipe %d : %s (%s)\n", + usbhs_pipe_number(pipe), + usbhsp_pipe_name[usb_endpoint_type(desc)], + usbhs_pipe_is_dir_in(pipe) ? "in" : "out"); + + return pipe; +} + +/* + * dcp control + */ +struct usbhs_pipe *usbhs_dcp_malloc(struct usbhs_priv *priv) +{ + struct usbhs_pipe *pipe; + + pipe = usbhsp_get_pipe(priv, USB_ENDPOINT_XFER_CONTROL); + if (!pipe) + return NULL; + + /* + * dcpcfg : default + * dcpmaxp : default + * pipebuf : nothing to do + */ + + usbhsp_pipe_select(pipe); + usbhs_pipe_clear_sequence(pipe); + + return pipe; +} + +void usbhs_dcp_control_transfer_done(struct usbhs_pipe *pipe) +{ + WARN_ON(!usbhsp_is_dcp(pipe)); + + usbhs_fifo_enable(pipe); + usbhsp_pipectrl_set(pipe, CCPL, CCPL); +} + + +/* + * pipe module function + */ +int usbhs_pipe_probe(struct usbhs_priv *priv) +{ + struct usbhs_pipe_info *info = usbhsp_priv_to_pipeinfo(priv); + struct usbhs_pipe *pipe; + struct device *dev = usbhs_priv_to_dev(priv); + u32 *pipe_type = usbhs_get_dparam(priv, pipe_type); + int pipe_size = usbhs_get_dparam(priv, pipe_size); + int i; + + /* This driver expects 1st pipe is DCP */ + if (pipe_type[0] != USB_ENDPOINT_XFER_CONTROL) { + dev_err(dev, "1st PIPE is not DCP\n"); + return -EINVAL; + } + + info->pipe = kzalloc(sizeof(struct usbhs_pipe) * pipe_size, GFP_KERNEL); + if (!info->pipe) { + dev_err(dev, "Could not allocate pipe\n"); + return -ENOMEM; + } + + info->size = pipe_size; + + /* + * init pipe + */ + usbhs_for_each_pipe_with_dcp(pipe, priv, i) { + pipe->priv = priv; + usbhsp_type(pipe) = pipe_type[i] & USB_ENDPOINT_XFERTYPE_MASK; + + dev_dbg(dev, "pipe %x\t: %s\n", + i, usbhsp_pipe_name[pipe_type[i]]); + } + + return 0; +} + +void usbhs_pipe_remove(struct usbhs_priv *priv) +{ + struct usbhs_pipe_info *info = usbhsp_priv_to_pipeinfo(priv); + + kfree(info->pipe); +} diff --git a/drivers/usb/renesas_usbhs/pipe.h b/drivers/usb/renesas_usbhs/pipe.h new file mode 100644 index 000000000000..4a60dcef9676 --- /dev/null +++ b/drivers/usb/renesas_usbhs/pipe.h @@ -0,0 +1,105 @@ +/* + * Renesas USB driver + * + * Copyright (C) 2011 Renesas Solutions Corp. + * Kuninori Morimoto + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#ifndef RENESAS_USB_PIPE_H +#define RENESAS_USB_PIPE_H + +#include "./common.h" + +/* + * struct + */ +struct usbhs_pipe { + u32 pipe_type; /* USB_ENDPOINT_XFER_xxx */ + + struct usbhs_priv *priv; + + u32 flags; +#define USBHS_PIPE_FLAGS_IS_USED (1 << 0) +#define USBHS_PIPE_FLAGS_IS_DIR_IN (1 << 1) + + void *mod_private; +}; + +struct usbhs_pipe_info { + struct usbhs_pipe *pipe; + int size; /* array size of "pipe" */ + int bufnmb_last; /* FIXME : driver needs good allocator */ +}; + +/* + * pipe list + */ +#define __usbhs_for_each_pipe(start, pos, info, i) \ + for (i = start, pos = (info)->pipe; \ + i < (info)->size; \ + i++, pos = (info)->pipe + i) + +#define usbhs_for_each_pipe(pos, priv, i) \ + __usbhs_for_each_pipe(1, pos, &((priv)->pipe_info), i) + +#define usbhs_for_each_pipe_with_dcp(pos, priv, i) \ + __usbhs_for_each_pipe(0, pos, &((priv)->pipe_info), i) + +/* + * pipe module probe / remove + */ +int usbhs_pipe_probe(struct usbhs_priv *priv); +void usbhs_pipe_remove(struct usbhs_priv *priv); + +/* + * cfifo + */ +int usbhs_fifo_write(struct usbhs_pipe *pipe, u8 *buf, int len); +int usbhs_fifo_read(struct usbhs_pipe *pipe, u8 *buf, int len); +int usbhs_fifo_prepare_write(struct usbhs_pipe *pipe); +int usbhs_fifo_prepare_read(struct usbhs_pipe *pipe); + +void usbhs_fifo_enable(struct usbhs_pipe *pipe); +void usbhs_fifo_disable(struct usbhs_pipe *pipe); +void usbhs_fifo_stall(struct usbhs_pipe *pipe); + +void usbhs_fifo_send_terminator(struct usbhs_pipe *pipe); + + +/* + * usb request + */ +void usbhs_usbreq_get_val(struct usbhs_priv *priv, struct usb_ctrlrequest *req); +void usbhs_usbreq_set_val(struct usbhs_priv *priv, struct usb_ctrlrequest *req); + +/* + * pipe control + */ +struct usbhs_pipe +*usbhs_pipe_malloc(struct usbhs_priv *priv, + const struct usb_endpoint_descriptor *desc); + +int usbhs_pipe_is_dir_in(struct usbhs_pipe *pipe); +void usbhs_pipe_init(struct usbhs_priv *priv); +int usbhs_pipe_get_maxpacket(struct usbhs_pipe *pipe); +void usbhs_pipe_clear_sequence(struct usbhs_pipe *pipe); + +#define usbhs_pipe_number(p) (((u32)(p) - (u32)(p)->priv->pipe_info.pipe) / \ + sizeof(struct usbhs_pipe)) + +/* + * dcp control + */ +struct usbhs_pipe *usbhs_dcp_malloc(struct usbhs_priv *priv); +void usbhs_dcp_control_transfer_done(struct usbhs_pipe *pipe); + +#endif /* RENESAS_USB_PIPE_H */ diff --git a/include/linux/usb/renesas_usbhs.h b/include/linux/usb/renesas_usbhs.h new file mode 100644 index 000000000000..565bca3aa440 --- /dev/null +++ b/include/linux/usb/renesas_usbhs.h @@ -0,0 +1,149 @@ +/* + * Renesas USB + * + * Copyright (C) 2011 Renesas Solutions Corp. + * Kuninori Morimoto + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#ifndef RENESAS_USB_H +#define RENESAS_USB_H +#include +#include + +/* + * module type + * + * it will be return value from get_id + */ +enum { + USBHS_HOST = 0, + USBHS_GADGET, + USBHS_MAX, +}; + +/* + * callback functions table for driver + * + * These functions are called from platform for driver. + * Callback function's pointer will be set before + * renesas_usbhs_platform_callback :: hardware_init was called + */ +struct renesas_usbhs_driver_callback { + int (*notify_hotplug)(struct platform_device *pdev); +}; + +/* + * callback functions for platform + * + * These functions are called from driver for platform + */ +struct renesas_usbhs_platform_callback { + + /* + * option: + * + * Hardware init function for platform. + * it is called when driver was probed. + */ + int (*hardware_init)(struct platform_device *pdev); + + /* + * option: + * + * Hardware exit function for platform. + * it is called when driver was removed + */ + void (*hardware_exit)(struct platform_device *pdev); + + /* + * option: + * + * Phy reset for platform + */ + void (*phy_reset)(struct platform_device *pdev); + + /* + * get USB ID function + * - USBHS_HOST + * - USBHS_GADGET + */ + int (*get_id)(struct platform_device *pdev); + + /* + * get VBUS status function. + */ + int (*get_vbus)(struct platform_device *pdev); +}; + +/* + * parameters for renesas usbhs + * + * some register needs USB chip specific parameters. + * This struct show it to driver + */ +struct renesas_usbhs_driver_param { + /* + * pipe settings + */ + u32 *pipe_type; /* array of USB_ENDPOINT_XFER_xxx (from ep0) */ + int pipe_size; /* pipe_type array size */ + + /* + * option: + * + * for BUSWAIT :: BWAIT + * */ + int buswait_bwait; +}; + +/* + * option: + * + * platform information for renesas_usbhs driver. + */ +struct renesas_usbhs_platform_info { + /* + * option: + * + * platform set these functions before + * call platform_add_devices if needed + */ + struct renesas_usbhs_platform_callback platform_callback; + + /* + * driver set these callback functions pointer. + * platform can use it on callback functions + */ + struct renesas_usbhs_driver_callback driver_callback; + + /* + * option: + * + * driver use these param for some register + */ + struct renesas_usbhs_driver_param driver_param; +}; + +/* + * macro for platform + */ +#define renesas_usbhs_get_info(pdev)\ + ((struct renesas_usbhs_platform_info *)(pdev)->dev.platform_data) + +#define renesas_usbhs_call_notify_hotplug(pdev) \ + ({ \ + struct renesas_usbhs_driver_callback *dc; \ + dc = &(renesas_usbhs_get_info(pdev)->driver_callback); \ + if (dc) \ + dc->notify_hotplug(pdev); \ + }) +#endif /* RENESAS_USB_H */ -- cgit From 3ab810f19d71f4083be44b41770bcd784ff82e51 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 1 Apr 2011 11:24:30 -0700 Subject: usb gadget: fix all Section mismatch warnings Fix 41 occurrences of this type of Section mismatch warning in g_mass_storage, g_serial, g_cdc, g_multi, g_nokia, g_ether, g_ffs: (the 75 number reported earlier contained some duplicates.) WARNING: drivers/usb/gadget/g_mass_storage.o(.text+0x687a): Section mismatch in reference from the function fsg_bind() to the function .devinit.text:usb_ep_autoconfig() The function fsg_bind() references the function __devinit usb_ep_autoconfig(). This is often because fsg_bind lacks a __devinit annotation or the annotation of usb_ep_autoconfig is wrong. Also remove __devinit from usb_ep_autoconfig_reset() to prevent possible section mismatch problems with it. Signed-off-by: Randy Dunlap Cc: Alan Stern Signed-off-by: Greg Kroah-Hartman --- include/linux/usb/gadget.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index e538172c0f64..dd1571db55e7 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -890,8 +890,8 @@ static inline void usb_free_descriptors(struct usb_descriptor_header **v) /* utility wrapping a simple endpoint selection policy */ extern struct usb_ep *usb_ep_autoconfig(struct usb_gadget *, - struct usb_endpoint_descriptor *) __devinit; + struct usb_endpoint_descriptor *); -extern void usb_ep_autoconfig_reset(struct usb_gadget *) __devinit; +extern void usb_ep_autoconfig_reset(struct usb_gadget *); #endif /* __LINUX_USB_GADGET_H */ -- cgit From c326de88b8ac7ed1cd1027017ba6079dbe91be49 Mon Sep 17 00:00:00 2001 From: "Mathieu J. Poirier" Date: Wed, 13 Apr 2011 17:13:00 -0700 Subject: net: allow shifted access in smsc911x V2 This is a revised patch that permits a shifted access to the LAN9221 registers. More specifically: It adds a shift parameter in the platform_data. It introduces an ops in smsc911x_data. A choice of access function to use at run-time. Four new shifted access function. Signed-off-by: Mathieu Poirier Signed-off-by: Alessandro Rubini Signed-off-by: David S. Miller --- drivers/net/smsc911x.c | 156 ++++++++++++++++++++++++++++++++++++++++++++--- include/linux/smsc911x.h | 1 + 2 files changed, 150 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index b8faab7780da..c6d47d10590c 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c @@ -71,6 +71,17 @@ static int debug = 3; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); +struct smsc911x_data; + +struct smsc911x_ops { + u32 (*reg_read)(struct smsc911x_data *pdata, u32 reg); + void (*reg_write)(struct smsc911x_data *pdata, u32 reg, u32 val); + void (*rx_readfifo)(struct smsc911x_data *pdata, + unsigned int *buf, unsigned int wordcount); + void (*tx_writefifo)(struct smsc911x_data *pdata, + unsigned int *buf, unsigned int wordcount); +}; + struct smsc911x_data { void __iomem *ioaddr; @@ -118,8 +129,14 @@ struct smsc911x_data { unsigned int clear_bits_mask; unsigned int hashhi; unsigned int hashlo; + + /* register access functions */ + const struct smsc911x_ops *ops; }; +/* Easy access to information */ +#define __smsc_shift(pdata, reg) ((reg) << ((pdata)->config.shift)) + static inline u32 __smsc911x_reg_read(struct smsc911x_data *pdata, u32 reg) { if (pdata->config.flags & SMSC911X_USE_32BIT) @@ -133,13 +150,29 @@ static inline u32 __smsc911x_reg_read(struct smsc911x_data *pdata, u32 reg) return 0; } +static inline u32 +__smsc911x_reg_read_shift(struct smsc911x_data *pdata, u32 reg) +{ + if (pdata->config.flags & SMSC911X_USE_32BIT) + return readl(pdata->ioaddr + __smsc_shift(pdata, reg)); + + if (pdata->config.flags & SMSC911X_USE_16BIT) + return (readw(pdata->ioaddr + + __smsc_shift(pdata, reg)) & 0xFFFF) | + ((readw(pdata->ioaddr + + __smsc_shift(pdata, reg + 2)) & 0xFFFF) << 16); + + BUG(); + return 0; +} + static inline u32 smsc911x_reg_read(struct smsc911x_data *pdata, u32 reg) { u32 data; unsigned long flags; spin_lock_irqsave(&pdata->dev_lock, flags); - data = __smsc911x_reg_read(pdata, reg); + data = pdata->ops->reg_read(pdata, reg); spin_unlock_irqrestore(&pdata->dev_lock, flags); return data; @@ -162,13 +195,32 @@ static inline void __smsc911x_reg_write(struct smsc911x_data *pdata, u32 reg, BUG(); } +static inline void +__smsc911x_reg_write_shift(struct smsc911x_data *pdata, u32 reg, u32 val) +{ + if (pdata->config.flags & SMSC911X_USE_32BIT) { + writel(val, pdata->ioaddr + __smsc_shift(pdata, reg)); + return; + } + + if (pdata->config.flags & SMSC911X_USE_16BIT) { + writew(val & 0xFFFF, + pdata->ioaddr + __smsc_shift(pdata, reg)); + writew((val >> 16) & 0xFFFF, + pdata->ioaddr + __smsc_shift(pdata, reg + 2)); + return; + } + + BUG(); +} + static inline void smsc911x_reg_write(struct smsc911x_data *pdata, u32 reg, u32 val) { unsigned long flags; spin_lock_irqsave(&pdata->dev_lock, flags); - __smsc911x_reg_write(pdata, reg, val); + pdata->ops->reg_write(pdata, reg, val); spin_unlock_irqrestore(&pdata->dev_lock, flags); } @@ -204,6 +256,40 @@ out: spin_unlock_irqrestore(&pdata->dev_lock, flags); } +/* Writes a packet to the TX_DATA_FIFO - shifted version */ +static inline void +smsc911x_tx_writefifo_shift(struct smsc911x_data *pdata, unsigned int *buf, + unsigned int wordcount) +{ + unsigned long flags; + + spin_lock_irqsave(&pdata->dev_lock, flags); + + if (pdata->config.flags & SMSC911X_SWAP_FIFO) { + while (wordcount--) + __smsc911x_reg_write_shift(pdata, TX_DATA_FIFO, + swab32(*buf++)); + goto out; + } + + if (pdata->config.flags & SMSC911X_USE_32BIT) { + writesl(pdata->ioaddr + __smsc_shift(pdata, + TX_DATA_FIFO), buf, wordcount); + goto out; + } + + if (pdata->config.flags & SMSC911X_USE_16BIT) { + while (wordcount--) + __smsc911x_reg_write_shift(pdata, + TX_DATA_FIFO, *buf++); + goto out; + } + + BUG(); +out: + spin_unlock_irqrestore(&pdata->dev_lock, flags); +} + /* Reads a packet out of the RX_DATA_FIFO */ static inline void smsc911x_rx_readfifo(struct smsc911x_data *pdata, unsigned int *buf, @@ -236,6 +322,40 @@ out: spin_unlock_irqrestore(&pdata->dev_lock, flags); } +/* Reads a packet out of the RX_DATA_FIFO - shifted version */ +static inline void +smsc911x_rx_readfifo_shift(struct smsc911x_data *pdata, unsigned int *buf, + unsigned int wordcount) +{ + unsigned long flags; + + spin_lock_irqsave(&pdata->dev_lock, flags); + + if (pdata->config.flags & SMSC911X_SWAP_FIFO) { + while (wordcount--) + *buf++ = swab32(__smsc911x_reg_read_shift(pdata, + RX_DATA_FIFO)); + goto out; + } + + if (pdata->config.flags & SMSC911X_USE_32BIT) { + readsl(pdata->ioaddr + __smsc_shift(pdata, + RX_DATA_FIFO), buf, wordcount); + goto out; + } + + if (pdata->config.flags & SMSC911X_USE_16BIT) { + while (wordcount--) + *buf++ = __smsc911x_reg_read_shift(pdata, + RX_DATA_FIFO); + goto out; + } + + BUG(); +out: + spin_unlock_irqrestore(&pdata->dev_lock, flags); +} + /* waits for MAC not busy, with timeout. Only called by smsc911x_mac_read * and smsc911x_mac_write, so assumes mac_lock is held */ static int smsc911x_mac_complete(struct smsc911x_data *pdata) @@ -500,7 +620,7 @@ static int smsc911x_phy_check_loopbackpkt(struct smsc911x_data *pdata) wrsz += (u32)((ulong)pdata->loopback_tx_pkt & 0x3); wrsz >>= 2; - smsc911x_tx_writefifo(pdata, (unsigned int *)bufp, wrsz); + pdata->ops->tx_writefifo(pdata, (unsigned int *)bufp, wrsz); /* Wait till transmit is done */ i = 60; @@ -544,7 +664,7 @@ static int smsc911x_phy_check_loopbackpkt(struct smsc911x_data *pdata) rdsz += (u32)((ulong)pdata->loopback_rx_pkt & 0x3); rdsz >>= 2; - smsc911x_rx_readfifo(pdata, (unsigned int *)bufp, rdsz); + pdata->ops->rx_readfifo(pdata, (unsigned int *)bufp, rdsz); if (pktlength != (MIN_PACKET_SIZE + 4)) { SMSC_WARN(pdata, hw, "Unexpected packet size " @@ -1046,8 +1166,8 @@ static int smsc911x_poll(struct napi_struct *napi, int budget) /* Align IP on 16B boundary */ skb_reserve(skb, NET_IP_ALIGN); skb_put(skb, pktlength - 4); - smsc911x_rx_readfifo(pdata, (unsigned int *)skb->head, - pktwords); + pdata->ops->rx_readfifo(pdata, + (unsigned int *)skb->head, pktwords); skb->protocol = eth_type_trans(skb, dev); skb_checksum_none_assert(skb); netif_receive_skb(skb); @@ -1351,7 +1471,7 @@ static int smsc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) wrsz += (u32)((ulong)skb->data & 0x3); wrsz >>= 2; - smsc911x_tx_writefifo(pdata, (unsigned int *)bufp, wrsz); + pdata->ops->tx_writefifo(pdata, (unsigned int *)bufp, wrsz); freespace -= (skb->len + 32); dev_kfree_skb(skb); @@ -1957,6 +2077,22 @@ static int __devexit smsc911x_drv_remove(struct platform_device *pdev) return 0; } +/* standard register acces */ +static const struct smsc911x_ops standard_smsc911x_ops = { + .reg_read = __smsc911x_reg_read, + .reg_write = __smsc911x_reg_write, + .rx_readfifo = smsc911x_rx_readfifo, + .tx_writefifo = smsc911x_tx_writefifo, +}; + +/* shifted register access */ +static const struct smsc911x_ops shifted_smsc911x_ops = { + .reg_read = __smsc911x_reg_read_shift, + .reg_write = __smsc911x_reg_write_shift, + .rx_readfifo = smsc911x_rx_readfifo_shift, + .tx_writefifo = smsc911x_tx_writefifo_shift, +}; + static int __devinit smsc911x_drv_probe(struct platform_device *pdev) { struct net_device *dev; @@ -2026,6 +2162,12 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev) goto out_free_netdev_2; } + /* assume standard, non-shifted, access to HW registers */ + pdata->ops = &standard_smsc911x_ops; + /* apply the right access if shifting is needed */ + if (config->shift) + pdata->ops = &shifted_smsc911x_ops; + retval = smsc911x_init(dev); if (retval < 0) goto out_unmap_io_3; diff --git a/include/linux/smsc911x.h b/include/linux/smsc911x.h index 7144e8aa1e41..4dde70e74822 100644 --- a/include/linux/smsc911x.h +++ b/include/linux/smsc911x.h @@ -29,6 +29,7 @@ struct smsc911x_platform_config { unsigned int irq_polarity; unsigned int irq_type; unsigned int flags; + unsigned int shift; phy_interface_t phy_interface; unsigned char mac[6]; }; -- cgit From 184748cc50b2dceb8287f9fb657eda48ff8fcfe7 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 5 Apr 2011 17:23:39 +0200 Subject: sched: Provide scheduler_ipi() callback in response to smp_send_reschedule() For future rework of try_to_wake_up() we'd like to push part of that function onto the CPU the task is actually going to run on. In order to do so we need a generic callback from the existing scheduler IPI. This patch introduces such a generic callback: scheduler_ipi() and implements it as a NOP. BenH notes: PowerPC might use this IPI on offline CPUs under rare conditions! Acked-by: Russell King Acked-by: Martin Schwidefsky Acked-by: Chris Metcalf Acked-by: Jesper Nilsson Acked-by: Benjamin Herrenschmidt Signed-off-by: Ralf Baechle Reviewed-by: Frank Rowand Cc: Mike Galbraith Cc: Nick Piggin Cc: Linus Torvalds Cc: Andrew Morton Signed-off-by: Ingo Molnar Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/20110405152728.744338123@chello.nl --- arch/alpha/kernel/smp.c | 3 +-- arch/arm/kernel/smp.c | 5 +---- arch/blackfin/mach-common/smp.c | 3 +++ arch/cris/arch-v32/kernel/smp.c | 13 ++++++++----- arch/ia64/kernel/irq_ia64.c | 2 ++ arch/ia64/xen/irq_xen.c | 10 +++++++++- arch/m32r/kernel/smp.c | 4 +--- arch/mips/cavium-octeon/smp.c | 2 ++ arch/mips/kernel/smtc.c | 2 +- arch/mips/mti-malta/malta-int.c | 2 ++ arch/mips/pmc-sierra/yosemite/smp.c | 4 ++++ arch/mips/sgi-ip27/ip27-irq.c | 2 ++ arch/mips/sibyte/bcm1480/smp.c | 7 +++---- arch/mips/sibyte/sb1250/smp.c | 7 +++---- arch/mn10300/kernel/smp.c | 5 +---- arch/parisc/kernel/smp.c | 5 +---- arch/powerpc/kernel/smp.c | 4 ++-- arch/s390/kernel/smp.c | 6 +++--- arch/sh/kernel/smp.c | 2 ++ arch/sparc/kernel/smp_32.c | 4 +++- arch/sparc/kernel/smp_64.c | 1 + arch/tile/kernel/smp.c | 6 +----- arch/um/kernel/smp.c | 2 +- arch/x86/kernel/smp.c | 5 ++--- arch/x86/xen/smp.c | 5 ++--- include/linux/sched.h | 2 ++ 26 files changed, 63 insertions(+), 50 deletions(-) (limited to 'include/linux') diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c index 42aa078a5e4d..5a621c6d22ab 100644 --- a/arch/alpha/kernel/smp.c +++ b/arch/alpha/kernel/smp.c @@ -585,8 +585,7 @@ handle_ipi(struct pt_regs *regs) switch (which) { case IPI_RESCHEDULE: - /* Reschedule callback. Everything to be done - is done by the interrupt return path. */ + scheduler_ipi(); break; case IPI_CALL_FUNC: diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 8fe05ad932e4..7a561eb731ea 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -560,10 +560,7 @@ asmlinkage void __exception_irq_entry do_IPI(int ipinr, struct pt_regs *regs) break; case IPI_RESCHEDULE: - /* - * nothing more to do - eveything is - * done on the interrupt return path - */ + scheduler_ipi(); break; case IPI_CALL_FUNC: diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c index 6e17a265c4d3..326bb86f4d29 100644 --- a/arch/blackfin/mach-common/smp.c +++ b/arch/blackfin/mach-common/smp.c @@ -164,6 +164,9 @@ static irqreturn_t ipi_handler_int1(int irq, void *dev_instance) while (msg_queue->count) { msg = &msg_queue->ipi_message[msg_queue->head]; switch (msg->type) { + case BFIN_IPI_RESCHEDULE: + scheduler_ipi(); + break; case BFIN_IPI_CALL_FUNC: spin_unlock_irqrestore(&msg_queue->lock, flags); ipi_call_function(cpu, msg); diff --git a/arch/cris/arch-v32/kernel/smp.c b/arch/cris/arch-v32/kernel/smp.c index 4c9e3e1ba5d1..66cc75657e2f 100644 --- a/arch/cris/arch-v32/kernel/smp.c +++ b/arch/cris/arch-v32/kernel/smp.c @@ -342,15 +342,18 @@ irqreturn_t crisv32_ipi_interrupt(int irq, void *dev_id) ipi = REG_RD(intr_vect, irq_regs[smp_processor_id()], rw_ipi); + if (ipi.vector & IPI_SCHEDULE) { + scheduler_ipi(); + } if (ipi.vector & IPI_CALL) { - func(info); + func(info); } if (ipi.vector & IPI_FLUSH_TLB) { - if (flush_mm == FLUSH_ALL) - __flush_tlb_all(); - else if (flush_vma == FLUSH_ALL) + if (flush_mm == FLUSH_ALL) + __flush_tlb_all(); + else if (flush_vma == FLUSH_ALL) __flush_tlb_mm(flush_mm); - else + else __flush_tlb_page(flush_vma, flush_addr); } diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index 5b704740f160..782c3a357f24 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -496,6 +497,7 @@ ia64_handle_irq (ia64_vector vector, struct pt_regs *regs) smp_local_flush_tlb(); kstat_incr_irqs_this_cpu(irq, desc); } else if (unlikely(IS_RESCHEDULE(vector))) { + scheduler_ipi(); kstat_incr_irqs_this_cpu(irq, desc); } else { ia64_setreg(_IA64_REG_CR_TPR, vector); diff --git a/arch/ia64/xen/irq_xen.c b/arch/ia64/xen/irq_xen.c index 108bb858acf2..b279e142c633 100644 --- a/arch/ia64/xen/irq_xen.c +++ b/arch/ia64/xen/irq_xen.c @@ -92,6 +92,8 @@ static unsigned short saved_irq_cnt; static int xen_slab_ready; #ifdef CONFIG_SMP +#include + /* Dummy stub. Though we may check XEN_RESCHEDULE_VECTOR before __do_IRQ, * it ends up to issue several memory accesses upon percpu data and * thus adds unnecessary traffic to other paths. @@ -99,7 +101,13 @@ static int xen_slab_ready; static irqreturn_t xen_dummy_handler(int irq, void *dev_id) { + return IRQ_HANDLED; +} +static irqreturn_t +xen_resched_handler(int irq, void *dev_id) +{ + scheduler_ipi(); return IRQ_HANDLED; } @@ -110,7 +118,7 @@ static struct irqaction xen_ipi_irqaction = { }; static struct irqaction xen_resched_irqaction = { - .handler = xen_dummy_handler, + .handler = xen_resched_handler, .flags = IRQF_DISABLED, .name = "resched" }; diff --git a/arch/m32r/kernel/smp.c b/arch/m32r/kernel/smp.c index 31cef20b2996..fc10b39893d4 100644 --- a/arch/m32r/kernel/smp.c +++ b/arch/m32r/kernel/smp.c @@ -122,8 +122,6 @@ void smp_send_reschedule(int cpu_id) * * Description: This routine executes on CPU which received * 'RESCHEDULE_IPI'. - * Rescheduling is processed at the exit of interrupt - * operation. * * Born on Date: 2002.02.05 * @@ -138,7 +136,7 @@ void smp_send_reschedule(int cpu_id) *==========================================================================*/ void smp_reschedule_interrupt(void) { - /* nothing to do */ + scheduler_ipi(); } /*==========================================================================* diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c index ba78b21cc8d0..76923eeb58b9 100644 --- a/arch/mips/cavium-octeon/smp.c +++ b/arch/mips/cavium-octeon/smp.c @@ -44,6 +44,8 @@ static irqreturn_t mailbox_interrupt(int irq, void *dev_id) if (action & SMP_CALL_FUNCTION) smp_call_function_interrupt(); + if (action & SMP_RESCHEDULE_YOURSELF) + scheduler_ipi(); /* Check if we've been told to flush the icache */ if (action & SMP_ICACHE_FLUSH) diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index 5a88cc4ccd5a..cedac4633741 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c @@ -929,7 +929,7 @@ static void post_direct_ipi(int cpu, struct smtc_ipi *pipi) static void ipi_resched_interrupt(void) { - /* Return from interrupt should be enough to cause scheduler check */ + scheduler_ipi(); } static void ipi_call_interrupt(void) diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c index 9027061f0ead..7d93e6fbfa5a 100644 --- a/arch/mips/mti-malta/malta-int.c +++ b/arch/mips/mti-malta/malta-int.c @@ -309,6 +309,8 @@ static void ipi_call_dispatch(void) static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id) { + scheduler_ipi(); + return IRQ_HANDLED; } diff --git a/arch/mips/pmc-sierra/yosemite/smp.c b/arch/mips/pmc-sierra/yosemite/smp.c index efc9e889b349..2608752898c0 100644 --- a/arch/mips/pmc-sierra/yosemite/smp.c +++ b/arch/mips/pmc-sierra/yosemite/smp.c @@ -55,6 +55,8 @@ void titan_mailbox_irq(void) if (status & 0x2) smp_call_function_interrupt(); + if (status & 0x4) + scheduler_ipi(); break; case 1: @@ -63,6 +65,8 @@ void titan_mailbox_irq(void) if (status & 0x2) smp_call_function_interrupt(); + if (status & 0x4) + scheduler_ipi(); break; } } diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c index 0a04603d577c..b18b04e48577 100644 --- a/arch/mips/sgi-ip27/ip27-irq.c +++ b/arch/mips/sgi-ip27/ip27-irq.c @@ -147,8 +147,10 @@ static void ip27_do_irq_mask0(void) #ifdef CONFIG_SMP if (pend0 & (1UL << CPU_RESCHED_A_IRQ)) { LOCAL_HUB_CLR_INTR(CPU_RESCHED_A_IRQ); + scheduler_ipi(); } else if (pend0 & (1UL << CPU_RESCHED_B_IRQ)) { LOCAL_HUB_CLR_INTR(CPU_RESCHED_B_IRQ); + scheduler_ipi(); } else if (pend0 & (1UL << CPU_CALL_A_IRQ)) { LOCAL_HUB_CLR_INTR(CPU_CALL_A_IRQ); smp_call_function_interrupt(); diff --git a/arch/mips/sibyte/bcm1480/smp.c b/arch/mips/sibyte/bcm1480/smp.c index 47b347c992ea..d667875be564 100644 --- a/arch/mips/sibyte/bcm1480/smp.c +++ b/arch/mips/sibyte/bcm1480/smp.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -189,10 +190,8 @@ void bcm1480_mailbox_interrupt(void) /* Clear the mailbox to clear the interrupt */ __raw_writeq(((u64)action)<<48, mailbox_0_clear_regs[cpu]); - /* - * Nothing to do for SMP_RESCHEDULE_YOURSELF; returning from the - * interrupt will do the reschedule for us - */ + if (action & SMP_RESCHEDULE_YOURSELF) + scheduler_ipi(); if (action & SMP_CALL_FUNCTION) smp_call_function_interrupt(); diff --git a/arch/mips/sibyte/sb1250/smp.c b/arch/mips/sibyte/sb1250/smp.c index c00a5cb1128d..38e7f6bd7922 100644 --- a/arch/mips/sibyte/sb1250/smp.c +++ b/arch/mips/sibyte/sb1250/smp.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -177,10 +178,8 @@ void sb1250_mailbox_interrupt(void) /* Clear the mailbox to clear the interrupt */ ____raw_writeq(((u64)action) << 48, mailbox_clear_regs[cpu]); - /* - * Nothing to do for SMP_RESCHEDULE_YOURSELF; returning from the - * interrupt will do the reschedule for us - */ + if (action & SMP_RESCHEDULE_YOURSELF) + scheduler_ipi(); if (action & SMP_CALL_FUNCTION) smp_call_function_interrupt(); diff --git a/arch/mn10300/kernel/smp.c b/arch/mn10300/kernel/smp.c index 226c826a2194..83fb27912231 100644 --- a/arch/mn10300/kernel/smp.c +++ b/arch/mn10300/kernel/smp.c @@ -494,14 +494,11 @@ void smp_send_stop(void) * @irq: The interrupt number. * @dev_id: The device ID. * - * We need do nothing here, since the scheduling will be effected on our way - * back through entry.S. - * * Returns IRQ_HANDLED to indicate we handled the interrupt successfully. */ static irqreturn_t smp_reschedule_interrupt(int irq, void *dev_id) { - /* do nothing */ + scheduler_ipi(); return IRQ_HANDLED; } diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c index 69d63d354ef0..828305f19cff 100644 --- a/arch/parisc/kernel/smp.c +++ b/arch/parisc/kernel/smp.c @@ -155,10 +155,7 @@ ipi_interrupt(int irq, void *dev_id) case IPI_RESCHEDULE: smp_debug(100, KERN_DEBUG "CPU%d IPI_RESCHEDULE\n", this_cpu); - /* - * Reschedule callback. Everything to be - * done is done by the interrupt return path. - */ + scheduler_ipi(); break; case IPI_CALL_FUNC: diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index cbdbb14be4b0..9f9c204bef69 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -116,7 +116,7 @@ void smp_message_recv(int msg) generic_smp_call_function_interrupt(); break; case PPC_MSG_RESCHEDULE: - /* we notice need_resched on exit */ + scheduler_ipi(); break; case PPC_MSG_CALL_FUNC_SINGLE: generic_smp_call_function_single_interrupt(); @@ -146,7 +146,7 @@ static irqreturn_t call_function_action(int irq, void *data) static irqreturn_t reschedule_action(int irq, void *data) { - /* we just need the return path side effect of checking need_resched */ + scheduler_ipi(); return IRQ_HANDLED; } diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 63a97db83f96..63c7d9ff220d 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -165,12 +165,12 @@ static void do_ext_call_interrupt(unsigned int ext_int_code, kstat_cpu(smp_processor_id()).irqs[EXTINT_IPI]++; /* * handle bit signal external calls - * - * For the ec_schedule signal we have to do nothing. All the work - * is done automatically when we return from the interrupt. */ bits = xchg(&S390_lowcore.ext_call_fast, 0); + if (test_bit(ec_schedule, &bits)) + scheduler_ipi(); + if (test_bit(ec_call_function, &bits)) generic_smp_call_function_interrupt(); diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c index 509b36b45115..6207561ea34a 100644 --- a/arch/sh/kernel/smp.c +++ b/arch/sh/kernel/smp.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -323,6 +324,7 @@ void smp_message_recv(unsigned int msg) generic_smp_call_function_interrupt(); break; case SMP_MSG_RESCHEDULE: + scheduler_ipi(); break; case SMP_MSG_FUNCTION_SINGLE: generic_smp_call_function_single_interrupt(); diff --git a/arch/sparc/kernel/smp_32.c b/arch/sparc/kernel/smp_32.c index 91c10fb70858..f95690c167b6 100644 --- a/arch/sparc/kernel/smp_32.c +++ b/arch/sparc/kernel/smp_32.c @@ -125,7 +125,9 @@ struct linux_prom_registers smp_penguin_ctable __cpuinitdata = { 0 }; void smp_send_reschedule(int cpu) { - /* See sparc64 */ + /* + * XXX missing reschedule IPI, see scheduler_ipi() + */ } void smp_send_stop(void) diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c index 3e94a8c23238..9478da7fdb3e 100644 --- a/arch/sparc/kernel/smp_64.c +++ b/arch/sparc/kernel/smp_64.c @@ -1368,6 +1368,7 @@ void smp_send_reschedule(int cpu) void __irq_entry smp_receive_signal_client(int irq, struct pt_regs *regs) { clear_softint(1 << irq); + scheduler_ipi(); } /* This is a nop because we capture all other cpus diff --git a/arch/tile/kernel/smp.c b/arch/tile/kernel/smp.c index a4293102ef81..c52224d5ed45 100644 --- a/arch/tile/kernel/smp.c +++ b/arch/tile/kernel/smp.c @@ -189,12 +189,8 @@ void flush_icache_range(unsigned long start, unsigned long end) /* Called when smp_send_reschedule() triggers IRQ_RESCHEDULE. */ static irqreturn_t handle_reschedule_ipi(int irq, void *token) { - /* - * Nothing to do here; when we return from interrupt, the - * rescheduling will occur there. But do bump the interrupt - * profiler count in the meantime. - */ __get_cpu_var(irq_stat).irq_resched_count++; + scheduler_ipi(); return IRQ_HANDLED; } diff --git a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c index 106bf27e2a9a..eefb107d2d73 100644 --- a/arch/um/kernel/smp.c +++ b/arch/um/kernel/smp.c @@ -173,7 +173,7 @@ void IPI_handler(int cpu) break; case 'R': - set_tsk_need_resched(current); + scheduler_ipi(); break; case 'S': diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c index 513deac7228d..013e7eba83bb 100644 --- a/arch/x86/kernel/smp.c +++ b/arch/x86/kernel/smp.c @@ -194,14 +194,13 @@ static void native_stop_other_cpus(int wait) } /* - * Reschedule call back. Nothing to do, - * all the work is done automatically when - * we return from the interrupt. + * Reschedule call back. */ void smp_reschedule_interrupt(struct pt_regs *regs) { ack_APIC_irq(); inc_irq_stat(irq_resched_count); + scheduler_ipi(); /* * KVM uses this interrupt to force a cpu out of guest mode */ diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index 30612441ed99..762b46ab14d5 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c @@ -46,13 +46,12 @@ static irqreturn_t xen_call_function_interrupt(int irq, void *dev_id); static irqreturn_t xen_call_function_single_interrupt(int irq, void *dev_id); /* - * Reschedule call back. Nothing to do, - * all the work is done automatically when - * we return from the interrupt. + * Reschedule call back. */ static irqreturn_t xen_reschedule_interrupt(int irq, void *dev_id) { inc_irq_stat(irq_resched_count); + scheduler_ipi(); return IRQ_HANDLED; } diff --git a/include/linux/sched.h b/include/linux/sched.h index 4ec2c027e92c..758e27afcda5 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -2189,8 +2189,10 @@ extern void set_task_comm(struct task_struct *tsk, char *from); extern char *get_task_comm(char *to, struct task_struct *tsk); #ifdef CONFIG_SMP +static inline void scheduler_ipi(void) { } extern unsigned long wait_task_inactive(struct task_struct *, long match_state); #else +static inline void scheduler_ipi(void) { } static inline unsigned long wait_task_inactive(struct task_struct *p, long match_state) { -- cgit From 3ca7a440da394808571dad32d33d3bc0389982e6 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 5 Apr 2011 17:23:40 +0200 Subject: sched: Always provide p->on_cpu Always provide p->on_cpu so that we can determine if its on a cpu without having to lock the rq. Reviewed-by: Frank Rowand Signed-off-by: Peter Zijlstra Cc: Mike Galbraith Cc: Nick Piggin Cc: Linus Torvalds Cc: Andrew Morton Link: http://lkml.kernel.org/r/20110405152728.785452014@chello.nl Signed-off-by: Ingo Molnar --- include/linux/sched.h | 4 +--- kernel/sched.c | 46 +++++++++++++++++++++++++++++----------------- 2 files changed, 30 insertions(+), 20 deletions(-) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index 758e27afcda5..3435837e89ff 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1200,9 +1200,7 @@ struct task_struct { int lock_depth; /* BKL lock depth */ #ifdef CONFIG_SMP -#ifdef __ARCH_WANT_UNLOCKED_CTXSW - int oncpu; -#endif + int on_cpu; #endif int prio, static_prio, normal_prio; diff --git a/kernel/sched.c b/kernel/sched.c index a187c3fe027b..cd2593e1a3ec 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -838,18 +838,39 @@ static inline int task_current(struct rq *rq, struct task_struct *p) return rq->curr == p; } -#ifndef __ARCH_WANT_UNLOCKED_CTXSW static inline int task_running(struct rq *rq, struct task_struct *p) { +#ifdef CONFIG_SMP + return p->on_cpu; +#else return task_current(rq, p); +#endif } +#ifndef __ARCH_WANT_UNLOCKED_CTXSW static inline void prepare_lock_switch(struct rq *rq, struct task_struct *next) { +#ifdef CONFIG_SMP + /* + * We can optimise this out completely for !SMP, because the + * SMP rebalancing from interrupt is the only thing that cares + * here. + */ + next->on_cpu = 1; +#endif } static inline void finish_lock_switch(struct rq *rq, struct task_struct *prev) { +#ifdef CONFIG_SMP + /* + * After ->on_cpu is cleared, the task can be moved to a different CPU. + * We must ensure this doesn't happen until the switch is completely + * finished. + */ + smp_wmb(); + prev->on_cpu = 0; +#endif #ifdef CONFIG_DEBUG_SPINLOCK /* this is a valid case when another task releases the spinlock */ rq->lock.owner = current; @@ -865,15 +886,6 @@ static inline void finish_lock_switch(struct rq *rq, struct task_struct *prev) } #else /* __ARCH_WANT_UNLOCKED_CTXSW */ -static inline int task_running(struct rq *rq, struct task_struct *p) -{ -#ifdef CONFIG_SMP - return p->oncpu; -#else - return task_current(rq, p); -#endif -} - static inline void prepare_lock_switch(struct rq *rq, struct task_struct *next) { #ifdef CONFIG_SMP @@ -882,7 +894,7 @@ static inline void prepare_lock_switch(struct rq *rq, struct task_struct *next) * SMP rebalancing from interrupt is the only thing that cares * here. */ - next->oncpu = 1; + next->on_cpu = 1; #endif #ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW raw_spin_unlock_irq(&rq->lock); @@ -895,12 +907,12 @@ static inline void finish_lock_switch(struct rq *rq, struct task_struct *prev) { #ifdef CONFIG_SMP /* - * After ->oncpu is cleared, the task can be moved to a different CPU. + * After ->on_cpu is cleared, the task can be moved to a different CPU. * We must ensure this doesn't happen until the switch is completely * finished. */ smp_wmb(); - prev->oncpu = 0; + prev->on_cpu = 0; #endif #ifndef __ARCH_WANT_INTERRUPTS_ON_CTXSW local_irq_enable(); @@ -2686,8 +2698,8 @@ void sched_fork(struct task_struct *p, int clone_flags) if (likely(sched_info_on())) memset(&p->sched_info, 0, sizeof(p->sched_info)); #endif -#if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW) - p->oncpu = 0; +#if defined(CONFIG_SMP) + p->on_cpu = 0; #endif #ifdef CONFIG_PREEMPT /* Want to start with kernel preemption disabled. */ @@ -5776,8 +5788,8 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu) rcu_read_unlock(); rq->curr = rq->idle = idle; -#if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW) - idle->oncpu = 1; +#if defined(CONFIG_SMP) + idle->on_cpu = 1; #endif raw_spin_unlock_irqrestore(&rq->lock, flags); -- cgit From c6eb3dda25892f1f974f5420f63e6721aab02f6f Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 5 Apr 2011 17:23:41 +0200 Subject: mutex: Use p->on_cpu for the adaptive spin Since we now have p->on_cpu unconditionally available, use it to re-implement mutex_spin_on_owner. Requested-by: Thomas Gleixner Reviewed-by: Frank Rowand Cc: Mike Galbraith Cc: Nick Piggin Cc: Linus Torvalds Cc: Andrew Morton Signed-off-by: Ingo Molnar Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/20110405152728.826338173@chello.nl --- include/linux/mutex.h | 2 +- include/linux/sched.h | 2 +- kernel/mutex-debug.c | 2 +- kernel/mutex-debug.h | 2 +- kernel/mutex.c | 2 +- kernel/mutex.h | 2 +- kernel/sched.c | 83 ++++++++++++++++++++------------------------------- 7 files changed, 39 insertions(+), 56 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mutex.h b/include/linux/mutex.h index 94b48bd40dd7..c75471db576e 100644 --- a/include/linux/mutex.h +++ b/include/linux/mutex.h @@ -51,7 +51,7 @@ struct mutex { spinlock_t wait_lock; struct list_head wait_list; #if defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_SMP) - struct thread_info *owner; + struct task_struct *owner; #endif #ifdef CONFIG_DEBUG_MUTEXES const char *name; diff --git a/include/linux/sched.h b/include/linux/sched.h index 3435837e89ff..173850479e2c 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -360,7 +360,7 @@ extern signed long schedule_timeout_interruptible(signed long timeout); extern signed long schedule_timeout_killable(signed long timeout); extern signed long schedule_timeout_uninterruptible(signed long timeout); asmlinkage void schedule(void); -extern int mutex_spin_on_owner(struct mutex *lock, struct thread_info *owner); +extern int mutex_spin_on_owner(struct mutex *lock, struct task_struct *owner); struct nsproxy; struct user_namespace; diff --git a/kernel/mutex-debug.c b/kernel/mutex-debug.c index ec815a960b5d..73da83aff418 100644 --- a/kernel/mutex-debug.c +++ b/kernel/mutex-debug.c @@ -75,7 +75,7 @@ void debug_mutex_unlock(struct mutex *lock) return; DEBUG_LOCKS_WARN_ON(lock->magic != lock); - DEBUG_LOCKS_WARN_ON(lock->owner != current_thread_info()); + DEBUG_LOCKS_WARN_ON(lock->owner != current); DEBUG_LOCKS_WARN_ON(!lock->wait_list.prev && !lock->wait_list.next); mutex_clear_owner(lock); } diff --git a/kernel/mutex-debug.h b/kernel/mutex-debug.h index 57d527a16f9d..0799fd3e4cfa 100644 --- a/kernel/mutex-debug.h +++ b/kernel/mutex-debug.h @@ -29,7 +29,7 @@ extern void debug_mutex_init(struct mutex *lock, const char *name, static inline void mutex_set_owner(struct mutex *lock) { - lock->owner = current_thread_info(); + lock->owner = current; } static inline void mutex_clear_owner(struct mutex *lock) diff --git a/kernel/mutex.c b/kernel/mutex.c index c4195fa98900..fe4706cb0c5b 100644 --- a/kernel/mutex.c +++ b/kernel/mutex.c @@ -160,7 +160,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, */ for (;;) { - struct thread_info *owner; + struct task_struct *owner; /* * If we own the BKL, then don't spin. The owner of diff --git a/kernel/mutex.h b/kernel/mutex.h index 67578ca48f94..4115fbf83b12 100644 --- a/kernel/mutex.h +++ b/kernel/mutex.h @@ -19,7 +19,7 @@ #ifdef CONFIG_SMP static inline void mutex_set_owner(struct mutex *lock) { - lock->owner = current_thread_info(); + lock->owner = current; } static inline void mutex_clear_owner(struct mutex *lock) diff --git a/kernel/sched.c b/kernel/sched.c index cd2593e1a3ec..55cc50323ce1 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -4173,70 +4173,53 @@ need_resched: EXPORT_SYMBOL(schedule); #ifdef CONFIG_MUTEX_SPIN_ON_OWNER -/* - * Look out! "owner" is an entirely speculative pointer - * access and not reliable. - */ -int mutex_spin_on_owner(struct mutex *lock, struct thread_info *owner) -{ - unsigned int cpu; - struct rq *rq; - if (!sched_feat(OWNER_SPIN)) - return 0; +static inline bool owner_running(struct mutex *lock, struct task_struct *owner) +{ + bool ret = false; -#ifdef CONFIG_DEBUG_PAGEALLOC - /* - * Need to access the cpu field knowing that - * DEBUG_PAGEALLOC could have unmapped it if - * the mutex owner just released it and exited. - */ - if (probe_kernel_address(&owner->cpu, cpu)) - return 0; -#else - cpu = owner->cpu; -#endif + rcu_read_lock(); + if (lock->owner != owner) + goto fail; /* - * Even if the access succeeded (likely case), - * the cpu field may no longer be valid. + * Ensure we emit the owner->on_cpu, dereference _after_ checking + * lock->owner still matches owner, if that fails, owner might + * point to free()d memory, if it still matches, the rcu_read_lock() + * ensures the memory stays valid. */ - if (cpu >= nr_cpumask_bits) - return 0; + barrier(); - /* - * We need to validate that we can do a - * get_cpu() and that we have the percpu area. - */ - if (!cpu_online(cpu)) - return 0; + ret = owner->on_cpu; +fail: + rcu_read_unlock(); - rq = cpu_rq(cpu); + return ret; +} - for (;;) { - /* - * Owner changed, break to re-assess state. - */ - if (lock->owner != owner) { - /* - * If the lock has switched to a different owner, - * we likely have heavy contention. Return 0 to quit - * optimistic spinning and not contend further: - */ - if (lock->owner) - return 0; - break; - } +/* + * Look out! "owner" is an entirely speculative pointer + * access and not reliable. + */ +int mutex_spin_on_owner(struct mutex *lock, struct task_struct *owner) +{ + if (!sched_feat(OWNER_SPIN)) + return 0; - /* - * Is that owner really running on that cpu? - */ - if (task_thread_info(rq->curr) != owner || need_resched()) + while (owner_running(lock, owner)) { + if (need_resched()) return 0; arch_mutex_cpu_relax(); } + /* + * If the owner changed to another task there is likely + * heavy contention, stop spinning. + */ + if (lock->owner) + return 0; + return 1; } #endif -- cgit From fd2f4419b4cbe8fe90796df9617c355762afd6a4 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 5 Apr 2011 17:23:44 +0200 Subject: sched: Provide p->on_rq Provide a generic p->on_rq because the p->se.on_rq semantics are unfavourable for lockless wakeups but needed for sched_fair. In particular, p->on_rq is only cleared when we actually dequeue the task in schedule() and not on any random dequeue as done by things like __migrate_task() and __sched_setscheduler(). This also allows us to remove p->se usage from !sched_fair code. Reviewed-by: Frank Rowand Cc: Mike Galbraith Cc: Nick Piggin Cc: Linus Torvalds Cc: Andrew Morton Signed-off-by: Ingo Molnar Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/20110405152728.949545047@chello.nl --- include/linux/sched.h | 1 + kernel/sched.c | 38 ++++++++++++++++++++------------------ kernel/sched_debug.c | 2 +- kernel/sched_rt.c | 16 ++++++++-------- kernel/sched_stoptask.c | 2 +- 5 files changed, 31 insertions(+), 28 deletions(-) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index 173850479e2c..b33a700652dc 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1202,6 +1202,7 @@ struct task_struct { #ifdef CONFIG_SMP int on_cpu; #endif + int on_rq; int prio, static_prio, normal_prio; unsigned int rt_priority; diff --git a/kernel/sched.c b/kernel/sched.c index 4481638f9178..dece28e505c9 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -1785,7 +1785,6 @@ static void enqueue_task(struct rq *rq, struct task_struct *p, int flags) update_rq_clock(rq); sched_info_queued(p); p->sched_class->enqueue_task(rq, p, flags); - p->se.on_rq = 1; } static void dequeue_task(struct rq *rq, struct task_struct *p, int flags) @@ -1793,7 +1792,6 @@ static void dequeue_task(struct rq *rq, struct task_struct *p, int flags) update_rq_clock(rq); sched_info_dequeued(p); p->sched_class->dequeue_task(rq, p, flags); - p->se.on_rq = 0; } /* @@ -2128,7 +2126,7 @@ static void check_preempt_curr(struct rq *rq, struct task_struct *p, int flags) * A queue event has occurred, and we're going to schedule. In * this case, we can save a useless back to back clock update. */ - if (rq->curr->se.on_rq && test_tsk_need_resched(rq->curr)) + if (rq->curr->on_rq && test_tsk_need_resched(rq->curr)) rq->skip_clock_update = 1; } @@ -2203,7 +2201,7 @@ static bool migrate_task(struct task_struct *p, struct rq *rq) * If the task is not on a runqueue (and not running), then * the next wake-up will properly place the task. */ - return p->se.on_rq || task_running(rq, p); + return p->on_rq || task_running(rq, p); } /* @@ -2263,7 +2261,7 @@ unsigned long wait_task_inactive(struct task_struct *p, long match_state) rq = task_rq_lock(p, &flags); trace_sched_wait_task(p); running = task_running(rq, p); - on_rq = p->se.on_rq; + on_rq = p->on_rq; ncsw = 0; if (!match_state || p->state == match_state) ncsw = p->nvcsw | LONG_MIN; /* sets MSB */ @@ -2444,6 +2442,7 @@ ttwu_stat(struct rq *rq, struct task_struct *p, int cpu, int wake_flags) static void ttwu_activate(struct rq *rq, struct task_struct *p, int en_flags) { activate_task(rq, p, en_flags); + p->on_rq = 1; /* if a worker is waking up, notify workqueue */ if (p->flags & PF_WQ_WORKER) @@ -2506,7 +2505,7 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, cpu = task_cpu(p); - if (p->se.on_rq) + if (p->on_rq) goto out_running; orig_cpu = cpu; @@ -2583,7 +2582,7 @@ static void try_to_wake_up_local(struct task_struct *p) if (!(p->state & TASK_NORMAL)) return; - if (!p->se.on_rq) + if (!p->on_rq) ttwu_activate(rq, p, ENQUEUE_WAKEUP); ttwu_post_activation(p, rq, 0); @@ -2620,19 +2619,21 @@ int wake_up_state(struct task_struct *p, unsigned int state) */ static void __sched_fork(struct task_struct *p) { + p->on_rq = 0; + + p->se.on_rq = 0; p->se.exec_start = 0; p->se.sum_exec_runtime = 0; p->se.prev_sum_exec_runtime = 0; p->se.nr_migrations = 0; p->se.vruntime = 0; + INIT_LIST_HEAD(&p->se.group_node); #ifdef CONFIG_SCHEDSTATS memset(&p->se.statistics, 0, sizeof(p->se.statistics)); #endif INIT_LIST_HEAD(&p->rt.run_list); - p->se.on_rq = 0; - INIT_LIST_HEAD(&p->se.group_node); #ifdef CONFIG_PREEMPT_NOTIFIERS INIT_HLIST_HEAD(&p->preempt_notifiers); @@ -2750,6 +2751,7 @@ void wake_up_new_task(struct task_struct *p, unsigned long clone_flags) rq = task_rq_lock(p, &flags); activate_task(rq, p, 0); + p->on_rq = 1; trace_sched_wakeup_new(p, true); check_preempt_curr(rq, p, WF_FORK); #ifdef CONFIG_SMP @@ -4051,7 +4053,7 @@ static inline void schedule_debug(struct task_struct *prev) static void put_prev_task(struct rq *rq, struct task_struct *prev) { - if (prev->se.on_rq) + if (prev->on_rq) update_rq_clock(rq); prev->sched_class->put_prev_task(rq, prev); } @@ -4126,7 +4128,9 @@ need_resched: if (to_wakeup) try_to_wake_up_local(to_wakeup); } + deactivate_task(rq, prev, DEQUEUE_SLEEP); + prev->on_rq = 0; /* * If we are going to sleep and we have plugged IO queued, make @@ -4695,7 +4699,7 @@ void rt_mutex_setprio(struct task_struct *p, int prio) trace_sched_pi_setprio(p, prio); oldprio = p->prio; prev_class = p->sched_class; - on_rq = p->se.on_rq; + on_rq = p->on_rq; running = task_current(rq, p); if (on_rq) dequeue_task(rq, p, 0); @@ -4743,7 +4747,7 @@ void set_user_nice(struct task_struct *p, long nice) p->static_prio = NICE_TO_PRIO(nice); goto out_unlock; } - on_rq = p->se.on_rq; + on_rq = p->on_rq; if (on_rq) dequeue_task(rq, p, 0); @@ -4877,8 +4881,6 @@ static struct task_struct *find_process_by_pid(pid_t pid) static void __setscheduler(struct rq *rq, struct task_struct *p, int policy, int prio) { - BUG_ON(p->se.on_rq); - p->policy = policy; p->rt_priority = prio; p->normal_prio = normal_prio(p); @@ -5044,7 +5046,7 @@ recheck: raw_spin_unlock_irqrestore(&p->pi_lock, flags); goto recheck; } - on_rq = p->se.on_rq; + on_rq = p->on_rq; running = task_current(rq, p); if (on_rq) deactivate_task(rq, p, 0); @@ -5965,7 +5967,7 @@ static int __migrate_task(struct task_struct *p, int src_cpu, int dest_cpu) * If we're not on a rq, the next wake-up will ensure we're * placed properly. */ - if (p->se.on_rq) { + if (p->on_rq) { deactivate_task(rq_src, p, 0); set_task_cpu(p, dest_cpu); activate_task(rq_dest, p, 0); @@ -8339,7 +8341,7 @@ static void normalize_task(struct rq *rq, struct task_struct *p) int old_prio = p->prio; int on_rq; - on_rq = p->se.on_rq; + on_rq = p->on_rq; if (on_rq) deactivate_task(rq, p, 0); __setscheduler(rq, p, SCHED_NORMAL, 0); @@ -8682,7 +8684,7 @@ void sched_move_task(struct task_struct *tsk) rq = task_rq_lock(tsk, &flags); running = task_current(rq, tsk); - on_rq = tsk->se.on_rq; + on_rq = tsk->on_rq; if (on_rq) dequeue_task(rq, tsk, 0); diff --git a/kernel/sched_debug.c b/kernel/sched_debug.c index 7bacd83a4158..3669bec6e130 100644 --- a/kernel/sched_debug.c +++ b/kernel/sched_debug.c @@ -152,7 +152,7 @@ static void print_rq(struct seq_file *m, struct rq *rq, int rq_cpu) read_lock_irqsave(&tasklist_lock, flags); do_each_thread(g, p) { - if (!p->se.on_rq || task_cpu(p) != rq_cpu) + if (!p->on_rq || task_cpu(p) != rq_cpu) continue; print_task(m, rq, p); diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c index e7cebdc65f82..9ca4f5f879c4 100644 --- a/kernel/sched_rt.c +++ b/kernel/sched_rt.c @@ -1136,7 +1136,7 @@ static void put_prev_task_rt(struct rq *rq, struct task_struct *p) * The previous task needs to be made eligible for pushing * if it is still active */ - if (p->se.on_rq && p->rt.nr_cpus_allowed > 1) + if (on_rt_rq(&p->rt) && p->rt.nr_cpus_allowed > 1) enqueue_pushable_task(rq, p); } @@ -1287,7 +1287,7 @@ static struct rq *find_lock_lowest_rq(struct task_struct *task, struct rq *rq) !cpumask_test_cpu(lowest_rq->cpu, &task->cpus_allowed) || task_running(rq, task) || - !task->se.on_rq)) { + !task->on_rq)) { raw_spin_unlock(&lowest_rq->lock); lowest_rq = NULL; @@ -1321,7 +1321,7 @@ static struct task_struct *pick_next_pushable_task(struct rq *rq) BUG_ON(task_current(rq, p)); BUG_ON(p->rt.nr_cpus_allowed <= 1); - BUG_ON(!p->se.on_rq); + BUG_ON(!p->on_rq); BUG_ON(!rt_task(p)); return p; @@ -1467,7 +1467,7 @@ static int pull_rt_task(struct rq *this_rq) */ if (p && (p->prio < this_rq->rt.highest_prio.curr)) { WARN_ON(p == src_rq->curr); - WARN_ON(!p->se.on_rq); + WARN_ON(!p->on_rq); /* * There's a chance that p is higher in priority @@ -1538,7 +1538,7 @@ static void set_cpus_allowed_rt(struct task_struct *p, * Update the migration status of the RQ if we have an RT task * which is running AND changing its weight value. */ - if (p->se.on_rq && (weight != p->rt.nr_cpus_allowed)) { + if (p->on_rq && (weight != p->rt.nr_cpus_allowed)) { struct rq *rq = task_rq(p); if (!task_current(rq, p)) { @@ -1608,7 +1608,7 @@ static void switched_from_rt(struct rq *rq, struct task_struct *p) * we may need to handle the pulling of RT tasks * now. */ - if (p->se.on_rq && !rq->rt.rt_nr_running) + if (p->on_rq && !rq->rt.rt_nr_running) pull_rt_task(rq); } @@ -1638,7 +1638,7 @@ static void switched_to_rt(struct rq *rq, struct task_struct *p) * If that current running task is also an RT task * then see if we can move to another run queue. */ - if (p->se.on_rq && rq->curr != p) { + if (p->on_rq && rq->curr != p) { #ifdef CONFIG_SMP if (rq->rt.overloaded && push_rt_task(rq) && /* Don't resched if we changed runqueues */ @@ -1657,7 +1657,7 @@ static void switched_to_rt(struct rq *rq, struct task_struct *p) static void prio_changed_rt(struct rq *rq, struct task_struct *p, int oldprio) { - if (!p->se.on_rq) + if (!p->on_rq) return; if (rq->curr == p) { diff --git a/kernel/sched_stoptask.c b/kernel/sched_stoptask.c index 1ba2bd40fdac..f607de42e6fc 100644 --- a/kernel/sched_stoptask.c +++ b/kernel/sched_stoptask.c @@ -26,7 +26,7 @@ static struct task_struct *pick_next_task_stop(struct rq *rq) { struct task_struct *stop = rq->stop; - if (stop && stop->se.on_rq) + if (stop && stop->on_rq) return stop; return NULL; -- cgit From 7608dec2ce2004c234339bef8c8074e5e601d0e9 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 5 Apr 2011 17:23:46 +0200 Subject: sched: Drop the rq argument to sched_class::select_task_rq() In preparation of calling select_task_rq() without rq->lock held, drop the dependency on the rq argument. Reviewed-by: Frank Rowand Signed-off-by: Peter Zijlstra Cc: Mike Galbraith Cc: Nick Piggin Cc: Linus Torvalds Cc: Andrew Morton Link: http://lkml.kernel.org/r/20110405152729.031077745@chello.nl Signed-off-by: Ingo Molnar --- include/linux/sched.h | 3 +-- kernel/sched.c | 20 +++++++++++--------- kernel/sched_fair.c | 2 +- kernel/sched_idletask.c | 2 +- kernel/sched_rt.c | 38 ++++++++++++++++++++++++++------------ kernel/sched_stoptask.c | 3 +-- 6 files changed, 41 insertions(+), 27 deletions(-) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index b33a700652dc..ff4e2f9c24a7 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1067,8 +1067,7 @@ struct sched_class { void (*put_prev_task) (struct rq *rq, struct task_struct *p); #ifdef CONFIG_SMP - int (*select_task_rq)(struct rq *rq, struct task_struct *p, - int sd_flag, int flags); + int (*select_task_rq)(struct task_struct *p, int sd_flag, int flags); void (*pre_schedule) (struct rq *this_rq, struct task_struct *task); void (*post_schedule) (struct rq *this_rq); diff --git a/kernel/sched.c b/kernel/sched.c index d398f2f0a3c9..d4b815d345b3 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2195,13 +2195,15 @@ static int migration_cpu_stop(void *data); * The task's runqueue lock must be held. * Returns true if you have to wait for migration thread. */ -static bool migrate_task(struct task_struct *p, struct rq *rq) +static bool need_migrate_task(struct task_struct *p) { /* * If the task is not on a runqueue (and not running), then * the next wake-up will properly place the task. */ - return p->on_rq || task_running(rq, p); + bool running = p->on_rq || p->on_cpu; + smp_rmb(); /* finish_lock_switch() */ + return running; } /* @@ -2376,9 +2378,9 @@ static int select_fallback_rq(int cpu, struct task_struct *p) * The caller (fork, wakeup) owns p->pi_lock, ->cpus_allowed is stable. */ static inline -int select_task_rq(struct rq *rq, struct task_struct *p, int sd_flags, int wake_flags) +int select_task_rq(struct task_struct *p, int sd_flags, int wake_flags) { - int cpu = p->sched_class->select_task_rq(rq, p, sd_flags, wake_flags); + int cpu = p->sched_class->select_task_rq(p, sd_flags, wake_flags); /* * In order not to call set_task_cpu() on a blocking task we need @@ -2533,7 +2535,7 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, en_flags |= ENQUEUE_WAKING; } - cpu = select_task_rq(rq, p, SD_BALANCE_WAKE, wake_flags); + cpu = select_task_rq(p, SD_BALANCE_WAKE, wake_flags); if (cpu != orig_cpu) set_task_cpu(p, cpu); __task_rq_unlock(rq); @@ -2744,7 +2746,7 @@ void wake_up_new_task(struct task_struct *p, unsigned long clone_flags) * We set TASK_WAKING so that select_task_rq() can drop rq->lock * without people poking at ->cpus_allowed. */ - cpu = select_task_rq(rq, p, SD_BALANCE_FORK, 0); + cpu = select_task_rq(p, SD_BALANCE_FORK, 0); set_task_cpu(p, cpu); p->state = TASK_RUNNING; @@ -3474,7 +3476,7 @@ void sched_exec(void) int dest_cpu; rq = task_rq_lock(p, &flags); - dest_cpu = p->sched_class->select_task_rq(rq, p, SD_BALANCE_EXEC, 0); + dest_cpu = p->sched_class->select_task_rq(p, SD_BALANCE_EXEC, 0); if (dest_cpu == smp_processor_id()) goto unlock; @@ -3482,7 +3484,7 @@ void sched_exec(void) * select_task_rq() can race against ->cpus_allowed */ if (cpumask_test_cpu(dest_cpu, &p->cpus_allowed) && - likely(cpu_active(dest_cpu)) && migrate_task(p, rq)) { + likely(cpu_active(dest_cpu)) && need_migrate_task(p)) { struct migration_arg arg = { p, dest_cpu }; task_rq_unlock(rq, &flags); @@ -5911,7 +5913,7 @@ int set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask) goto out; dest_cpu = cpumask_any_and(cpu_active_mask, new_mask); - if (migrate_task(p, rq)) { + if (need_migrate_task(p)) { struct migration_arg arg = { p, dest_cpu }; /* Need help from migration thread: drop lock and wait. */ __task_rq_unlock(rq); diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 4ee50f0af8d1..96b2c95ac356 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -1657,7 +1657,7 @@ static int select_idle_sibling(struct task_struct *p, int target) * preempt must be disabled. */ static int -select_task_rq_fair(struct rq *rq, struct task_struct *p, int sd_flag, int wake_flags) +select_task_rq_fair(struct task_struct *p, int sd_flag, int wake_flags) { struct sched_domain *tmp, *affine_sd = NULL, *sd = NULL; int cpu = smp_processor_id(); diff --git a/kernel/sched_idletask.c b/kernel/sched_idletask.c index a776a6396427..0a51882534ea 100644 --- a/kernel/sched_idletask.c +++ b/kernel/sched_idletask.c @@ -7,7 +7,7 @@ #ifdef CONFIG_SMP static int -select_task_rq_idle(struct rq *rq, struct task_struct *p, int sd_flag, int flags) +select_task_rq_idle(struct task_struct *p, int sd_flag, int flags) { return task_cpu(p); /* IDLE tasks as never migrated */ } diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c index 9ca4f5f879c4..19ecb3127379 100644 --- a/kernel/sched_rt.c +++ b/kernel/sched_rt.c @@ -977,13 +977,23 @@ static void yield_task_rt(struct rq *rq) static int find_lowest_rq(struct task_struct *task); static int -select_task_rq_rt(struct rq *rq, struct task_struct *p, int sd_flag, int flags) +select_task_rq_rt(struct task_struct *p, int sd_flag, int flags) { + struct task_struct *curr; + struct rq *rq; + int cpu; + if (sd_flag != SD_BALANCE_WAKE) return smp_processor_id(); + cpu = task_cpu(p); + rq = cpu_rq(cpu); + + rcu_read_lock(); + curr = ACCESS_ONCE(rq->curr); /* unlocked access */ + /* - * If the current task is an RT task, then + * If the current task on @p's runqueue is an RT task, then * try to see if we can wake this RT task up on another * runqueue. Otherwise simply start this RT task * on its current runqueue. @@ -997,21 +1007,25 @@ select_task_rq_rt(struct rq *rq, struct task_struct *p, int sd_flag, int flags) * lock? * * For equal prio tasks, we just let the scheduler sort it out. + * + * Otherwise, just let it ride on the affined RQ and the + * post-schedule router will push the preempted task away + * + * This test is optimistic, if we get it wrong the load-balancer + * will have to sort it out. */ - if (unlikely(rt_task(rq->curr)) && - (rq->curr->rt.nr_cpus_allowed < 2 || - rq->curr->prio < p->prio) && + if (curr && unlikely(rt_task(curr)) && + (curr->rt.nr_cpus_allowed < 2 || + curr->prio < p->prio) && (p->rt.nr_cpus_allowed > 1)) { - int cpu = find_lowest_rq(p); + int target = find_lowest_rq(p); - return (cpu == -1) ? task_cpu(p) : cpu; + if (target != -1) + cpu = target; } + rcu_read_unlock(); - /* - * Otherwise, just let it ride on the affined RQ and the - * post-schedule router will push the preempted task away - */ - return task_cpu(p); + return cpu; } static void check_preempt_equal_prio(struct rq *rq, struct task_struct *p) diff --git a/kernel/sched_stoptask.c b/kernel/sched_stoptask.c index f607de42e6fc..6f437632afab 100644 --- a/kernel/sched_stoptask.c +++ b/kernel/sched_stoptask.c @@ -9,8 +9,7 @@ #ifdef CONFIG_SMP static int -select_task_rq_stop(struct rq *rq, struct task_struct *p, - int sd_flag, int flags) +select_task_rq_stop(struct task_struct *p, int sd_flag, int flags) { return task_cpu(p); /* stop tasks as never migrate */ } -- cgit From 74f8e4b2335de45485b8d5b31a504747f13c8070 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 5 Apr 2011 17:23:47 +0200 Subject: sched: Remove rq argument to sched_class::task_waking() In preparation of calling this without rq->lock held, remove the dependency on the rq argument. Reviewed-by: Frank Rowand Signed-off-by: Peter Zijlstra Cc: Mike Galbraith Cc: Nick Piggin Cc: Linus Torvalds Cc: Andrew Morton Link: http://lkml.kernel.org/r/20110405152729.071474242@chello.nl Signed-off-by: Ingo Molnar --- include/linux/sched.h | 10 +++++++--- kernel/sched.c | 2 +- kernel/sched_fair.c | 4 +++- 3 files changed, 11 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index ff4e2f9c24a7..7f5732f8c618 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1048,8 +1048,12 @@ struct sched_domain; #define WF_FORK 0x02 /* child wakeup after fork */ #define ENQUEUE_WAKEUP 1 -#define ENQUEUE_WAKING 2 -#define ENQUEUE_HEAD 4 +#define ENQUEUE_HEAD 2 +#ifdef CONFIG_SMP +#define ENQUEUE_WAKING 4 /* sched_class::task_waking was called */ +#else +#define ENQUEUE_WAKING 0 +#endif #define DEQUEUE_SLEEP 1 @@ -1071,7 +1075,7 @@ struct sched_class { void (*pre_schedule) (struct rq *this_rq, struct task_struct *task); void (*post_schedule) (struct rq *this_rq); - void (*task_waking) (struct rq *this_rq, struct task_struct *task); + void (*task_waking) (struct task_struct *task); void (*task_woken) (struct rq *this_rq, struct task_struct *task); void (*set_cpus_allowed)(struct task_struct *p, diff --git a/kernel/sched.c b/kernel/sched.c index d4b815d345b3..46f42cac4eb1 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2531,7 +2531,7 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, p->state = TASK_WAKING; if (p->sched_class->task_waking) { - p->sched_class->task_waking(rq, p); + p->sched_class->task_waking(p); en_flags |= ENQUEUE_WAKING; } diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 96b2c95ac356..ad4c414f456d 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -1372,11 +1372,13 @@ static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int flags) #ifdef CONFIG_SMP -static void task_waking_fair(struct rq *rq, struct task_struct *p) +static void task_waking_fair(struct task_struct *p) { struct sched_entity *se = &p->se; struct cfs_rq *cfs_rq = cfs_rq_of(se); + lockdep_assert_held(&task_rq(p)->lock); + se->vruntime -= cfs_rq->min_vruntime; } -- cgit From a8e4f2eaecc9bfa4954adf79a04f4f22fddd829c Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 5 Apr 2011 17:23:49 +0200 Subject: sched: Delay task_contributes_to_load() In prepratation of having to call task_contributes_to_load() without holding rq->lock, we need to store the result until we do and can update the rq accounting accordingly. Reviewed-by: Frank Rowand Cc: Mike Galbraith Cc: Nick Piggin Cc: Linus Torvalds Cc: Andrew Morton Signed-off-by: Ingo Molnar Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/20110405152729.151523907@chello.nl --- include/linux/sched.h | 1 + kernel/sched.c | 16 ++++------------ 2 files changed, 5 insertions(+), 12 deletions(-) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index 7f5732f8c618..25c50317ddc1 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1273,6 +1273,7 @@ struct task_struct { /* Revert to default priority/policy when forking */ unsigned sched_reset_on_fork:1; + unsigned sched_contributes_to_load:1; pid_t pid; pid_t tgid; diff --git a/kernel/sched.c b/kernel/sched.c index 7a5eb2620785..fd32b78c123c 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2519,18 +2519,7 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, if (unlikely(task_running(rq, p))) goto out_activate; - /* - * In order to handle concurrent wakeups and release the rq->lock - * we put the task in TASK_WAKING state. - * - * First fix up the nr_uninterruptible count: - */ - if (task_contributes_to_load(p)) { - if (likely(cpu_online(orig_cpu))) - rq->nr_uninterruptible--; - else - this_rq()->nr_uninterruptible--; - } + p->sched_contributes_to_load = !!task_contributes_to_load(p); p->state = TASK_WAKING; if (p->sched_class->task_waking) { @@ -2555,6 +2544,9 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, WARN_ON(task_cpu(p) != cpu); WARN_ON(p->state != TASK_WAKING); + if (p->sched_contributes_to_load) + rq->nr_uninterruptible--; + out_activate: #endif /* CONFIG_SMP */ ttwu_activate(rq, p, en_flags); -- cgit From 317f394160e9beb97d19a84c39b7e5eb3d7815a8 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 5 Apr 2011 17:23:58 +0200 Subject: sched: Move the second half of ttwu() to the remote cpu Now that we've removed the rq->lock requirement from the first part of ttwu() and can compute placement without holding any rq->lock, ensure we execute the second half of ttwu() on the actual cpu we want the task to run on. This avoids having to take rq->lock and doing the task enqueue remotely, saving lots on cacheline transfers. As measured using: http://oss.oracle.com/~mason/sembench.c $ for i in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor ; do echo performance > $i; done $ echo 4096 32000 64 128 > /proc/sys/kernel/sem $ ./sembench -t 2048 -w 1900 -o 0 unpatched: run time 30 seconds 647278 worker burns per second patched: run time 30 seconds 816715 worker burns per second Reviewed-by: Frank Rowand Cc: Mike Galbraith Cc: Nick Piggin Cc: Linus Torvalds Cc: Andrew Morton Signed-off-by: Ingo Molnar Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/20110405152729.515897185@chello.nl --- include/linux/sched.h | 3 ++- init/Kconfig | 5 +++++ kernel/sched.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++ kernel/sched_features.h | 6 ++++++ 4 files changed, 69 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index 25c50317ddc1..e09dafa6e149 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1203,6 +1203,7 @@ struct task_struct { int lock_depth; /* BKL lock depth */ #ifdef CONFIG_SMP + struct task_struct *wake_entry; int on_cpu; #endif int on_rq; @@ -2192,7 +2193,7 @@ extern void set_task_comm(struct task_struct *tsk, char *from); extern char *get_task_comm(char *to, struct task_struct *tsk); #ifdef CONFIG_SMP -static inline void scheduler_ipi(void) { } +void scheduler_ipi(void); extern unsigned long wait_task_inactive(struct task_struct *, long match_state); #else static inline void scheduler_ipi(void) { } diff --git a/init/Kconfig b/init/Kconfig index 56240e724d9a..32745bfe059e 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -827,6 +827,11 @@ config SCHED_AUTOGROUP desktop applications. Task group autogeneration is currently based upon task session. +config SCHED_TTWU_QUEUE + bool + depends on !SPARC32 + default y + config MM_OWNER bool diff --git a/kernel/sched.c b/kernel/sched.c index 7d8b85fcdf06..9e3ede120e81 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -556,6 +556,10 @@ struct rq { unsigned int ttwu_count; unsigned int ttwu_local; #endif + +#ifdef CONFIG_SMP + struct task_struct *wake_list; +#endif }; static DEFINE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues); @@ -2516,10 +2520,61 @@ static int ttwu_remote(struct task_struct *p, int wake_flags) return ret; } +#ifdef CONFIG_SMP +static void sched_ttwu_pending(void) +{ + struct rq *rq = this_rq(); + struct task_struct *list = xchg(&rq->wake_list, NULL); + + if (!list) + return; + + raw_spin_lock(&rq->lock); + + while (list) { + struct task_struct *p = list; + list = list->wake_entry; + ttwu_do_activate(rq, p, 0); + } + + raw_spin_unlock(&rq->lock); +} + +void scheduler_ipi(void) +{ + sched_ttwu_pending(); +} + +static void ttwu_queue_remote(struct task_struct *p, int cpu) +{ + struct rq *rq = cpu_rq(cpu); + struct task_struct *next = rq->wake_list; + + for (;;) { + struct task_struct *old = next; + + p->wake_entry = next; + next = cmpxchg(&rq->wake_list, old, p); + if (next == old) + break; + } + + if (!next) + smp_send_reschedule(cpu); +} +#endif + static void ttwu_queue(struct task_struct *p, int cpu) { struct rq *rq = cpu_rq(cpu); +#if defined(CONFIG_SMP) && defined(CONFIG_SCHED_TTWU_QUEUE) + if (sched_feat(TTWU_QUEUE) && cpu != smp_processor_id()) { + ttwu_queue_remote(p, cpu); + return; + } +#endif + raw_spin_lock(&rq->lock); ttwu_do_activate(rq, p, 0); raw_spin_unlock(&rq->lock); @@ -6331,6 +6386,7 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu) #ifdef CONFIG_HOTPLUG_CPU case CPU_DYING: + sched_ttwu_pending(); /* Update our root-domain */ raw_spin_lock_irqsave(&rq->lock, flags); if (rq->rd) { diff --git a/kernel/sched_features.h b/kernel/sched_features.h index 68e69acc29b9..be40f7371ee1 100644 --- a/kernel/sched_features.h +++ b/kernel/sched_features.h @@ -64,3 +64,9 @@ SCHED_FEAT(OWNER_SPIN, 1) * Decrement CPU power based on irq activity */ SCHED_FEAT(NONIRQ_POWER, 1) + +/* + * Queue remote wakeups on the target CPU and process them + * using the scheduler IPI. Reduces rq->lock contention/bounces. + */ +SCHED_FEAT(TTWU_QUEUE, 1) -- cgit From 38a2f37258f9e2ae3f6e4241e01088be8dfaf4e9 Mon Sep 17 00:00:00 2001 From: huajun li Date: Wed, 13 Apr 2011 15:43:32 +0000 Subject: usbnet: Fix up 'FLAG_POINTTOPOINT' and 'FLAG_MULTI_PACKET' overlaps. USB tethering does not work anymore since 2.6.39-rc2, but it's okay in -rc1. The root cause is the new added mask code 'FLAG_POINTTOPOINT' overlaps 'FLAG_MULTI_PACKET' in include/linux/usb/usbnet.h, this causes logic issue in rx_process(). This patch cleans up the overlap. Reported-and-Tested-by: Gottfried Haider Signed-off-by: Huajun Li Signed-off-by: David S. Miller --- include/linux/usb/usbnet.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h index 3c7329b8ea0e..0e1855079fbb 100644 --- a/include/linux/usb/usbnet.h +++ b/include/linux/usb/usbnet.h @@ -103,8 +103,8 @@ struct driver_info { * Indicates to usbnet, that USB driver accumulates multiple IP packets. * Affects statistic (counters) and short packet handling. */ -#define FLAG_MULTI_PACKET 0x1000 -#define FLAG_RX_ASSEMBLE 0x2000 /* rx packets may span >1 frames */ +#define FLAG_MULTI_PACKET 0x2000 +#define FLAG_RX_ASSEMBLE 0x4000 /* rx packets may span >1 frames */ /* init device ... can sleep, or cause probe() failure */ int (*bind)(struct usbnet *, struct usb_interface *); -- cgit From feddbb34ebd75e9b6bf573b852079e327a88c07a Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Mon, 28 Mar 2011 10:12:25 +0300 Subject: UBI: fix minor stylistic issues Fix checkpatch.pl errors and warnings: * space before tab * line over 80 characters * include linux/ioctl.h instead of asm/ioctl.h Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/cdev.c | 4 ++-- drivers/mtd/ubi/debug.c | 18 +++++++++--------- drivers/mtd/ubi/io.c | 4 ++-- drivers/mtd/ubi/scan.c | 2 +- drivers/mtd/ubi/ubi.h | 4 ++-- drivers/mtd/ubi/wl.c | 3 ++- include/linux/mtd/ubi.h | 4 ++-- include/mtd/ubi-user.h | 6 +++--- 8 files changed, 23 insertions(+), 22 deletions(-) (limited to 'include/linux') diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index 4119cb857c97..191f3bb3c41a 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -115,7 +115,7 @@ static int vol_cdev_open(struct inode *inode, struct file *file) mode = UBI_READONLY; dbg_gen("open device %d, volume %d, mode %d", - ubi_num, vol_id, mode); + ubi_num, vol_id, mode); desc = ubi_open_volume(ubi_num, vol_id, mode); if (IS_ERR(desc)) @@ -158,7 +158,7 @@ static loff_t vol_cdev_llseek(struct file *file, loff_t offset, int origin) loff_t new_offset; if (vol->updating) { - /* Update is in progress, seeking is prohibited */ + /* Update is in progress, seeking is prohibited */ dbg_err("updating"); return -EBUSY; } diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index d4d07e5f138f..0cd5beabe9c9 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c @@ -75,15 +75,15 @@ void ubi_dbg_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr) { printk(KERN_DEBUG "Volume identifier header dump:\n"); printk(KERN_DEBUG "\tmagic %08x\n", be32_to_cpu(vid_hdr->magic)); - printk(KERN_DEBUG "\tversion %d\n", (int)vid_hdr->version); - printk(KERN_DEBUG "\tvol_type %d\n", (int)vid_hdr->vol_type); - printk(KERN_DEBUG "\tcopy_flag %d\n", (int)vid_hdr->copy_flag); - printk(KERN_DEBUG "\tcompat %d\n", (int)vid_hdr->compat); - printk(KERN_DEBUG "\tvol_id %d\n", be32_to_cpu(vid_hdr->vol_id)); - printk(KERN_DEBUG "\tlnum %d\n", be32_to_cpu(vid_hdr->lnum)); - printk(KERN_DEBUG "\tdata_size %d\n", be32_to_cpu(vid_hdr->data_size)); - printk(KERN_DEBUG "\tused_ebs %d\n", be32_to_cpu(vid_hdr->used_ebs)); - printk(KERN_DEBUG "\tdata_pad %d\n", be32_to_cpu(vid_hdr->data_pad)); + printk(KERN_DEBUG "\tversion %d\n", (int)vid_hdr->version); + printk(KERN_DEBUG "\tvol_type %d\n", (int)vid_hdr->vol_type); + printk(KERN_DEBUG "\tcopy_flag %d\n", (int)vid_hdr->copy_flag); + printk(KERN_DEBUG "\tcompat %d\n", (int)vid_hdr->compat); + printk(KERN_DEBUG "\tvol_id %d\n", be32_to_cpu(vid_hdr->vol_id)); + printk(KERN_DEBUG "\tlnum %d\n", be32_to_cpu(vid_hdr->lnum)); + printk(KERN_DEBUG "\tdata_size %d\n", be32_to_cpu(vid_hdr->data_size)); + printk(KERN_DEBUG "\tused_ebs %d\n", be32_to_cpu(vid_hdr->used_ebs)); + printk(KERN_DEBUG "\tdata_pad %d\n", be32_to_cpu(vid_hdr->data_pad)); printk(KERN_DEBUG "\tsqnum %llu\n", (unsigned long long)be64_to_cpu(vid_hdr->sqnum)); printk(KERN_DEBUG "\thdr_crc %08x\n", be32_to_cpu(vid_hdr->hdr_crc)); diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index e347cc4388ed..d58ceb1ca8fd 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c @@ -189,8 +189,8 @@ retry: } if (retries++ < UBI_IO_RETRIES) { - dbg_io("error %d%s while reading %d bytes from PEB %d:%d," - " read only %zd bytes, retry", + dbg_io("error %d%s while reading %d bytes from PEB " + "%d:%d, read only %zd bytes, retry", err, errstr, len, pnum, offset, read); yield(); goto retry; diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index d2d12ab7def4..2135a53732ff 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -1103,7 +1103,7 @@ static int check_what_we_have(struct ubi_device *ubi, struct ubi_scan_info *si) * otherwise, only print a warning. */ if (si->corr_peb_count >= max_corr) { - ubi_err("too many corrupted PEBs, refusing this device"); + ubi_err("too many corrupted PEBs, refusing"); return -EINVAL; } } diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index f1be8b79663c..c6c22295898e 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -341,8 +341,8 @@ struct ubi_wl_entry; * protected from the wear-leveling worker) * @pq_head: protection queue head * @wl_lock: protects the @used, @free, @pq, @pq_head, @lookuptbl, @move_from, - * @move_to, @move_to_put @erase_pending, @wl_scheduled, @works, - * @erroneous, and @erroneous_peb_count fields + * @move_to, @move_to_put @erase_pending, @wl_scheduled, @works, + * @erroneous, and @erroneous_peb_count fields * @move_mutex: serializes eraseblock moves * @work_sem: synchronizes the WL worker with use tasks * @wl_scheduled: non-zero if the wear-leveling was scheduled diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index b4cf57db2556..ff2c4956eeff 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -1570,7 +1570,8 @@ void ubi_wl_close(struct ubi_device *ubi) * @ec: the erase counter to check * * This function returns zero if the erase counter of physical eraseblock @pnum - * is equivalent to @ec, and a negative error code if not or if an error occurred. + * is equivalent to @ec, and a negative error code if not or if an error + * occurred. */ static int paranoid_check_ec(struct ubi_device *ubi, int pnum, int ec) { diff --git a/include/linux/mtd/ubi.h b/include/linux/mtd/ubi.h index 84854edf4436..15da0e99f48a 100644 --- a/include/linux/mtd/ubi.h +++ b/include/linux/mtd/ubi.h @@ -21,7 +21,7 @@ #ifndef __LINUX_UBI_H__ #define __LINUX_UBI_H__ -#include +#include #include #include @@ -87,7 +87,7 @@ enum { * physical eraseblock size and on how much bytes UBI headers consume. But * because of the volume alignment (@alignment), the usable size of logical * eraseblocks if a volume may be less. The following equation is true: - * @usable_leb_size = LEB size - (LEB size mod @alignment), + * @usable_leb_size = LEB size - (LEB size mod @alignment), * where LEB size is the logical eraseblock size defined by the UBI device. * * The alignment is multiple to the minimal flash input/output unit size or %1 diff --git a/include/mtd/ubi-user.h b/include/mtd/ubi-user.h index a3903423c005..3c4109777aff 100644 --- a/include/mtd/ubi-user.h +++ b/include/mtd/ubi-user.h @@ -406,9 +406,9 @@ struct ubi_map_req { * @value: value to set */ struct ubi_set_vol_prop_req { - __u8 property; - __u8 padding[7]; - __u64 value; + __u8 property; + __u8 padding[7]; + __u64 value; } __packed; #endif /* __UBI_USER_H__ */ -- cgit From 67954fe95705a8ff80335964bd7e621d13fbc499 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 14 Apr 2011 15:21:52 -0700 Subject: memcg: fix mem_cgroup_rotate_reclaimable_page() commit 3f58a8294333 ("move memcg reclaimable page into tail of inactive list") added inline keyword twice in its prototype. CC arch/x86/kernel/asm-offsets.s In file included from include/linux/swap.h:8, from include/linux/suspend.h:4, from arch/x86/kernel/asm-offsets.c:12: include/linux/memcontrol.h:220: error: duplicate `inline' Signed-off-by: Eric Dumazet Reviewed-by: Minchan Kim Cc: Balbir Singh Cc: KAMEZAWA Hiroyuki Cc: KOSAKI Motohiro Cc: Johannes Weiner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memcontrol.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 5a5ce7055839..5e9840f50980 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -216,7 +216,7 @@ static inline void mem_cgroup_del_lru_list(struct page *page, int lru) return ; } -static inline inline void mem_cgroup_rotate_reclaimable_page(struct page *page) +static inline void mem_cgroup_rotate_reclaimable_page(struct page *page) { return ; } -- cgit From 81ab4201fb7d91d6b0cd9ad5b4b16776e4bed145 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 14 Apr 2011 15:22:06 -0700 Subject: mm: add VM counters for transparent hugepages I found it difficult to make sense of transparent huge pages without having any counters for its actions. Add some counters to vmstat for allocation of transparent hugepages and fallback to smaller pages. Optional patch, but useful for development and understanding the system. Contains improvements from Andrea Arcangeli and Johannes Weiner [akpm@linux-foundation.org: coding-style fixes] [hannes@cmpxchg.org: fix vmstat_text[] entries] Signed-off-by: Andi Kleen Acked-by: Andrea Arcangeli Reviewed-by: KAMEZAWA Hiroyuki Signed-off-by: Johannes Weiner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/vmstat.h | 7 +++++++ mm/huge_memory.c | 25 +++++++++++++++++++++---- mm/vmstat.c | 9 +++++++++ 3 files changed, 37 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h index 461c0119664f..2b3831b58aa4 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h @@ -58,6 +58,13 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT, UNEVICTABLE_PGCLEARED, /* on COW, page truncate */ UNEVICTABLE_PGSTRANDED, /* unable to isolate on unlock */ UNEVICTABLE_MLOCKFREED, +#ifdef CONFIG_TRANSPARENT_HUGEPAGE + THP_FAULT_ALLOC, + THP_FAULT_FALLBACK, + THP_COLLAPSE_ALLOC, + THP_COLLAPSE_ALLOC_FAILED, + THP_SPLIT, +#endif NR_VM_EVENT_ITEMS }; diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 0a619e0e2e0b..1722683bde23 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -680,8 +680,11 @@ int do_huge_pmd_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma, return VM_FAULT_OOM; page = alloc_hugepage_vma(transparent_hugepage_defrag(vma), vma, haddr, numa_node_id(), 0); - if (unlikely(!page)) + if (unlikely(!page)) { + count_vm_event(THP_FAULT_FALLBACK); goto out; + } + count_vm_event(THP_FAULT_ALLOC); if (unlikely(mem_cgroup_newpage_charge(page, mm, GFP_KERNEL))) { put_page(page); goto out; @@ -909,11 +912,13 @@ int do_huge_pmd_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, new_page = NULL; if (unlikely(!new_page)) { + count_vm_event(THP_FAULT_FALLBACK); ret = do_huge_pmd_wp_page_fallback(mm, vma, address, pmd, orig_pmd, page, haddr); put_page(page); goto out; } + count_vm_event(THP_FAULT_ALLOC); if (unlikely(mem_cgroup_newpage_charge(new_page, mm, GFP_KERNEL))) { put_page(new_page); @@ -1390,6 +1395,7 @@ int split_huge_page(struct page *page) BUG_ON(!PageSwapBacked(page)); __split_huge_page(page, anon_vma); + count_vm_event(THP_SPLIT); BUG_ON(PageCompound(page)); out_unlock: @@ -1784,9 +1790,11 @@ static void collapse_huge_page(struct mm_struct *mm, node, __GFP_OTHER_NODE); if (unlikely(!new_page)) { up_read(&mm->mmap_sem); + count_vm_event(THP_COLLAPSE_ALLOC_FAILED); *hpage = ERR_PTR(-ENOMEM); return; } + count_vm_event(THP_COLLAPSE_ALLOC); if (unlikely(mem_cgroup_newpage_charge(new_page, mm, GFP_KERNEL))) { up_read(&mm->mmap_sem); put_page(new_page); @@ -2151,8 +2159,11 @@ static void khugepaged_do_scan(struct page **hpage) #ifndef CONFIG_NUMA if (!*hpage) { *hpage = alloc_hugepage(khugepaged_defrag()); - if (unlikely(!*hpage)) + if (unlikely(!*hpage)) { + count_vm_event(THP_COLLAPSE_ALLOC_FAILED); break; + } + count_vm_event(THP_COLLAPSE_ALLOC); } #else if (IS_ERR(*hpage)) @@ -2192,8 +2203,11 @@ static struct page *khugepaged_alloc_hugepage(void) do { hpage = alloc_hugepage(khugepaged_defrag()); - if (!hpage) + if (!hpage) { + count_vm_event(THP_COLLAPSE_ALLOC_FAILED); khugepaged_alloc_sleep(); + } else + count_vm_event(THP_COLLAPSE_ALLOC); } while (unlikely(!hpage) && likely(khugepaged_enabled())); return hpage; @@ -2210,8 +2224,11 @@ static void khugepaged_loop(void) while (likely(khugepaged_enabled())) { #ifndef CONFIG_NUMA hpage = khugepaged_alloc_hugepage(); - if (unlikely(!hpage)) + if (unlikely(!hpage)) { + count_vm_event(THP_COLLAPSE_ALLOC_FAILED); break; + } + count_vm_event(THP_COLLAPSE_ALLOC); #else if (IS_ERR(hpage)) { khugepaged_alloc_sleep(); diff --git a/mm/vmstat.c b/mm/vmstat.c index 8cb0f0a703e5..897ea9e88238 100644 --- a/mm/vmstat.c +++ b/mm/vmstat.c @@ -948,7 +948,16 @@ static const char * const vmstat_text[] = { "unevictable_pgs_cleared", "unevictable_pgs_stranded", "unevictable_pgs_mlockfreed", + +#ifdef CONFIG_TRANSPARENT_HUGEPAGE + "thp_fault_alloc", + "thp_fault_fallback", + "thp_collapse_alloc", + "thp_collapse_alloc_failed", + "thp_split", #endif + +#endif /* CONFIG_VM_EVENTS_COUNTERS */ }; static void zoneinfo_show_print(struct seq_file *m, pg_data_t *pgdat, -- cgit From 4471a675dfc7ca676c165079e91c712b09dc9ce4 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Thu, 14 Apr 2011 15:22:09 -0700 Subject: brk: COMPAT_BRK: fix detection of randomized brk 5520e89 ("brk: fix min_brk lower bound computation for COMPAT_BRK") tried to get the whole logic of brk randomization for legacy (libc5-based) applications finally right. It turns out that the way to detect whether brk has actually been randomized in the end or not introduced by that patch still doesn't work for those binaries, as reported by Geert: : /sbin/init from my old m68k ramdisk exists prematurely. : : Before the patch: : : | brk(0x80005c8e) = 0x80006000 : : After the patch: : : | brk(0x80005c8e) = 0x80005c8e : : Old libc5 considers brk() to have failed if the return value is not : identical to the requested value. I don't like it, but currently see no better option than a bit flag in task_struct to catch the CONFIG_COMPAT_BRK && randomize_va_space == 2 case. Signed-off-by: Jiri Kosina Tested-by: Geert Uytterhoeven Reported-by: Geert Uytterhoeven Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/binfmt_elf.c | 6 +++++- include/linux/sched.h | 3 +++ mm/mmap.c | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index f34078d702d3..303983fabfd6 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -941,9 +941,13 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) current->mm->start_stack = bprm->p; #ifdef arch_randomize_brk - if ((current->flags & PF_RANDOMIZE) && (randomize_va_space > 1)) + if ((current->flags & PF_RANDOMIZE) && (randomize_va_space > 1)) { current->mm->brk = current->mm->start_brk = arch_randomize_brk(current->mm); +#ifdef CONFIG_COMPAT_BRK + current->brk_randomized = 1; +#endif + } #endif if (current->personality & MMAP_PAGE_ZERO) { diff --git a/include/linux/sched.h b/include/linux/sched.h index 4ec2c027e92c..18d63cea2848 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1254,6 +1254,9 @@ struct task_struct { #endif struct mm_struct *mm, *active_mm; +#ifdef CONFIG_COMPAT_BRK + unsigned brk_randomized:1; +#endif #if defined(SPLIT_RSS_COUNTING) struct task_rss_stat rss_stat; #endif diff --git a/mm/mmap.c b/mm/mmap.c index 8c05e5b43b69..e27e0cf0de03 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -259,7 +259,7 @@ SYSCALL_DEFINE1(brk, unsigned long, brk) * randomize_va_space to 2, which will still cause mm->start_brk * to be arbitrarily shifted */ - if (mm->start_brk > PAGE_ALIGN(mm->end_data)) + if (current->brk_randomized) min_brk = mm->start_brk; else min_brk = mm->end_data; -- cgit From 13209c2a52afa691ca19e7e6ebd22d4034bdfeed Mon Sep 17 00:00:00 2001 From: Alexandre Bounine Date: Thu, 14 Apr 2011 15:22:14 -0700 Subject: RapidIO: add IDT CPS-1432 switch definitions Signed-off-by: Alexandre Bounine Cc: Matt Porter Cc: Kumar Gala Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rapidio/switches/idt_gen2.c | 1 + include/linux/rio_ids.h | 1 + 2 files changed, 2 insertions(+) (limited to 'include/linux') diff --git a/drivers/rapidio/switches/idt_gen2.c b/drivers/rapidio/switches/idt_gen2.c index 095016a9dec1..ac2701b22e71 100644 --- a/drivers/rapidio/switches/idt_gen2.c +++ b/drivers/rapidio/switches/idt_gen2.c @@ -418,3 +418,4 @@ DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS1848, idtg2_switch_init); DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS1616, idtg2_switch_init); DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTVPS1616, idtg2_switch_init); DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTSPS1616, idtg2_switch_init); +DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS1432, idtg2_switch_init); diff --git a/include/linux/rio_ids.h b/include/linux/rio_ids.h index 7410d3365e2a..0cee0152aca9 100644 --- a/include/linux/rio_ids.h +++ b/include/linux/rio_ids.h @@ -35,6 +35,7 @@ #define RIO_DID_IDTCPS6Q 0x035f #define RIO_DID_IDTCPS10Q 0x035e #define RIO_DID_IDTCPS1848 0x0374 +#define RIO_DID_IDTCPS1432 0x0375 #define RIO_DID_IDTCPS1616 0x0379 #define RIO_DID_IDTVPS1616 0x0377 #define RIO_DID_IDTSPS1616 0x0378 -- cgit From 59f9996555542f901f2d01ccab5c0612c8c5c480 Mon Sep 17 00:00:00 2001 From: Alexandre Bounine Date: Thu, 14 Apr 2011 15:22:14 -0700 Subject: RapidIO/mpc85xx: fix possible mport registration problems Fix a possible problem with mport registration left non-cleared after fsl_rio_setup() exits on link error. Abort mport initialization if registration failed. This patch is applicable to 2.6.39-rc1 only. The problem does not exist for earlier versions. Signed-off-by: Alexandre Bounine Cc: Kumar Gala Cc: Matt Porter Cc: Li Yang Cc: Thomas Moll Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/powerpc/sysdev/fsl_rio.c | 4 +++- drivers/rapidio/rio.c | 5 +++-- include/linux/rio.h | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index 14232d57369c..49798532b477 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c @@ -1457,7 +1457,6 @@ int fsl_rio_setup(struct platform_device *dev) port->ops = ops; port->priv = priv; port->phys_efptr = 0x100; - rio_register_mport(port); priv->regs_win = ioremap(regs.start, regs.end - regs.start + 1); rio_regs_win = priv->regs_win; @@ -1504,6 +1503,9 @@ int fsl_rio_setup(struct platform_device *dev) dev_info(&dev->dev, "RapidIO Common Transport System size: %d\n", port->sys_size ? 65536 : 256); + if (rio_register_mport(port)) + goto err; + if (port->host_deviceid >= 0) out_be32(priv->regs_win + RIO_GCCSR, RIO_PORT_GEN_HOST | RIO_PORT_GEN_MASTER | RIO_PORT_GEN_DISCOVERED); diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c index c29719cacbca..86c9a091a2ff 100644 --- a/drivers/rapidio/rio.c +++ b/drivers/rapidio/rio.c @@ -1171,16 +1171,17 @@ static int rio_hdid_setup(char *str) __setup("riohdid=", rio_hdid_setup); -void rio_register_mport(struct rio_mport *port) +int rio_register_mport(struct rio_mport *port) { if (next_portid >= RIO_MAX_MPORTS) { pr_err("RIO: reached specified max number of mports\n"); - return; + return 1; } port->id = next_portid++; port->host_deviceid = rio_get_hdid(port->id); list_add_tail(&port->node, &rio_mports); + return 0; } EXPORT_SYMBOL_GPL(rio_local_get_device_id); diff --git a/include/linux/rio.h b/include/linux/rio.h index 4e37a7cfa726..4d50611112ba 100644 --- a/include/linux/rio.h +++ b/include/linux/rio.h @@ -396,7 +396,7 @@ union rio_pw_msg { }; /* Architecture and hardware-specific functions */ -extern void rio_register_mport(struct rio_mport *); +extern int rio_register_mport(struct rio_mport *); extern int rio_open_inb_mbox(struct rio_mport *, void *, int, int); extern void rio_close_inb_mbox(struct rio_mport *, int); extern int rio_open_outb_mbox(struct rio_mport *, void *, int, int); -- cgit From fce55922f5299a04c0a56b170a141fab34f13465 Mon Sep 17 00:00:00 2001 From: "Allan, Bruce W" Date: Wed, 13 Apr 2011 13:09:10 +0000 Subject: ethtool: allow custom interval for physical identification When physical identification of an adapter is done by toggling the mechanism on and off through software utilizing the set_phys_id operation, it is done with a fixed duration for both on and off states. Some drivers may want to set a custom duration for the on/off intervals. This patch changes the API so the return code from the driver's entry point when it is called with ETHTOOL_ID_ACTIVE can specify the frequency at which to cycle the on/off states, and updates the drivers that have already been converted to use the new set_phys_id and use the synchronous method for identifying an adapter. The physical identification frequency set in the updated drivers is based on how it was done prior to the introduction of set_phys_id. Compile tested only. Also fixes a compiler warning in sfc. v2: drivers do not return -EINVAL for ETHOOL_ID_ACTIVE v3: fold patchset into single patch and cleanup per Ben's feedback Signed-off-by: Bruce Allan Cc: Ben Hutchings Cc: Sathya Perla Cc: Subbu Seetharaman Cc: Ajit Khaparde Cc: Michael Chan Cc: Eilon Greenstein Cc: Divy Le Ray Cc: Don Fry Cc: Jon Mason Cc: Solarflare linux maintainers Cc: Steve Hodgson Cc: Stephen Hemminger Cc: Matt Carlson Acked-by: Jon Mason Acked-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/benet/be_ethtool.c | 2 +- drivers/net/bnx2.c | 2 +- drivers/net/bnx2x/bnx2x_ethtool.c | 2 +- drivers/net/cxgb3/cxgb3_main.c | 2 +- drivers/net/ewrk3.c | 2 +- drivers/net/niu.c | 2 +- drivers/net/pcnet32.c | 2 +- drivers/net/s2io.c | 2 +- drivers/net/sfc/ethtool.c | 6 +++--- drivers/net/skge.c | 2 +- drivers/net/sky2.c | 2 +- drivers/net/tg3.c | 2 +- include/linux/ethtool.h | 6 ++++-- net/core/ethtool.c | 31 ++++++++++++++++--------------- 14 files changed, 34 insertions(+), 31 deletions(-) (limited to 'include/linux') diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index 96f5502e0ef7..80226e4801f3 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c @@ -516,7 +516,7 @@ be_set_phys_id(struct net_device *netdev, case ETHTOOL_ID_ACTIVE: be_cmd_get_beacon_state(adapter, adapter->hba_port_num, &adapter->beacon_state); - return -EINVAL; + return 1; /* cycle on/off once per second */ case ETHTOOL_ID_ON: be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0, diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 0a52079bafef..bf729ee6acbd 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -7473,7 +7473,7 @@ bnx2_set_phys_id(struct net_device *dev, enum ethtool_phys_id_state state) bp->leds_save = REG_RD(bp, BNX2_MISC_CFG); REG_WR(bp, BNX2_MISC_CFG, BNX2_MISC_CFG_LEDMODE_MAC); - return -EINVAL; + return 1; /* cycle on/off once per second */ case ETHTOOL_ID_ON: REG_WR(bp, BNX2_EMAC_LED, BNX2_EMAC_LED_OVERRIDE | diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index ad7d91e499f4..0a5e88d6ba2c 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -2025,7 +2025,7 @@ static int bnx2x_set_phys_id(struct net_device *dev, switch (state) { case ETHTOOL_ID_ACTIVE: - return -EINVAL; + return 1; /* cycle on/off once per second */ case ETHTOOL_ID_ON: bnx2x_set_led(&bp->link_params, &bp->link_vars, diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 802c7a7c3b25..a087e0691dce 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c @@ -1757,7 +1757,7 @@ static int set_phys_id(struct net_device *dev, switch (state) { case ETHTOOL_ID_ACTIVE: - return -EINVAL; + return 1; /* cycle on/off once per second */ case ETHTOOL_ID_OFF: t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, F_GPIO0_OUT_VAL, 0); diff --git a/drivers/net/ewrk3.c b/drivers/net/ewrk3.c index c7ce4438e923..17b6027d8be8 100644 --- a/drivers/net/ewrk3.c +++ b/drivers/net/ewrk3.c @@ -1618,7 +1618,7 @@ static int ewrk3_set_phys_id(struct net_device *dev, /* Prevent ISR from twiddling the LED */ lp->led_mask = 0; spin_unlock_irq(&lp->hw_lock); - return -EINVAL; + return 2; /* cycle on/off twice per second */ case ETHTOOL_ID_ON: cr = inb(EWRK3_CR); diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 3fa1e9cdb4a8..ea2272f0f37e 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -7896,7 +7896,7 @@ static int niu_set_phys_id(struct net_device *dev, switch (state) { case ETHTOOL_ID_ACTIVE: np->orig_led_state = niu_led_state_save(np); - return -EINVAL; + return 1; /* cycle on/off once per second */ case ETHTOOL_ID_ON: niu_force_led(np, 1); diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index e89afb929740..0a1efbae1bc0 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c @@ -1038,7 +1038,7 @@ static int pcnet32_set_phys_id(struct net_device *dev, for (i = 4; i < 8; i++) lp->save_regs[i - 4] = a->read_bcr(ioaddr, i); spin_unlock_irqrestore(&lp->lock, flags); - return -EINVAL; + return 2; /* cycle on/off twice per second */ case ETHTOOL_ID_ON: case ETHTOOL_ID_OFF: diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 2d5cc6142c04..2302d9743744 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -5541,7 +5541,7 @@ static int s2io_ethtool_set_led(struct net_device *dev, switch (state) { case ETHTOOL_ID_ACTIVE: sp->adapt_ctrl_org = readq(&bar0->gpio_control); - return -EINVAL; + return 1; /* cycle on/off once per second */ case ETHTOOL_ID_ON: s2io_set_led(sp, true); diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index 644f7c1d6e7b..5d8468fc5804 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c @@ -182,7 +182,7 @@ static int efx_ethtool_phys_id(struct net_device *net_dev, enum ethtool_phys_id_state state) { struct efx_nic *efx = netdev_priv(net_dev); - enum efx_led_mode mode; + enum efx_led_mode mode = EFX_LED_DEFAULT; switch (state) { case ETHTOOL_ID_ON: @@ -194,8 +194,8 @@ static int efx_ethtool_phys_id(struct net_device *net_dev, case ETHTOOL_ID_INACTIVE: mode = EFX_LED_DEFAULT; break; - default: - return -EINVAL; + case ETHTOOL_ID_ACTIVE: + return 1; /* cycle on/off once per second */ } efx->type->set_id_led(efx, mode); diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 310dcbce2519..176d784cbb54 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -753,7 +753,7 @@ static int skge_set_phys_id(struct net_device *dev, switch (state) { case ETHTOOL_ID_ACTIVE: - return -EINVAL; + return 2; /* cycle on/off twice per second */ case ETHTOOL_ID_ON: skge_led(skge, LED_MODE_TST); diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index a4b8fe564eb0..c8d045114c66 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -3813,7 +3813,7 @@ static int sky2_set_phys_id(struct net_device *dev, switch (state) { case ETHTOOL_ID_ACTIVE: - return -EINVAL; + return 1; /* cycle on/off once per second */ case ETHTOOL_ID_INACTIVE: sky2_led(sky2, MO_LED_NORM); break; diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 10fa476fede3..9915734ac3e9 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -10384,7 +10384,7 @@ static int tg3_set_phys_id(struct net_device *dev, switch (state) { case ETHTOOL_ID_ACTIVE: - return -EINVAL; + return 1; /* cycle on/off once per second */ case ETHTOOL_ID_ON: tw32(MAC_LED_CTRL, LED_CTRL_LNKLED_OVERRIDE | diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index ad22a68c2e5d..9de31274341d 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -798,8 +798,10 @@ bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported); * attached to it. The implementation may update the indicator * asynchronously or synchronously, but in either case it must return * quickly. It is initially called with the argument %ETHTOOL_ID_ACTIVE, - * and must either activate asynchronous updates or return -%EINVAL. - * If it returns -%EINVAL then it will be called again at intervals with + * and must either activate asynchronous updates and return zero, return + * a negative error or return a positive frequency for synchronous + * indication (e.g. 1 for one on/off cycle per second). If it returns + * a frequency then it will be called again at intervals with the * argument %ETHTOOL_ID_ON or %ETHTOOL_ID_OFF and should set the state of * the indicator accordingly. Finally, it is called with the argument * %ETHTOOL_ID_INACTIVE and must deactivate the indicator. Returns a diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 41dee2de13ad..13d79f5a86e5 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -1669,7 +1669,7 @@ static int ethtool_phys_id(struct net_device *dev, void __user *useraddr) return dev->ethtool_ops->phys_id(dev, id.data); rc = dev->ethtool_ops->set_phys_id(dev, ETHTOOL_ID_ACTIVE); - if (rc && rc != -EINVAL) + if (rc < 0) return rc; /* Drop the RTNL lock while waiting, but prevent reentry or @@ -1684,21 +1684,22 @@ static int ethtool_phys_id(struct net_device *dev, void __user *useraddr) schedule_timeout_interruptible( id.data ? (id.data * HZ) : MAX_SCHEDULE_TIMEOUT); } else { - /* Driver expects to be called periodically */ + /* Driver expects to be called at twice the frequency in rc */ + int n = rc * 2, i, interval = HZ / n; + + /* Count down seconds */ do { - rtnl_lock(); - rc = dev->ethtool_ops->set_phys_id(dev, ETHTOOL_ID_ON); - rtnl_unlock(); - if (rc) - break; - schedule_timeout_interruptible(HZ / 2); - - rtnl_lock(); - rc = dev->ethtool_ops->set_phys_id(dev, ETHTOOL_ID_OFF); - rtnl_unlock(); - if (rc) - break; - schedule_timeout_interruptible(HZ / 2); + /* Count down iterations per second */ + i = n; + do { + rtnl_lock(); + rc = dev->ethtool_ops->set_phys_id(dev, + (i & 1) ? ETHTOOL_ID_OFF : ETHTOOL_ID_ON); + rtnl_unlock(); + if (rc) + break; + schedule_timeout_interruptible(interval); + } while (!signal_pending(current) && --i != 0); } while (!signal_pending(current) && (id.data == 0 || --id.data != 0)); } -- cgit From 88b996cd0652280cc9b9fc70008fda15f14175e1 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 15 Apr 2011 15:20:10 +0200 Subject: block: cleanup the block plug helper functions It's a bit of a mess currently. task->plug is being cleared and reset in __blk_finish_plug(), and blk_finish_plug() is testing for a NULL plug which cannot happen even from schedule() anymore since it uses blk_needs_flush_plug() to determine whether to call into this function at all. So get rid of some of the cruft. Signed-off-by: Jens Axboe --- block/blk-core.c | 24 ++++++------------------ include/linux/blkdev.h | 6 +++--- 2 files changed, 9 insertions(+), 21 deletions(-) (limited to 'include/linux') diff --git a/block/blk-core.c b/block/blk-core.c index 36b1a7559f94..b598fa7720d4 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -2671,7 +2671,7 @@ static void queue_unplugged(struct request_queue *q, unsigned int depth) q->unplugged_fn(q); } -static void flush_plug_list(struct blk_plug *plug) +void blk_flush_plug_list(struct blk_plug *plug) { struct request_queue *q; unsigned long flags; @@ -2733,28 +2733,16 @@ static void flush_plug_list(struct blk_plug *plug) local_irq_restore(flags); } - -static void __blk_finish_plug(struct task_struct *tsk, struct blk_plug *plug) -{ - flush_plug_list(plug); - - if (plug == tsk->plug) - tsk->plug = NULL; -} +EXPORT_SYMBOL(blk_flush_plug_list); void blk_finish_plug(struct blk_plug *plug) { - if (plug) - __blk_finish_plug(current, plug); -} -EXPORT_SYMBOL(blk_finish_plug); + blk_flush_plug_list(plug); -void __blk_flush_plug(struct task_struct *tsk, struct blk_plug *plug) -{ - __blk_finish_plug(tsk, plug); - tsk->plug = plug; + if (plug == current->plug) + current->plug = NULL; } -EXPORT_SYMBOL(__blk_flush_plug); +EXPORT_SYMBOL(blk_finish_plug); int __init blk_dev_init(void) { diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index c07ffafac5d4..ffe48ff318f9 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -865,14 +865,14 @@ struct blk_plug { extern void blk_start_plug(struct blk_plug *); extern void blk_finish_plug(struct blk_plug *); -extern void __blk_flush_plug(struct task_struct *, struct blk_plug *); +extern void blk_flush_plug_list(struct blk_plug *); static inline void blk_flush_plug(struct task_struct *tsk) { struct blk_plug *plug = tsk->plug; - if (unlikely(plug)) - __blk_flush_plug(tsk, plug); + if (plug) + blk_flush_plug_list(plug); } static inline bool blk_needs_flush_plug(struct task_struct *tsk) -- cgit From f6603783f9f099bf7a83b3f6c689bbbf74f0e96e Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 15 Apr 2011 15:49:07 +0200 Subject: block: only force kblockd unplugging from the schedule() path For the explicit unplugging, we'd prefer to kick things off immediately and not pay the penalty of the latency to switch to kblockd. So let blk_finish_plug() do the run inline, while the implicit-on-schedule-out unplug will punt to kblockd. Signed-off-by: Jens Axboe --- block/blk-core.c | 13 +++++++------ include/linux/blkdev.h | 4 ++-- 2 files changed, 9 insertions(+), 8 deletions(-) (limited to 'include/linux') diff --git a/block/blk-core.c b/block/blk-core.c index b598fa7720d4..3c8121072507 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -2662,16 +2662,17 @@ static int plug_rq_cmp(void *priv, struct list_head *a, struct list_head *b) return !(rqa->q <= rqb->q); } -static void queue_unplugged(struct request_queue *q, unsigned int depth) +static void queue_unplugged(struct request_queue *q, unsigned int depth, + bool force_kblockd) { trace_block_unplug_io(q, depth); - __blk_run_queue(q, true); + __blk_run_queue(q, force_kblockd); if (q->unplugged_fn) q->unplugged_fn(q); } -void blk_flush_plug_list(struct blk_plug *plug) +void blk_flush_plug_list(struct blk_plug *plug, bool force_kblockd) { struct request_queue *q; unsigned long flags; @@ -2706,7 +2707,7 @@ void blk_flush_plug_list(struct blk_plug *plug) BUG_ON(!rq->q); if (rq->q != q) { if (q) { - queue_unplugged(q, depth); + queue_unplugged(q, depth, force_kblockd); spin_unlock(q->queue_lock); } q = rq->q; @@ -2727,7 +2728,7 @@ void blk_flush_plug_list(struct blk_plug *plug) } if (q) { - queue_unplugged(q, depth); + queue_unplugged(q, depth, force_kblockd); spin_unlock(q->queue_lock); } @@ -2737,7 +2738,7 @@ EXPORT_SYMBOL(blk_flush_plug_list); void blk_finish_plug(struct blk_plug *plug) { - blk_flush_plug_list(plug); + blk_flush_plug_list(plug, false); if (plug == current->plug) current->plug = NULL; diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index ffe48ff318f9..1c76506fcf11 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -865,14 +865,14 @@ struct blk_plug { extern void blk_start_plug(struct blk_plug *); extern void blk_finish_plug(struct blk_plug *); -extern void blk_flush_plug_list(struct blk_plug *); +extern void blk_flush_plug_list(struct blk_plug *, bool); static inline void blk_flush_plug(struct task_struct *tsk) { struct blk_plug *plug = tsk->plug; if (plug) - blk_flush_plug_list(plug); + blk_flush_plug_list(plug, true); } static inline bool blk_needs_flush_plug(struct task_struct *tsk) -- cgit From a237c1c5bc5dc5c76a21be922dca4826f3eca8ca Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Sat, 16 Apr 2011 13:27:55 +0200 Subject: block: let io_schedule() flush the plug inline Linus correctly observes that the most important dispatch cases are now done from kblockd, this isn't ideal for latency reasons. The original reason for switching dispatches out-of-line was to avoid too deep a stack, so by _only_ letting the "accidental" flush directly in schedule() be guarded by offload to kblockd, we should be able to get the best of both worlds. So add a blk_schedule_flush_plug() that offloads to kblockd, and only use that from the schedule() path. Signed-off-by: Jens Axboe --- include/linux/blkdev.h | 13 +++++++++++++ kernel/sched.c | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 1c76506fcf11..ec0357d8c4a5 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -871,6 +871,14 @@ static inline void blk_flush_plug(struct task_struct *tsk) { struct blk_plug *plug = tsk->plug; + if (plug) + blk_flush_plug_list(plug, false); +} + +static inline void blk_schedule_flush_plug(struct task_struct *tsk) +{ + struct blk_plug *plug = tsk->plug; + if (plug) blk_flush_plug_list(plug, true); } @@ -1317,6 +1325,11 @@ static inline void blk_flush_plug(struct task_struct *task) { } +static inline void blk_schedule_flush_plug(struct task_struct *task) +{ +} + + static inline bool blk_needs_flush_plug(struct task_struct *tsk) { return false; diff --git a/kernel/sched.c b/kernel/sched.c index a187c3fe027b..312f8b95c2d4 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -4118,7 +4118,7 @@ need_resched: */ if (blk_needs_flush_plug(prev)) { raw_spin_unlock(&rq->lock); - blk_flush_plug(prev); + blk_schedule_flush_plug(prev); raw_spin_lock(&rq->lock); } } -- cgit From 048c9374a749a27f16493cea033fa4a8ff492356 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 18 Apr 2011 09:52:22 +0200 Subject: block: Enhance new plugging support to support general callbacks md/raid requires an unplug callback, but as it does not uses requests the current code cannot provide one. So allow arbitrary callbacks to be attached to the blk_plug. Signed-off-by: NeilBrown Signed-off-by: Jens Axboe --- block/blk-core.c | 20 ++++++++++++++++++++ include/linux/blkdev.h | 7 ++++++- 2 files changed, 26 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/block/blk-core.c b/block/blk-core.c index 78b7b0cb7216..77edf0512338 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -2638,6 +2638,7 @@ void blk_start_plug(struct blk_plug *plug) plug->magic = PLUG_MAGIC; INIT_LIST_HEAD(&plug->list); + INIT_LIST_HEAD(&plug->cb_list); plug->should_sort = 0; /* @@ -2678,6 +2679,24 @@ static void queue_unplugged(struct request_queue *q, unsigned int depth, q->unplugged_fn(q); } +static void flush_plug_callbacks(struct blk_plug *plug) +{ + LIST_HEAD(callbacks); + + if (list_empty(&plug->cb_list)) + return; + + list_splice_init(&plug->cb_list, &callbacks); + + while (!list_empty(&callbacks)) { + struct blk_plug_cb *cb = list_first_entry(&callbacks, + struct blk_plug_cb, + list); + list_del(&cb->list); + cb->callback(cb); + } +} + void blk_flush_plug_list(struct blk_plug *plug, bool from_schedule) { struct request_queue *q; @@ -2688,6 +2707,7 @@ void blk_flush_plug_list(struct blk_plug *plug, bool from_schedule) BUG_ON(plug->magic != PLUG_MAGIC); + flush_plug_callbacks(plug); if (list_empty(&plug->list)) return; diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index ec0357d8c4a5..f3f7879391a7 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -860,8 +860,13 @@ extern void blk_put_queue(struct request_queue *); struct blk_plug { unsigned long magic; struct list_head list; + struct list_head cb_list; unsigned int should_sort; }; +struct blk_plug_cb { + struct list_head list; + void (*callback)(struct blk_plug_cb *); +}; extern void blk_start_plug(struct blk_plug *); extern void blk_finish_plug(struct blk_plug *); @@ -887,7 +892,7 @@ static inline bool blk_needs_flush_plug(struct task_struct *tsk) { struct blk_plug *plug = tsk->plug; - return plug && !list_empty(&plug->list); + return plug && (!list_empty(&plug->list) || !list_empty(&plug->cb_list)); } /* -- cgit From b4cb290e0a7d19235bd075c2ad4d60dbab0bac15 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 18 Apr 2011 09:54:05 +0200 Subject: Revert "block: add callback function for unplug notification" MD can't use this since it really requires us to be able to keep more than a single piece of state for the unplug. Commit 048c9374 added the required support for MD, so get rid of this now unused code. This reverts commit f75664570d8b75469cc468f23c2b27220984983b. Conflicts: block/blk-core.c Signed-off-by: Jens Axboe --- block/blk-core.c | 3 --- block/blk-settings.c | 16 ---------------- include/linux/blkdev.h | 3 --- 3 files changed, 22 deletions(-) (limited to 'include/linux') diff --git a/block/blk-core.c b/block/blk-core.c index 77edf0512338..09b262811fff 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -2674,9 +2674,6 @@ static void queue_unplugged(struct request_queue *q, unsigned int depth, { trace_block_unplug(q, depth, !from_schedule); __blk_run_queue(q, from_schedule); - - if (q->unplugged_fn) - q->unplugged_fn(q); } static void flush_plug_callbacks(struct blk_plug *plug) diff --git a/block/blk-settings.c b/block/blk-settings.c index eb949045bb12..1fa769293597 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c @@ -790,22 +790,6 @@ void blk_queue_flush(struct request_queue *q, unsigned int flush) } EXPORT_SYMBOL_GPL(blk_queue_flush); -/** - * blk_queue_unplugged - register a callback for an unplug event - * @q: the request queue for the device - * @fn: the function to call - * - * Some stacked drivers may need to know when IO is dispatched on an - * unplug event. By registrering a callback here, they will be notified - * when someone flushes their on-stack queue plug. The function will be - * called with the queue lock held. - */ -void blk_queue_unplugged(struct request_queue *q, unplugged_fn *fn) -{ - q->unplugged_fn = fn; -} -EXPORT_SYMBOL(blk_queue_unplugged); - static int __init blk_settings_init(void) { blk_max_low_pfn = max_low_pfn - 1; diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index f3f7879391a7..3448d89297e8 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -196,7 +196,6 @@ typedef void (request_fn_proc) (struct request_queue *q); typedef int (make_request_fn) (struct request_queue *q, struct bio *bio); typedef int (prep_rq_fn) (struct request_queue *, struct request *); typedef void (unprep_rq_fn) (struct request_queue *, struct request *); -typedef void (unplugged_fn) (struct request_queue *); struct bio_vec; struct bvec_merge_data { @@ -284,7 +283,6 @@ struct request_queue rq_timed_out_fn *rq_timed_out_fn; dma_drain_needed_fn *dma_drain_needed; lld_busy_fn *lld_busy_fn; - unplugged_fn *unplugged_fn; /* * Dispatch queue sorting @@ -843,7 +841,6 @@ extern void blk_queue_dma_alignment(struct request_queue *, int); extern void blk_queue_update_dma_alignment(struct request_queue *, int); extern void blk_queue_softirq_done(struct request_queue *, softirq_done_fn *); extern void blk_queue_rq_timed_out(struct request_queue *, rq_timed_out_fn *); -extern void blk_queue_unplugged(struct request_queue *, unplugged_fn *); extern void blk_queue_rq_timeout(struct request_queue *, unsigned int); extern void blk_queue_flush(struct request_queue *q, unsigned int flush); extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev); -- cgit From af1db72d8b340f97ad12b60175afdef43e6f0e60 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 18 Apr 2011 18:25:41 +1000 Subject: md/dm - remove remains of plug_fn callback. Now that unplugging is done differently, the unplug_fn callback is never called, so it can be completely discarded. Signed-off-by: NeilBrown --- drivers/md/dm-raid.c | 8 -------- include/linux/device-mapper.h | 1 - 2 files changed, 9 deletions(-) (limited to 'include/linux') diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index 5ef136cdba91..e5d8904fc8f6 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c @@ -390,13 +390,6 @@ static int raid_is_congested(struct dm_target_callbacks *cb, int bits) return md_raid5_congested(&rs->md, bits); } -static void raid_unplug(struct dm_target_callbacks *cb) -{ - struct raid_set *rs = container_of(cb, struct raid_set, callbacks); - - md_raid5_kick_device(rs->md.private); -} - /* * Construct a RAID4/5/6 mapping: * Args: @@ -487,7 +480,6 @@ static int raid_ctr(struct dm_target *ti, unsigned argc, char **argv) } rs->callbacks.congested_fn = raid_is_congested; - rs->callbacks.unplug_fn = raid_unplug; dm_table_add_target_callbacks(ti->table, &rs->callbacks); return 0; diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index e2768834f397..32a4423710f5 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -197,7 +197,6 @@ struct dm_target { struct dm_target_callbacks { struct list_head list; int (*congested_fn) (struct dm_target_callbacks *, int); - void (*unplug_fn)(struct dm_target_callbacks *); }; int dm_register_target(struct target_type *t); -- cgit From 1791f881435fab951939ad700e947b66c062e083 Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Wed, 30 Mar 2011 15:24:21 +0200 Subject: posix clocks: Replace mutex with reader/writer semaphore A dynamic posix clock is protected from asynchronous removal by a mutex. However, using a mutex has the unwanted effect that a long running clock operation in one process will unnecessarily block other processes. For example, one process might call read() to get an external time stamp coming in at one pulse per second. A second process calling clock_gettime would have to wait for almost a whole second. This patch fixes the issue by using a reader/writer semaphore instead of a mutex. Signed-off-by: Richard Cochran Cc: John Stultz Link: http://lkml.kernel.org/r/%3C20110330132421.GA31771%40riccoc20.at.omicron.at%3E Signed-off-by: Thomas Gleixner --- include/linux/posix-clock.h | 5 +++-- kernel/time/posix-clock.c | 24 +++++++++--------------- 2 files changed, 12 insertions(+), 17 deletions(-) (limited to 'include/linux') diff --git a/include/linux/posix-clock.h b/include/linux/posix-clock.h index 369e19d3750b..7f1183dcd119 100644 --- a/include/linux/posix-clock.h +++ b/include/linux/posix-clock.h @@ -24,6 +24,7 @@ #include #include #include +#include struct posix_clock; @@ -104,7 +105,7 @@ struct posix_clock_operations { * @ops: Functional interface to the clock * @cdev: Character device instance for this clock * @kref: Reference count. - * @mutex: Protects the 'zombie' field from concurrent access. + * @rwsem: Protects the 'zombie' field from concurrent access. * @zombie: If 'zombie' is true, then the hardware has disappeared. * @release: A function to free the structure when the reference count reaches * zero. May be NULL if structure is statically allocated. @@ -117,7 +118,7 @@ struct posix_clock { struct posix_clock_operations ops; struct cdev cdev; struct kref kref; - struct mutex mutex; + struct rw_semaphore rwsem; bool zombie; void (*release)(struct posix_clock *clk); }; diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c index 25028dd4fa18..c340ca658f37 100644 --- a/kernel/time/posix-clock.c +++ b/kernel/time/posix-clock.c @@ -19,7 +19,6 @@ */ #include #include -#include #include #include #include @@ -34,19 +33,19 @@ static struct posix_clock *get_posix_clock(struct file *fp) { struct posix_clock *clk = fp->private_data; - mutex_lock(&clk->mutex); + down_read(&clk->rwsem); if (!clk->zombie) return clk; - mutex_unlock(&clk->mutex); + up_read(&clk->rwsem); return NULL; } static void put_posix_clock(struct posix_clock *clk) { - mutex_unlock(&clk->mutex); + up_read(&clk->rwsem); } static ssize_t posix_clock_read(struct file *fp, char __user *buf, @@ -156,7 +155,7 @@ static int posix_clock_open(struct inode *inode, struct file *fp) struct posix_clock *clk = container_of(inode->i_cdev, struct posix_clock, cdev); - mutex_lock(&clk->mutex); + down_read(&clk->rwsem); if (clk->zombie) { err = -ENODEV; @@ -172,7 +171,7 @@ static int posix_clock_open(struct inode *inode, struct file *fp) fp->private_data = clk; } out: - mutex_unlock(&clk->mutex); + up_read(&clk->rwsem); return err; } @@ -211,25 +210,20 @@ int posix_clock_register(struct posix_clock *clk, dev_t devid) int err; kref_init(&clk->kref); - mutex_init(&clk->mutex); + init_rwsem(&clk->rwsem); cdev_init(&clk->cdev, &posix_clock_file_operations); clk->cdev.owner = clk->ops.owner; err = cdev_add(&clk->cdev, devid, 1); - if (err) - goto no_cdev; return err; -no_cdev: - mutex_destroy(&clk->mutex); - return err; } EXPORT_SYMBOL_GPL(posix_clock_register); static void delete_clock(struct kref *kref) { struct posix_clock *clk = container_of(kref, struct posix_clock, kref); - mutex_destroy(&clk->mutex); + if (clk->release) clk->release(clk); } @@ -238,9 +232,9 @@ void posix_clock_unregister(struct posix_clock *clk) { cdev_del(&clk->cdev); - mutex_lock(&clk->mutex); + down_write(&clk->rwsem); clk->zombie = true; - mutex_unlock(&clk->mutex); + up_write(&clk->rwsem); kref_put(&clk->kref, delete_clock); } -- cgit From 24ecfbe27f65563909b14492afda2f1c21f7c044 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 18 Apr 2011 11:41:33 +0200 Subject: block: add blk_run_queue_async Instead of overloading __blk_run_queue to force an offload to kblockd add a new blk_run_queue_async helper to do it explicitly. I've kept the blk_queue_stopped check for now, but I suspect it's not needed as the check we do when the workqueue items runs should be enough. Signed-off-by: Christoph Hellwig Signed-off-by: Jens Axboe --- block/blk-core.c | 36 ++++++++++++++++++++++++------------ block/blk-exec.c | 2 +- block/blk-flush.c | 4 ++-- block/blk.h | 1 + block/cfq-iosched.c | 6 +++--- block/elevator.c | 4 ++-- drivers/scsi/scsi_lib.c | 2 +- drivers/scsi/scsi_transport_fc.c | 2 +- include/linux/blkdev.h | 2 +- 9 files changed, 36 insertions(+), 23 deletions(-) (limited to 'include/linux') diff --git a/block/blk-core.c b/block/blk-core.c index e2bacfa46cc3..5fa3dd2705c6 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -204,7 +204,7 @@ static void blk_delay_work(struct work_struct *work) q = container_of(work, struct request_queue, delay_work.work); spin_lock_irq(q->queue_lock); - __blk_run_queue(q, false); + __blk_run_queue(q); spin_unlock_irq(q->queue_lock); } @@ -239,7 +239,7 @@ void blk_start_queue(struct request_queue *q) WARN_ON(!irqs_disabled()); queue_flag_clear(QUEUE_FLAG_STOPPED, q); - __blk_run_queue(q, false); + __blk_run_queue(q); } EXPORT_SYMBOL(blk_start_queue); @@ -296,11 +296,9 @@ EXPORT_SYMBOL(blk_sync_queue); * * Description: * See @blk_run_queue. This variant must be called with the queue lock - * held and interrupts disabled. If force_kblockd is true, then it is - * safe to call this without holding the queue lock. - * + * held and interrupts disabled. */ -void __blk_run_queue(struct request_queue *q, bool force_kblockd) +void __blk_run_queue(struct request_queue *q) { if (unlikely(blk_queue_stopped(q))) return; @@ -309,7 +307,7 @@ void __blk_run_queue(struct request_queue *q, bool force_kblockd) * Only recurse once to avoid overrunning the stack, let the unplug * handling reinvoke the handler shortly if we already got there. */ - if (!force_kblockd && !queue_flag_test_and_set(QUEUE_FLAG_REENTER, q)) { + if (!queue_flag_test_and_set(QUEUE_FLAG_REENTER, q)) { q->request_fn(q); queue_flag_clear(QUEUE_FLAG_REENTER, q); } else @@ -317,6 +315,20 @@ void __blk_run_queue(struct request_queue *q, bool force_kblockd) } EXPORT_SYMBOL(__blk_run_queue); +/** + * blk_run_queue_async - run a single device queue in workqueue context + * @q: The queue to run + * + * Description: + * Tells kblockd to perform the equivalent of @blk_run_queue on behalf + * of us. + */ +void blk_run_queue_async(struct request_queue *q) +{ + if (likely(!blk_queue_stopped(q))) + queue_delayed_work(kblockd_workqueue, &q->delay_work, 0); +} + /** * blk_run_queue - run a single device queue * @q: The queue to run @@ -330,7 +342,7 @@ void blk_run_queue(struct request_queue *q) unsigned long flags; spin_lock_irqsave(q->queue_lock, flags); - __blk_run_queue(q, false); + __blk_run_queue(q); spin_unlock_irqrestore(q->queue_lock, flags); } EXPORT_SYMBOL(blk_run_queue); @@ -979,7 +991,7 @@ void blk_insert_request(struct request_queue *q, struct request *rq, blk_queue_end_tag(q, rq); add_acct_request(q, rq, where); - __blk_run_queue(q, false); + __blk_run_queue(q); spin_unlock_irqrestore(q->queue_lock, flags); } EXPORT_SYMBOL(blk_insert_request); @@ -1323,7 +1335,7 @@ get_rq: } else { spin_lock_irq(q->queue_lock); add_acct_request(q, req, where); - __blk_run_queue(q, false); + __blk_run_queue(q); out_unlock: spin_unlock_irq(q->queue_lock); } @@ -2684,9 +2696,9 @@ static void queue_unplugged(struct request_queue *q, unsigned int depth, */ if (from_schedule) { spin_unlock(q->queue_lock); - __blk_run_queue(q, true); + blk_run_queue_async(q); } else { - __blk_run_queue(q, false); + __blk_run_queue(q); spin_unlock(q->queue_lock); } diff --git a/block/blk-exec.c b/block/blk-exec.c index 7482b7fa863b..81e31819a597 100644 --- a/block/blk-exec.c +++ b/block/blk-exec.c @@ -55,7 +55,7 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk, WARN_ON(irqs_disabled()); spin_lock_irq(q->queue_lock); __elv_add_request(q, rq, where); - __blk_run_queue(q, false); + __blk_run_queue(q); /* the queue is stopped so it won't be plugged+unplugged */ if (rq->cmd_type == REQ_TYPE_PM_RESUME) q->request_fn(q); diff --git a/block/blk-flush.c b/block/blk-flush.c index eba4a2790c6c..6c9b5e189e62 100644 --- a/block/blk-flush.c +++ b/block/blk-flush.c @@ -218,7 +218,7 @@ static void flush_end_io(struct request *flush_rq, int error) * request_fn may confuse the driver. Always use kblockd. */ if (queued) - __blk_run_queue(q, true); + blk_run_queue_async(q); } /** @@ -274,7 +274,7 @@ static void flush_data_end_io(struct request *rq, int error) * the comment in flush_end_io(). */ if (blk_flush_complete_seq(rq, REQ_FSEQ_DATA, error)) - __blk_run_queue(q, true); + blk_run_queue_async(q); } /** diff --git a/block/blk.h b/block/blk.h index 61263463e38e..c9df8fc3c999 100644 --- a/block/blk.h +++ b/block/blk.h @@ -22,6 +22,7 @@ void blk_rq_timed_out_timer(unsigned long data); void blk_delete_timer(struct request *); void blk_add_timer(struct request *); void __generic_unplug_device(struct request_queue *); +void blk_run_queue_async(struct request_queue *q); /* * Internal atomic flags for request handling diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 3be881ec95ad..46b0a1d1d925 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -3368,7 +3368,7 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, cfqd->busy_queues > 1) { cfq_del_timer(cfqd, cfqq); cfq_clear_cfqq_wait_request(cfqq); - __blk_run_queue(cfqd->queue, false); + __blk_run_queue(cfqd->queue); } else { cfq_blkiocg_update_idle_time_stats( &cfqq->cfqg->blkg); @@ -3383,7 +3383,7 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, * this new queue is RT and the current one is BE */ cfq_preempt_queue(cfqd, cfqq); - __blk_run_queue(cfqd->queue, false); + __blk_run_queue(cfqd->queue); } } @@ -3743,7 +3743,7 @@ static void cfq_kick_queue(struct work_struct *work) struct request_queue *q = cfqd->queue; spin_lock_irq(q->queue_lock); - __blk_run_queue(cfqd->queue, false); + __blk_run_queue(cfqd->queue); spin_unlock_irq(q->queue_lock); } diff --git a/block/elevator.c b/block/elevator.c index 0cdb4e7ebab4..6f6abc08bb56 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -642,7 +642,7 @@ void elv_quiesce_start(struct request_queue *q) */ elv_drain_elevator(q); while (q->rq.elvpriv) { - __blk_run_queue(q, false); + __blk_run_queue(q); spin_unlock_irq(q->queue_lock); msleep(10); spin_lock_irq(q->queue_lock); @@ -695,7 +695,7 @@ void __elv_add_request(struct request_queue *q, struct request *rq, int where) * with anything. There's no point in delaying queue * processing. */ - __blk_run_queue(q, false); + __blk_run_queue(q); break; case ELEVATOR_INSERT_SORT_MERGE: diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 6d5c7ff43f5b..ab55c2fa7ce2 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -443,7 +443,7 @@ static void scsi_run_queue(struct request_queue *q) &sdev->request_queue->queue_flags); if (flagset) queue_flag_set(QUEUE_FLAG_REENTER, sdev->request_queue); - __blk_run_queue(sdev->request_queue, false); + __blk_run_queue(sdev->request_queue); if (flagset) queue_flag_clear(QUEUE_FLAG_REENTER, sdev->request_queue); spin_unlock(sdev->request_queue->queue_lock); diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index fdf3fa639056..28c33506e4ad 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -3829,7 +3829,7 @@ fc_bsg_goose_queue(struct fc_rport *rport) !test_bit(QUEUE_FLAG_REENTER, &rport->rqst_q->queue_flags); if (flagset) queue_flag_set(QUEUE_FLAG_REENTER, rport->rqst_q); - __blk_run_queue(rport->rqst_q, false); + __blk_run_queue(rport->rqst_q); if (flagset) queue_flag_clear(QUEUE_FLAG_REENTER, rport->rqst_q); spin_unlock_irqrestore(rport->rqst_q->queue_lock, flags); diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 3448d89297e8..cbbfd98ad4a3 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -697,7 +697,7 @@ extern void blk_start_queue(struct request_queue *q); extern void blk_stop_queue(struct request_queue *q); extern void blk_sync_queue(struct request_queue *q); extern void __blk_stop_queue(struct request_queue *q); -extern void __blk_run_queue(struct request_queue *q, bool force_kblockd); +extern void __blk_run_queue(struct request_queue *q); extern void blk_run_queue(struct request_queue *); extern int blk_rq_map_user(struct request_queue *, struct request *, struct rq_map_data *, void __user *, unsigned long, -- cgit From 80b4895aa4578e9372d76cd4063f82d0c3994d77 Mon Sep 17 00:00:00 2001 From: Jeff Brown Date: Mon, 18 Apr 2011 10:08:02 -0700 Subject: Input: estimate number of events per packet Calculate a default based on the number of ABS axes, REL axes, and MT slots for the device during input device registration. Signed-off-by: Jeff Brown Reviewed-by: Henrik Rydberg Signed-off-by: Dmitry Torokhov --- drivers/input/input.c | 40 ++++++++++++++++++++++++++++++++++++++++ include/linux/input/mt.h | 6 ++++++ 2 files changed, 46 insertions(+) (limited to 'include/linux') diff --git a/drivers/input/input.c b/drivers/input/input.c index d6e8bd8a851c..ebbceedc92f4 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -1746,6 +1746,42 @@ void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int } EXPORT_SYMBOL(input_set_capability); +static unsigned int input_estimate_events_per_packet(struct input_dev *dev) +{ + int mt_slots; + int i; + unsigned int events; + + if (dev->mtsize) { + mt_slots = dev->mtsize; + } else if (test_bit(ABS_MT_TRACKING_ID, dev->absbit)) { + mt_slots = dev->absinfo[ABS_MT_TRACKING_ID].maximum - + dev->absinfo[ABS_MT_TRACKING_ID].minimum + 1, + clamp(mt_slots, 2, 32); + } else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) { + mt_slots = 2; + } else { + mt_slots = 0; + } + + events = mt_slots + 1; /* count SYN_MT_REPORT and SYN_REPORT */ + + for (i = 0; i < ABS_CNT; i++) { + if (test_bit(i, dev->absbit)) { + if (input_is_mt_axis(i)) + events += mt_slots; + else + events++; + } + } + + for (i = 0; i < REL_CNT; i++) + if (test_bit(i, dev->relbit)) + events++; + + return events; +} + #define INPUT_CLEANSE_BITMASK(dev, type, bits) \ do { \ if (!test_bit(EV_##type, dev->evbit)) \ @@ -1793,6 +1829,10 @@ int input_register_device(struct input_dev *dev) /* Make sure that bitmasks not mentioned in dev->evbit are clean. */ input_cleanse_bitmasks(dev); + if (!dev->hint_events_per_packet) + dev->hint_events_per_packet = + input_estimate_events_per_packet(dev); + /* * If delay and period are pre-set by the driver, then autorepeating * is handled by the driver itself and we don't do it in input.c. diff --git a/include/linux/input/mt.h b/include/linux/input/mt.h index b3ac06a4435d..318bb82325a6 100644 --- a/include/linux/input/mt.h +++ b/include/linux/input/mt.h @@ -48,6 +48,12 @@ static inline void input_mt_slot(struct input_dev *dev, int slot) input_event(dev, EV_ABS, ABS_MT_SLOT, slot); } +static inline bool input_is_mt_axis(int axis) +{ + return axis == ABS_MT_SLOT || + (axis >= ABS_MT_FIRST && axis <= ABS_MT_LAST); +} + void input_mt_report_slot_state(struct input_dev *dev, unsigned int tool_type, bool active); -- cgit From c78193e9c7bcbf25b8237ad0dec82f805c4ea69b Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 18 Apr 2011 10:35:30 -0700 Subject: next_pidmap: fix overflow condition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit next_pidmap() just quietly accepted whatever 'last' pid that was passed in, which is not all that safe when one of the users is /proc. Admittedly the proc code should do some sanity checking on the range (and that will be the next commit), but that doesn't mean that the helper functions should just do that pidmap pointer arithmetic without checking the range of its arguments. So clamp 'last' to PID_MAX_LIMIT. The fact that we then do "last+1" doesn't really matter, the for-loop does check against the end of the pidmap array properly (it's only the actual pointer arithmetic overflow case we need to worry about, and going one bit beyond isn't going to overflow). [ Use PID_MAX_LIMIT rather than pid_max as per Eric Biederman ] Reported-by: Tavis Ormandy Analyzed-by: Robert ÅšwiÄ™cki Cc: Eric W. Biederman Cc: Pavel Emelyanov Signed-off-by: Linus Torvalds --- include/linux/pid.h | 2 +- kernel/pid.c | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pid.h b/include/linux/pid.h index 31afb7ecbe1f..cdced84261d7 100644 --- a/include/linux/pid.h +++ b/include/linux/pid.h @@ -117,7 +117,7 @@ extern struct pid *find_vpid(int nr); */ extern struct pid *find_get_pid(int nr); extern struct pid *find_ge_pid(int nr, struct pid_namespace *); -int next_pidmap(struct pid_namespace *pid_ns, int last); +int next_pidmap(struct pid_namespace *pid_ns, unsigned int last); extern struct pid *alloc_pid(struct pid_namespace *ns); extern void free_pid(struct pid *pid); diff --git a/kernel/pid.c b/kernel/pid.c index 02f221274265..57a8346a270e 100644 --- a/kernel/pid.c +++ b/kernel/pid.c @@ -217,11 +217,14 @@ static int alloc_pidmap(struct pid_namespace *pid_ns) return -1; } -int next_pidmap(struct pid_namespace *pid_ns, int last) +int next_pidmap(struct pid_namespace *pid_ns, unsigned int last) { int offset; struct pidmap *map, *end; + if (last >= PID_MAX_LIMIT) + return -1; + offset = (last + 1) & BITS_PER_PAGE_MASK; map = &pid_ns->pidmap[(last + 1)/BITS_PER_PAGE]; end = &pid_ns->pidmap[PIDMAP_ENTRIES]; -- cgit From 468f86134ee515234afe5c5b3f39f266c50e61a5 Mon Sep 17 00:00:00 2001 From: Bryan Schumaker Date: Mon, 18 Apr 2011 15:57:32 -0400 Subject: NFSv4.1: Don't update sequence number if rpc_task is not sent If we fail to contact the gss upcall program, then no message will be sent to the server. The client still updated the sequence number, however, and this lead to NFS4ERR_SEQ_MISMATCH for the next several RPC calls. Signed-off-by: Bryan Schumaker Signed-off-by: Trond Myklebust --- fs/nfs/nfs4proc.c | 4 ++-- include/linux/sunrpc/sched.h | 2 ++ net/sunrpc/xprt.c | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index b8e1ac69b743..e7e2077eebd9 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -444,8 +444,8 @@ static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res * if (res->sr_status == 1) res->sr_status = NFS_OK; - /* -ERESTARTSYS can result in skipping nfs41_sequence_setup */ - if (!res->sr_slot) + /* don't increment the sequence number if the task wasn't sent */ + if (!RPC_WAS_SENT(task)) goto out; /* Check the SEQUENCE operation status */ diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h index d81db8012c63..3b94f804b852 100644 --- a/include/linux/sunrpc/sched.h +++ b/include/linux/sunrpc/sched.h @@ -127,6 +127,7 @@ struct rpc_task_setup { #define RPC_TASK_KILLED 0x0100 /* task was killed */ #define RPC_TASK_SOFT 0x0200 /* Use soft timeouts */ #define RPC_TASK_SOFTCONN 0x0400 /* Fail if can't connect */ +#define RPC_TASK_SENT 0x0800 /* message was sent */ #define RPC_IS_ASYNC(t) ((t)->tk_flags & RPC_TASK_ASYNC) #define RPC_IS_SWAPPER(t) ((t)->tk_flags & RPC_TASK_SWAPPER) @@ -134,6 +135,7 @@ struct rpc_task_setup { #define RPC_ASSASSINATED(t) ((t)->tk_flags & RPC_TASK_KILLED) #define RPC_IS_SOFT(t) ((t)->tk_flags & RPC_TASK_SOFT) #define RPC_IS_SOFTCONN(t) ((t)->tk_flags & RPC_TASK_SOFTCONN) +#define RPC_WAS_SENT(t) ((t)->tk_flags & RPC_TASK_SENT) #define RPC_TASK_RUNNING 0 #define RPC_TASK_QUEUED 1 diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 9494c3767356..ce5eb68a9664 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -906,6 +906,7 @@ void xprt_transmit(struct rpc_task *task) } dprintk("RPC: %5u xmit complete\n", task->tk_pid); + task->tk_flags |= RPC_TASK_SENT; spin_lock_bh(&xprt->transport_lock); xprt->ops->set_retrans_timeout(task); -- cgit From c21e6beba8835d09bb80e34961430b13e60381c5 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 19 Apr 2011 13:32:46 +0200 Subject: block: get rid of QUEUE_FLAG_REENTER We are currently using this flag to check whether it's safe to call into ->request_fn(). If it is set, we punt to kblockd. But we get a lot of false positives and excessive punts to kblockd, which hurts performance. The only real abuser of this infrastructure is SCSI. So export the async queue run and convert SCSI over to use that. There's room for improvement in that SCSI need not always use the async call, but this fixes our performance issue and they can fix that up in due time. Signed-off-by: Jens Axboe --- block/blk-core.c | 11 ++--------- block/blk.h | 1 - drivers/scsi/scsi_lib.c | 17 +---------------- drivers/scsi/scsi_transport_fc.c | 19 ++++--------------- include/linux/blkdev.h | 26 +++++++++++++------------- 5 files changed, 20 insertions(+), 54 deletions(-) (limited to 'include/linux') diff --git a/block/blk-core.c b/block/blk-core.c index 580eee5743e5..40725b9091f1 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -303,15 +303,7 @@ void __blk_run_queue(struct request_queue *q) if (unlikely(blk_queue_stopped(q))) return; - /* - * Only recurse once to avoid overrunning the stack, let the unplug - * handling reinvoke the handler shortly if we already got there. - */ - if (!queue_flag_test_and_set(QUEUE_FLAG_REENTER, q)) { - q->request_fn(q); - queue_flag_clear(QUEUE_FLAG_REENTER, q); - } else - queue_delayed_work(kblockd_workqueue, &q->delay_work, 0); + q->request_fn(q); } EXPORT_SYMBOL(__blk_run_queue); @@ -328,6 +320,7 @@ void blk_run_queue_async(struct request_queue *q) if (likely(!blk_queue_stopped(q))) queue_delayed_work(kblockd_workqueue, &q->delay_work, 0); } +EXPORT_SYMBOL(blk_run_queue_async); /** * blk_run_queue - run a single device queue diff --git a/block/blk.h b/block/blk.h index c9df8fc3c999..61263463e38e 100644 --- a/block/blk.h +++ b/block/blk.h @@ -22,7 +22,6 @@ void blk_rq_timed_out_timer(unsigned long data); void blk_delete_timer(struct request *); void blk_add_timer(struct request *); void __generic_unplug_device(struct request_queue *); -void blk_run_queue_async(struct request_queue *q); /* * Internal atomic flags for request handling diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index ab55c2fa7ce2..e9901b8f8443 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -411,8 +411,6 @@ static void scsi_run_queue(struct request_queue *q) list_splice_init(&shost->starved_list, &starved_list); while (!list_empty(&starved_list)) { - int flagset; - /* * As long as shost is accepting commands and we have * starved queues, call blk_run_queue. scsi_request_fn @@ -435,20 +433,7 @@ static void scsi_run_queue(struct request_queue *q) continue; } - spin_unlock(shost->host_lock); - - spin_lock(sdev->request_queue->queue_lock); - flagset = test_bit(QUEUE_FLAG_REENTER, &q->queue_flags) && - !test_bit(QUEUE_FLAG_REENTER, - &sdev->request_queue->queue_flags); - if (flagset) - queue_flag_set(QUEUE_FLAG_REENTER, sdev->request_queue); - __blk_run_queue(sdev->request_queue); - if (flagset) - queue_flag_clear(QUEUE_FLAG_REENTER, sdev->request_queue); - spin_unlock(sdev->request_queue->queue_lock); - - spin_lock(shost->host_lock); + blk_run_queue_async(sdev->request_queue); } /* put any unprocessed entries back */ list_splice(&starved_list, &shost->starved_list); diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 28c33506e4ad..815069d13f9b 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -3816,28 +3816,17 @@ fail_host_msg: static void fc_bsg_goose_queue(struct fc_rport *rport) { - int flagset; - unsigned long flags; - if (!rport->rqst_q) return; + /* + * This get/put dance makes no sense + */ get_device(&rport->dev); - - spin_lock_irqsave(rport->rqst_q->queue_lock, flags); - flagset = test_bit(QUEUE_FLAG_REENTER, &rport->rqst_q->queue_flags) && - !test_bit(QUEUE_FLAG_REENTER, &rport->rqst_q->queue_flags); - if (flagset) - queue_flag_set(QUEUE_FLAG_REENTER, rport->rqst_q); - __blk_run_queue(rport->rqst_q); - if (flagset) - queue_flag_clear(QUEUE_FLAG_REENTER, rport->rqst_q); - spin_unlock_irqrestore(rport->rqst_q->queue_lock, flags); - + blk_run_queue_async(rport->rqst_q); put_device(&rport->dev); } - /** * fc_bsg_rport_dispatch - process rport bsg requests and dispatch to LLDD * @q: rport request queue diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index cbbfd98ad4a3..2ad95fa1d130 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -388,20 +388,19 @@ struct request_queue #define QUEUE_FLAG_SYNCFULL 3 /* read queue has been filled */ #define QUEUE_FLAG_ASYNCFULL 4 /* write queue has been filled */ #define QUEUE_FLAG_DEAD 5 /* queue being torn down */ -#define QUEUE_FLAG_REENTER 6 /* Re-entrancy avoidance */ -#define QUEUE_FLAG_ELVSWITCH 7 /* don't use elevator, just do FIFO */ -#define QUEUE_FLAG_BIDI 8 /* queue supports bidi requests */ -#define QUEUE_FLAG_NOMERGES 9 /* disable merge attempts */ -#define QUEUE_FLAG_SAME_COMP 10 /* force complete on same CPU */ -#define QUEUE_FLAG_FAIL_IO 11 /* fake timeout */ -#define QUEUE_FLAG_STACKABLE 12 /* supports request stacking */ -#define QUEUE_FLAG_NONROT 13 /* non-rotational device (SSD) */ +#define QUEUE_FLAG_ELVSWITCH 6 /* don't use elevator, just do FIFO */ +#define QUEUE_FLAG_BIDI 7 /* queue supports bidi requests */ +#define QUEUE_FLAG_NOMERGES 8 /* disable merge attempts */ +#define QUEUE_FLAG_SAME_COMP 9 /* force complete on same CPU */ +#define QUEUE_FLAG_FAIL_IO 10 /* fake timeout */ +#define QUEUE_FLAG_STACKABLE 11 /* supports request stacking */ +#define QUEUE_FLAG_NONROT 12 /* non-rotational device (SSD) */ #define QUEUE_FLAG_VIRT QUEUE_FLAG_NONROT /* paravirt device */ -#define QUEUE_FLAG_IO_STAT 15 /* do IO stats */ -#define QUEUE_FLAG_DISCARD 16 /* supports DISCARD */ -#define QUEUE_FLAG_NOXMERGES 17 /* No extended merges */ -#define QUEUE_FLAG_ADD_RANDOM 18 /* Contributes to random pool */ -#define QUEUE_FLAG_SECDISCARD 19 /* supports SECDISCARD */ +#define QUEUE_FLAG_IO_STAT 13 /* do IO stats */ +#define QUEUE_FLAG_DISCARD 14 /* supports DISCARD */ +#define QUEUE_FLAG_NOXMERGES 15 /* No extended merges */ +#define QUEUE_FLAG_ADD_RANDOM 16 /* Contributes to random pool */ +#define QUEUE_FLAG_SECDISCARD 17 /* supports SECDISCARD */ #define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \ (1 << QUEUE_FLAG_STACKABLE) | \ @@ -699,6 +698,7 @@ extern void blk_sync_queue(struct request_queue *q); extern void __blk_stop_queue(struct request_queue *q); extern void __blk_run_queue(struct request_queue *q); extern void blk_run_queue(struct request_queue *); +extern void blk_run_queue_async(struct request_queue *q); extern int blk_rq_map_user(struct request_queue *, struct request *, struct rq_map_data *, void __user *, unsigned long, gfp_t); -- cgit From 62c7d085e1f2a1f2b4d89560551eff18d703b3b1 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 Mar 2011 16:42:47 +0200 Subject: wl12xx: add new board_tcxo_clock element to the platform data This new value is a new type of clock setting that is used by wl128x chipsets. Signed-off-by: Luciano Coelho --- include/linux/wl12xx.h | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h index bebb8efea0a6..eb8aacab8d4e 100644 --- a/include/linux/wl12xx.h +++ b/include/linux/wl12xx.h @@ -24,7 +24,7 @@ #ifndef _LINUX_WL12XX_H #define _LINUX_WL12XX_H -/* The board reference clock values */ +/* Reference clock values */ enum { WL12XX_REFCLOCK_19 = 0, /* 19.2 MHz */ WL12XX_REFCLOCK_26 = 1, /* 26 MHz */ @@ -32,12 +32,25 @@ enum { WL12XX_REFCLOCK_54 = 3, /* 54 MHz */ }; +/* TCXO clock values */ +enum { + WL12XX_TCXOCLOCK_19_2 = 0, /* 19.2MHz */ + WL12XX_TCXOCLOCK_26 = 1, /* 26 MHz */ + WL12XX_TCXOCLOCK_38_4 = 2, /* 38.4MHz */ + WL12XX_TCXOCLOCK_52 = 3, /* 52 MHz */ + WL12XX_TCXOCLOCK_16_368 = 4, /* 16.368 MHz */ + WL12XX_TCXOCLOCK_32_736 = 5, /* 32.736 MHz */ + WL12XX_TCXOCLOCK_16_8 = 6, /* 16.8 MHz */ + WL12XX_TCXOCLOCK_33_6 = 7, /* 33.6 MHz */ +}; + struct wl12xx_platform_data { void (*set_power)(bool enable); /* SDIO only: IRQ number if WLAN_IRQ line is used, 0 for SDIO IRQs */ int irq; bool use_eeprom; int board_ref_clock; + int board_tcxo_clock; }; #ifdef CONFIG_WL12XX_PLATFORM_DATA -- cgit From d29633b40e6afc6b4276a4e381bc532cc84be104 Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Thu, 31 Mar 2011 10:06:57 +0200 Subject: wl12xx: Clean up and fix the 128x boot sequence Clean up the boot sequence code & fix the following issues: 1. Always read the registers' values and set the relevant bits instead of zeroing all other bits 2. Handle cases where wl1271_top_reg_read returns an error 3. Verify that the HW can detect the selected clock source 4. Remove 128x PG10 initialization code 5. Configure the MCS PLL to work in HP mode Signed-off-by: Ido Yariv Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/boot.c | 235 ++++++++++++++++++------------------- drivers/net/wireless/wl12xx/boot.h | 1 + include/linux/wl12xx.h | 10 +- 3 files changed, 123 insertions(+), 123 deletions(-) (limited to 'include/linux') diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c index 34bf2fe47dc7..b5ec2c2b6f78 100644 --- a/drivers/net/wireless/wl12xx/boot.c +++ b/drivers/net/wireless/wl12xx/boot.c @@ -523,137 +523,137 @@ static void wl1271_boot_hw_version(struct wl1271 *wl) wl->quirks |= WL12XX_QUIRK_END_OF_TRANSACTION; } -/* - * WL128x has two clocks input - TCXO and FREF. - * TCXO is the main clock of the device, while FREF is used to sync - * between the GPS and the cellular modem. - * In cases where TCXO is 32.736MHz or 16.368MHz, the FREF will be used - * as the WLAN/BT main clock. - */ -static int wl128x_switch_fref(struct wl1271 *wl, bool *is_ref_clk) +static int wl128x_switch_tcxo_to_fref(struct wl1271 *wl) { - u16 sys_clk_cfg_val; + u16 spare_reg; - /* if working on XTAL-only mode go directly to TCXO TO FREF SWITCH */ - if ((wl->ref_clock == CONF_REF_CLK_38_4_M_XTAL) || - (wl->ref_clock == CONF_REF_CLK_26_M_XTAL)) - return true; + /* Mask bits [2] & [8:4] in the sys_clk_cfg register */ + spare_reg = wl1271_top_reg_read(wl, WL_SPARE_REG); + if (spare_reg == 0xFFFF) + return -EFAULT; + spare_reg |= (BIT(3) | BIT(5) | BIT(6)); + wl1271_top_reg_write(wl, WL_SPARE_REG, spare_reg); - /* Read clock source FREF or TCXO */ - sys_clk_cfg_val = wl1271_top_reg_read(wl, SYS_CLK_CFG_REG); + /* Enable FREF_CLK_REQ & mux MCS and coex PLLs to FREF */ + wl1271_top_reg_write(wl, SYS_CLK_CFG_REG, + WL_CLK_REQ_TYPE_PG2 | MCS_PLL_CLK_SEL_FREF); - if (sys_clk_cfg_val & PRCM_CM_EN_MUX_WLAN_FREF) { - /* if bit 3 is set - working with FREF clock */ - wl1271_debug(DEBUG_BOOT, "working with FREF clock, skip" - " to FREF"); + /* Delay execution for 15msec, to let the HW settle */ + mdelay(15); - *is_ref_clk = true; - } else { - /* if bit 3 is clear - working with TCXO clock */ - wl1271_debug(DEBUG_BOOT, "working with TCXO clock"); - - /* TCXO to FREF switch, check TXCO clock config */ - if ((wl->tcxo_clock != WL12XX_TCXOCLOCK_16_368) && - (wl->tcxo_clock != WL12XX_TCXOCLOCK_32_736)) { - /* - * not 16.368Mhz and not 32.736Mhz - skip to - * configure ELP stage - */ - wl1271_debug(DEBUG_BOOT, "NEW PLL ALGO:" - " TcxoRefClk=%d - not 16.368Mhz and not" - " 32.736Mhz - skip to configure ELP" - " stage", wl->tcxo_clock); - - *is_ref_clk = false; - } else { - wl1271_debug(DEBUG_BOOT, "NEW PLL ALGO:" - "TcxoRefClk=%d - 16.368Mhz or 32.736Mhz" - " - TCXO to FREF switch", - wl->tcxo_clock); + return 0; +} - return true; - } - } +static bool wl128x_is_tcxo_valid(struct wl1271 *wl) +{ + u16 tcxo_detection; + + tcxo_detection = wl1271_top_reg_read(wl, TCXO_CLK_DETECT_REG); + if (tcxo_detection & TCXO_DET_FAILED) + return false; - return false; + return true; } -static int wl128x_boot_clk(struct wl1271 *wl, bool *is_ref_clk) +static bool wl128x_is_fref_valid(struct wl1271 *wl) { - if (wl128x_switch_fref(wl, is_ref_clk)) { - wl1271_debug(DEBUG_BOOT, "XTAL-only mode go directly to" - " TCXO TO FREF SWITCH"); - /* TCXO to FREF switch - for PG2.0 */ - wl1271_top_reg_write(wl, WL_SPARE_REG, - WL_SPARE_MASK_8526); - - wl1271_top_reg_write(wl, SYS_CLK_CFG_REG, - WL_CLK_REQ_TYPE_PG2 | MCS_PLL_CLK_SEL_FREF); - - *is_ref_clk = true; - mdelay(15); - } + u16 fref_detection; - /* Set bit 2 in spare register to avoid illegal access */ - wl1271_top_reg_write(wl, WL_SPARE_REG, WL_SPARE_VAL); + fref_detection = wl1271_top_reg_read(wl, FREF_CLK_DETECT_REG); + if (fref_detection & FREF_CLK_DETECT_FAIL) + return false; - /* working with TCXO clock */ - if ((*is_ref_clk == false) && - ((wl->tcxo_clock == WL12XX_TCXOCLOCK_16_8) || - (wl->tcxo_clock == WL12XX_TCXOCLOCK_33_6))) { - wl1271_debug(DEBUG_BOOT, "16_8_M or 33_6_M TCXO detected"); + return true; +} - /* Manually Configure MCS PLL settings PG2.0 Only */ - wl1271_top_reg_write(wl, MCS_PLL_M_REG, MCS_PLL_M_REG_VAL); - wl1271_top_reg_write(wl, MCS_PLL_N_REG, MCS_PLL_N_REG_VAL); - wl1271_top_reg_write(wl, MCS_PLL_CONFIG_REG, - MCS_PLL_CONFIG_REG_VAL); - } else { - int pll_config; - u16 mcs_pll_config_val; +static int wl128x_manually_configure_mcs_pll(struct wl1271 *wl) +{ + wl1271_top_reg_write(wl, MCS_PLL_M_REG, MCS_PLL_M_REG_VAL); + wl1271_top_reg_write(wl, MCS_PLL_N_REG, MCS_PLL_N_REG_VAL); + wl1271_top_reg_write(wl, MCS_PLL_CONFIG_REG, MCS_PLL_CONFIG_REG_VAL); - /* - * Configure MCS PLL settings to FREF Freq - * Set the values that determine the time elapse since the PLL's - * get their enable signal until the lock indication is set - */ - wl1271_top_reg_write(wl, PLL_LOCK_COUNTERS_REG, - PLL_LOCK_COUNTERS_COEX | PLL_LOCK_COUNTERS_MCS); + return 0; +} - mcs_pll_config_val = wl1271_top_reg_read(wl, - MCS_PLL_CONFIG_REG); - /* - * Set the MCS PLL input frequency value according to the - * reference clock value detected/read - */ - if (*is_ref_clk == false) { - if ((wl->tcxo_clock == WL12XX_TCXOCLOCK_19_2) || - (wl->tcxo_clock == WL12XX_TCXOCLOCK_38_4)) - pll_config = 1; - else if ((wl->tcxo_clock == WL12XX_TCXOCLOCK_26) - || - (wl->tcxo_clock == WL12XX_TCXOCLOCK_52)) - pll_config = 2; - else - return -EINVAL; - } else { - if ((wl->ref_clock == CONF_REF_CLK_19_2_E) || - (wl->ref_clock == CONF_REF_CLK_38_4_E)) - pll_config = 1; - else if ((wl->ref_clock == CONF_REF_CLK_26_E) || - (wl->ref_clock == CONF_REF_CLK_52_E)) - pll_config = 2; - else - return -EINVAL; - } +static int wl128x_configure_mcs_pll(struct wl1271 *wl, int clk) +{ + u16 spare_reg; + u16 pll_config; + u8 input_freq; + + /* Mask bits [3:1] in the sys_clk_cfg register */ + spare_reg = wl1271_top_reg_read(wl, WL_SPARE_REG); + if (spare_reg == 0xFFFF) + return -EFAULT; + spare_reg |= BIT(2); + wl1271_top_reg_write(wl, WL_SPARE_REG, spare_reg); + + /* Handle special cases of the TCXO clock */ + if (wl->tcxo_clock == WL12XX_TCXOCLOCK_16_8 || + wl->tcxo_clock == WL12XX_TCXOCLOCK_33_6) + return wl128x_manually_configure_mcs_pll(wl); + + /* Set the input frequency according to the selected clock source */ + input_freq = (clk & 1) + 1; + + pll_config = wl1271_top_reg_read(wl, MCS_PLL_CONFIG_REG); + if (pll_config == 0xFFFF) + return -EFAULT; + pll_config |= (input_freq << MCS_SEL_IN_FREQ_SHIFT); + pll_config |= MCS_PLL_ENABLE_HP; + wl1271_top_reg_write(wl, MCS_PLL_CONFIG_REG, pll_config); - mcs_pll_config_val |= (pll_config << (MCS_SEL_IN_FREQ_SHIFT)) & - (MCS_SEL_IN_FREQ_MASK); - wl1271_top_reg_write(wl, MCS_PLL_CONFIG_REG, - mcs_pll_config_val); + return 0; +} + +/* + * WL128x has two clocks input - TCXO and FREF. + * TCXO is the main clock of the device, while FREF is used to sync + * between the GPS and the cellular modem. + * In cases where TCXO is 32.736MHz or 16.368MHz, the FREF will be used + * as the WLAN/BT main clock. + */ +static int wl128x_boot_clk(struct wl1271 *wl, int *selected_clock) +{ + u16 sys_clk_cfg; + + /* For XTAL-only modes, FREF will be used after switching from TCXO */ + if (wl->ref_clock == WL12XX_REFCLOCK_26_XTAL || + wl->ref_clock == WL12XX_REFCLOCK_38_XTAL) { + if (!wl128x_switch_tcxo_to_fref(wl)) + return -EINVAL; + goto fref_clk; } - return 0; + /* Query the HW, to determine which clock source we should use */ + sys_clk_cfg = wl1271_top_reg_read(wl, SYS_CLK_CFG_REG); + if (sys_clk_cfg == 0xFFFF) + return -EINVAL; + if (sys_clk_cfg & PRCM_CM_EN_MUX_WLAN_FREF) + goto fref_clk; + + /* If TCXO is either 32.736MHz or 16.368MHz, switch to FREF */ + if (wl->tcxo_clock == WL12XX_TCXOCLOCK_16_368 || + wl->tcxo_clock == WL12XX_TCXOCLOCK_32_736) { + if (!wl128x_switch_tcxo_to_fref(wl)) + return -EINVAL; + goto fref_clk; + } + + /* TCXO clock is selected */ + if (!wl128x_is_tcxo_valid(wl)) + return -EINVAL; + *selected_clock = wl->tcxo_clock; + goto config_mcs_pll; + +fref_clk: + /* FREF clock is selected */ + if (!wl128x_is_fref_valid(wl)) + return -EINVAL; + *selected_clock = wl->ref_clock; + +config_mcs_pll: + return wl128x_configure_mcs_pll(wl, *selected_clock); } static int wl127x_boot_clk(struct wl1271 *wl) @@ -713,10 +713,10 @@ int wl1271_load_firmware(struct wl1271 *wl) { int ret = 0; u32 tmp, clk; - bool is_ref_clk = false; + int selected_clock = -1; if (wl->chip.id == CHIP_ID_1283_PG20) { - ret = wl128x_boot_clk(wl, &is_ref_clk); + ret = wl128x_boot_clk(wl, &selected_clock); if (ret < 0) goto out; } else { @@ -741,10 +741,7 @@ int wl1271_load_firmware(struct wl1271 *wl) wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk); if (wl->chip.id == CHIP_ID_1283_PG20) { - if (is_ref_clk == false) - clk |= ((wl->tcxo_clock & 0x3) << 1) << 4; - else - clk |= ((wl->ref_clock & 0x3) << 1) << 4; + clk |= ((selected_clock & 0x3) << 1) << 4; } else { clk |= (wl->ref_clock << 1) << 4; } diff --git a/drivers/net/wireless/wl12xx/boot.h b/drivers/net/wireless/wl12xx/boot.h index 1f5ee31dc0b1..d9de64ac1442 100644 --- a/drivers/net/wireless/wl12xx/boot.h +++ b/drivers/net/wireless/wl12xx/boot.h @@ -107,6 +107,7 @@ struct wl1271_static_data { #define MCS_SEL_IN_FREQ_MASK 0x0070 #define MCS_SEL_IN_FREQ_SHIFT 4 #define MCS_PLL_CONFIG_REG_VAL 0x73 +#define MCS_PLL_ENABLE_HP (BIT(0) | BIT(1)) #define MCS_PLL_M_REG 0xD94 #define MCS_PLL_N_REG 0xD96 diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h index eb8aacab8d4e..c1a743ea7470 100644 --- a/include/linux/wl12xx.h +++ b/include/linux/wl12xx.h @@ -26,10 +26,12 @@ /* Reference clock values */ enum { - WL12XX_REFCLOCK_19 = 0, /* 19.2 MHz */ - WL12XX_REFCLOCK_26 = 1, /* 26 MHz */ - WL12XX_REFCLOCK_38 = 2, /* 38.4 MHz */ - WL12XX_REFCLOCK_54 = 3, /* 54 MHz */ + WL12XX_REFCLOCK_19 = 0, /* 19.2 MHz */ + WL12XX_REFCLOCK_26 = 1, /* 26 MHz */ + WL12XX_REFCLOCK_38 = 2, /* 38.4 MHz */ + WL12XX_REFCLOCK_52 = 3, /* 52 MHz */ + WL12XX_REFCLOCK_38_XTAL = 4, /* 38.4 MHz, XTAL */ + WL12XX_REFCLOCK_26_XTAL = 5, /* 26 MHz, XTAL */ }; /* TCXO clock values */ -- cgit From 341b7cde6ccc60672fcd7fc84dd24a1b7c0b8d94 Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Thu, 31 Mar 2011 10:07:01 +0200 Subject: wl12xx: Handle platforms without level trigger interrupts Some platforms are incapable of triggering on level interrupts. Add a platform quirks member in the platform data structure, as well as an edge interrupt quirk which can be set on such platforms. When the interrupt is requested with IRQF_TRIGGER_RISING, IRQF_ONESHOT cannot be used, as we might miss interrupts that occur after the FW status is cleared and before the threaded interrupt handler exits. Moreover, when IRQF_ONESHOT is not set, iterating more than once in the threaded interrupt handler introduces a few race conditions between this handler and the hardirq handler. Currently this is worked around by limiting the loop to one iteration only. This workaround has an impact on performance. To remove to this restriction, the race conditions will need to be addressed. Signed-off-by: Ido Yariv Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 9 +++++++++ drivers/net/wireless/wl12xx/sdio.c | 9 ++++++++- drivers/net/wireless/wl12xx/spi.c | 9 ++++++++- drivers/net/wireless/wl12xx/wl12xx.h | 3 +++ include/linux/wl12xx.h | 4 ++++ 5 files changed, 32 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 1feb9551ef8f..7126506611c1 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "wl12xx.h" #include "wl12xx_80211.h" @@ -719,6 +720,13 @@ irqreturn_t wl1271_irq(int irq, void *cookie) set_bit(WL1271_FLAG_TX_PENDING, &wl->flags); cancel_work_sync(&wl->tx_work); + /* + * In case edge triggered interrupt must be used, we cannot iterate + * more than once without introducing race conditions with the hardirq. + */ + if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ) + loopcount = 1; + mutex_lock(&wl->mutex); wl1271_debug(DEBUG_IRQ, "IRQ work"); @@ -3648,6 +3656,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void) wl->ap_ps_map = 0; wl->ap_fw_ps_map = 0; wl->quirks = 0; + wl->platform_quirks = 0; memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map)); for (i = 0; i < ACX_TX_DESCRIPTORS; i++) diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c index 8246e9de4306..bcd4ad7ba90d 100644 --- a/drivers/net/wireless/wl12xx/sdio.c +++ b/drivers/net/wireless/wl12xx/sdio.c @@ -220,6 +220,7 @@ static int __devinit wl1271_probe(struct sdio_func *func, struct ieee80211_hw *hw; const struct wl12xx_platform_data *wlan_data; struct wl1271 *wl; + unsigned long irqflags; int ret; /* We are only able to handle the wlan function */ @@ -251,9 +252,15 @@ static int __devinit wl1271_probe(struct sdio_func *func, wl->irq = wlan_data->irq; wl->ref_clock = wlan_data->board_ref_clock; wl->tcxo_clock = wlan_data->board_tcxo_clock; + wl->platform_quirks = wlan_data->platform_quirks; + + if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ) + irqflags = IRQF_TRIGGER_RISING; + else + irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT; ret = request_threaded_irq(wl->irq, wl1271_hardirq, wl1271_irq, - IRQF_TRIGGER_HIGH | IRQF_ONESHOT, + irqflags, DRIVER_NAME, wl); if (ret < 0) { wl1271_error("request_irq() failed: %d", ret); diff --git a/drivers/net/wireless/wl12xx/spi.c b/drivers/net/wireless/wl12xx/spi.c index 7b82b5f0e490..51662bb68019 100644 --- a/drivers/net/wireless/wl12xx/spi.c +++ b/drivers/net/wireless/wl12xx/spi.c @@ -364,6 +364,7 @@ static int __devinit wl1271_probe(struct spi_device *spi) struct wl12xx_platform_data *pdata; struct ieee80211_hw *hw; struct wl1271 *wl; + unsigned long irqflags; int ret; pdata = spi->dev.platform_data; @@ -402,6 +403,12 @@ static int __devinit wl1271_probe(struct spi_device *spi) wl->ref_clock = pdata->board_ref_clock; wl->tcxo_clock = pdata->board_tcxo_clock; + wl->platform_quirks = pdata->platform_quirks; + + if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ) + irqflags = IRQF_TRIGGER_RISING; + else + irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT; wl->irq = spi->irq; if (wl->irq < 0) { @@ -411,7 +418,7 @@ static int __devinit wl1271_probe(struct spi_device *spi) } ret = request_threaded_irq(wl->irq, wl1271_hardirq, wl1271_irq, - IRQF_TRIGGER_HIGH | IRQF_ONESHOT, + irqflags, DRIVER_NAME, wl); if (ret < 0) { wl1271_error("request_irq() failed: %d", ret); diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 9ccbcfdd0802..fb2b79fa42b4 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -579,6 +579,9 @@ struct wl1271 { /* Quirks of specific hardware revisions */ unsigned int quirks; + + /* Platform limitations */ + unsigned int platform_quirks; }; struct wl1271_station { diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h index c1a743ea7470..4b697395326e 100644 --- a/include/linux/wl12xx.h +++ b/include/linux/wl12xx.h @@ -53,8 +53,12 @@ struct wl12xx_platform_data { bool use_eeprom; int board_ref_clock; int board_tcxo_clock; + unsigned long platform_quirks; }; +/* Platform does not support level trigger interrupts */ +#define WL12XX_PLATFORM_QUIRK_EDGE_IRQ BIT(0) + #ifdef CONFIG_WL12XX_PLATFORM_DATA int wl12xx_set_platform_data(const struct wl12xx_platform_data *data); -- cgit From d924de09cac6e18bdfbe9461a2ab2adeb36e77b0 Mon Sep 17 00:00:00 2001 From: Michael Jones Date: Tue, 29 Mar 2011 05:19:06 -0300 Subject: [media] v4l: add V4L2_PIX_FMT_Y12 format Y12 is a grey-scale format with a depth of 12 bits per pixel stored in 16-bit words. Signed-off-by: Michael Jones Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- Documentation/DocBook/media-entities.tmpl | 1 + Documentation/DocBook/v4l/pixfmt-y12.xml | 79 +++++++++++++++++++++++++++++++ Documentation/DocBook/v4l/pixfmt.xml | 1 + include/linux/videodev2.h | 1 + 4 files changed, 82 insertions(+) create mode 100644 Documentation/DocBook/v4l/pixfmt-y12.xml (limited to 'include/linux') diff --git a/Documentation/DocBook/media-entities.tmpl b/Documentation/DocBook/media-entities.tmpl index 5d259c632cdf..fea63b45471a 100644 --- a/Documentation/DocBook/media-entities.tmpl +++ b/Documentation/DocBook/media-entities.tmpl @@ -294,6 +294,7 @@ + diff --git a/Documentation/DocBook/v4l/pixfmt-y12.xml b/Documentation/DocBook/v4l/pixfmt-y12.xml new file mode 100644 index 000000000000..ff417b858cc9 --- /dev/null +++ b/Documentation/DocBook/v4l/pixfmt-y12.xml @@ -0,0 +1,79 @@ + + + V4L2_PIX_FMT_Y12 ('Y12 ') + &manvol; + + + V4L2_PIX_FMT_Y12 + Grey-scale image + + + Description + + This is a grey-scale image with a depth of 12 bits per pixel. Pixels +are stored in 16-bit words with unused high bits padded with 0. The least +significant byte is stored at lower memory addresses (little-endian). + + + <constant>V4L2_PIX_FMT_Y12</constant> 4 × 4 +pixel image + + + Byte Order. + Each cell is one byte. + + + + + + start + 0: + Y'00low + Y'00high + Y'01low + Y'01high + Y'02low + Y'02high + Y'03low + Y'03high + + + start + 8: + Y'10low + Y'10high + Y'11low + Y'11high + Y'12low + Y'12high + Y'13low + Y'13high + + + start + 16: + Y'20low + Y'20high + Y'21low + Y'21high + Y'22low + Y'22high + Y'23low + Y'23high + + + start + 24: + Y'30low + Y'30high + Y'31low + Y'31high + Y'32low + Y'32high + Y'33low + Y'33high + + + + + + + + + diff --git a/Documentation/DocBook/v4l/pixfmt.xml b/Documentation/DocBook/v4l/pixfmt.xml index c6fdcbbd1b41..40af4beb48b9 100644 --- a/Documentation/DocBook/v4l/pixfmt.xml +++ b/Documentation/DocBook/v4l/pixfmt.xml @@ -696,6 +696,7 @@ information. &sub-packed-yuv; &sub-grey; &sub-y10; + &sub-y12; &sub-y16; &sub-yuyv; &sub-uyvy; diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index aa6c393b7ae9..be82c8ead1af 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -308,6 +308,7 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_Y4 v4l2_fourcc('Y', '0', '4', ' ') /* 4 Greyscale */ #define V4L2_PIX_FMT_Y6 v4l2_fourcc('Y', '0', '6', ' ') /* 6 Greyscale */ #define V4L2_PIX_FMT_Y10 v4l2_fourcc('Y', '1', '0', ' ') /* 10 Greyscale */ +#define V4L2_PIX_FMT_Y12 v4l2_fourcc('Y', '1', '2', ' ') /* 12 Greyscale */ #define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y', '1', '6', ' ') /* 16 Greyscale */ /* Palette formats */ -- cgit From cbbc69a4a98081740f0e3d7717fbfa0b584b983d Mon Sep 17 00:00:00 2001 From: Michael Jones Date: Tue, 29 Mar 2011 05:19:07 -0300 Subject: [media] media: add missing 8-bit bayer formats and Y12 8-bit SGBRG and SRGGB media bus formats are missing, as well as the 12-bit grey format. Add them. Signed-off-by: Michael Jones Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- Documentation/DocBook/v4l/subdev-formats.xml | 59 ++++++++++++++++++++++++++++ include/linux/v4l2-mediabus.h | 7 +++- 2 files changed, 64 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/Documentation/DocBook/v4l/subdev-formats.xml b/Documentation/DocBook/v4l/subdev-formats.xml index 7041127d6dfc..d7ccd25edcc1 100644 --- a/Documentation/DocBook/v4l/subdev-formats.xml +++ b/Documentation/DocBook/v4l/subdev-formats.xml @@ -456,6 +456,23 @@ b1 b0 + + V4L2_MBUS_FMT_SGBRG8_1X8 + 0x3013 + + - + - + - + - + g7 + g6 + g5 + g4 + g3 + g2 + g1 + g0 + V4L2_MBUS_FMT_SGRBG8_1X8 0x3002 @@ -473,6 +490,23 @@ g1 g0 + + V4L2_MBUS_FMT_SRGGB8_1X8 + 0x3014 + + - + - + - + - + r7 + r6 + r5 + r4 + r3 + r2 + r1 + r0 + V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8 0x300b @@ -2159,6 +2193,31 @@ u1 u0 + + V4L2_MBUS_FMT_Y12_1X12 + 0x2013 + + - + - + - + - + - + - + - + - + y11 + y10 + y9 + y8 + y7 + y6 + y5 + y4 + y3 + y2 + y1 + y0 + V4L2_MBUS_FMT_UYVY8_1X16 0x200f diff --git a/include/linux/v4l2-mediabus.h b/include/linux/v4l2-mediabus.h index 7054a7a8065e..de5c15921025 100644 --- a/include/linux/v4l2-mediabus.h +++ b/include/linux/v4l2-mediabus.h @@ -47,7 +47,7 @@ enum v4l2_mbus_pixelcode { V4L2_MBUS_FMT_RGB565_2X8_BE = 0x1007, V4L2_MBUS_FMT_RGB565_2X8_LE = 0x1008, - /* YUV (including grey) - next is 0x2013 */ + /* YUV (including grey) - next is 0x2014 */ V4L2_MBUS_FMT_Y8_1X8 = 0x2001, V4L2_MBUS_FMT_UYVY8_1_5X8 = 0x2002, V4L2_MBUS_FMT_VYUY8_1_5X8 = 0x2003, @@ -60,6 +60,7 @@ enum v4l2_mbus_pixelcode { V4L2_MBUS_FMT_Y10_1X10 = 0x200a, V4L2_MBUS_FMT_YUYV10_2X10 = 0x200b, V4L2_MBUS_FMT_YVYU10_2X10 = 0x200c, + V4L2_MBUS_FMT_Y12_1X12 = 0x2013, V4L2_MBUS_FMT_UYVY8_1X16 = 0x200f, V4L2_MBUS_FMT_VYUY8_1X16 = 0x2010, V4L2_MBUS_FMT_YUYV8_1X16 = 0x2011, @@ -67,9 +68,11 @@ enum v4l2_mbus_pixelcode { V4L2_MBUS_FMT_YUYV10_1X20 = 0x200d, V4L2_MBUS_FMT_YVYU10_1X20 = 0x200e, - /* Bayer - next is 0x3013 */ + /* Bayer - next is 0x3015 */ V4L2_MBUS_FMT_SBGGR8_1X8 = 0x3001, + V4L2_MBUS_FMT_SGBRG8_1X8 = 0x3013, V4L2_MBUS_FMT_SGRBG8_1X8 = 0x3002, + V4L2_MBUS_FMT_SRGGB8_1X8 = 0x3014, V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8 = 0x300b, V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8 = 0x300c, V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8 = 0x3009, -- cgit From cbc6a6ed0900aed789b5ca77192845f2f987af70 Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Wed, 13 Apr 2011 21:40:45 +0200 Subject: rfkill: Regulator consumer driver for rfkill Add a regulator consumer driver for rfkill to enable controlling radio transmitters connected to voltage regulators using the regulator framework. A new "vrfkill" virtual supply is provided to use in platform code. Signed-off-by: Guiming Zhuo Signed-off-by: Antonio Ospite Reviewed-by: Johannes Berg Signed-off-by: John W. Linville --- include/linux/rfkill-regulator.h | 48 ++++++++++++ net/rfkill/Kconfig | 11 +++ net/rfkill/Makefile | 1 + net/rfkill/rfkill-regulator.c | 164 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 224 insertions(+) create mode 100644 include/linux/rfkill-regulator.h create mode 100644 net/rfkill/rfkill-regulator.c (limited to 'include/linux') diff --git a/include/linux/rfkill-regulator.h b/include/linux/rfkill-regulator.h new file mode 100644 index 000000000000..aca36bc83315 --- /dev/null +++ b/include/linux/rfkill-regulator.h @@ -0,0 +1,48 @@ +/* + * rfkill-regulator.c - Regulator consumer driver for rfkill + * + * Copyright (C) 2009 Guiming Zhuo + * Copyright (C) 2011 Antonio Ospite + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef __LINUX_RFKILL_REGULATOR_H +#define __LINUX_RFKILL_REGULATOR_H + +/* + * Use "vrfkill" as supply id when declaring the regulator consumer: + * + * static struct regulator_consumer_supply pcap_regulator_V6_consumers [] = { + * { .dev_name = "rfkill-regulator.0", .supply = "vrfkill" }, + * }; + * + * If you have several regulator driven rfkill, you can append a numerical id to + * .dev_name as done above, and use the same id when declaring the platform + * device: + * + * static struct rfkill_regulator_platform_data ezx_rfkill_bt_data = { + * .name = "ezx-bluetooth", + * .type = RFKILL_TYPE_BLUETOOTH, + * }; + * + * static struct platform_device a910_rfkill = { + * .name = "rfkill-regulator", + * .id = 0, + * .dev = { + * .platform_data = &ezx_rfkill_bt_data, + * }, + * }; + */ + +#include + +struct rfkill_regulator_platform_data { + char *name; /* the name for the rfkill switch */ + enum rfkill_type type; /* the type as specified in rfkill.h */ +}; + +#endif /* __LINUX_RFKILL_REGULATOR_H */ diff --git a/net/rfkill/Kconfig b/net/rfkill/Kconfig index 7fce6dfd2180..48464ca13b24 100644 --- a/net/rfkill/Kconfig +++ b/net/rfkill/Kconfig @@ -22,3 +22,14 @@ config RFKILL_INPUT depends on RFKILL depends on INPUT = y || RFKILL = INPUT default y if !EXPERT + +config RFKILL_REGULATOR + tristate "Generic rfkill regulator driver" + depends on RFKILL || !RFKILL + depends on REGULATOR + help + This options enable controlling radio transmitters connected to + voltage regulator using the regulator framework. + + To compile this driver as a module, choose M here: the module will + be called rfkill-regulator. diff --git a/net/rfkill/Makefile b/net/rfkill/Makefile index 662105352691..d9a5a58ffd8c 100644 --- a/net/rfkill/Makefile +++ b/net/rfkill/Makefile @@ -5,3 +5,4 @@ rfkill-y += core.o rfkill-$(CONFIG_RFKILL_INPUT) += input.o obj-$(CONFIG_RFKILL) += rfkill.o +obj-$(CONFIG_RFKILL_REGULATOR) += rfkill-regulator.o diff --git a/net/rfkill/rfkill-regulator.c b/net/rfkill/rfkill-regulator.c new file mode 100644 index 000000000000..18dc512a10f3 --- /dev/null +++ b/net/rfkill/rfkill-regulator.c @@ -0,0 +1,164 @@ +/* + * rfkill-regulator.c - Regulator consumer driver for rfkill + * + * Copyright (C) 2009 Guiming Zhuo + * Copyright (C) 2011 Antonio Ospite + * + * Implementation inspired by leds-regulator driver. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +struct rfkill_regulator_data { + struct rfkill *rf_kill; + bool reg_enabled; + + struct regulator *vcc; +}; + +static int rfkill_regulator_set_block(void *data, bool blocked) +{ + struct rfkill_regulator_data *rfkill_data = data; + + pr_debug("%s: blocked: %d\n", __func__, blocked); + + if (blocked) { + if (rfkill_data->reg_enabled) { + regulator_disable(rfkill_data->vcc); + rfkill_data->reg_enabled = 0; + } + } else { + if (!rfkill_data->reg_enabled) { + regulator_enable(rfkill_data->vcc); + rfkill_data->reg_enabled = 1; + } + } + + pr_debug("%s: regulator_is_enabled after set_block: %d\n", __func__, + regulator_is_enabled(rfkill_data->vcc)); + + return 0; +} + +struct rfkill_ops rfkill_regulator_ops = { + .set_block = rfkill_regulator_set_block, +}; + +static int __devinit rfkill_regulator_probe(struct platform_device *pdev) +{ + struct rfkill_regulator_platform_data *pdata = pdev->dev.platform_data; + struct rfkill_regulator_data *rfkill_data; + struct regulator *vcc; + struct rfkill *rf_kill; + int ret = 0; + + if (pdata == NULL) { + dev_err(&pdev->dev, "no platform data\n"); + return -ENODEV; + } + + if (pdata->name == NULL || pdata->type == 0) { + dev_err(&pdev->dev, "invalid name or type in platform data\n"); + return -EINVAL; + } + + vcc = regulator_get_exclusive(&pdev->dev, "vrfkill"); + if (IS_ERR(vcc)) { + dev_err(&pdev->dev, "Cannot get vcc for %s\n", pdata->name); + ret = PTR_ERR(vcc); + goto out; + } + + rfkill_data = kzalloc(sizeof(*rfkill_data), GFP_KERNEL); + if (rfkill_data == NULL) { + ret = -ENOMEM; + goto err_data_alloc; + } + + rf_kill = rfkill_alloc(pdata->name, &pdev->dev, + pdata->type, + &rfkill_regulator_ops, rfkill_data); + if (rf_kill == NULL) { + dev_err(&pdev->dev, "Cannot alloc rfkill device\n"); + ret = -ENOMEM; + goto err_rfkill_alloc; + } + + if (regulator_is_enabled(vcc)) { + dev_dbg(&pdev->dev, "Regulator already enabled\n"); + rfkill_data->reg_enabled = 1; + } + rfkill_data->vcc = vcc; + rfkill_data->rf_kill = rf_kill; + + ret = rfkill_register(rf_kill); + if (ret) { + dev_err(&pdev->dev, "Cannot register rfkill device\n"); + goto err_rfkill_register; + } + + platform_set_drvdata(pdev, rfkill_data); + dev_info(&pdev->dev, "%s initialized\n", pdata->name); + + return 0; + +err_rfkill_register: + rfkill_destroy(rf_kill); +err_rfkill_alloc: + kfree(rfkill_data); +err_data_alloc: + regulator_put(vcc); +out: + return ret; +} + +static int __devexit rfkill_regulator_remove(struct platform_device *pdev) +{ + struct rfkill_regulator_data *rfkill_data = platform_get_drvdata(pdev); + struct rfkill *rf_kill = rfkill_data->rf_kill; + + rfkill_unregister(rf_kill); + rfkill_destroy(rf_kill); + regulator_put(rfkill_data->vcc); + kfree(rfkill_data); + + return 0; +} + +static struct platform_driver rfkill_regulator_driver = { + .probe = rfkill_regulator_probe, + .remove = __devexit_p(rfkill_regulator_remove), + .driver = { + .name = "rfkill-regulator", + .owner = THIS_MODULE, + }, +}; + +static int __init rfkill_regulator_init(void) +{ + return platform_driver_register(&rfkill_regulator_driver); +} +module_init(rfkill_regulator_init); + +static void __exit rfkill_regulator_exit(void) +{ + platform_driver_unregister(&rfkill_regulator_driver); +} +module_exit(rfkill_regulator_exit); + +MODULE_AUTHOR("Guiming Zhuo "); +MODULE_AUTHOR("Antonio Ospite "); +MODULE_DESCRIPTION("Regulator consumer driver for rfkill"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:rfkill-regulator"); -- cgit From 6716671d8c1c07a8072098764d1b7cbfef7412ad Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 23 Mar 2011 10:48:35 +0100 Subject: TTY: introduce deinit helpers for proper ldisc shutdown Introduce deinitialize_tty_struct which should be called after initialize_tty_struct and before successfull tty_ldisc_setup. It calls tty_ldisc_deinit which is opposite of tty_ldisc_init. It only puts a reference to ldisc and assigns NULL to tty->ldisc. It will be used to shut down ldisc when tty_release cannot be called yet. Signed-off-by: Jiri Slaby Cc: Alan Cox Cc: Julian Anastasov Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 14 ++++++++++++++ drivers/tty/tty_ldisc.c | 13 +++++++++++++ include/linux/tty.h | 2 ++ 3 files changed, 29 insertions(+) (limited to 'include/linux') diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 026bf2f6f5f2..f5dd23520fe3 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -2886,6 +2886,20 @@ void initialize_tty_struct(struct tty_struct *tty, tty->dev = tty_get_device(tty); } +/** + * deinitialize_tty_struct + * @tty: tty to deinitialize + * + * This subroutine deinitializes a tty structure that has been newly + * allocated but tty_release cannot be called on that yet. + * + * Locking: none - tty in question must not be exposed at this point + */ +void deinitialize_tty_struct(struct tty_struct *tty) +{ + tty_ldisc_deinit(tty); +} + /** * tty_put_char - write one character to a tty * @tty: tty diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index e19e13647116..5d01d32e2cf0 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -956,6 +956,19 @@ void tty_ldisc_init(struct tty_struct *tty) tty_ldisc_assign(tty, ld); } +/** + * tty_ldisc_init - ldisc cleanup for new tty + * @tty: tty that was allocated recently + * + * The tty structure must not becompletely set up (tty_ldisc_setup) when + * this call is made. + */ +void tty_ldisc_deinit(struct tty_struct *tty) +{ + put_ldisc(tty->ldisc); + tty_ldisc_assign(tty, NULL); +} + void tty_ldisc_begin(void) { /* Setup the default TTY line discipline. */ diff --git a/include/linux/tty.h b/include/linux/tty.h index 9f469c700550..4db4ca79f895 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -472,6 +472,7 @@ extern int tty_add_file(struct tty_struct *tty, struct file *file); extern void free_tty_struct(struct tty_struct *tty); extern void initialize_tty_struct(struct tty_struct *tty, struct tty_driver *driver, int idx); +extern void deinitialize_tty_struct(struct tty_struct *tty); extern struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx, int first_ok); extern int tty_release(struct inode *inode, struct file *filp); @@ -525,6 +526,7 @@ extern int tty_set_ldisc(struct tty_struct *tty, int ldisc); extern int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty); extern void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty); extern void tty_ldisc_init(struct tty_struct *tty); +extern void tty_ldisc_deinit(struct tty_struct *tty); extern void tty_ldisc_begin(void); /* This last one is just for the tty layer internals and shouldn't be used elsewhere */ extern void tty_ldisc_enable(struct tty_struct *tty); -- cgit From bcdd323b893ad3c9b7ef26b5e4a0bef974238501 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 16 Mar 2011 15:59:35 +0200 Subject: device: add dev_WARN_ONCE it's quite useful to print the device name on the stack dump caused by WARN(), but there are other cases where we might want to use WARN_ONCE. Introduce a helper similar to dev_WARN() for that case too. Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- include/linux/device.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/device.h b/include/linux/device.h index ab8dfc095709..d4840511e877 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -742,13 +742,17 @@ do { \ #endif /* - * dev_WARN() acts like dev_printk(), but with the key difference + * dev_WARN*() acts like dev_printk(), but with the key difference * of using a WARN/WARN_ON to get the message out, including the * file/line information and a backtrace. */ #define dev_WARN(dev, format, arg...) \ WARN(1, "Device: %s\n" format, dev_driver_string(dev), ## arg); +#define dev_WARN_ONCE(dev, condition, format, arg...) \ + WARN_ONCE(condition, "Device %s\n" format, \ + dev_driver_string(dev), ## arg) + /* Create alias, so I can be autoloaded. */ #define MODULE_ALIAS_CHARDEV(major,minor) \ MODULE_ALIAS("char-major-" __stringify(major) "-" __stringify(minor)) -- cgit From aed65af1cc2f6fc9ded5a8158f1405a02cf6d2ff Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 28 Mar 2011 09:12:52 -0700 Subject: drivers: make device_type const The device_type structure does not contain data that changes during usage and should be const. This allows devices to declare the struct const. I have patches to change all the subsystems, but need the infra structure change first. Signed-off-by: Stephen Hemminger Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 4 ++-- include/linux/device.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/drivers/base/core.c b/drivers/base/core.c index 81b78ede37c4..fb8130ceea10 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -400,7 +400,7 @@ static void device_remove_groups(struct device *dev, static int device_add_attrs(struct device *dev) { struct class *class = dev->class; - struct device_type *type = dev->type; + const struct device_type *type = dev->type; int error; if (class) { @@ -440,7 +440,7 @@ static int device_add_attrs(struct device *dev) static void device_remove_attrs(struct device *dev) { struct class *class = dev->class; - struct device_type *type = dev->type; + const struct device_type *type = dev->type; device_remove_groups(dev, dev->groups); diff --git a/include/linux/device.h b/include/linux/device.h index d4840511e877..350ceda4de97 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -408,7 +408,7 @@ struct device { struct kobject kobj; const char *init_name; /* initial name of the device */ - struct device_type *type; + const struct device_type *type; struct mutex mutex; /* mutex to synchronize calls to * its driver. -- cgit From 0b2e9a8e10ad2d191e5c37e77f1ce23e148e7a0b Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 14 Apr 2011 22:31:57 +0000 Subject: of: Export of_irq_find_parent() We have platform code that needs to find a node's interrupt parent, so export of_irq_find_parent() so we can use it. Signed-off-by: Michael Ellerman Signed-off-by: Benjamin Herrenschmidt --- drivers/of/irq.c | 2 +- include/linux/of_irq.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 75b0d3cb7676..9f689f1da0fc 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -56,7 +56,7 @@ EXPORT_SYMBOL_GPL(irq_of_parse_and_map); * Returns a pointer to the interrupt parent node, or NULL if the interrupt * parent could not be determined. */ -static struct device_node *of_irq_find_parent(struct device_node *child) +struct device_node *of_irq_find_parent(struct device_node *child) { struct device_node *p; const __be32 *parp; diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h index 109e013b1772..e6955f5d1f08 100644 --- a/include/linux/of_irq.h +++ b/include/linux/of_irq.h @@ -68,6 +68,7 @@ extern int of_irq_to_resource(struct device_node *dev, int index, extern int of_irq_count(struct device_node *dev); extern int of_irq_to_resource_table(struct device_node *dev, struct resource *res, int nr_irqs); +extern struct device_node *of_irq_find_parent(struct device_node *child); #endif /* CONFIG_OF_IRQ */ #endif /* CONFIG_OF */ -- cgit From b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1db Mon Sep 17 00:00:00 2001 From: MyungJoo Ham Date: Tue, 29 Mar 2011 10:10:16 +0900 Subject: power_supply: Add driver for MAX8903 charger MAX8903 is an integrated battery charger and selector with two power inputs (USB and AC adapter). This driver enables the charger, handles interrupts, and provides power-supply-class information to userland. Tested on Exynos4 NURI / S5PC210 SLP7 boards. Signed-off-by: MyungJoo Ham Signed-off-by: Kyungmin Park Signed-off-by: Anton Vorontsov --- drivers/power/Kconfig | 8 + drivers/power/Makefile | 1 + drivers/power/max8903_charger.c | 391 ++++++++++++++++++++++++++++++++++ include/linux/power/max8903_charger.h | 57 +++++ 4 files changed, 457 insertions(+) create mode 100644 drivers/power/max8903_charger.c create mode 100644 include/linux/power/max8903_charger.h (limited to 'include/linux') diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 52a462fc6b84..1f50ebcc6399 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -203,6 +203,14 @@ config CHARGER_ISP1704 Say Y to enable support for USB Charger Detection with ISP1707/ISP1704 USB transceivers. +config CHARGER_MAX8903 + tristate "MAX8903 Battery DC-DC Charger for USB and Adapter Power" + help + Say Y to enable support for the MAX8903 DC-DC charger and sysfs. + The driver supports controlling charger-enable and current-limit + pins based on the status of charger connections with interrupt + handlers. + config CHARGER_TWL4030 tristate "OMAP TWL4030 BCI charger driver" depends on TWL4030_CORE diff --git a/drivers/power/Makefile b/drivers/power/Makefile index 8385bfae8728..8fcd93ff2353 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -32,5 +32,6 @@ obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o obj-$(CONFIG_BATTERY_JZ4740) += jz4740-battery.o obj-$(CONFIG_BATTERY_INTEL_MID) += intel_mid_battery.o obj-$(CONFIG_CHARGER_ISP1704) += isp1704_charger.o +obj-$(CONFIG_CHARGER_MAX8903) += max8903_charger.o obj-$(CONFIG_CHARGER_TWL4030) += twl4030_charger.o obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o diff --git a/drivers/power/max8903_charger.c b/drivers/power/max8903_charger.c new file mode 100644 index 000000000000..33ff0e37809e --- /dev/null +++ b/drivers/power/max8903_charger.c @@ -0,0 +1,391 @@ +/* + * max8903_charger.c - Maxim 8903 USB/Adapter Charger Driver + * + * Copyright (C) 2011 Samsung Electronics + * MyungJoo Ham + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include + +struct max8903_data { + struct max8903_pdata *pdata; + struct device *dev; + struct power_supply psy; + bool fault; + bool usb_in; + bool ta_in; +}; + +static enum power_supply_property max8903_charger_props[] = { + POWER_SUPPLY_PROP_STATUS, /* Charger status output */ + POWER_SUPPLY_PROP_ONLINE, /* External power source */ + POWER_SUPPLY_PROP_HEALTH, /* Fault or OK */ +}; + +static int max8903_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct max8903_data *data = container_of(psy, + struct max8903_data, psy); + + switch (psp) { + case POWER_SUPPLY_PROP_STATUS: + val->intval = POWER_SUPPLY_STATUS_UNKNOWN; + if (data->pdata->chg) { + if (gpio_get_value(data->pdata->chg) == 0) + val->intval = POWER_SUPPLY_STATUS_CHARGING; + else if (data->usb_in || data->ta_in) + val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; + else + val->intval = POWER_SUPPLY_STATUS_DISCHARGING; + } + break; + case POWER_SUPPLY_PROP_ONLINE: + val->intval = 0; + if (data->usb_in || data->ta_in) + val->intval = 1; + break; + case POWER_SUPPLY_PROP_HEALTH: + val->intval = POWER_SUPPLY_HEALTH_GOOD; + if (data->fault) + val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; + break; + default: + return -EINVAL; + } + return 0; +} + +static irqreturn_t max8903_dcin(int irq, void *_data) +{ + struct max8903_data *data = _data; + struct max8903_pdata *pdata = data->pdata; + bool ta_in; + enum power_supply_type old_type; + + ta_in = gpio_get_value(pdata->dok) ? false : true; + + if (ta_in == data->ta_in) + return IRQ_HANDLED; + + data->ta_in = ta_in; + + /* Set Current-Limit-Mode 1:DC 0:USB */ + if (pdata->dcm) + gpio_set_value(pdata->dcm, ta_in ? 1 : 0); + + /* Charger Enable / Disable (cen is negated) */ + if (pdata->cen) + gpio_set_value(pdata->cen, ta_in ? 0 : + (data->usb_in ? 0 : 1)); + + dev_dbg(data->dev, "TA(DC-IN) Charger %s.\n", ta_in ? + "Connected" : "Disconnected"); + + old_type = data->psy.type; + + if (data->ta_in) + data->psy.type = POWER_SUPPLY_TYPE_MAINS; + else if (data->usb_in) + data->psy.type = POWER_SUPPLY_TYPE_USB; + else + data->psy.type = POWER_SUPPLY_TYPE_BATTERY; + + if (old_type != data->psy.type) + power_supply_changed(&data->psy); + + return IRQ_HANDLED; +} + +static irqreturn_t max8903_usbin(int irq, void *_data) +{ + struct max8903_data *data = _data; + struct max8903_pdata *pdata = data->pdata; + bool usb_in; + enum power_supply_type old_type; + + usb_in = gpio_get_value(pdata->uok) ? false : true; + + if (usb_in == data->usb_in) + return IRQ_HANDLED; + + data->usb_in = usb_in; + + /* Do not touch Current-Limit-Mode */ + + /* Charger Enable / Disable (cen is negated) */ + if (pdata->cen) + gpio_set_value(pdata->cen, usb_in ? 0 : + (data->ta_in ? 0 : 1)); + + dev_dbg(data->dev, "USB Charger %s.\n", usb_in ? + "Connected" : "Disconnected"); + + old_type = data->psy.type; + + if (data->ta_in) + data->psy.type = POWER_SUPPLY_TYPE_MAINS; + else if (data->usb_in) + data->psy.type = POWER_SUPPLY_TYPE_USB; + else + data->psy.type = POWER_SUPPLY_TYPE_BATTERY; + + if (old_type != data->psy.type) + power_supply_changed(&data->psy); + + return IRQ_HANDLED; +} + +static irqreturn_t max8903_fault(int irq, void *_data) +{ + struct max8903_data *data = _data; + struct max8903_pdata *pdata = data->pdata; + bool fault; + + fault = gpio_get_value(pdata->flt) ? false : true; + + if (fault == data->fault) + return IRQ_HANDLED; + + data->fault = fault; + + if (fault) + dev_err(data->dev, "Charger suffers a fault and stops.\n"); + else + dev_err(data->dev, "Charger recovered from a fault.\n"); + + return IRQ_HANDLED; +} + +static __devinit int max8903_probe(struct platform_device *pdev) +{ + struct max8903_data *data; + struct device *dev = &pdev->dev; + struct max8903_pdata *pdata = pdev->dev.platform_data; + int ret = 0; + int gpio; + int ta_in = 0; + int usb_in = 0; + + data = kzalloc(sizeof(struct max8903_data), GFP_KERNEL); + if (data == NULL) { + dev_err(dev, "Cannot allocate memory.\n"); + return -ENOMEM; + } + data->pdata = pdata; + data->dev = dev; + platform_set_drvdata(pdev, data); + + if (pdata->dc_valid == false && pdata->usb_valid == false) { + dev_err(dev, "No valid power sources.\n"); + ret = -EINVAL; + goto err; + } + + if (pdata->dc_valid) { + if (pdata->dok && gpio_is_valid(pdata->dok) && + pdata->dcm && gpio_is_valid(pdata->dcm)) { + gpio = pdata->dok; /* PULL_UPed Interrupt */ + ta_in = gpio_get_value(gpio) ? 0 : 1; + + gpio = pdata->dcm; /* Output */ + gpio_set_value(gpio, ta_in); + } else { + dev_err(dev, "When DC is wired, DOK and DCM should" + " be wired as well.\n"); + ret = -EINVAL; + goto err; + } + } else { + if (pdata->dcm) { + if (gpio_is_valid(pdata->dcm)) + gpio_set_value(pdata->dcm, 0); + else { + dev_err(dev, "Invalid pin: dcm.\n"); + ret = -EINVAL; + goto err; + } + } + } + + if (pdata->usb_valid) { + if (pdata->uok && gpio_is_valid(pdata->uok)) { + gpio = pdata->uok; + usb_in = gpio_get_value(gpio) ? 0 : 1; + } else { + dev_err(dev, "When USB is wired, UOK should be wired." + "as well.\n"); + ret = -EINVAL; + goto err; + } + } + + if (pdata->cen) { + if (gpio_is_valid(pdata->cen)) { + gpio_set_value(pdata->cen, (ta_in || usb_in) ? 0 : 1); + } else { + dev_err(dev, "Invalid pin: cen.\n"); + ret = -EINVAL; + goto err; + } + } + + if (pdata->chg) { + if (!gpio_is_valid(pdata->chg)) { + dev_err(dev, "Invalid pin: chg.\n"); + ret = -EINVAL; + goto err; + } + } + + if (pdata->flt) { + if (!gpio_is_valid(pdata->flt)) { + dev_err(dev, "Invalid pin: flt.\n"); + ret = -EINVAL; + goto err; + } + } + + if (pdata->usus) { + if (!gpio_is_valid(pdata->usus)) { + dev_err(dev, "Invalid pin: usus.\n"); + ret = -EINVAL; + goto err; + } + } + + data->fault = false; + data->ta_in = ta_in; + data->usb_in = usb_in; + + data->psy.name = "max8903_charger"; + data->psy.type = (ta_in) ? POWER_SUPPLY_TYPE_MAINS : + ((usb_in) ? POWER_SUPPLY_TYPE_USB : + POWER_SUPPLY_TYPE_BATTERY); + data->psy.get_property = max8903_get_property; + data->psy.properties = max8903_charger_props; + data->psy.num_properties = ARRAY_SIZE(max8903_charger_props); + + ret = power_supply_register(dev, &data->psy); + if (ret) { + dev_err(dev, "failed: power supply register.\n"); + goto err; + } + + if (pdata->dc_valid) { + ret = request_threaded_irq(gpio_to_irq(pdata->dok), + NULL, max8903_dcin, + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, + "MAX8903 DC IN", data); + if (ret) { + dev_err(dev, "Cannot request irq %d for DC (%d)\n", + gpio_to_irq(pdata->dok), ret); + goto err_psy; + } + } + + if (pdata->usb_valid) { + ret = request_threaded_irq(gpio_to_irq(pdata->uok), + NULL, max8903_usbin, + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, + "MAX8903 USB IN", data); + if (ret) { + dev_err(dev, "Cannot request irq %d for USB (%d)\n", + gpio_to_irq(pdata->uok), ret); + goto err_dc_irq; + } + } + + if (pdata->flt) { + ret = request_threaded_irq(gpio_to_irq(pdata->flt), + NULL, max8903_fault, + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, + "MAX8903 Fault", data); + if (ret) { + dev_err(dev, "Cannot request irq %d for Fault (%d)\n", + gpio_to_irq(pdata->flt), ret); + goto err_usb_irq; + } + } + + return 0; + +err_usb_irq: + if (pdata->usb_valid) + free_irq(gpio_to_irq(pdata->uok), data); +err_dc_irq: + if (pdata->dc_valid) + free_irq(gpio_to_irq(pdata->dok), data); +err_psy: + power_supply_unregister(&data->psy); +err: + kfree(data); + return ret; +} + +static __devexit int max8903_remove(struct platform_device *pdev) +{ + struct max8903_data *data = platform_get_drvdata(pdev); + + if (data) { + struct max8903_pdata *pdata = data->pdata; + + if (pdata->flt) + free_irq(gpio_to_irq(pdata->flt), data); + if (pdata->usb_valid) + free_irq(gpio_to_irq(pdata->uok), data); + if (pdata->dc_valid) + free_irq(gpio_to_irq(pdata->dok), data); + power_supply_unregister(&data->psy); + kfree(data); + } + + return 0; +} + +static struct platform_driver max8903_driver = { + .probe = max8903_probe, + .remove = __devexit_p(max8903_remove), + .driver = { + .name = "max8903-charger", + .owner = THIS_MODULE, + }, +}; + +static int __init max8903_init(void) +{ + return platform_driver_register(&max8903_driver); +} +module_init(max8903_init); + +static void __exit max8903_exit(void) +{ + platform_driver_unregister(&max8903_driver); +} +module_exit(max8903_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("MAX8903 Charger Driver"); +MODULE_AUTHOR("MyungJoo Ham "); +MODULE_ALIAS("max8903-charger"); diff --git a/include/linux/power/max8903_charger.h b/include/linux/power/max8903_charger.h new file mode 100644 index 000000000000..24f51db8a83f --- /dev/null +++ b/include/linux/power/max8903_charger.h @@ -0,0 +1,57 @@ +/* + * max8903_charger.h - Maxim 8903 USB/Adapter Charger Driver + * + * Copyright (C) 2011 Samsung Electronics + * MyungJoo Ham + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __MAX8903_CHARGER_H__ +#define __MAX8903_CHARGER_H__ + +struct max8903_pdata { + /* + * GPIOs + * cen, chg, flt, and usus are optional. + * dok, dcm, and uok are not optional depending on the status of + * dc_valid and usb_valid. + */ + int cen; /* Charger Enable input */ + int dok; /* DC(Adapter) Power OK output */ + int uok; /* USB Power OK output */ + int chg; /* Charger status output */ + int flt; /* Fault output */ + int dcm; /* Current-Limit Mode input (1: DC, 2: USB) */ + int usus; /* USB Suspend Input (1: suspended) */ + + /* + * DC(Adapter/TA) is wired + * When dc_valid is true, + * dok and dcm should be valid. + * + * At least one of dc_valid or usb_valid should be true. + */ + bool dc_valid; + /* + * USB is wired + * When usb_valid is true, + * uok should be valid. + */ + bool usb_valid; +}; + +#endif /* __MAX8903_CHARGER_H__ */ -- cgit From 2785cefc98051646bd1d36a627822a3f43736697 Mon Sep 17 00:00:00 2001 From: Kalle Jokiniemi Date: Tue, 29 Mar 2011 16:27:59 +0300 Subject: isp1704_charger: Allow board specific powering routine The ISP1704/1707 chip can be put to full power down state by asserting the CHIP_SEL line. This patch enables platform or board specific hooks to put the device into power down mode in case not needed. This patch is a preparation for enabling this powering routine in n900 (rx-51) devices. Thanks to Heikki Krogerus for helping out with the patch. Signed-off-by: Kalle Jokiniemi Acked-By: Heikki Krogerus Signed-off-by: Anton Vorontsov --- drivers/power/isp1704_charger.c | 22 ++++++++++++++++++++++ include/linux/power/isp1704_charger.h | 29 +++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 include/linux/power/isp1704_charger.h (limited to 'include/linux') diff --git a/drivers/power/isp1704_charger.c b/drivers/power/isp1704_charger.c index 2ad9b14a5ce3..f6d72b402a8e 100644 --- a/drivers/power/isp1704_charger.c +++ b/drivers/power/isp1704_charger.c @@ -33,6 +33,7 @@ #include #include #include +#include /* Vendor specific Power Control register */ #define ISP1704_PWR_CTRL 0x3d @@ -70,6 +71,18 @@ struct isp1704_charger { unsigned max_power; }; +/* + * Disable/enable the power from the isp1704 if a function for it + * has been provided with platform data. + */ +static void isp1704_charger_set_power(struct isp1704_charger *isp, bool on) +{ + struct isp1704_charger_data *board = isp->dev->platform_data; + + if (board->set_power) + board->set_power(on); +} + /* * Determine is the charging port DCP (dedicated charger) or CDP (Host/HUB * chargers). @@ -222,6 +235,9 @@ static void isp1704_charger_work(struct work_struct *data) mutex_lock(&lock); + if (event != USB_EVENT_NONE) + isp1704_charger_set_power(isp, 1); + switch (event) { case USB_EVENT_VBUS: isp->online = true; @@ -269,6 +285,8 @@ static void isp1704_charger_work(struct work_struct *data) */ if (isp->otg->gadget) usb_gadget_disconnect(isp->otg->gadget); + + isp1704_charger_set_power(isp, 0); break; case USB_EVENT_ENUMERATED: if (isp->present) @@ -394,6 +412,8 @@ static int __devinit isp1704_charger_probe(struct platform_device *pdev) isp->dev = &pdev->dev; platform_set_drvdata(pdev, isp); + isp1704_charger_set_power(isp, 1); + ret = isp1704_test_ulpi(isp); if (ret < 0) goto fail1; @@ -434,6 +454,7 @@ static int __devinit isp1704_charger_probe(struct platform_device *pdev) /* Detect charger if VBUS is valid (the cable was already plugged). */ ret = otg_io_read(isp->otg, ULPI_USB_INT_STS); + isp1704_charger_set_power(isp, 0); if ((ret & ULPI_INT_VBUS_VALID) && !isp->otg->default_a) { isp->event = USB_EVENT_VBUS; schedule_work(&isp->work); @@ -459,6 +480,7 @@ static int __devexit isp1704_charger_remove(struct platform_device *pdev) otg_unregister_notifier(isp->otg, &isp->nb); power_supply_unregister(&isp->psy); otg_put_transceiver(isp->otg); + isp1704_charger_set_power(isp, 0); kfree(isp); return 0; diff --git a/include/linux/power/isp1704_charger.h b/include/linux/power/isp1704_charger.h new file mode 100644 index 000000000000..68096a6aa2d7 --- /dev/null +++ b/include/linux/power/isp1704_charger.h @@ -0,0 +1,29 @@ +/* + * ISP1704 USB Charger Detection driver + * + * Copyright (C) 2011 Nokia Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef __ISP1704_CHARGER_H +#define __ISP1704_CHARGER_H + +struct isp1704_charger_data { + void (*set_power)(bool on); +}; + +#endif -- cgit From d4dc210f69bcb0b4bef5a83b1c323817be89bad1 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 21 Apr 2011 20:54:46 +0200 Subject: block: don't block events on excl write for non-optical devices Disk event code automatically blocks events on excl write. This is primarily to avoid issuing polling commands while burning is in progress. This behavior doesn't fit other types of devices with removeable media where polling commands don't have adverse side effects and door locking usually doesn't exist. This patch introduces new genhd flag which controls the auto-blocking behavior and uses it to enable auto-blocking only on optical devices. Note for stable: 2.6.38 and later only Cc: stable@kernel.org Signed-off-by: Tejun Heo Reported-by: Kay Sievers Signed-off-by: Jens Axboe --- drivers/block/paride/pcd.c | 1 + drivers/cdrom/viocd.c | 3 ++- drivers/ide/ide-cd.c | 2 +- drivers/scsi/sr.c | 2 +- fs/block_dev.c | 17 ++++++++++------- include/linux/genhd.h | 1 + 6 files changed, 16 insertions(+), 10 deletions(-) (limited to 'include/linux') diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c index 2f2ccf686251..a0aabd904a51 100644 --- a/drivers/block/paride/pcd.c +++ b/drivers/block/paride/pcd.c @@ -320,6 +320,7 @@ static void pcd_init_units(void) disk->first_minor = unit; strcpy(disk->disk_name, cd->name); /* umm... */ disk->fops = &pcd_bdops; + disk->flags = GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE; disk->events = DISK_EVENT_MEDIA_CHANGE; } } diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index 4e874c5fa605..ae15a4ddaa9b 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c @@ -625,7 +625,8 @@ static int viocd_probe(struct vio_dev *vdev, const struct vio_device_id *id) blk_queue_max_hw_sectors(q, 4096 / 512); gendisk->queue = q; gendisk->fops = &viocd_fops; - gendisk->flags = GENHD_FL_CD|GENHD_FL_REMOVABLE; + gendisk->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE | + GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE; gendisk->events = DISK_EVENT_MEDIA_CHANGE; set_capacity(gendisk, 0); gendisk->private_data = d; diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index fd1e11799137..6e5123b1d341 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1781,7 +1781,7 @@ static int ide_cd_probe(ide_drive_t *drive) ide_cd_read_toc(drive, &sense); g->fops = &idecd_ops; - g->flags |= GENHD_FL_REMOVABLE; + g->flags |= GENHD_FL_REMOVABLE | GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE; g->events = DISK_EVENT_MEDIA_CHANGE; add_disk(g); return 0; diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 95019c747cc1..4778e2707168 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -636,7 +636,7 @@ static int sr_probe(struct device *dev) disk->first_minor = minor; sprintf(disk->disk_name, "sr%d", minor); disk->fops = &sr_bdops; - disk->flags = GENHD_FL_CD; + disk->flags = GENHD_FL_CD | GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE; disk->events = DISK_EVENT_MEDIA_CHANGE | DISK_EVENT_EJECT_REQUEST; blk_queue_rq_timeout(sdev->request_queue, SR_TIMEOUT); diff --git a/fs/block_dev.c b/fs/block_dev.c index 257b00e98428..d7c2e0fddc6f 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -1237,6 +1237,8 @@ int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder) res = __blkdev_get(bdev, mode, 0); if (whole) { + struct gendisk *disk = whole->bd_disk; + /* finish claiming */ mutex_lock(&bdev->bd_mutex); spin_lock(&bdev_lock); @@ -1263,15 +1265,16 @@ int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder) spin_unlock(&bdev_lock); /* - * Block event polling for write claims. Any write - * holder makes the write_holder state stick until all - * are released. This is good enough and tracking - * individual writeable reference is too fragile given - * the way @mode is used in blkdev_get/put(). + * Block event polling for write claims if requested. Any + * write holder makes the write_holder state stick until + * all are released. This is good enough and tracking + * individual writeable reference is too fragile given the + * way @mode is used in blkdev_get/put(). */ - if (!res && (mode & FMODE_WRITE) && !bdev->bd_write_holder) { + if ((disk->flags & GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE) && + !res && (mode & FMODE_WRITE) && !bdev->bd_write_holder) { bdev->bd_write_holder = true; - disk_block_events(bdev->bd_disk); + disk_block_events(disk); } mutex_unlock(&bdev->bd_mutex); diff --git a/include/linux/genhd.h b/include/linux/genhd.h index d764a426e9fd..300d7582006e 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -127,6 +127,7 @@ struct hd_struct { #define GENHD_FL_SUPPRESS_PARTITION_INFO 32 #define GENHD_FL_EXT_DEVT 64 /* allow extended devt */ #define GENHD_FL_NATIVE_CAPACITY 128 +#define GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE 256 enum { DISK_EVENT_MEDIA_CHANGE = 1 << 0, /* media changed */ -- cgit From 8c9e80ed276fc4b9c9fadf29d8bf6b3576112f1a Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 21 Apr 2011 17:23:19 -0700 Subject: SECURITY: Move exec_permission RCU checks into security modules Right now all RCU walks fall back to reference walk when CONFIG_SECURITY is enabled, even though just the standard capability module is active. This is because security_inode_exec_permission unconditionally fails RCU walks. Move this decision to the low level security module. This requires passing the RCU flags down the security hook. This way at least the capability module and a few easy cases in selinux/smack work with RCU walks with CONFIG_SECURITY=y Signed-off-by: Andi Kleen Acked-by: Eric Paris Signed-off-by: Linus Torvalds --- include/linux/security.h | 2 +- security/capability.c | 2 +- security/security.c | 6 ++---- security/selinux/hooks.c | 6 +++++- security/smack/smack_lsm.c | 6 +++++- 5 files changed, 14 insertions(+), 8 deletions(-) (limited to 'include/linux') diff --git a/include/linux/security.h b/include/linux/security.h index ca02f1716736..8ce59ef3e5af 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -1456,7 +1456,7 @@ struct security_operations { struct inode *new_dir, struct dentry *new_dentry); int (*inode_readlink) (struct dentry *dentry); int (*inode_follow_link) (struct dentry *dentry, struct nameidata *nd); - int (*inode_permission) (struct inode *inode, int mask); + int (*inode_permission) (struct inode *inode, int mask, unsigned flags); int (*inode_setattr) (struct dentry *dentry, struct iattr *attr); int (*inode_getattr) (struct vfsmount *mnt, struct dentry *dentry); int (*inode_setxattr) (struct dentry *dentry, const char *name, diff --git a/security/capability.c b/security/capability.c index 2984ea4f776f..bbb51156261b 100644 --- a/security/capability.c +++ b/security/capability.c @@ -181,7 +181,7 @@ static int cap_inode_follow_link(struct dentry *dentry, return 0; } -static int cap_inode_permission(struct inode *inode, int mask) +static int cap_inode_permission(struct inode *inode, int mask, unsigned flags) { return 0; } diff --git a/security/security.c b/security/security.c index 101142369db4..4ba6d4cc061f 100644 --- a/security/security.c +++ b/security/security.c @@ -518,16 +518,14 @@ int security_inode_permission(struct inode *inode, int mask) { if (unlikely(IS_PRIVATE(inode))) return 0; - return security_ops->inode_permission(inode, mask); + return security_ops->inode_permission(inode, mask, 0); } int security_inode_exec_permission(struct inode *inode, unsigned int flags) { if (unlikely(IS_PRIVATE(inode))) return 0; - if (flags) - return -ECHILD; - return security_ops->inode_permission(inode, MAY_EXEC); + return security_ops->inode_permission(inode, MAY_EXEC, flags); } int security_inode_setattr(struct dentry *dentry, struct iattr *attr) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index f9c3764e4859..a73f4e463774 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2635,7 +2635,7 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *na return dentry_has_perm(cred, NULL, dentry, FILE__READ); } -static int selinux_inode_permission(struct inode *inode, int mask) +static int selinux_inode_permission(struct inode *inode, int mask, unsigned flags) { const struct cred *cred = current_cred(); struct common_audit_data ad; @@ -2649,6 +2649,10 @@ static int selinux_inode_permission(struct inode *inode, int mask) if (!mask) return 0; + /* May be droppable after audit */ + if (flags & IPERM_FLAG_RCU) + return -ECHILD; + COMMON_AUDIT_DATA_INIT(&ad, FS); ad.u.fs.inode = inode; diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index c6f8fcadae07..400a5d5cde61 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -686,7 +686,7 @@ static int smack_inode_rename(struct inode *old_inode, * * Returns 0 if access is permitted, -EACCES otherwise */ -static int smack_inode_permission(struct inode *inode, int mask) +static int smack_inode_permission(struct inode *inode, int mask, unsigned flags) { struct smk_audit_info ad; @@ -696,6 +696,10 @@ static int smack_inode_permission(struct inode *inode, int mask) */ if (mask == 0) return 0; + + /* May be droppable after audit */ + if (flags & IPERM_FLAG_RCU) + return -ECHILD; smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); smk_ad_setfield_u_fs_inode(&ad, inode); return smk_curacc(smk_of_inode(inode), mask, &ad); -- cgit From 764b0c4b3256ad4431cb52eaf99c0abe6df0a085 Mon Sep 17 00:00:00 2001 From: Pavan Savoy Date: Fri, 8 Apr 2011 04:57:42 -0500 Subject: drivers:misc:ti-st: handle delayed tty receive When certain technologies shutdown their interface without waiting for the acknowledgement from the chip. The receive_buf from the TTY would be invoked a while after the relevant technology is unregistered. This patch introduces a new flag "is_registered" which maintains the state of protocols BT, FM or GPS and thereby removes the need to clear the protocol data from ST when protocols gets unregistered. This fixes corner cases when HCI RESET is sent down from bluetooth stack and the receive_buf is called from tty after 250ms before which bluetooth would have unregistered from the system. OR - when FM application decides to close down the device without sending a power-off FM command resulting in some RDS data or interrupt data coming in after the driver is unregistered. Signed-off-by: Pavan Savoy Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ti-st/st_core.c | 23 +++++++++++++---------- include/linux/ti_wilink_st.h | 3 ++- 2 files changed, 15 insertions(+), 11 deletions(-) (limited to 'include/linux') diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c index 486117f72c9f..f91f82eabda7 100644 --- a/drivers/misc/ti-st/st_core.c +++ b/drivers/misc/ti-st/st_core.c @@ -43,13 +43,15 @@ static void add_channel_to_table(struct st_data_s *st_gdata, pr_info("%s: id %d\n", __func__, new_proto->chnl_id); /* list now has the channel id as index itself */ st_gdata->list[new_proto->chnl_id] = new_proto; + st_gdata->is_registered[new_proto->chnl_id] = true; } static void remove_channel_from_table(struct st_data_s *st_gdata, struct st_proto_s *proto) { pr_info("%s: id %d\n", __func__, proto->chnl_id); - st_gdata->list[proto->chnl_id] = NULL; +/* st_gdata->list[proto->chnl_id] = NULL; */ + st_gdata->is_registered[proto->chnl_id] = false; } /* @@ -104,7 +106,7 @@ void st_send_frame(unsigned char chnl_id, struct st_data_s *st_gdata) if (unlikely (st_gdata == NULL || st_gdata->rx_skb == NULL - || st_gdata->list[chnl_id] == NULL)) { + || st_gdata->is_registered[chnl_id] == false)) { pr_err("chnl_id %d not registered, no data to send?", chnl_id); kfree_skb(st_gdata->rx_skb); @@ -141,14 +143,15 @@ void st_reg_complete(struct st_data_s *st_gdata, char err) unsigned char i = 0; pr_info(" %s ", __func__); for (i = 0; i < ST_MAX_CHANNELS; i++) { - if (likely(st_gdata != NULL && st_gdata->list[i] != NULL && - st_gdata->list[i]->reg_complete_cb != NULL)) { + if (likely(st_gdata != NULL && + st_gdata->is_registered[i] == true && + st_gdata->list[i]->reg_complete_cb != NULL)) { st_gdata->list[i]->reg_complete_cb (st_gdata->list[i]->priv_data, err); pr_info("protocol %d's cb sent %d\n", i, err); if (err) { /* cleanup registered protocol */ st_gdata->protos_registered--; - st_gdata->list[i] = NULL; + st_gdata->is_registered[i] = false; } } } @@ -475,9 +478,9 @@ void kim_st_list_protocols(struct st_data_s *st_gdata, void *buf) { seq_printf(buf, "[%d]\nBT=%c\nFM=%c\nGPS=%c\n", st_gdata->protos_registered, - st_gdata->list[0x04] != NULL ? 'R' : 'U', - st_gdata->list[0x08] != NULL ? 'R' : 'U', - st_gdata->list[0x09] != NULL ? 'R' : 'U'); + st_gdata->is_registered[0x04] == true ? 'R' : 'U', + st_gdata->is_registered[0x08] == true ? 'R' : 'U', + st_gdata->is_registered[0x09] == true ? 'R' : 'U'); } /********************************************************************/ @@ -504,7 +507,7 @@ long st_register(struct st_proto_s *new_proto) return -EPROTONOSUPPORT; } - if (st_gdata->list[new_proto->chnl_id] != NULL) { + if (st_gdata->is_registered[new_proto->chnl_id] == true) { pr_err("chnl_id %d already registered", new_proto->chnl_id); return -EALREADY; } @@ -563,7 +566,7 @@ long st_register(struct st_proto_s *new_proto) /* check for already registered once more, * since the above check is old */ - if (st_gdata->list[new_proto->chnl_id] != NULL) { + if (st_gdata->is_registered[new_proto->chnl_id] == true) { pr_err(" proto %d already registered ", new_proto->chnl_id); return -EALREADY; diff --git a/include/linux/ti_wilink_st.h b/include/linux/ti_wilink_st.h index 7071ec5d0118..b004e557caa9 100644 --- a/include/linux/ti_wilink_st.h +++ b/include/linux/ti_wilink_st.h @@ -140,12 +140,12 @@ extern long st_unregister(struct st_proto_s *); */ struct st_data_s { unsigned long st_state; - struct tty_struct *tty; struct sk_buff *tx_skb; #define ST_TX_SENDING 1 #define ST_TX_WAKEUP 2 unsigned long tx_state; struct st_proto_s *list[ST_MAX_CHANNELS]; + bool is_registered[ST_MAX_CHANNELS]; unsigned long rx_state; unsigned long rx_count; struct sk_buff *rx_skb; @@ -155,6 +155,7 @@ struct st_data_s { unsigned char protos_registered; unsigned long ll_state; void *kim_data; + struct tty_struct *tty; }; /* -- cgit From c8705082404823a5bb3e02a32ba0764399b9e6f2 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Wed, 20 Apr 2011 09:44:46 +0200 Subject: driver core: let dev_set_drvdata return int instead of void as it can fail MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before commit b402843 (Driver core: move dev_get/set_drvdata to drivers/base/dd.c) calling dev_set_drvdata with dev=NULL was an unchecked error. After some discussion about what to return in this case removing the check (and so producing a null pointer exception) seems fine. Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/base/dd.c | 7 +++---- include/linux/device.h | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 7e9219b02796..e3a3eff1dacc 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -413,17 +413,16 @@ void *dev_get_drvdata(const struct device *dev) } EXPORT_SYMBOL(dev_get_drvdata); -void dev_set_drvdata(struct device *dev, void *data) +int dev_set_drvdata(struct device *dev, void *data) { int error; - if (!dev) - return; if (!dev->p) { error = device_private_init(dev); if (error) - return; + return error; } dev->p->driver_data = data; + return 0; } EXPORT_SYMBOL(dev_set_drvdata); diff --git a/include/linux/device.h b/include/linux/device.h index 350ceda4de97..2215d013ca96 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -557,7 +557,7 @@ extern int device_move(struct device *dev, struct device *new_parent, extern const char *device_get_devnode(struct device *dev, mode_t *mode, const char **tmp); extern void *dev_get_drvdata(const struct device *dev); -extern void dev_set_drvdata(struct device *dev, void *data); +extern int dev_set_drvdata(struct device *dev, void *data); /* * Root device objects for grouping under /sys/devices -- cgit From b1c43f82c5aa265442f82dba31ce985ebb7aa71c Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 21 Mar 2011 12:25:08 +0200 Subject: tty: make receive_buf() return the amout of bytes received it makes it simpler to keep track of the amount of bytes received and simplifies how flush_to_ldisc counts the remaining bytes. It also fixes a bug of lost bytes on n_tty when flushing too many bytes via the USB serial gadget driver. Tested-by: Stefan Bigler Tested-by: Toby Gray Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/bluetooth/hci_ldisc.c | 12 +++++--- drivers/input/serio/serport.c | 10 +++++-- drivers/isdn/gigaset/ser-gigaset.c | 8 +++-- drivers/misc/ti-st/st_core.c | 6 ++-- drivers/net/caif/caif_serial.c | 6 ++-- drivers/net/can/slcan.c | 9 ++++-- drivers/net/hamradio/6pack.c | 8 +++-- drivers/net/hamradio/mkiss.c | 11 ++++--- drivers/net/irda/irtty-sir.c | 16 +++++----- drivers/net/ppp_async.c | 6 ++-- drivers/net/ppp_synctty.c | 6 ++-- drivers/net/slip.c | 11 ++++--- drivers/net/wan/x25_asy.c | 7 +++-- drivers/tty/n_gsm.c | 6 ++-- drivers/tty/n_hdlc.c | 18 ++++++----- drivers/tty/n_r3964.c | 10 ++++--- drivers/tty/n_tty.c | 61 +++++++++----------------------------- drivers/tty/tty_buffer.c | 15 ++++++---- drivers/tty/vt/selection.c | 3 +- include/linux/tty_ldisc.h | 9 +++--- 20 files changed, 125 insertions(+), 113 deletions(-) (limited to 'include/linux') diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 48ad2a7ab080..0d4da5e14ba0 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -357,22 +357,26 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty) * * Return Value: None */ -static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *flags, int count) +static unsigned int hci_uart_tty_receive(struct tty_struct *tty, + const u8 *data, char *flags, int count) { struct hci_uart *hu = (void *)tty->disc_data; + int received; if (!hu || tty != hu->tty) - return; + return -ENODEV; if (!test_bit(HCI_UART_PROTO_SET, &hu->flags)) - return; + return -EINVAL; spin_lock(&hu->rx_lock); - hu->proto->recv(hu, (void *) data, count); + received = hu->proto->recv(hu, (void *) data, count); hu->hdev->stat.byte_rx += count; spin_unlock(&hu->rx_lock); tty_unthrottle(tty); + + return received; } static int hci_uart_register_dev(struct hci_uart *hu) diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c index 8755f5f3ad37..f3698967edf6 100644 --- a/drivers/input/serio/serport.c +++ b/drivers/input/serio/serport.c @@ -120,17 +120,21 @@ static void serport_ldisc_close(struct tty_struct *tty) * 'interrupt' routine. */ -static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) +static unsigned int serport_ldisc_receive(struct tty_struct *tty, + const unsigned char *cp, char *fp, int count) { struct serport *serport = (struct serport*) tty->disc_data; unsigned long flags; unsigned int ch_flags; + int ret = 0; int i; spin_lock_irqsave(&serport->lock, flags); - if (!test_bit(SERPORT_ACTIVE, &serport->flags)) + if (!test_bit(SERPORT_ACTIVE, &serport->flags)) { + ret = -EINVAL; goto out; + } for (i = 0; i < count; i++) { switch (fp[i]) { @@ -152,6 +156,8 @@ static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *c out: spin_unlock_irqrestore(&serport->lock, flags); + + return ret == 0 ? count : ret; } /* diff --git a/drivers/isdn/gigaset/ser-gigaset.c b/drivers/isdn/gigaset/ser-gigaset.c index 86a5c4f7775e..1d44d470897c 100644 --- a/drivers/isdn/gigaset/ser-gigaset.c +++ b/drivers/isdn/gigaset/ser-gigaset.c @@ -674,7 +674,7 @@ gigaset_tty_ioctl(struct tty_struct *tty, struct file *file, * cflags buffer containing error flags for received characters (ignored) * count number of received characters */ -static void +static unsigned int gigaset_tty_receive(struct tty_struct *tty, const unsigned char *buf, char *cflags, int count) { @@ -683,12 +683,12 @@ gigaset_tty_receive(struct tty_struct *tty, const unsigned char *buf, struct inbuf_t *inbuf; if (!cs) - return; + return -ENODEV; inbuf = cs->inbuf; if (!inbuf) { dev_err(cs->dev, "%s: no inbuf\n", __func__); cs_put(cs); - return; + return -EINVAL; } tail = inbuf->tail; @@ -725,6 +725,8 @@ gigaset_tty_receive(struct tty_struct *tty, const unsigned char *buf, gig_dbg(DEBUG_INTR, "%s-->BH", __func__); gigaset_schedule_event(cs); cs_put(cs); + + return count; } /* diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c index 486117f72c9f..cb98a7da98ef 100644 --- a/drivers/misc/ti-st/st_core.c +++ b/drivers/misc/ti-st/st_core.c @@ -744,8 +744,8 @@ static void st_tty_close(struct tty_struct *tty) pr_debug("%s: done ", __func__); } -static void st_tty_receive(struct tty_struct *tty, const unsigned char *data, - char *tty_flags, int count) +static unsigned int st_tty_receive(struct tty_struct *tty, + const unsigned char *data, char *tty_flags, int count) { #ifdef VERBOSE print_hex_dump(KERN_DEBUG, ">in>", DUMP_PREFIX_NONE, @@ -758,6 +758,8 @@ static void st_tty_receive(struct tty_struct *tty, const unsigned char *data, */ st_recv(tty->disc_data, data, count); pr_debug("done %s", __func__); + + return count; } /* wake-up function called in from the TTY layer diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c index 3df0c0f8b8bf..73c7e03617ec 100644 --- a/drivers/net/caif/caif_serial.c +++ b/drivers/net/caif/caif_serial.c @@ -167,8 +167,8 @@ static inline void debugfs_tx(struct ser_device *ser, const u8 *data, int size) #endif -static void ldisc_receive(struct tty_struct *tty, const u8 *data, - char *flags, int count) +static unsigned int ldisc_receive(struct tty_struct *tty, + const u8 *data, char *flags, int count) { struct sk_buff *skb = NULL; struct ser_device *ser; @@ -215,6 +215,8 @@ static void ldisc_receive(struct tty_struct *tty, const u8 *data, } else ++ser->dev->stats.rx_dropped; update_tty_status(ser); + + return count; } static int handle_tx(struct ser_device *ser) diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c index b423965a78d1..c600954998d5 100644 --- a/drivers/net/can/slcan.c +++ b/drivers/net/can/slcan.c @@ -425,16 +425,17 @@ static void slc_setup(struct net_device *dev) * in parallel */ -static void slcan_receive_buf(struct tty_struct *tty, +static unsigned int slcan_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) { struct slcan *sl = (struct slcan *) tty->disc_data; + int bytes = count; if (!sl || sl->magic != SLCAN_MAGIC || !netif_running(sl->dev)) - return; + return -ENODEV; /* Read the characters out of the buffer */ - while (count--) { + while (bytes--) { if (fp && *fp++) { if (!test_and_set_bit(SLF_ERROR, &sl->flags)) sl->dev->stats.rx_errors++; @@ -443,6 +444,8 @@ static void slcan_receive_buf(struct tty_struct *tty, } slcan_unesc(sl, *cp++); } + + return count; } /************************************ diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 3e5d0b6b6516..992089639ea4 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c @@ -456,7 +456,7 @@ out: * a block of 6pack data has been received, which can now be decapsulated * and sent on to some IP layer for further processing. */ -static void sixpack_receive_buf(struct tty_struct *tty, +static unsigned int sixpack_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) { struct sixpack *sp; @@ -464,11 +464,11 @@ static void sixpack_receive_buf(struct tty_struct *tty, int count1; if (!count) - return; + return 0; sp = sp_get(tty); if (!sp) - return; + return -ENODEV; memcpy(buf, cp, count < sizeof(buf) ? count : sizeof(buf)); @@ -487,6 +487,8 @@ static void sixpack_receive_buf(struct tty_struct *tty, sp_put(sp); tty_unthrottle(tty); + + return count1; } /* diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index 4c628393c8b1..0e4f23531140 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c @@ -923,13 +923,14 @@ static long mkiss_compat_ioctl(struct tty_struct *tty, struct file *file, * a block of data has been received, which can now be decapsulated * and sent on to the AX.25 layer for further processing. */ -static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp, - char *fp, int count) +static unsigned int mkiss_receive_buf(struct tty_struct *tty, + const unsigned char *cp, char *fp, int count) { struct mkiss *ax = mkiss_get(tty); + int bytes = count; if (!ax) - return; + return -ENODEV; /* * Argh! mtu change time! - costs us the packet part received @@ -939,7 +940,7 @@ static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp, ax_changedmtu(ax); /* Read the characters out of the buffer */ - while (count--) { + while (bytes--) { if (fp != NULL && *fp++) { if (!test_and_set_bit(AXF_ERROR, &ax->flags)) ax->dev->stats.rx_errors++; @@ -952,6 +953,8 @@ static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp, mkiss_put(ax); tty_unthrottle(tty); + + return count; } /* diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c index 3352b2443e58..035861d8acb1 100644 --- a/drivers/net/irda/irtty-sir.c +++ b/drivers/net/irda/irtty-sir.c @@ -216,23 +216,23 @@ static int irtty_do_write(struct sir_dev *dev, const unsigned char *ptr, size_t * usbserial: urb-complete-interrupt / softint */ -static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp, - char *fp, int count) +static unsigned int irtty_receive_buf(struct tty_struct *tty, + const unsigned char *cp, char *fp, int count) { struct sir_dev *dev; struct sirtty_cb *priv = tty->disc_data; int i; - IRDA_ASSERT(priv != NULL, return;); - IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return;); + IRDA_ASSERT(priv != NULL, return -ENODEV;); + IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return -EINVAL;); if (unlikely(count==0)) /* yes, this happens */ - return; + return 0; dev = priv->dev; if (!dev) { IRDA_WARNING("%s(), not ready yet!\n", __func__); - return; + return -ENODEV; } for (i = 0; i < count; i++) { @@ -242,11 +242,13 @@ static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp, if (fp && *fp++) { IRDA_DEBUG(0, "Framing or parity error!\n"); sirdev_receive(dev, NULL, 0); /* notify sir_dev (updating stats) */ - return; + return -EINVAL; } } sirdev_receive(dev, cp, count); + + return count; } /* diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c index a1b82c9c67d2..53872d7d7382 100644 --- a/drivers/net/ppp_async.c +++ b/drivers/net/ppp_async.c @@ -340,7 +340,7 @@ ppp_asynctty_poll(struct tty_struct *tty, struct file *file, poll_table *wait) } /* May sleep, don't call from interrupt level or with interrupts disabled */ -static void +static unsigned int ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf, char *cflags, int count) { @@ -348,7 +348,7 @@ ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf, unsigned long flags; if (!ap) - return; + return -ENODEV; spin_lock_irqsave(&ap->recv_lock, flags); ppp_async_input(ap, buf, cflags, count); spin_unlock_irqrestore(&ap->recv_lock, flags); @@ -356,6 +356,8 @@ ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf, tasklet_schedule(&ap->tsk); ap_put(ap); tty_unthrottle(tty); + + return count; } static void diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c index 2573f525f11c..0815790a5cf9 100644 --- a/drivers/net/ppp_synctty.c +++ b/drivers/net/ppp_synctty.c @@ -381,7 +381,7 @@ ppp_sync_poll(struct tty_struct *tty, struct file *file, poll_table *wait) } /* May sleep, don't call from interrupt level or with interrupts disabled */ -static void +static unsigned int ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf, char *cflags, int count) { @@ -389,7 +389,7 @@ ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf, unsigned long flags; if (!ap) - return; + return -ENODEV; spin_lock_irqsave(&ap->recv_lock, flags); ppp_sync_input(ap, buf, cflags, count); spin_unlock_irqrestore(&ap->recv_lock, flags); @@ -397,6 +397,8 @@ ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf, tasklet_schedule(&ap->tsk); sp_put(ap); tty_unthrottle(tty); + + return count; } static void diff --git a/drivers/net/slip.c b/drivers/net/slip.c index 86cbb9ea2f26..86718d358395 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -670,16 +670,17 @@ static void sl_setup(struct net_device *dev) * in parallel */ -static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp, - char *fp, int count) +static unsigned int slip_receive_buf(struct tty_struct *tty, + const unsigned char *cp, char *fp, int count) { struct slip *sl = tty->disc_data; + int bytes = count; if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev)) - return; + return -ENODEV; /* Read the characters out of the buffer */ - while (count--) { + while (bytes--) { if (fp && *fp++) { if (!test_and_set_bit(SLF_ERROR, &sl->flags)) sl->dev->stats.rx_errors++; @@ -693,6 +694,8 @@ static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp, #endif slip_unesc(sl, *cp++); } + + return count; } /************************************ diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c index 24297b274cd4..40398bf7d036 100644 --- a/drivers/net/wan/x25_asy.c +++ b/drivers/net/wan/x25_asy.c @@ -517,17 +517,18 @@ static int x25_asy_close(struct net_device *dev) * and sent on to some IP layer for further processing. */ -static void x25_asy_receive_buf(struct tty_struct *tty, +static unsigned int x25_asy_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) { struct x25_asy *sl = tty->disc_data; + int bytes = count; if (!sl || sl->magic != X25_ASY_MAGIC || !netif_running(sl->dev)) return; /* Read the characters out of the buffer */ - while (count--) { + while (bytes--) { if (fp && *fp++) { if (!test_and_set_bit(SLF_ERROR, &sl->flags)) sl->dev->stats.rx_errors++; @@ -536,6 +537,8 @@ static void x25_asy_receive_buf(struct tty_struct *tty, } x25_asy_unesc(sl, *cp++); } + + return count; } /* diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 47f8cdb207f1..6abc73598847 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -2138,8 +2138,8 @@ static void gsmld_detach_gsm(struct tty_struct *tty, struct gsm_mux *gsm) gsm->tty = NULL; } -static void gsmld_receive_buf(struct tty_struct *tty, const unsigned char *cp, - char *fp, int count) +static unsigned int gsmld_receive_buf(struct tty_struct *tty, + const unsigned char *cp, char *fp, int count) { struct gsm_mux *gsm = tty->disc_data; const unsigned char *dp; @@ -2173,6 +2173,8 @@ static void gsmld_receive_buf(struct tty_struct *tty, const unsigned char *cp, } /* FASYNC if needed ? */ /* If clogged call tty_throttle(tty); */ + + return count; } /** diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c index cea56033b34c..cac666314aef 100644 --- a/drivers/tty/n_hdlc.c +++ b/drivers/tty/n_hdlc.c @@ -188,8 +188,8 @@ static unsigned int n_hdlc_tty_poll(struct tty_struct *tty, struct file *filp, poll_table *wait); static int n_hdlc_tty_open(struct tty_struct *tty); static void n_hdlc_tty_close(struct tty_struct *tty); -static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *cp, - char *fp, int count); +static unsigned int n_hdlc_tty_receive(struct tty_struct *tty, + const __u8 *cp, char *fp, int count); static void n_hdlc_tty_wakeup(struct tty_struct *tty); #define bset(p,b) ((p)[(b) >> 5] |= (1 << ((b) & 0x1f))) @@ -509,8 +509,8 @@ static void n_hdlc_tty_wakeup(struct tty_struct *tty) * Called by tty low level driver when receive data is available. Data is * interpreted as one HDLC frame. */ -static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data, - char *flags, int count) +static unsigned int n_hdlc_tty_receive(struct tty_struct *tty, + const __u8 *data, char *flags, int count) { register struct n_hdlc *n_hdlc = tty2n_hdlc (tty); register struct n_hdlc_buf *buf; @@ -521,20 +521,20 @@ static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data, /* This can happen if stuff comes in on the backup tty */ if (!n_hdlc || tty != n_hdlc->tty) - return; + return -ENODEV; /* verify line is using HDLC discipline */ if (n_hdlc->magic != HDLC_MAGIC) { printk("%s(%d) line not using HDLC discipline\n", __FILE__,__LINE__); - return; + return -EINVAL; } if ( count>maxframe ) { if (debuglevel >= DEBUG_LEVEL_INFO) printk("%s(%d) rx count>maxframesize, data discarded\n", __FILE__,__LINE__); - return; + return -EINVAL; } /* get a free HDLC buffer */ @@ -550,7 +550,7 @@ static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data, if (debuglevel >= DEBUG_LEVEL_INFO) printk("%s(%d) no more rx buffers, data discarded\n", __FILE__,__LINE__); - return; + return -EINVAL; } /* copy received data to HDLC buffer */ @@ -565,6 +565,8 @@ static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data, if (n_hdlc->tty->fasync != NULL) kill_fasync (&n_hdlc->tty->fasync, SIGIO, POLL_IN); + return count; + } /* end of n_hdlc_tty_receive() */ /** diff --git a/drivers/tty/n_r3964.c b/drivers/tty/n_r3964.c index 5c6c31459a2f..a4bc39c21a43 100644 --- a/drivers/tty/n_r3964.c +++ b/drivers/tty/n_r3964.c @@ -139,8 +139,8 @@ static int r3964_ioctl(struct tty_struct *tty, struct file *file, static void r3964_set_termios(struct tty_struct *tty, struct ktermios *old); static unsigned int r3964_poll(struct tty_struct *tty, struct file *file, struct poll_table_struct *wait); -static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp, - char *fp, int count); +static unsigned int r3964_receive_buf(struct tty_struct *tty, + const unsigned char *cp, char *fp, int count); static struct tty_ldisc_ops tty_ldisc_N_R3964 = { .owner = THIS_MODULE, @@ -1239,8 +1239,8 @@ static unsigned int r3964_poll(struct tty_struct *tty, struct file *file, return result; } -static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp, - char *fp, int count) +static unsigned int r3964_receive_buf(struct tty_struct *tty, + const unsigned char *cp, char *fp, int count) { struct r3964_info *pInfo = tty->disc_data; const unsigned char *p; @@ -1257,6 +1257,8 @@ static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp, } } + + return count; } MODULE_LICENSE("GPL"); diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 0ad32888091c..95d0a9c2dd13 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -81,38 +81,6 @@ static inline int tty_put_user(struct tty_struct *tty, unsigned char x, return put_user(x, ptr); } -/** - * n_tty_set__room - receive space - * @tty: terminal - * - * Called by the driver to find out how much data it is - * permitted to feed to the line discipline without any being lost - * and thus to manage flow control. Not serialized. Answers for the - * "instant". - */ - -static void n_tty_set_room(struct tty_struct *tty) -{ - /* tty->read_cnt is not read locked ? */ - int left = N_TTY_BUF_SIZE - tty->read_cnt - 1; - int old_left; - - /* - * If we are doing input canonicalization, and there are no - * pending newlines, let characters through without limit, so - * that erase characters will be handled. Other excess - * characters will be beeped. - */ - if (left <= 0) - left = tty->icanon && !tty->canon_data; - old_left = tty->receive_room; - tty->receive_room = left; - - /* Did this open up the receive buffer? We may need to flip */ - if (left && !old_left) - schedule_work(&tty->buf.work); -} - static void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty) { if (tty->read_cnt < N_TTY_BUF_SIZE) { @@ -184,7 +152,6 @@ static void reset_buffer_flags(struct tty_struct *tty) tty->canon_head = tty->canon_data = tty->erasing = 0; memset(&tty->read_flags, 0, sizeof tty->read_flags); - n_tty_set_room(tty); check_unthrottle(tty); } @@ -1360,17 +1327,19 @@ static void n_tty_write_wakeup(struct tty_struct *tty) * calls one at a time and in order (or using flush_to_ldisc) */ -static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, - char *fp, int count) +static unsigned int n_tty_receive_buf(struct tty_struct *tty, + const unsigned char *cp, char *fp, int count) { const unsigned char *p; char *f, flags = TTY_NORMAL; int i; char buf[64]; unsigned long cpuflags; + int left; + int ret = 0; if (!tty->read_buf) - return; + return 0; if (tty->real_raw) { spin_lock_irqsave(&tty->read_lock, cpuflags); @@ -1380,6 +1349,7 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, memcpy(tty->read_buf + tty->read_head, cp, i); tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1); tty->read_cnt += i; + ret += i; cp += i; count -= i; @@ -1389,8 +1359,10 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, memcpy(tty->read_buf + tty->read_head, cp, i); tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1); tty->read_cnt += i; + ret += i; spin_unlock_irqrestore(&tty->read_lock, cpuflags); } else { + ret = count; for (i = count, p = cp, f = fp; i; i--, p++) { if (f) flags = *f++; @@ -1418,8 +1390,6 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, tty->ops->flush_chars(tty); } - n_tty_set_room(tty); - if ((!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) || L_EXTPROC(tty)) { kill_fasync(&tty->fasync, SIGIO, POLL_IN); @@ -1432,8 +1402,12 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, * mode. We don't want to throttle the driver if we're in * canonical mode and don't have a newline yet! */ - if (tty->receive_room < TTY_THRESHOLD_THROTTLE) + left = N_TTY_BUF_SIZE - tty->read_cnt - 1; + + if (left < TTY_THRESHOLD_THROTTLE) tty_throttle(tty); + + return ret; } int is_ignored(int sig) @@ -1477,7 +1451,6 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) if (test_bit(TTY_HW_COOK_IN, &tty->flags)) { tty->raw = 1; tty->real_raw = 1; - n_tty_set_room(tty); return; } if (I_ISTRIP(tty) || I_IUCLC(tty) || I_IGNCR(tty) || @@ -1530,7 +1503,6 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) else tty->real_raw = 0; } - n_tty_set_room(tty); /* The termios change make the tty ready for I/O */ wake_up_interruptible(&tty->write_wait); wake_up_interruptible(&tty->read_wait); @@ -1812,8 +1784,6 @@ do_it_again: retval = -ERESTARTSYS; break; } - /* FIXME: does n_tty_set_room need locking ? */ - n_tty_set_room(tty); timeout = schedule_timeout(timeout); continue; } @@ -1885,10 +1855,8 @@ do_it_again: * longer than TTY_THRESHOLD_UNTHROTTLE in canonical mode, * we won't get any more characters. */ - if (n_tty_chars_in_buffer(tty) <= TTY_THRESHOLD_UNTHROTTLE) { - n_tty_set_room(tty); + if (n_tty_chars_in_buffer(tty) <= TTY_THRESHOLD_UNTHROTTLE) check_unthrottle(tty); - } if (b - buf >= minimum) break; @@ -1910,7 +1878,6 @@ do_it_again: } else if (test_and_clear_bit(TTY_PUSH, &tty->flags)) goto do_it_again; - n_tty_set_room(tty); return retval; } diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index f1a7918d71aa..46de2e075dac 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -416,6 +416,7 @@ static void flush_to_ldisc(struct work_struct *work) struct tty_buffer *head, *tail = tty->buf.tail; int seen_tail = 0; while ((head = tty->buf.head) != NULL) { + int copied; int count; char *char_buf; unsigned char *flag_buf; @@ -442,17 +443,19 @@ static void flush_to_ldisc(struct work_struct *work) line discipline as we want to empty the queue */ if (test_bit(TTY_FLUSHPENDING, &tty->flags)) break; - if (!tty->receive_room || seen_tail) - break; - if (count > tty->receive_room) - count = tty->receive_room; char_buf = head->char_buf_ptr + head->read; flag_buf = head->flag_buf_ptr + head->read; - head->read += count; spin_unlock_irqrestore(&tty->buf.lock, flags); - disc->ops->receive_buf(tty, char_buf, + copied = disc->ops->receive_buf(tty, char_buf, flag_buf, count); spin_lock_irqsave(&tty->buf.lock, flags); + + head->read += copied; + + if (copied == 0 || seen_tail) { + schedule_work(&tty->buf.work); + break; + } } clear_bit(TTY_FLUSHING, &tty->flags); } diff --git a/drivers/tty/vt/selection.c b/drivers/tty/vt/selection.c index fb864e7fcd13..67b1d0d7c8ac 100644 --- a/drivers/tty/vt/selection.c +++ b/drivers/tty/vt/selection.c @@ -332,8 +332,7 @@ int paste_selection(struct tty_struct *tty) continue; } count = sel_buffer_lth - pasted; - count = min(count, tty->receive_room); - tty->ldisc->ops->receive_buf(tty, sel_buffer + pasted, + count = tty->ldisc->ops->receive_buf(tty, sel_buffer + pasted, NULL, count); pasted += count; } diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h index ff7dc08696a8..5b07792ccb46 100644 --- a/include/linux/tty_ldisc.h +++ b/include/linux/tty_ldisc.h @@ -76,7 +76,7 @@ * tty device. It is solely the responsibility of the line * discipline to handle poll requests. * - * void (*receive_buf)(struct tty_struct *, const unsigned char *cp, + * unsigned int (*receive_buf)(struct tty_struct *, const unsigned char *cp, * char *fp, int count); * * This function is called by the low-level tty driver to send @@ -84,7 +84,8 @@ * processing. is a pointer to the buffer of input * character received by the device. is a pointer to a * pointer of flag bytes which indicate whether a character was - * received with a parity error, etc. + * received with a parity error, etc. Returns the amount of bytes + * received. * * void (*write_wakeup)(struct tty_struct *); * @@ -140,8 +141,8 @@ struct tty_ldisc_ops { /* * The following routines are called from below. */ - void (*receive_buf)(struct tty_struct *, const unsigned char *cp, - char *fp, int count); + unsigned int (*receive_buf)(struct tty_struct *, + const unsigned char *cp, char *fp, int count); void (*write_wakeup)(struct tty_struct *); void (*dcd_change)(struct tty_struct *, unsigned int, struct pps_event_time *); -- cgit From 0911f124bf55357803d53197cc1ae5479f5e37e2 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 10 Apr 2011 11:01:51 +0200 Subject: genirq: Forgotten updates/deletions after removal of compat code commit 0c6f8a8b917ad361319c8ace3e9f28e69bfdb4c1 ("genirq: Remove compat code") removed the compat code, but forgot to update some references in comments and delete some of its documentation. Signed-off-by: Geert Uytterhoeven Link: http://lkml.kernel.org/r/%3C1302426113-13808-1-git-send-email-geert%40linux-m68k.org%3E Signed-off-by: Thomas Gleixner --- include/linux/irq.h | 19 +------------------ include/linux/irqdesc.h | 2 +- 2 files changed, 2 insertions(+), 19 deletions(-) (limited to 'include/linux') diff --git a/include/linux/irq.h b/include/linux/irq.h index 09a308072f56..a71dd18639fb 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -53,7 +53,7 @@ typedef void (*irq_preflow_handler_t)(struct irq_data *data); * Bits which can be modified via irq_set/clear/modify_status_flags() * IRQ_LEVEL - Interrupt is level type. Will be also * updated in the code when the above trigger - * bits are modified via set_irq_type() + * bits are modified via irq_set_irq_type() * IRQ_PER_CPU - Mark an interrupt PER_CPU. Will protect * it from affinity setting * IRQ_NOPROBE - Interrupt cannot be probed by autoprobing @@ -261,23 +261,6 @@ static inline void irqd_clr_chained_irq_inprogress(struct irq_data *d) * struct irq_chip - hardware interrupt chip descriptor * * @name: name for /proc/interrupts - * @startup: deprecated, replaced by irq_startup - * @shutdown: deprecated, replaced by irq_shutdown - * @enable: deprecated, replaced by irq_enable - * @disable: deprecated, replaced by irq_disable - * @ack: deprecated, replaced by irq_ack - * @mask: deprecated, replaced by irq_mask - * @mask_ack: deprecated, replaced by irq_mask_ack - * @unmask: deprecated, replaced by irq_unmask - * @eoi: deprecated, replaced by irq_eoi - * @end: deprecated, will go away with __do_IRQ() - * @set_affinity: deprecated, replaced by irq_set_affinity - * @retrigger: deprecated, replaced by irq_retrigger - * @set_type: deprecated, replaced by irq_set_type - * @set_wake: deprecated, replaced by irq_wake - * @bus_lock: deprecated, replaced by irq_bus_lock - * @bus_sync_unlock: deprecated, replaced by irq_bus_sync_unlock - * * @irq_startup: start up the interrupt (defaults to ->enable if NULL) * @irq_shutdown: shut down the interrupt (defaults to ->disable if NULL) * @irq_enable: enable the interrupt (defaults to chip->unmask if NULL) diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h index a082905b5ebe..8e1dc8ea5471 100644 --- a/include/linux/irqdesc.h +++ b/include/linux/irqdesc.h @@ -21,7 +21,7 @@ struct timer_rand_state; * @status: status information * @core_internal_state__do_not_mess_with_it: core internal status information * @depth: disable-depth, for nested irq_disable() calls - * @wake_depth: enable depth, for multiple set_irq_wake() callers + * @wake_depth: enable depth, for multiple irq_set_irq_wake() callers * @irq_count: stats field to detect stalled irqs * @last_unhandled: aging timer for unhandled count * @irqs_unhandled: stats field for spurious unhandled interrupts -- cgit From 770767787c23040dc152e7ae230597ff55b39470 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 10 Apr 2011 11:01:52 +0200 Subject: genirq: irq_desc: Document preflow_handler and affinity_hint [ tglx: Filled in the FIXME place holders ] Signed-off-by: Geert Uytterhoeven Link: http://lkml.kernel.org/r/%3C1302426113-13808-2-git-send-email-geert%40linux-m68k.org%3E Signed-off-by: Thomas Gleixner --- include/linux/irqdesc.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h index 8e1dc8ea5471..c70b1aa4b93a 100644 --- a/include/linux/irqdesc.h +++ b/include/linux/irqdesc.h @@ -16,7 +16,8 @@ struct timer_rand_state; * @irq_data: per irq and chip data passed down to chip functions * @timer_rand_state: pointer to timer rand state struct * @kstat_irqs: irq stats per cpu - * @handle_irq: highlevel irq-events handler [if NULL, __do_IRQ()] + * @handle_irq: highlevel irq-events handler + * @preflow_handler: handler called before the flow handler (currently used by sparc) * @action: the irq action chain * @status: status information * @core_internal_state__do_not_mess_with_it: core internal status information @@ -26,6 +27,7 @@ struct timer_rand_state; * @last_unhandled: aging timer for unhandled count * @irqs_unhandled: stats field for spurious unhandled interrupts * @lock: locking for SMP + * @affinity_hint: hint to user space for preferred irq affinity * @affinity_notify: context for notification of affinity changes * @pending_mask: pending rebalanced interrupts * @threads_oneshot: bitfield to handle shared oneshot threads -- cgit From 7f1b1244e159a8490d7fb13667c6cb7e1e75046b Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 7 Apr 2011 06:01:44 +0900 Subject: genirq: Support per-IRQ thread disabling. This adds support for disabling threading on a per-IRQ basis via the IRQ status instead of the IRQ flow, which is necessary for interrupts that don't follow the natural IRQ flow channels, such as those that are virtually created. The new APIs added are simply: irq_set_thread() irq_set_nothread() which follow the rest of the IRQ status routines. Chained handlers also have IRQ_NOTHREAD set on them automatically, making the lack of threading explicit rather than implicit. Subsequently, the nothread flag can be viewed through the standard genirq debugging facilities. [ tglx: Fixed cleanup fallout ] Signed-off-by: Paul Mundt Link: http://lkml.kernel.org/r/%3C20110406210135.GF18426%40linux-sh.org%3E Signed-off-by: Thomas Gleixner --- include/linux/irq.h | 14 +++++++++++++- kernel/irq/chip.c | 1 + kernel/irq/debug.h | 1 + kernel/irq/manage.c | 3 ++- kernel/irq/settings.h | 17 +++++++++++++++++ 5 files changed, 34 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/irq.h b/include/linux/irq.h index a71dd18639fb..39c23786c1db 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -59,6 +59,7 @@ typedef void (*irq_preflow_handler_t)(struct irq_data *data); * IRQ_NOPROBE - Interrupt cannot be probed by autoprobing * IRQ_NOREQUEST - Interrupt cannot be requested via * request_irq() + * IRQ_NOTHREAD - Interrupt cannot be threaded * IRQ_NOAUTOEN - Interrupt is not automatically enabled in * request/setup_irq() * IRQ_NO_BALANCING - Interrupt cannot be balanced (affinity set) @@ -85,6 +86,7 @@ enum { IRQ_NO_BALANCING = (1 << 13), IRQ_MOVE_PCNTXT = (1 << 14), IRQ_NESTED_THREAD = (1 << 15), + IRQ_NOTHREAD = (1 << 16), }; #define IRQF_MODIFY_MASK \ @@ -422,7 +424,7 @@ irq_set_handler(unsigned int irq, irq_flow_handler_t handle) /* * Set a highlevel chained flow handler for a given IRQ. * (a chained handler is automatically enabled and set to - * IRQ_NOREQUEST and IRQ_NOPROBE) + * IRQ_NOREQUEST, IRQ_NOPROBE, and IRQ_NOTHREAD) */ static inline void irq_set_chained_handler(unsigned int irq, irq_flow_handler_t handle) @@ -452,6 +454,16 @@ static inline void irq_set_probe(unsigned int irq) irq_modify_status(irq, IRQ_NOPROBE, 0); } +static inline void irq_set_nothread(unsigned int irq) +{ + irq_modify_status(irq, 0, IRQ_NOTHREAD); +} + +static inline void irq_set_thread(unsigned int irq) +{ + irq_modify_status(irq, IRQ_NOTHREAD, 0); +} + static inline void irq_set_nested_thread(unsigned int irq, bool nest) { if (nest) diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 4af1e2b244cb..52d856d513ff 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -573,6 +573,7 @@ __irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, if (handle != handle_bad_irq && is_chained) { irq_settings_set_noprobe(desc); irq_settings_set_norequest(desc); + irq_settings_set_nothread(desc); irq_startup(desc); } out: diff --git a/kernel/irq/debug.h b/kernel/irq/debug.h index 306cba37e9a5..97a8bfadc88a 100644 --- a/kernel/irq/debug.h +++ b/kernel/irq/debug.h @@ -27,6 +27,7 @@ static inline void print_irq_desc(unsigned int irq, struct irq_desc *desc) P(IRQ_PER_CPU); P(IRQ_NOPROBE); P(IRQ_NOREQUEST); + P(IRQ_NOTHREAD); P(IRQ_NOAUTOEN); PS(IRQS_AUTODETECT); diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 07c1611f3899..f7ce0021e1c4 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -900,7 +900,8 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) */ new->handler = irq_nested_primary_handler; } else { - irq_setup_forced_threading(new); + if (irq_settings_can_thread(desc)) + irq_setup_forced_threading(new); } /* diff --git a/kernel/irq/settings.h b/kernel/irq/settings.h index 0d91730b6330..f1667833d444 100644 --- a/kernel/irq/settings.h +++ b/kernel/irq/settings.h @@ -8,6 +8,7 @@ enum { _IRQ_LEVEL = IRQ_LEVEL, _IRQ_NOPROBE = IRQ_NOPROBE, _IRQ_NOREQUEST = IRQ_NOREQUEST, + _IRQ_NOTHREAD = IRQ_NOTHREAD, _IRQ_NOAUTOEN = IRQ_NOAUTOEN, _IRQ_MOVE_PCNTXT = IRQ_MOVE_PCNTXT, _IRQ_NO_BALANCING = IRQ_NO_BALANCING, @@ -20,6 +21,7 @@ enum { #define IRQ_LEVEL GOT_YOU_MORON #define IRQ_NOPROBE GOT_YOU_MORON #define IRQ_NOREQUEST GOT_YOU_MORON +#define IRQ_NOTHREAD GOT_YOU_MORON #define IRQ_NOAUTOEN GOT_YOU_MORON #define IRQ_NESTED_THREAD GOT_YOU_MORON #undef IRQF_MODIFY_MASK @@ -94,6 +96,21 @@ static inline void irq_settings_set_norequest(struct irq_desc *desc) desc->status_use_accessors |= _IRQ_NOREQUEST; } +static inline bool irq_settings_can_thread(struct irq_desc *desc) +{ + return !(desc->status_use_accessors & _IRQ_NOTHREAD); +} + +static inline void irq_settings_clr_nothread(struct irq_desc *desc) +{ + desc->status_use_accessors &= ~_IRQ_NOTHREAD; +} + +static inline void irq_settings_set_nothread(struct irq_desc *desc) +{ + desc->status_use_accessors |= _IRQ_NOTHREAD; +} + static inline bool irq_settings_can_probe(struct irq_desc *desc) { return !(desc->status_use_accessors & _IRQ_NOPROBE); -- cgit From 7d8280624797bbe2f5170bd3c85c75a8c9c74242 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 3 Apr 2011 11:42:53 +0200 Subject: genirq: Implement a generic interrupt chip Implement a generic interrupt chip, which is configurable and is able to handle the most common irq chip implementations. Signed-off-by: Thomas Gleixner Cc: linux-arm-kernel@lists.infradead.org Tested-by: H Hartley Sweeten Tested-by: Tony Lindgren Tested-by; Kevin Hilman --- include/linux/irq.h | 135 ++++++++++++++++++++++++ kernel/irq/Makefile | 1 + kernel/irq/generic-chip.c | 261 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 397 insertions(+) create mode 100644 kernel/irq/generic-chip.c (limited to 'include/linux') diff --git a/include/linux/irq.h b/include/linux/irq.h index 39c23786c1db..2ba2f1216790 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -568,6 +568,141 @@ static inline int irq_reserve_irq(unsigned int irq) return irq_reserve_irqs(irq, 1); } +#ifndef irq_reg_writel +# define irq_reg_writel(val, addr) writel(val, addr) +#endif +#ifndef irq_reg_readl +# define irq_reg_readl(addr) readl(addr) +#endif + +/** + * struct irq_chip_regs - register offsets for struct irq_gci + * @enable: Enable register offset to reg_base + * @disable: Disable register offset to reg_base + * @mask: Mask register offset to reg_base + * @ack: Ack register offset to reg_base + * @eoi: Eoi register offset to reg_base + * @type: Type configuration register offset to reg_base + * @polarity: Polarity configuration register offset to reg_base + */ +struct irq_chip_regs { + unsigned long enable; + unsigned long disable; + unsigned long mask; + unsigned long ack; + unsigned long eoi; + unsigned long type; + unsigned long polarity; +}; + +/** + * struct irq_chip_type - Generic interrupt chip instance for a flow type + * @chip: The real interrupt chip which provides the callbacks + * @regs: Register offsets for this chip + * @handler: Flow handler associated with this chip + * @type: Chip can handle these flow types + * + * A irq_generic_chip can have several instances of irq_chip_type when + * it requires different functions and register offsets for different + * flow types. + */ +struct irq_chip_type { + struct irq_chip chip; + struct irq_chip_regs regs; + irq_flow_handler_t handler; + u32 type; +}; + +/** + * struct irq_chip_generic - Generic irq chip data structure + * @lock: Lock to protect register and cache data access + * @reg_base: Register base address (virtual) + * @irq_base: Interrupt base nr for this chip + * @irq_cnt: Number of interrupts handled by this chip + * @mask_cache: Cached mask register + * @type_cache: Cached type register + * @polarity_cache: Cached polarity register + * @wake_enabled: Interrupt can wakeup from suspend + * @wake_active: Interrupt is marked as an wakeup from suspend source + * @num_ct: Number of available irq_chip_type instances (usually 1) + * @private: Private data for non generic chip callbacks + * @chip_types: Array of interrupt irq_chip_types + * + * Note, that irq_chip_generic can have multiple irq_chip_type + * implementations which can be associated to a particular irq line of + * an irq_chip_generic instance. That allows to share and protect + * state in an irq_chip_generic instance when we need to implement + * different flow mechanisms (level/edge) for it. + */ +struct irq_chip_generic { + raw_spinlock_t lock; + void __iomem *reg_base; + unsigned int irq_base; + unsigned int irq_cnt; + u32 mask_cache; + u32 type_cache; + u32 polarity_cache; + u32 wake_enabled; + u32 wake_active; + unsigned int num_ct; + void *private; + struct irq_chip_type chip_types[0]; +}; + +/** + * enum irq_gc_flags - Initialization flags for generic irq chips + * @IRQ_GC_INIT_MASK_CACHE: Initialize the mask_cache by reading mask reg + * @IRQ_GC_INIT_NESTED_LOCK: Set the lock class of the irqs to nested for + * irq chips which need to call irq_set_wake() on + * the parent irq. Usually GPIO implementations + */ +enum irq_gc_flags { + IRQ_GC_INIT_MASK_CACHE = 1 << 0, + IRQ_GC_INIT_NESTED_LOCK = 1 << 1, +}; + +/* Generic chip callback functions */ +void irq_gc_noop(struct irq_data *d); +void irq_gc_mask_disable_reg(struct irq_data *d); +void irq_gc_mask_set_bit(struct irq_data *d); +void irq_gc_mask_clr_bit(struct irq_data *d); +void irq_gc_unmask_enable_reg(struct irq_data *d); +void irq_gc_ack(struct irq_data *d); +void irq_gc_mask_disable_reg_and_ack(struct irq_data *d); +void irq_gc_eoi(struct irq_data *d); +int irq_gc_set_wake(struct irq_data *d, unsigned int on); + +/* Setup functions for irq_chip_generic */ +struct irq_chip_generic * +irq_alloc_generic_chip(const char *name, int nr_ct, unsigned int irq_base, + void __iomem *reg_base, irq_flow_handler_t handler); +void irq_setup_generic_chip(struct irq_chip_generic *gc, u32 msk, + enum irq_gc_flags flags, unsigned int clr, + unsigned int set); +int irq_setup_alt_chip(struct irq_data *d, unsigned int type); + +static inline struct irq_chip_type *irq_data_get_chip_type(struct irq_data *d) +{ + return container_of(d->chip, struct irq_chip_type, chip); +} + +#define IRQ_MSK(n) (u32)((n) < 32 ? ((1 << (n)) - 1) : UINT_MAX) + +#ifdef CONFIG_SMP +static inline void irq_gc_lock(struct irq_chip_generic *gc) +{ + raw_spin_lock(&gc->lock); +} + +static inline void irq_gc_unlock(struct irq_chip_generic *gc) +{ + raw_spin_unlock(&gc->lock); +} +#else +static inline void irq_gc_lock(struct irq_chip_generic *gc) { } +static inline void irq_gc_unlock(struct irq_chip_generic *gc) { } +#endif + #endif /* CONFIG_GENERIC_HARDIRQS */ #endif /* !CONFIG_S390 */ diff --git a/kernel/irq/Makefile b/kernel/irq/Makefile index 54329cd7b3ee..e7a13bd3316a 100644 --- a/kernel/irq/Makefile +++ b/kernel/irq/Makefile @@ -1,5 +1,6 @@ obj-y := irqdesc.o handle.o manage.o spurious.o resend.o chip.o dummychip.o devres.o +obj-y += generic-chip.o obj-$(CONFIG_GENERIC_IRQ_PROBE) += autoprobe.o obj-$(CONFIG_PROC_FS) += proc.o obj-$(CONFIG_GENERIC_PENDING_IRQ) += migration.o diff --git a/kernel/irq/generic-chip.c b/kernel/irq/generic-chip.c new file mode 100644 index 000000000000..eb23e5924260 --- /dev/null +++ b/kernel/irq/generic-chip.c @@ -0,0 +1,261 @@ +/* + * Library implementing the most common irq chip callback functions + * + * Copyright (C) 2011, Thomas Gleixner + */ +#include +#include +#include +#include +#include + +#include "internals.h" + +static inline struct irq_chip_regs *cur_regs(struct irq_data *d) +{ + return &container_of(d->chip, struct irq_chip_type, chip)->regs; +} + +/** + * irq_gc_noop - NOOP function + * @d: irq_data + */ +void irq_gc_noop(struct irq_data *d) +{ +} + +/** + * irq_gc_mask_disable_reg - Mask chip via disable register + * @d: irq_data + * + * Chip has separate enable/disable registers instead of a single mask + * register. + */ +void irq_gc_mask_disable_reg(struct irq_data *d) +{ + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); + u32 mask = 1 << (d->irq - gc->irq_base); + + irq_gc_lock(gc); + irq_reg_writel(mask, gc->reg_base + cur_regs(d)->disable); + gc->mask_cache &= ~mask; + irq_gc_unlock(gc); +} + +/** + * irq_gc_mask_set_mask_bit - Mask chip via setting bit in mask register + * @d: irq_data + * + * Chip has a single mask register. Values of this register are cached + * and protected by gc->lock + */ +void irq_gc_mask_set_bit(struct irq_data *d) +{ + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); + u32 mask = 1 << (d->irq - gc->irq_base); + + irq_gc_lock(gc); + gc->mask_cache |= mask; + irq_reg_writel(gc->mask_cache, gc->reg_base + cur_regs(d)->mask); + irq_gc_unlock(gc); +} + +/** + * irq_gc_mask_set_mask_bit - Mask chip via clearing bit in mask register + * @d: irq_data + * + * Chip has a single mask register. Values of this register are cached + * and protected by gc->lock + */ +void irq_gc_mask_clr_bit(struct irq_data *d) +{ + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); + u32 mask = 1 << (d->irq - gc->irq_base); + + irq_gc_lock(gc); + gc->mask_cache &= ~mask; + irq_reg_writel(gc->mask_cache, gc->reg_base + cur_regs(d)->mask); + irq_gc_unlock(gc); +} + +/** + * irq_gc_unmask_enable_reg - Unmask chip via enable register + * @d: irq_data + * + * Chip has separate enable/disable registers instead of a single mask + * register. + */ +void irq_gc_unmask_enable_reg(struct irq_data *d) +{ + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); + u32 mask = 1 << (d->irq - gc->irq_base); + + irq_gc_lock(gc); + irq_reg_writel(mask, gc->reg_base + cur_regs(d)->enable); + gc->mask_cache |= mask; + irq_gc_unlock(gc); +} + +/** + * irq_gc_ack - Ack pending interrupt + * @d: irq_data + */ +void irq_gc_ack(struct irq_data *d) +{ + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); + u32 mask = 1 << (d->irq - gc->irq_base); + + irq_gc_lock(gc); + irq_reg_writel(mask, gc->reg_base + cur_regs(d)->ack); + irq_gc_unlock(gc); +} + +/** + * irq_gc_mask_disable_reg_and_ack- Mask and ack pending interrupt + * @d: irq_data + */ +void irq_gc_mask_disable_reg_and_ack(struct irq_data *d) +{ + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); + u32 mask = 1 << (d->irq - gc->irq_base); + + irq_gc_lock(gc); + irq_reg_writel(mask, gc->reg_base + cur_regs(d)->mask); + irq_reg_writel(mask, gc->reg_base + cur_regs(d)->ack); + irq_gc_unlock(gc); +} + +/** + * irq_gc_eoi - EOI interrupt + * @d: irq_data + */ +void irq_gc_eoi(struct irq_data *d) +{ + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); + u32 mask = 1 << (d->irq - gc->irq_base); + + irq_gc_lock(gc); + irq_reg_writel(mask, gc->reg_base + cur_regs(d)->eoi); + irq_gc_unlock(gc); +} + +/** + * irq_gc_set_wake - Set/clr wake bit for an interrupt + * @d: irq_data + * + * For chips where the wake from suspend functionality is not + * configured in a separate register and the wakeup active state is + * just stored in a bitmask. + */ +int irq_gc_set_wake(struct irq_data *d, unsigned int on) +{ + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); + u32 mask = 1 << (d->irq - gc->irq_base); + + if (!(mask & gc->wake_enabled)) + return -EINVAL; + + irq_gc_lock(gc); + if (on) + gc->wake_active |= mask; + else + gc->wake_active &= ~mask; + irq_gc_unlock(gc); + return 0; +} + +/** + * irq_alloc_generic_chip - Allocate a generic chip and initialize it + * @name: Name of the irq chip + * @num_ct: Number of irq_chip_type instances associated with this + * @irq_base: Interrupt base nr for this chip + * @reg_base: Register base address (virtual) + * @handler: Default flow handler associated with this chip + * + * Returns an initialized irq_chip_generic structure. The chip defaults + * to the primary (index 0) irq_chip_type and @handler + */ +struct irq_chip_generic * +irq_alloc_generic_chip(const char *name, int num_ct, unsigned int irq_base, + void __iomem *reg_base, irq_flow_handler_t handler) +{ + struct irq_chip_generic *gc; + unsigned long sz = sizeof(*gc) + num_ct * sizeof(struct irq_chip_type); + + gc = kzalloc(sz, GFP_KERNEL); + if (gc) { + raw_spin_lock_init(&gc->lock); + gc->num_ct = num_ct; + gc->irq_base = irq_base; + gc->reg_base = reg_base; + gc->chip_types->chip.name = name; + gc->chip_types->handler = handler; + } + return gc; +} + +/* + * Separate lockdep class for interrupt chip which can nest irq_desc + * lock. + */ +static struct lock_class_key irq_nested_lock_class; + +/** + * irq_setup_generic_chip - Setup a range of interrupts with a generic chip + * @gc: Generic irq chip holding all data + * @msk: Bitmask holding the irqs to initialize relative to gc->irq_base + * @flags: Flags for initialization + * @clr: IRQ_* bits to clear + * @set: IRQ_* bits to set + * + * Set up max. 32 interrupts starting from gc->irq_base. Note, this + * initializes all interrupts to the primary irq_chip_type and its + * associated handler. + */ +void irq_setup_generic_chip(struct irq_chip_generic *gc, u32 msk, + enum irq_gc_flags flags, unsigned int clr, + unsigned int set) +{ + struct irq_chip_type *ct = gc->chip_types; + unsigned int i; + + /* Init mask cache ? */ + if (flags & IRQ_GC_INIT_MASK_CACHE) + gc->mask_cache = irq_reg_readl(gc->reg_base + ct->regs.mask); + + for (i = gc->irq_base; msk; msk >>= 1, i++) { + if (!msk & 0x01) + continue; + + if (flags & IRQ_GC_INIT_NESTED_LOCK) + irq_set_lockdep_class(i, &irq_nested_lock_class); + + irq_set_chip_and_handler(i, &ct->chip, ct->handler); + irq_set_chip_data(i, gc); + irq_modify_status(i, clr, set); + } + gc->irq_cnt = i - gc->irq_base; +} + +/** + * irq_setup_alt_chip - Switch to alternative chip + * @d: irq_data for this interrupt + * @type Flow type to be initialized + * + * Only to be called from chip->irq_set_type() callbacks. + */ +int irq_setup_alt_chip(struct irq_data *d, unsigned int type) +{ + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); + struct irq_chip_type *ct = gc->chip_types; + unsigned int i; + + for (i = 0; i < gc->num_ct; i++, ct++) { + if (ct->type & type) { + d->chip = &ct->chip; + irq_data_to_desc(d)->handle_irq = ct->handler; + return 0; + } + } + return -EINVAL; +} -- cgit From cfefd21e693dca791bf9ecfc9dd3794facad533c Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 15 Apr 2011 22:36:08 +0200 Subject: genirq: Add chip suspend and resume callbacks These callbacks are only called in the syscore suspend/resume code on interrupt chips which have been registered via the generic irq chip mechanism. Calling those callbacks per irq would be rather icky, but with the generic irq chip mechanism we can call this per registered chip. Signed-off-by: Thomas Gleixner Cc: linux-arm-kernel@lists.infradead.org --- include/linux/irq.h | 11 ++++++ kernel/irq/generic-chip.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+) (limited to 'include/linux') diff --git a/include/linux/irq.h b/include/linux/irq.h index 2ba2f1216790..8b4538446636 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -280,6 +280,9 @@ static inline void irqd_clr_chained_irq_inprogress(struct irq_data *d) * @irq_bus_sync_unlock:function to sync and unlock slow bus (i2c) chips * @irq_cpu_online: configure an interrupt source for a secondary CPU * @irq_cpu_offline: un-configure an interrupt source for a secondary CPU + * @irq_suspend: function called from core code on suspend once per chip + * @irq_resume: function called from core code on resume once per chip + * @irq_pm_shutdown: function called from core code on shutdown once per chip * @irq_print_chip: optional to print special chip info in show_interrupts * @flags: chip specific flags * @@ -309,6 +312,10 @@ struct irq_chip { void (*irq_cpu_online)(struct irq_data *data); void (*irq_cpu_offline)(struct irq_data *data); + void (*irq_suspend)(struct irq_data *data); + void (*irq_resume)(struct irq_data *data); + void (*irq_pm_shutdown)(struct irq_data *data); + void (*irq_print_chip)(struct irq_data *data, struct seq_file *p); unsigned long flags; @@ -626,6 +633,7 @@ struct irq_chip_type { * @wake_active: Interrupt is marked as an wakeup from suspend source * @num_ct: Number of available irq_chip_type instances (usually 1) * @private: Private data for non generic chip callbacks + * @list: List head for keeping track of instances * @chip_types: Array of interrupt irq_chip_types * * Note, that irq_chip_generic can have multiple irq_chip_type @@ -646,6 +654,7 @@ struct irq_chip_generic { u32 wake_active; unsigned int num_ct; void *private; + struct list_head list; struct irq_chip_type chip_types[0]; }; @@ -680,6 +689,8 @@ void irq_setup_generic_chip(struct irq_chip_generic *gc, u32 msk, enum irq_gc_flags flags, unsigned int clr, unsigned int set); int irq_setup_alt_chip(struct irq_data *d, unsigned int type); +void irq_remove_generic_chip(struct irq_chip_generic *gc, u32 msk, + unsigned int clr, unsigned int set); static inline struct irq_chip_type *irq_data_get_chip_type(struct irq_data *d) { diff --git a/kernel/irq/generic-chip.c b/kernel/irq/generic-chip.c index eb23e5924260..31a9db711906 100644 --- a/kernel/irq/generic-chip.c +++ b/kernel/irq/generic-chip.c @@ -8,9 +8,13 @@ #include #include #include +#include #include "internals.h" +static LIST_HEAD(gc_list); +static DEFINE_RAW_SPINLOCK(gc_lock); + static inline struct irq_chip_regs *cur_regs(struct irq_data *d) { return &container_of(d->chip, struct irq_chip_type, chip)->regs; @@ -219,6 +223,10 @@ void irq_setup_generic_chip(struct irq_chip_generic *gc, u32 msk, struct irq_chip_type *ct = gc->chip_types; unsigned int i; + raw_spin_lock(&gc_lock); + list_add_tail(&gc->list, &gc_list); + raw_spin_unlock(&gc_lock); + /* Init mask cache ? */ if (flags & IRQ_GC_INIT_MASK_CACHE) gc->mask_cache = irq_reg_readl(gc->reg_base + ct->regs.mask); @@ -259,3 +267,88 @@ int irq_setup_alt_chip(struct irq_data *d, unsigned int type) } return -EINVAL; } + +/** + * irq_remove_generic_chip - Remove a chip + * @gc: Generic irq chip holding all data + * @msk: Bitmask holding the irqs to initialize relative to gc->irq_base + * @clr: IRQ_* bits to clear + * @set: IRQ_* bits to set + * + * Remove up to 32 interrupts starting from gc->irq_base. + */ +void irq_remove_generic_chip(struct irq_chip_generic *gc, u32 msk, + unsigned int clr, unsigned int set) +{ + unsigned int i = gc->irq_base; + + raw_spin_lock(&gc_lock); + list_del(&gc->list); + raw_spin_unlock(&gc_lock); + + for (; msk; msk >>= 1, i++) { + if (!msk & 0x01) + continue; + + /* Remove handler first. That will mask the irq line */ + irq_set_handler(i, NULL); + irq_set_chip(i, &no_irq_chip); + irq_set_chip_data(i, NULL); + irq_modify_status(i, clr, set); + } +} + +#ifdef CONFIG_PM +static int irq_gc_suspend(void) +{ + struct irq_chip_generic *gc; + + list_for_each_entry(gc, &gc_list, list) { + struct irq_chip_type *ct = gc->chip_types; + + if (ct->chip.irq_suspend) + ct->chip.irq_suspend(irq_get_irq_data(gc->irq_base)); + } + return 0; +} + +static void irq_gc_resume(void) +{ + struct irq_chip_generic *gc; + + list_for_each_entry(gc, &gc_list, list) { + struct irq_chip_type *ct = gc->chip_types; + + if (ct->chip.irq_resume) + ct->chip.irq_resume(irq_get_irq_data(gc->irq_base)); + } +} +#else +#define irq_gc_suspend NULL +#define irq_gc_resume NULL +#endif + +static void irq_gc_shutdown(void) +{ + struct irq_chip_generic *gc; + + list_for_each_entry(gc, &gc_list, list) { + struct irq_chip_type *ct = gc->chip_types; + + if (ct->chip.irq_pm_shutdown) + ct->chip.irq_pm_shutdown(irq_get_irq_data(gc->irq_base)); + } +} + +static struct syscore_ops irq_gc_syscore_ops = { + .suspend = irq_gc_suspend, + .resume = irq_gc_resume, + .shutdown = irq_gc_shutdown, +}; + +static int __init irq_gc_init_ops(void) +{ + register_syscore_ops(&irq_gc_syscore_ops); + return 0; +} +device_initcall(irq_gc_init_ops); -- cgit From 625f2a378e5a10f45fdc37932fc9f8a21676de9e Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Fri, 22 Apr 2011 11:19:10 -0600 Subject: sched: Get rid of lock_depth Neil Brown pointed out that lock_depth somehow escaped the BKL removal work. Let's get rid of it now. Note that the perf scripting utilities still have a bunch of code for dealing with common_lock_depth in tracepoints; I have left that in place in case anybody wants to use that code with older kernels. Suggested-by: Neil Brown Signed-off-by: Jonathan Corbet Cc: Arnd Bergmann Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: Linus Torvalds Cc: Andrew Morton Link: http://lkml.kernel.org/r/20110422111910.456c0e84@bike.lwn.net Signed-off-by: Ingo Molnar --- Documentation/trace/kprobetrace.txt | 1 - include/linux/init_task.h | 1 - include/linux/sched.h | 6 ------ kernel/fork.c | 1 - kernel/mutex.c | 7 ------- kernel/sched.c | 11 +---------- kernel/sched_debug.c | 4 ---- kernel/trace/trace_kprobe.c | 1 - tools/perf/Documentation/perf-script-perl.txt | 1 - tools/perf/Documentation/perf-script-python.txt | 1 - 10 files changed, 1 insertion(+), 33 deletions(-) (limited to 'include/linux') diff --git a/Documentation/trace/kprobetrace.txt b/Documentation/trace/kprobetrace.txt index 6d27ab8d6e9f..c83bd6b4e6e8 100644 --- a/Documentation/trace/kprobetrace.txt +++ b/Documentation/trace/kprobetrace.txt @@ -120,7 +120,6 @@ format: field:unsigned char common_flags; offset:2; size:1; signed:0; field:unsigned char common_preempt_count; offset:3; size:1;signed:0; field:int common_pid; offset:4; size:4; signed:1; - field:int common_lock_depth; offset:8; size:4; signed:1; field:unsigned long __probe_ip; offset:12; size:4; signed:0; field:int __probe_nargs; offset:16; size:4; signed:1; diff --git a/include/linux/init_task.h b/include/linux/init_task.h index caa151fbebb7..689496bb6654 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h @@ -134,7 +134,6 @@ extern struct cred init_cred; .stack = &init_thread_info, \ .usage = ATOMIC_INIT(2), \ .flags = PF_KTHREAD, \ - .lock_depth = -1, \ .prio = MAX_PRIO-20, \ .static_prio = MAX_PRIO-20, \ .normal_prio = MAX_PRIO-20, \ diff --git a/include/linux/sched.h b/include/linux/sched.h index 171ba24b08a7..013314a56105 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -731,10 +731,6 @@ struct sched_info { /* timestamps */ unsigned long long last_arrival,/* when we last ran on a cpu */ last_queued; /* when we were last queued to run */ -#ifdef CONFIG_SCHEDSTATS - /* BKL stats */ - unsigned int bkl_count; -#endif }; #endif /* defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) */ @@ -1190,8 +1186,6 @@ struct task_struct { unsigned int flags; /* per process flags, defined below */ unsigned int ptrace; - int lock_depth; /* BKL lock depth */ - #ifdef CONFIG_SMP struct task_struct *wake_entry; int on_cpu; diff --git a/kernel/fork.c b/kernel/fork.c index e7548dee636b..aca62871a4f9 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1103,7 +1103,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, posix_cpu_timers_init(p); - p->lock_depth = -1; /* -1 = no lock */ do_posix_clock_monotonic_gettime(&p->start_time); p->real_start_time = p->start_time; monotonic_to_bootbased(&p->real_start_time); diff --git a/kernel/mutex.c b/kernel/mutex.c index fe4706cb0c5b..2c938e2337cd 100644 --- a/kernel/mutex.c +++ b/kernel/mutex.c @@ -162,13 +162,6 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, for (;;) { struct task_struct *owner; - /* - * If we own the BKL, then don't spin. The owner of - * the mutex might be waiting on us to release the BKL. - */ - if (unlikely(current->lock_depth >= 0)) - break; - /* * If there's an owner, wait for it to either * release the lock or go to sleep. diff --git a/kernel/sched.c b/kernel/sched.c index 8cb0a5769a16..9cde2dd229c9 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -4121,12 +4121,6 @@ static inline void schedule_debug(struct task_struct *prev) profile_hit(SCHED_PROFILING, __builtin_return_address(0)); schedstat_inc(this_rq(), sched_count); -#ifdef CONFIG_SCHEDSTATS - if (unlikely(prev->lock_depth >= 0)) { - schedstat_inc(this_rq(), rq_sched_info.bkl_count); - schedstat_inc(prev, sched_info.bkl_count); - } -#endif } static void put_prev_task(struct rq *rq, struct task_struct *prev) @@ -5852,11 +5846,8 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu) raw_spin_unlock_irqrestore(&rq->lock, flags); /* Set the preempt count _outside_ the spinlocks! */ -#if defined(CONFIG_PREEMPT) - task_thread_info(idle)->preempt_count = (idle->lock_depth >= 0); -#else task_thread_info(idle)->preempt_count = 0; -#endif + /* * The idle tasks have their own, simple scheduling class: */ diff --git a/kernel/sched_debug.c b/kernel/sched_debug.c index 3669bec6e130..a6710a112b4f 100644 --- a/kernel/sched_debug.c +++ b/kernel/sched_debug.c @@ -296,9 +296,6 @@ static void print_cpu(struct seq_file *m, int cpu) P(ttwu_count); P(ttwu_local); - SEQ_printf(m, " .%-30s: %d\n", "bkl_count", - rq->rq_sched_info.bkl_count); - #undef P #undef P64 #endif @@ -441,7 +438,6 @@ void proc_sched_show_task(struct task_struct *p, struct seq_file *m) P(se.statistics.wait_count); PN(se.statistics.iowait_sum); P(se.statistics.iowait_count); - P(sched_info.bkl_count); P(se.nr_migrations); P(se.statistics.nr_migrations_cold); P(se.statistics.nr_failed_migrations_affine); diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 35d55a386145..f925c45f0afa 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -53,7 +53,6 @@ const char *reserved_field_names[] = { "common_preempt_count", "common_pid", "common_tgid", - "common_lock_depth", FIELD_STRING_IP, FIELD_STRING_RETIP, FIELD_STRING_FUNC, diff --git a/tools/perf/Documentation/perf-script-perl.txt b/tools/perf/Documentation/perf-script-perl.txt index 5bb41e55a3ac..3152cca15501 100644 --- a/tools/perf/Documentation/perf-script-perl.txt +++ b/tools/perf/Documentation/perf-script-perl.txt @@ -63,7 +63,6 @@ The format file for the sched_wakep event defines the following fields field:unsigned char common_flags; field:unsigned char common_preempt_count; field:int common_pid; - field:int common_lock_depth; field:char comm[TASK_COMM_LEN]; field:pid_t pid; diff --git a/tools/perf/Documentation/perf-script-python.txt b/tools/perf/Documentation/perf-script-python.txt index 36b38277422c..471022069119 100644 --- a/tools/perf/Documentation/perf-script-python.txt +++ b/tools/perf/Documentation/perf-script-python.txt @@ -463,7 +463,6 @@ The format file for the sched_wakep event defines the following fields field:unsigned char common_flags; field:unsigned char common_preempt_count; field:int common_pid; - field:int common_lock_depth; field:char comm[TASK_COMM_LEN]; field:pid_t pid; -- cgit From dea3667bc3c2a0521e8d8855e407a49d9d70028c Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 24 Apr 2011 07:58:46 -0700 Subject: vfs: get rid of insane dentry hashing rules The dentry hashing rules have been really quite complicated for a long while, in odd ways. That made functions like __d_drop() very fragile and non-obvious. In particular, whether a dentry was hashed or not was indicated with an explicit DCACHE_UNHASHED bit. That's despite the fact that the hash abstraction that the dentries use actually have a 'is this entry hashed or not' model (which is a simple test of the 'pprev' pointer). The reason that was done is because we used the normal 'is this entry unhashed' model to mark whether the dentry had _ever_ been hashed in the dentry hash tables, and that logic goes back many years (commit b3423415fbc2: "dcache: avoid RCU for never-hashed dentries"). That, in turn, meant that __d_drop had totally different unhashing logic for the dentry hash table case and for the anonymous dcache case, because in order to use the "is this dentry hashed" logic as a flag for whether it had ever been on the RCU hash table, we had to unhash such a dentry differently so that we'd never think that it wasn't 'unhashed' and wouldn't be free'd correctly. That's just insane. It made the logic really hard to follow, when there were two different kinds of "unhashed" states, and one of them (the one that used "list_bl_unhashed()") really had nothing at all to do with being unhashed per se, but with a very subtle lifetime rule instead. So turn all of it around, and make it logical. Instead of having a DENTRY_UNHASHED bit in d_flags to indicate whether the dentry is on the hash chains or not, use the hash chain unhashed logic for that. Suddenly "d_unhashed()" just uses "list_bl_unhashed()", and everything makes sense. And for the lifetime rule, just use an explicit DENTRY_RCUACCEES bit. If we ever insert the dentry into the dentry hash table so that it is visible to RCU lookup, we mark it DENTRY_RCUACCESS to show that it now needs the RCU lifetime rules. Now suddently that test at dentry free time makes sense too. And because unhashing now is sane and doesn't depend on where the dentry got unhashed from (because the dentry hash chain details doesn't have some subtle side effects), we can re-unify the __d_drop() logic and use common code for the unhashing. Also fix one more open-coded hash chain bit_spin_lock() that I missed in the previous chain locking cleanup commit. Signed-off-by: Linus Torvalds --- fs/dcache.c | 42 ++++++++++++++++-------------------------- include/linux/dcache.h | 4 ++-- 2 files changed, 18 insertions(+), 28 deletions(-) (limited to 'include/linux') diff --git a/fs/dcache.c b/fs/dcache.c index 7108c15685dd..d600a0af3b2e 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -164,8 +164,8 @@ static void d_free(struct dentry *dentry) if (dentry->d_op && dentry->d_op->d_release) dentry->d_op->d_release(dentry); - /* if dentry was never inserted into hash, immediate free is OK */ - if (hlist_bl_unhashed(&dentry->d_hash)) + /* if dentry was never visible to RCU, immediate free is OK */ + if (!(dentry->d_flags & DCACHE_RCUACCESS)) __d_free(&dentry->d_u.d_rcu); else call_rcu(&dentry->d_u.d_rcu, __d_free); @@ -327,28 +327,19 @@ static struct dentry *d_kill(struct dentry *dentry, struct dentry *parent) */ void __d_drop(struct dentry *dentry) { - if (!(dentry->d_flags & DCACHE_UNHASHED)) { + if (!d_unhashed(dentry)) { struct hlist_bl_head *b; - if (unlikely(dentry->d_flags & DCACHE_DISCONNECTED)) { + if (unlikely(dentry->d_flags & DCACHE_DISCONNECTED)) b = &dentry->d_sb->s_anon; - spin_lock_bucket(b); - dentry->d_flags |= DCACHE_UNHASHED; - hlist_bl_del_init(&dentry->d_hash); - spin_unlock_bucket(b); - } else { - struct hlist_bl_head *b; + else b = d_hash(dentry->d_parent, dentry->d_name.hash); - spin_lock_bucket(b); - /* - * We may not actually need to put DCACHE_UNHASHED - * manipulations under the hash lock, but follow - * the principle of least surprise. - */ - dentry->d_flags |= DCACHE_UNHASHED; - hlist_bl_del_rcu(&dentry->d_hash); - spin_unlock_bucket(b); - dentry_rcuwalk_barrier(dentry); - } + + spin_lock_bucket(b); + __hlist_bl_del(&dentry->d_hash); + dentry->d_hash.pprev = NULL; + spin_unlock_bucket(b); + + dentry_rcuwalk_barrier(dentry); } } EXPORT_SYMBOL(__d_drop); @@ -1301,7 +1292,7 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name) dname[name->len] = 0; dentry->d_count = 1; - dentry->d_flags = DCACHE_UNHASHED; + dentry->d_flags = 0; spin_lock_init(&dentry->d_lock); seqcount_init(&dentry->d_seq); dentry->d_inode = NULL; @@ -1603,10 +1594,9 @@ struct dentry *d_obtain_alias(struct inode *inode) tmp->d_inode = inode; tmp->d_flags |= DCACHE_DISCONNECTED; list_add(&tmp->d_alias, &inode->i_dentry); - bit_spin_lock(0, (unsigned long *)&tmp->d_sb->s_anon.first); - tmp->d_flags &= ~DCACHE_UNHASHED; + spin_lock_bucket(&tmp->d_sb->s_anon); hlist_bl_add_head(&tmp->d_hash, &tmp->d_sb->s_anon); - __bit_spin_unlock(0, (unsigned long *)&tmp->d_sb->s_anon.first); + spin_unlock_bucket(&tmp->d_sb->s_anon); spin_unlock(&tmp->d_lock); spin_unlock(&inode->i_lock); security_d_instantiate(tmp, inode); @@ -2087,7 +2077,7 @@ static void __d_rehash(struct dentry * entry, struct hlist_bl_head *b) { BUG_ON(!d_unhashed(entry)); spin_lock_bucket(b); - entry->d_flags &= ~DCACHE_UNHASHED; + entry->d_flags |= DCACHE_RCUACCESS; hlist_bl_add_head_rcu(&entry->d_hash, b); spin_unlock_bucket(b); } diff --git a/include/linux/dcache.h b/include/linux/dcache.h index f2afed4fa945..19d90a55541d 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -197,7 +197,7 @@ struct dentry_operations { * typically using d_splice_alias. */ #define DCACHE_REFERENCED 0x0008 /* Recently used, don't discard. */ -#define DCACHE_UNHASHED 0x0010 +#define DCACHE_RCUACCESS 0x0010 /* Entry has ever been RCU-visible */ #define DCACHE_INOTIFY_PARENT_WATCHED 0x0020 /* Parent inode is watched by inotify */ @@ -384,7 +384,7 @@ extern struct dentry *dget_parent(struct dentry *dentry); static inline int d_unhashed(struct dentry *dentry) { - return (dentry->d_flags & DCACHE_UNHASHED); + return hlist_bl_unhashed(&dentry->d_hash); } static inline int d_unlinked(struct dentry *dentry) -- cgit From 3f7ac1d6671ebca7a955853f7127c937f7befbd3 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 16 Mar 2011 11:14:25 +0100 Subject: libata: Kill unused ATA_DFLAG_{H|D}IPM flags ATA_DFLAG_{H|D}IPM flags are no longer used. Kill them. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 7f675aa81d87..3b4d223a6aff 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -137,8 +137,6 @@ enum { ATA_DFLAG_ACPI_PENDING = (1 << 5), /* ACPI resume action pending */ ATA_DFLAG_ACPI_FAILED = (1 << 6), /* ACPI on devcfg has failed */ ATA_DFLAG_AN = (1 << 7), /* AN configured */ - ATA_DFLAG_HIPM = (1 << 8), /* device supports HIPM */ - ATA_DFLAG_DIPM = (1 << 9), /* device supports DIPM */ ATA_DFLAG_DMADIR = (1 << 10), /* device requires DMADIR */ ATA_DFLAG_CFG_MASK = (1 << 12) - 1, -- cgit From ae01b2493c3bf03c504c32ac4ebb01d528508db3 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 16 Mar 2011 11:14:55 +0100 Subject: libata: Implement ATA_FLAG_NO_DIPM and apply it to mcp65 NVIDIA mcp65 familiy of controllers cause command timeouts when DIPM is used. Implement ATA_FLAG_NO_DIPM and apply it. This problem was reported by Stefan Bader in the following thread. http://thread.gmane.org/gmane.linux.ide/48841 stable: applicable to 2.6.37 and 38. Signed-off-by: Tejun Heo Reported-by: Stefan Bader Cc: stable@kernel.org Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 2 +- drivers/ata/libata-eh.c | 6 ++++-- include/linux/libata.h | 1 + 3 files changed, 6 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 39d829cd82dd..cbd38e130f05 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -150,7 +150,7 @@ static const struct ata_port_info ahci_port_info[] = { { AHCI_HFLAGS (AHCI_HFLAG_NO_FPDMA_AA | AHCI_HFLAG_NO_PMP | AHCI_HFLAG_YES_NCQ), - .flags = AHCI_FLAG_COMMON, + .flags = AHCI_FLAG_COMMON | ATA_FLAG_NO_DIPM, .pio_mask = ATA_PIO4, .udma_mask = ATA_UDMA6, .port_ops = &ahci_ops, diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 88cd22fa65cd..f26f2fe3480a 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -3316,6 +3316,7 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, struct ata_eh_context *ehc = &link->eh_context; struct ata_device *dev, *link_dev = NULL, *lpm_dev = NULL; enum ata_lpm_policy old_policy = link->lpm_policy; + bool no_dipm = ap->flags & ATA_FLAG_NO_DIPM; unsigned int hints = ATA_LPM_EMPTY | ATA_LPM_HIPM; unsigned int err_mask; int rc; @@ -3332,7 +3333,7 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, */ ata_for_each_dev(dev, link, ENABLED) { bool hipm = ata_id_has_hipm(dev->id); - bool dipm = ata_id_has_dipm(dev->id); + bool dipm = ata_id_has_dipm(dev->id) && !no_dipm; /* find the first enabled and LPM enabled devices */ if (!link_dev) @@ -3389,7 +3390,8 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, /* host config updated, enable DIPM if transitioning to MIN_POWER */ ata_for_each_dev(dev, link, ENABLED) { - if (policy == ATA_LPM_MIN_POWER && ata_id_has_dipm(dev->id)) { + if (policy == ATA_LPM_MIN_POWER && !no_dipm && + ata_id_has_dipm(dev->id)) { err_mask = ata_dev_set_feature(dev, SETFEATURES_SATA_ENABLE, SATA_DIPM); if (err_mask && err_mask != AC_ERR_DEV) { diff --git a/include/linux/libata.h b/include/linux/libata.h index 3b4d223a6aff..04f32a3eb26b 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -196,6 +196,7 @@ enum { * management */ ATA_FLAG_SW_ACTIVITY = (1 << 22), /* driver supports sw activity * led */ + ATA_FLAG_NO_DIPM = (1 << 23), /* host not happy with DIPM */ /* bits 24:31 of ap->flags are reserved for LLD specific flags */ -- cgit From fd954ae124e8a866e9cc1bc3de9a07be5492f608 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sun, 24 Apr 2011 14:28:18 -0400 Subject: NFSv4.1: Don't loop forever in nfs4_proc_create_session If a server for some reason keeps sending NFS4ERR_DELAY errors, we can end up looping forever inside nfs4_proc_create_session, and so the usual mechanisms for detecting if the nfs_client is dead don't work. Fix this by ensuring that we loop inside the nfs4_state_manager thread instead. Signed-off-by: Trond Myklebust --- fs/nfs/nfs4_fs.h | 1 + fs/nfs/nfs4proc.c | 45 +++++++-------------------------------------- fs/nfs/nfs4state.c | 46 +++++++++++++++++++++++++++++++--------------- include/linux/nfs_fs_sb.h | 1 + 4 files changed, 40 insertions(+), 53 deletions(-) (limited to 'include/linux') diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index e1c261ddd65d..c4a69833dd0d 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h @@ -47,6 +47,7 @@ enum nfs4_client_state { NFS4CLNT_LAYOUTRECALL, NFS4CLNT_SESSION_RESET, NFS4CLNT_RECALL_SLOT, + NFS4CLNT_LEASE_CONFIRM, }; enum nfs4_session_state { diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 628e35f75307..50c814828fcb 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -3754,18 +3754,17 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, status = rpc_call_sync(clp->cl_rpcclient, &msg, 0); if (status != -NFS4ERR_CLID_INUSE) break; - if (signalled()) + if (loop != 0) { + ++clp->cl_id_uniquifier; break; - if (loop++ & 1) - ssleep(clp->cl_lease_time / HZ + 1); - else - if (++clp->cl_id_uniquifier == 0) - break; + } + ++loop; + ssleep(clp->cl_lease_time / HZ + 1); } return status; } -static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp, +int nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct nfs4_setclientid_res *arg, struct rpc_cred *cred) { @@ -3790,26 +3789,6 @@ static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp, return status; } -int nfs4_proc_setclientid_confirm(struct nfs_client *clp, - struct nfs4_setclientid_res *arg, - struct rpc_cred *cred) -{ - long timeout = 0; - int err; - do { - err = _nfs4_proc_setclientid_confirm(clp, arg, cred); - switch (err) { - case 0: - return err; - case -NFS4ERR_RESOURCE: - /* The IBM lawyers misread another document! */ - case -NFS4ERR_DELAY: - err = nfs4_delay(clp->cl_rpcclient, &timeout); - } - } while (err == 0); - return err; -} - struct nfs4_delegreturndata { struct nfs4_delegreturnargs args; struct nfs4_delegreturnres res; @@ -5222,20 +5201,10 @@ int nfs4_proc_create_session(struct nfs_client *clp) int status; unsigned *ptr; struct nfs4_session *session = clp->cl_session; - long timeout = 0; - int err; dprintk("--> %s clp=%p session=%p\n", __func__, clp, session); - do { - status = _nfs4_proc_create_session(clp); - if (status == -NFS4ERR_DELAY) { - err = nfs4_delay(clp->cl_rpcclient, &timeout); - if (err) - status = err; - } - } while (status == -NFS4ERR_DELAY); - + status = _nfs4_proc_create_session(clp); if (status) goto out; diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 4dfb34b43ffb..4a810c8b0753 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -64,10 +64,15 @@ static LIST_HEAD(nfs4_clientid_list); int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred) { - struct nfs4_setclientid_res clid; + struct nfs4_setclientid_res clid = { + .clientid = clp->cl_clientid, + .confirm = clp->cl_confirm, + }; unsigned short port; int status; + if (test_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state)) + goto do_confirm; port = nfs_callback_tcpport; if (clp->cl_addr.ss_family == AF_INET6) port = nfs_callback_tcpport6; @@ -75,10 +80,14 @@ int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred) status = nfs4_proc_setclientid(clp, NFS4_CALLBACK, port, cred, &clid); if (status != 0) goto out; + clp->cl_clientid = clid.clientid; + clp->cl_confirm = clid.confirm; + set_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state); +do_confirm: status = nfs4_proc_setclientid_confirm(clp, &clid, cred); if (status != 0) goto out; - clp->cl_clientid = clid.clientid; + clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state); nfs4_schedule_state_renewal(clp); out: return status; @@ -230,13 +239,18 @@ int nfs41_init_clientid(struct nfs_client *clp, struct rpc_cred *cred) { int status; + if (test_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state)) + goto do_confirm; nfs4_begin_drain_session(clp); status = nfs4_proc_exchange_id(clp, cred); if (status != 0) goto out; + set_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state); +do_confirm: status = nfs4_proc_create_session(clp); if (status != 0) goto out; + clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state); nfs41_setup_state_renewal(clp); nfs_mark_client_ready(clp, NFS_CS_READY); out: @@ -1584,20 +1598,22 @@ static int nfs4_recall_slot(struct nfs_client *clp) { return 0; } */ static void nfs4_set_lease_expired(struct nfs_client *clp, int status) { - if (nfs4_has_session(clp)) { - switch (status) { - case -NFS4ERR_DELAY: - case -NFS4ERR_CLID_INUSE: - case -EAGAIN: - break; + switch (status) { + case -NFS4ERR_CLID_INUSE: + case -NFS4ERR_STALE_CLIENTID: + clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state); + break; + case -NFS4ERR_DELAY: + case -EAGAIN: + ssleep(1); + break; - case -EKEYEXPIRED: - nfs4_warn_keyexpired(clp->cl_hostname); - case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery - * in nfs4_exchange_id */ - default: - return; - } + case -EKEYEXPIRED: + nfs4_warn_keyexpired(clp->cl_hostname); + case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery + * in nfs4_exchange_id */ + default: + return; } set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); } diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 216cea5db0aa..87694ca86914 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -47,6 +47,7 @@ struct nfs_client { #ifdef CONFIG_NFS_V4 u64 cl_clientid; /* constant */ + nfs4_verifier cl_confirm; /* Clientid verifier */ unsigned long cl_state; spinlock_t cl_lock; -- cgit From 7494d00c7b826b6ceb79ec33892bd0ef59be5614 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sun, 24 Apr 2011 14:28:45 -0400 Subject: SUNRPC: Allow RPC calls to return ETIMEDOUT instead of EIO On occasion, it is useful for the NFS layer to distinguish between soft timeouts and other EIO errors due to (say) encoding errors, or authentication errors. The following patch ensures that the default behaviour of the RPC layer remains to return EIO on soft timeouts (until we have audited all the callers). Signed-off-by: Trond Myklebust --- include/linux/sunrpc/sched.h | 3 ++- net/sunrpc/clnt.c | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h index 3b94f804b852..f73c482ec9c6 100644 --- a/include/linux/sunrpc/sched.h +++ b/include/linux/sunrpc/sched.h @@ -128,12 +128,13 @@ struct rpc_task_setup { #define RPC_TASK_SOFT 0x0200 /* Use soft timeouts */ #define RPC_TASK_SOFTCONN 0x0400 /* Fail if can't connect */ #define RPC_TASK_SENT 0x0800 /* message was sent */ +#define RPC_TASK_TIMEOUT 0x1000 /* fail with ETIMEDOUT on timeout */ #define RPC_IS_ASYNC(t) ((t)->tk_flags & RPC_TASK_ASYNC) #define RPC_IS_SWAPPER(t) ((t)->tk_flags & RPC_TASK_SWAPPER) #define RPC_DO_ROOTOVERRIDE(t) ((t)->tk_flags & RPC_TASK_ROOTCREDS) #define RPC_ASSASSINATED(t) ((t)->tk_flags & RPC_TASK_KILLED) -#define RPC_IS_SOFT(t) ((t)->tk_flags & RPC_TASK_SOFT) +#define RPC_IS_SOFT(t) ((t)->tk_flags & (RPC_TASK_SOFT|RPC_TASK_TIMEOUT)) #define RPC_IS_SOFTCONN(t) ((t)->tk_flags & RPC_TASK_SOFTCONN) #define RPC_WAS_SENT(t) ((t)->tk_flags & RPC_TASK_SENT) diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index e7a96e478f63..8d83f9d48713 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -1508,7 +1508,10 @@ call_timeout(struct rpc_task *task) if (clnt->cl_chatty) printk(KERN_NOTICE "%s: server %s not responding, timed out\n", clnt->cl_protname, clnt->cl_server); - rpc_exit(task, -EIO); + if (task->tk_flags & RPC_TASK_TIMEOUT) + rpc_exit(task, -ETIMEDOUT); + else + rpc_exit(task, -EIO); return; } -- cgit From 1c9904297451f558191e211a48d8838b4bf792b0 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 21 Apr 2011 17:23:19 -0700 Subject: SECURITY: Move exec_permission RCU checks into security modules Right now all RCU walks fall back to reference walk when CONFIG_SECURITY is enabled, even though just the standard capability module is active. This is because security_inode_exec_permission unconditionally fails RCU walks. Move this decision to the low level security module. This requires passing the RCU flags down the security hook. This way at least the capability module and a few easy cases in selinux/smack work with RCU walks with CONFIG_SECURITY=y Signed-off-by: Andi Kleen Signed-off-by: Eric Paris --- include/linux/security.h | 2 +- security/capability.c | 2 +- security/security.c | 6 ++---- security/selinux/hooks.c | 6 +++++- security/smack/smack_lsm.c | 6 +++++- 5 files changed, 14 insertions(+), 8 deletions(-) (limited to 'include/linux') diff --git a/include/linux/security.h b/include/linux/security.h index 84a202ac3de9..2f99ecd0fb2a 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -1454,7 +1454,7 @@ struct security_operations { struct inode *new_dir, struct dentry *new_dentry); int (*inode_readlink) (struct dentry *dentry); int (*inode_follow_link) (struct dentry *dentry, struct nameidata *nd); - int (*inode_permission) (struct inode *inode, int mask); + int (*inode_permission) (struct inode *inode, int mask, unsigned flags); int (*inode_setattr) (struct dentry *dentry, struct iattr *attr); int (*inode_getattr) (struct vfsmount *mnt, struct dentry *dentry); int (*inode_setxattr) (struct dentry *dentry, const char *name, diff --git a/security/capability.c b/security/capability.c index ab3d807accc3..56bb1605fd79 100644 --- a/security/capability.c +++ b/security/capability.c @@ -181,7 +181,7 @@ static int cap_inode_follow_link(struct dentry *dentry, return 0; } -static int cap_inode_permission(struct inode *inode, int mask) +static int cap_inode_permission(struct inode *inode, int mask, unsigned flags) { return 0; } diff --git a/security/security.c b/security/security.c index 47b8a447118f..7e34f98bf433 100644 --- a/security/security.c +++ b/security/security.c @@ -514,16 +514,14 @@ int security_inode_permission(struct inode *inode, int mask) { if (unlikely(IS_PRIVATE(inode))) return 0; - return security_ops->inode_permission(inode, mask); + return security_ops->inode_permission(inode, mask, 0); } int security_inode_exec_permission(struct inode *inode, unsigned int flags) { if (unlikely(IS_PRIVATE(inode))) return 0; - if (flags) - return -ECHILD; - return security_ops->inode_permission(inode, MAY_EXEC); + return security_ops->inode_permission(inode, MAY_EXEC, flags); } int security_inode_setattr(struct dentry *dentry, struct iattr *attr) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 7a630a8a5cef..9a220be17a3f 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2635,7 +2635,7 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *na return dentry_has_perm(cred, NULL, dentry, FILE__READ); } -static int selinux_inode_permission(struct inode *inode, int mask) +static int selinux_inode_permission(struct inode *inode, int mask, unsigned flags) { const struct cred *cred = current_cred(); struct common_audit_data ad; @@ -2649,6 +2649,10 @@ static int selinux_inode_permission(struct inode *inode, int mask) if (!mask) return 0; + /* May be droppable after audit */ + if (flags & IPERM_FLAG_RCU) + return -ECHILD; + COMMON_AUDIT_DATA_INIT(&ad, FS); ad.u.fs.inode = inode; diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 23c7a6d0c80c..42fcb47747a3 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -686,7 +686,7 @@ static int smack_inode_rename(struct inode *old_inode, * * Returns 0 if access is permitted, -EACCES otherwise */ -static int smack_inode_permission(struct inode *inode, int mask) +static int smack_inode_permission(struct inode *inode, int mask, unsigned flags) { struct smk_audit_info ad; @@ -696,6 +696,10 @@ static int smack_inode_permission(struct inode *inode, int mask) */ if (mask == 0) return 0; + + /* May be droppable after audit */ + if (flags & IPERM_FLAG_RCU) + return -ECHILD; smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); smk_ad_setfield_u_fs_inode(&ad, inode); return smk_curacc(smk_of_inode(inode), mask, &ad); -- cgit From bf26c018490c2fce7fe9b629083b96ce0e6ad019 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Thu, 7 Apr 2011 16:53:20 +0200 Subject: ptrace: Prepare to fix racy accesses on task breakpoints When a task is traced and is in a stopped state, the tracer may execute a ptrace request to examine the tracee state and get its task struct. Right after, the tracee can be killed and thus its breakpoints released. This can happen concurrently when the tracer is in the middle of reading or modifying these breakpoints, leading to dereferencing a freed pointer. Hence, to prepare the fix, create a generic breakpoint reference holding API. When a reference on the breakpoints of a task is held, the breakpoints won't be released until the last reference is dropped. After that, no more ptrace request on the task's breakpoints can be serviced for the tracer. Reported-by: Oleg Nesterov Signed-off-by: Frederic Weisbecker Cc: Ingo Molnar Cc: Peter Zijlstra Cc: Will Deacon Cc: Prasad Cc: Paul Mundt Cc: v2.6.33.. Link: http://lkml.kernel.org/r/1302284067-7860-2-git-send-email-fweisbec@gmail.com --- include/linux/ptrace.h | 13 ++++++++++++- include/linux/sched.h | 3 +++ kernel/exit.c | 2 +- kernel/ptrace.c | 17 +++++++++++++++++ 4 files changed, 33 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h index a1147e5dd245..9178d5cc0b01 100644 --- a/include/linux/ptrace.h +++ b/include/linux/ptrace.h @@ -189,6 +189,10 @@ static inline void ptrace_init_task(struct task_struct *child, bool ptrace) child->ptrace = current->ptrace; __ptrace_link(child, current->parent); } + +#ifdef CONFIG_HAVE_HW_BREAKPOINT + atomic_set(&child->ptrace_bp_refcnt, 1); +#endif } /** @@ -350,6 +354,13 @@ extern int task_current_syscall(struct task_struct *target, long *callno, unsigned long args[6], unsigned int maxargs, unsigned long *sp, unsigned long *pc); -#endif +#ifdef CONFIG_HAVE_HW_BREAKPOINT +extern int ptrace_get_breakpoints(struct task_struct *tsk); +extern void ptrace_put_breakpoints(struct task_struct *tsk); +#else +static inline void ptrace_put_breakpoints(struct task_struct *tsk) { } +#endif /* CONFIG_HAVE_HW_BREAKPOINT */ + +#endif /* __KERNEL */ #endif diff --git a/include/linux/sched.h b/include/linux/sched.h index 18d63cea2848..781abd137673 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1537,6 +1537,9 @@ struct task_struct { unsigned long memsw_nr_pages; /* uncharged mem+swap usage */ } memcg_batch; #endif +#ifdef CONFIG_HAVE_HW_BREAKPOINT + atomic_t ptrace_bp_refcnt; +#endif }; /* Future-safe accessor for struct task_struct's cpus_allowed. */ diff --git a/kernel/exit.c b/kernel/exit.c index f5d2f63bae0b..8dd874181542 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -1016,7 +1016,7 @@ NORET_TYPE void do_exit(long code) /* * FIXME: do that only when needed, using sched_exit tracepoint */ - flush_ptrace_hw_breakpoint(tsk); + ptrace_put_breakpoints(tsk); exit_notify(tsk, group_dead); #ifdef CONFIG_NUMA diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 0fc1eed28d27..dc7ab65f3b36 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -22,6 +22,7 @@ #include #include #include +#include /* @@ -879,3 +880,19 @@ asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid, return ret; } #endif /* CONFIG_COMPAT */ + +#ifdef CONFIG_HAVE_HW_BREAKPOINT +int ptrace_get_breakpoints(struct task_struct *tsk) +{ + if (atomic_inc_not_zero(&tsk->ptrace_bp_refcnt)) + return 0; + + return -1; +} + +void ptrace_put_breakpoints(struct task_struct *tsk) +{ + if (atomic_dec_and_test(&tsk->ptrace_bp_refcnt)) + flush_ptrace_hw_breakpoint(tsk); +} +#endif /* CONFIG_HAVE_HW_BREAKPOINT */ -- cgit From f2f5f2a1cedc803a5a517557d436e6cb10c007de Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Tue, 19 Apr 2011 19:29:01 +0530 Subject: ath9k_hw: Get AHB clock information from ath9k_platform_data Add a bool in ath9k_platform_data to pass AHB clock speed information. Driver needs this to configure PLL on some SOCs. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.h | 2 ++ drivers/net/wireless/ath/ath9k/init.c | 1 + include/linux/ath9k_platform.h | 2 ++ 3 files changed, 5 insertions(+) (limited to 'include/linux') diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 450b64263bc9..5a4ba09a2f1c 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -846,6 +846,8 @@ struct ath_hw { /* Enterprise mode cap */ u32 ent_mode; + + bool is_clk_25mhz; }; struct ath_bus_ops { diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 1ac8318d82a3..e78b6aefa108 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -574,6 +574,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, sc->sc_ah->gpio_mask = pdata->gpio_mask; sc->sc_ah->gpio_val = pdata->gpio_val; sc->sc_ah->led_pin = pdata->led_pin; + ah->is_clk_25mhz = pdata->is_clk_25mhz; } common = ath9k_hw_common(ah); diff --git a/include/linux/ath9k_platform.h b/include/linux/ath9k_platform.h index 020387a114e3..60a7c49dcb49 100644 --- a/include/linux/ath9k_platform.h +++ b/include/linux/ath9k_platform.h @@ -28,6 +28,8 @@ struct ath9k_platform_data { int led_pin; u32 gpio_mask; u32 gpio_val; + + bool is_clk_25mhz; }; #endif /* _LINUX_ATH9K_PLATFORM_H */ -- cgit From 9f2e731d1d278d853def1567735d8a823668a3c8 Mon Sep 17 00:00:00 2001 From: RafaÅ‚ MiÅ‚ecki Date: Wed, 20 Apr 2011 11:12:30 +0200 Subject: ssb: cc: add & fix defines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We probably got false positive results for checking PLL being down. Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- include/linux/ssb/ssb_driver_chipcommon.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ssb/ssb_driver_chipcommon.h b/include/linux/ssb/ssb_driver_chipcommon.h index 2cdf249b4e5f..4f2d77a0c021 100644 --- a/include/linux/ssb/ssb_driver_chipcommon.h +++ b/include/linux/ssb/ssb_driver_chipcommon.h @@ -131,6 +131,9 @@ #define SSB_CHIPCO_GPIOIRQ 0x0074 #define SSB_CHIPCO_WATCHDOG 0x0080 #define SSB_CHIPCO_GPIOTIMER 0x0088 /* LED powersave (corerev >= 16) */ +#define SSB_CHIPCO_GPIOTIMER_OFFTIME 0x0000FFFF +#define SSB_CHIPCO_GPIOTIMER_OFFTIME_SHIFT 0 +#define SSB_CHIPCO_GPIOTIMER_ONTIME 0xFFFF0000 #define SSB_CHIPCO_GPIOTIMER_ONTIME_SHIFT 16 #define SSB_CHIPCO_GPIOTOUTM 0x008C /* LED powersave (corerev >= 16) */ #define SSB_CHIPCO_CLOCK_N 0x0090 @@ -189,8 +192,10 @@ #define SSB_CHIPCO_CLKCTLST_HAVEALPREQ 0x00000008 /* ALP available request */ #define SSB_CHIPCO_CLKCTLST_HAVEHTREQ 0x00000010 /* HT available request */ #define SSB_CHIPCO_CLKCTLST_HWCROFF 0x00000020 /* Force HW clock request off */ -#define SSB_CHIPCO_CLKCTLST_HAVEHT 0x00010000 /* HT available */ -#define SSB_CHIPCO_CLKCTLST_HAVEALP 0x00020000 /* APL available */ +#define SSB_CHIPCO_CLKCTLST_HAVEALP 0x00010000 /* ALP available */ +#define SSB_CHIPCO_CLKCTLST_HAVEHT 0x00020000 /* HT available */ +#define SSB_CHIPCO_CLKCTLST_4328A0_HAVEHT 0x00010000 /* 4328a0 has reversed bits */ +#define SSB_CHIPCO_CLKCTLST_4328A0_HAVEALP 0x00020000 /* 4328a0 has reversed bits */ #define SSB_CHIPCO_HW_WORKAROUND 0x01E4 /* Hardware workaround (rev >= 20) */ #define SSB_CHIPCO_UART0_DATA 0x0300 #define SSB_CHIPCO_UART0_IMR 0x0304 -- cgit From 9835a30e980561082beb02ce724f6e555787bc19 Mon Sep 17 00:00:00 2001 From: RafaÅ‚ MiÅ‚ecki Date: Sun, 24 Apr 2011 11:04:19 +0200 Subject: ssb: cc: clear GPIOPULL registers on init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/ssb/driver_chipcommon.c | 6 ++++++ include/linux/ssb/ssb_driver_chipcommon.h | 2 ++ 2 files changed, 8 insertions(+) (limited to 'include/linux') diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c index 7c031fdc8205..b4b3733aefcf 100644 --- a/drivers/ssb/driver_chipcommon.c +++ b/drivers/ssb/driver_chipcommon.c @@ -260,6 +260,12 @@ void ssb_chipcommon_init(struct ssb_chipcommon *cc) if (cc->dev->id.revision >= 11) cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT); ssb_dprintk(KERN_INFO PFX "chipcommon status is 0x%x\n", cc->status); + + if (cc->dev->id.revision >= 20) { + chipco_write32(cc, SSB_CHIPCO_GPIOPULLUP, 0); + chipco_write32(cc, SSB_CHIPCO_GPIOPULLDOWN, 0); + } + ssb_pmu_init(cc); chipco_powercontrol_init(cc); ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST); diff --git a/include/linux/ssb/ssb_driver_chipcommon.h b/include/linux/ssb/ssb_driver_chipcommon.h index 4f2d77a0c021..a08d693d8324 100644 --- a/include/linux/ssb/ssb_driver_chipcommon.h +++ b/include/linux/ssb/ssb_driver_chipcommon.h @@ -123,6 +123,8 @@ #define SSB_CHIPCO_FLASHDATA 0x0048 #define SSB_CHIPCO_BCAST_ADDR 0x0050 #define SSB_CHIPCO_BCAST_DATA 0x0054 +#define SSB_CHIPCO_GPIOPULLUP 0x0058 /* Rev >= 20 only */ +#define SSB_CHIPCO_GPIOPULLDOWN 0x005C /* Rev >= 20 only */ #define SSB_CHIPCO_GPIOIN 0x0060 #define SSB_CHIPCO_GPIOOUT 0x0064 #define SSB_CHIPCO_GPIOOUTEN 0x0068 -- cgit From f48b7399840b453e7282b523f535561fe9638a2d Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Mon, 25 Apr 2011 12:54:27 -0400 Subject: LSM: split LSM_AUDIT_DATA_FS into _PATH and _INODE The lsm common audit code has wacky contortions making sure which pieces of information are set based on if it was given a path, dentry, or inode. Split this into path and inode to get rid of some of the code complexity. Signed-off-by: Eric Paris Acked-by: Casey Schaufler --- include/linux/lsm_audit.h | 9 ++++----- security/lsm_audit.c | 50 ++++++++++++++++++++++++++-------------------- security/selinux/avc.c | 2 +- security/selinux/hooks.c | 50 +++++++++++++++++++++++----------------------- security/smack/smack.h | 8 ++++---- security/smack/smack_lsm.c | 32 ++++++++++++++--------------- 6 files changed, 78 insertions(+), 73 deletions(-) (limited to 'include/linux') diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h index 112a55033352..bbaceab83a65 100644 --- a/include/linux/lsm_audit.h +++ b/include/linux/lsm_audit.h @@ -27,7 +27,7 @@ /* Auxiliary data to use in generating the audit record. */ struct common_audit_data { char type; -#define LSM_AUDIT_DATA_FS 1 +#define LSM_AUDIT_DATA_PATH 1 #define LSM_AUDIT_DATA_NET 2 #define LSM_AUDIT_DATA_CAP 3 #define LSM_AUDIT_DATA_IPC 4 @@ -35,12 +35,11 @@ struct common_audit_data { #define LSM_AUDIT_DATA_KEY 6 #define LSM_AUDIT_DATA_NONE 7 #define LSM_AUDIT_DATA_KMOD 8 +#define LSM_AUDIT_DATA_INODE 9 struct task_struct *tsk; union { - struct { - struct path path; - struct inode *inode; - } fs; + struct path path; + struct inode *inode; struct { int netif; struct sock *sk; diff --git a/security/lsm_audit.c b/security/lsm_audit.c index 908aa712816a..2e846052cbf4 100644 --- a/security/lsm_audit.c +++ b/security/lsm_audit.c @@ -210,7 +210,6 @@ static inline void print_ipv4_addr(struct audit_buffer *ab, __be32 addr, static void dump_common_audit_data(struct audit_buffer *ab, struct common_audit_data *a) { - struct inode *inode = NULL; struct task_struct *tsk = current; if (a->tsk) @@ -229,33 +228,40 @@ static void dump_common_audit_data(struct audit_buffer *ab, case LSM_AUDIT_DATA_CAP: audit_log_format(ab, " capability=%d ", a->u.cap); break; - case LSM_AUDIT_DATA_FS: - if (a->u.fs.path.dentry) { - struct dentry *dentry = a->u.fs.path.dentry; - if (a->u.fs.path.mnt) { - audit_log_d_path(ab, "path=", &a->u.fs.path); - } else { - audit_log_format(ab, " name="); - audit_log_untrustedstring(ab, - dentry->d_name.name); - } - inode = dentry->d_inode; - } else if (a->u.fs.inode) { - struct dentry *dentry; - inode = a->u.fs.inode; - dentry = d_find_alias(inode); - if (dentry) { - audit_log_format(ab, " name="); - audit_log_untrustedstring(ab, - dentry->d_name.name); - dput(dentry); - } + case LSM_AUDIT_DATA_PATH: { + struct dentry *dentry = a->u.path.dentry; + struct inode *inode; + + if (a->u.path.mnt) { + audit_log_d_path(ab, "path=", &a->u.path); + } else { + audit_log_format(ab, " name="); + audit_log_untrustedstring(ab, + dentry->d_name.name); } + inode = dentry->d_inode; if (inode) audit_log_format(ab, " dev=%s ino=%lu", inode->i_sb->s_id, inode->i_ino); break; + } + case LSM_AUDIT_DATA_INODE: { + struct dentry *dentry; + struct inode *inode; + + inode = a->u.inode; + dentry = d_find_alias(inode); + if (dentry) { + audit_log_format(ab, " name="); + audit_log_untrustedstring(ab, + dentry->d_name.name); + dput(dentry); + } + audit_log_format(ab, " dev=%s ino=%lu", inode->i_sb->s_id, + inode->i_ino); + break; + } case LSM_AUDIT_DATA_TASK: tsk = a->u.tsk; if (tsk && tsk->pid) { diff --git a/security/selinux/avc.c b/security/selinux/avc.c index 1d027e29ce8d..ce742f1778e1 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -531,7 +531,7 @@ int avc_audit(u32 ssid, u32 tsid, * during retry. However this is logically just as if the operation * happened a little later. */ - if ((a->type == LSM_AUDIT_DATA_FS) && + if ((a->type == LSM_AUDIT_DATA_INODE) && (flags & IPERM_FLAG_RCU)) return -ECHILD; diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index ed5f29aa0a38..ad664d3056eb 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -1488,8 +1488,8 @@ static int inode_has_perm(const struct cred *cred, if (!adp) { adp = &ad; - COMMON_AUDIT_DATA_INIT(&ad, FS); - ad.u.fs.inode = inode; + COMMON_AUDIT_DATA_INIT(&ad, INODE); + ad.u.inode = inode; } return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, flags); @@ -1506,9 +1506,9 @@ static inline int dentry_has_perm(const struct cred *cred, struct inode *inode = dentry->d_inode; struct common_audit_data ad; - COMMON_AUDIT_DATA_INIT(&ad, FS); - ad.u.fs.path.mnt = mnt; - ad.u.fs.path.dentry = dentry; + COMMON_AUDIT_DATA_INIT(&ad, PATH); + ad.u.path.mnt = mnt; + ad.u.path.dentry = dentry; return inode_has_perm(cred, inode, av, &ad, 0); } @@ -1530,8 +1530,8 @@ static int file_has_perm(const struct cred *cred, u32 sid = cred_sid(cred); int rc; - COMMON_AUDIT_DATA_INIT(&ad, FS); - ad.u.fs.path = file->f_path; + COMMON_AUDIT_DATA_INIT(&ad, PATH); + ad.u.path = file->f_path; if (sid != fsec->sid) { rc = avc_has_perm(sid, fsec->sid, @@ -1569,8 +1569,8 @@ static int may_create(struct inode *dir, sid = tsec->sid; newsid = tsec->create_sid; - COMMON_AUDIT_DATA_INIT(&ad, FS); - ad.u.fs.path.dentry = dentry; + COMMON_AUDIT_DATA_INIT(&ad, PATH); + ad.u.path.dentry = dentry; rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR, DIR__ADD_NAME | DIR__SEARCH, @@ -1621,8 +1621,8 @@ static int may_link(struct inode *dir, dsec = dir->i_security; isec = dentry->d_inode->i_security; - COMMON_AUDIT_DATA_INIT(&ad, FS); - ad.u.fs.path.dentry = dentry; + COMMON_AUDIT_DATA_INIT(&ad, PATH); + ad.u.path.dentry = dentry; av = DIR__SEARCH; av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME); @@ -1667,9 +1667,9 @@ static inline int may_rename(struct inode *old_dir, old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode); new_dsec = new_dir->i_security; - COMMON_AUDIT_DATA_INIT(&ad, FS); + COMMON_AUDIT_DATA_INIT(&ad, PATH); - ad.u.fs.path.dentry = old_dentry; + ad.u.path.dentry = old_dentry; rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR, DIR__REMOVE_NAME | DIR__SEARCH, &ad); if (rc) @@ -1685,7 +1685,7 @@ static inline int may_rename(struct inode *old_dir, return rc; } - ad.u.fs.path.dentry = new_dentry; + ad.u.path.dentry = new_dentry; av = DIR__ADD_NAME | DIR__SEARCH; if (new_dentry->d_inode) av |= DIR__REMOVE_NAME; @@ -1991,8 +1991,8 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) return rc; } - COMMON_AUDIT_DATA_INIT(&ad, FS); - ad.u.fs.path = bprm->file->f_path; + COMMON_AUDIT_DATA_INIT(&ad, PATH); + ad.u.path = bprm->file->f_path; if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) new_tsec->sid = old_tsec->sid; @@ -2120,7 +2120,7 @@ static inline void flush_unauthorized_files(const struct cred *cred, /* Revalidate access to inherited open files. */ - COMMON_AUDIT_DATA_INIT(&ad, FS); + COMMON_AUDIT_DATA_INIT(&ad, INODE); spin_lock(&files->file_lock); for (;;) { @@ -2468,8 +2468,8 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data) if (flags & MS_KERNMOUNT) return 0; - COMMON_AUDIT_DATA_INIT(&ad, FS); - ad.u.fs.path.dentry = sb->s_root; + COMMON_AUDIT_DATA_INIT(&ad, PATH); + ad.u.path.dentry = sb->s_root; return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad); } @@ -2478,8 +2478,8 @@ static int selinux_sb_statfs(struct dentry *dentry) const struct cred *cred = current_cred(); struct common_audit_data ad; - COMMON_AUDIT_DATA_INIT(&ad, FS); - ad.u.fs.path.dentry = dentry->d_sb->s_root; + COMMON_AUDIT_DATA_INIT(&ad, PATH); + ad.u.path.dentry = dentry->d_sb->s_root; return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad); } @@ -2653,8 +2653,8 @@ static int selinux_inode_permission(struct inode *inode, int mask, unsigned flag if (!mask) return 0; - COMMON_AUDIT_DATA_INIT(&ad, FS); - ad.u.fs.inode = inode; + COMMON_AUDIT_DATA_INIT(&ad, INODE); + ad.u.inode = inode; if (from_access) ad.selinux_audit_data.auditdeny |= FILE__AUDIT_ACCESS; @@ -2732,8 +2732,8 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, if (!is_owner_or_cap(inode)) return -EPERM; - COMMON_AUDIT_DATA_INIT(&ad, FS); - ad.u.fs.path.dentry = dentry; + COMMON_AUDIT_DATA_INIT(&ad, PATH); + ad.u.path.dentry = dentry; rc = avc_has_perm(sid, isec->sid, isec->sclass, FILE__RELABELFROM, &ad); diff --git a/security/smack/smack.h b/security/smack/smack.h index b449cfdad21c..a16925c0e91a 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h @@ -316,22 +316,22 @@ static inline void smk_ad_setfield_u_tsk(struct smk_audit_info *a, static inline void smk_ad_setfield_u_fs_path_dentry(struct smk_audit_info *a, struct dentry *d) { - a->a.u.fs.path.dentry = d; + a->a.u.path.dentry = d; } static inline void smk_ad_setfield_u_fs_path_mnt(struct smk_audit_info *a, struct vfsmount *m) { - a->a.u.fs.path.mnt = m; + a->a.u.path.mnt = m; } static inline void smk_ad_setfield_u_fs_inode(struct smk_audit_info *a, struct inode *i) { - a->a.u.fs.inode = i; + a->a.u.inode = i; } static inline void smk_ad_setfield_u_fs_path(struct smk_audit_info *a, struct path p) { - a->a.u.fs.path = p; + a->a.u.path = p; } static inline void smk_ad_setfield_u_net_sk(struct smk_audit_info *a, struct sock *sk) diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 42fcb47747a3..eeb393fbf925 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -383,7 +383,7 @@ static int smack_sb_statfs(struct dentry *dentry) int rc; struct smk_audit_info ad; - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_setfield_u_fs_path_dentry(&ad, dentry); rc = smk_curacc(sbp->smk_floor, MAY_READ, &ad); @@ -407,7 +407,7 @@ static int smack_sb_mount(char *dev_name, struct path *path, struct superblock_smack *sbp = path->mnt->mnt_sb->s_security; struct smk_audit_info ad; - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_setfield_u_fs_path(&ad, *path); return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad); @@ -426,7 +426,7 @@ static int smack_sb_umount(struct vfsmount *mnt, int flags) struct superblock_smack *sbp; struct smk_audit_info ad; - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_setfield_u_fs_path_dentry(&ad, mnt->mnt_root); smk_ad_setfield_u_fs_path_mnt(&ad, mnt); @@ -563,7 +563,7 @@ static int smack_inode_link(struct dentry *old_dentry, struct inode *dir, struct smk_audit_info ad; int rc; - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry); isp = smk_of_inode(old_dentry->d_inode); @@ -592,7 +592,7 @@ static int smack_inode_unlink(struct inode *dir, struct dentry *dentry) struct smk_audit_info ad; int rc; - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_setfield_u_fs_path_dentry(&ad, dentry); /* @@ -623,7 +623,7 @@ static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry) struct smk_audit_info ad; int rc; - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_setfield_u_fs_path_dentry(&ad, dentry); /* @@ -663,7 +663,7 @@ static int smack_inode_rename(struct inode *old_inode, char *isp; struct smk_audit_info ad; - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry); isp = smk_of_inode(old_dentry->d_inode); @@ -700,7 +700,7 @@ static int smack_inode_permission(struct inode *inode, int mask, unsigned flags) /* May be droppable after audit */ if (flags & IPERM_FLAG_RCU) return -ECHILD; - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_INODE); smk_ad_setfield_u_fs_inode(&ad, inode); return smk_curacc(smk_of_inode(inode), mask, &ad); } @@ -720,7 +720,7 @@ static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr) */ if (iattr->ia_valid & ATTR_FORCE) return 0; - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_setfield_u_fs_path_dentry(&ad, dentry); return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); @@ -737,7 +737,7 @@ static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) { struct smk_audit_info ad; - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_setfield_u_fs_path_dentry(&ad, dentry); smk_ad_setfield_u_fs_path_mnt(&ad, mnt); return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad); @@ -784,7 +784,7 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name, } else rc = cap_inode_setxattr(dentry, name, value, size, flags); - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_setfield_u_fs_path_dentry(&ad, dentry); if (rc == 0) @@ -845,7 +845,7 @@ static int smack_inode_getxattr(struct dentry *dentry, const char *name) { struct smk_audit_info ad; - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_setfield_u_fs_path_dentry(&ad, dentry); return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad); @@ -877,7 +877,7 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name) } else rc = cap_inode_removexattr(dentry, name); - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_setfield_u_fs_path_dentry(&ad, dentry); if (rc == 0) rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); @@ -1047,7 +1047,7 @@ static int smack_file_ioctl(struct file *file, unsigned int cmd, int rc = 0; struct smk_audit_info ad; - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_setfield_u_fs_path(&ad, file->f_path); if (_IOC_DIR(cmd) & _IOC_WRITE) @@ -1070,7 +1070,7 @@ static int smack_file_lock(struct file *file, unsigned int cmd) { struct smk_audit_info ad; - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_setfield_u_fs_path_dentry(&ad, file->f_path.dentry); return smk_curacc(file->f_security, MAY_WRITE, &ad); } @@ -1089,7 +1089,7 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd, struct smk_audit_info ad; int rc; - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_setfield_u_fs_path(&ad, file->f_path); switch (cmd) { -- cgit From a269434d2fb48a4d66c1d7bf821b7874b59c5b41 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Mon, 25 Apr 2011 13:10:27 -0400 Subject: LSM: separate LSM_AUDIT_DATA_DENTRY from LSM_AUDIT_DATA_PATH This patch separates and audit message that only contains a dentry from one that contains a full path. This allows us to make it harder to misuse the interfaces or for the interfaces to be implemented wrong. Signed-off-by: Eric Paris Acked-by: Casey Schaufler --- include/linux/lsm_audit.h | 2 ++ security/lsm_audit.c | 25 ++++++++++++++++--------- security/selinux/hooks.c | 26 +++++++++++++------------- security/smack/smack.h | 7 +------ security/smack/smack_lsm.c | 34 ++++++++++++++++++++-------------- 5 files changed, 52 insertions(+), 42 deletions(-) (limited to 'include/linux') diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h index bbaceab83a65..88e78dedc2e8 100644 --- a/include/linux/lsm_audit.h +++ b/include/linux/lsm_audit.h @@ -36,9 +36,11 @@ struct common_audit_data { #define LSM_AUDIT_DATA_NONE 7 #define LSM_AUDIT_DATA_KMOD 8 #define LSM_AUDIT_DATA_INODE 9 +#define LSM_AUDIT_DATA_DENTRY 10 struct task_struct *tsk; union { struct path path; + struct dentry *dentry; struct inode *inode; struct { int netif; diff --git a/security/lsm_audit.c b/security/lsm_audit.c index 2e846052cbf4..893af8a2fa1e 100644 --- a/security/lsm_audit.c +++ b/security/lsm_audit.c @@ -229,17 +229,24 @@ static void dump_common_audit_data(struct audit_buffer *ab, audit_log_format(ab, " capability=%d ", a->u.cap); break; case LSM_AUDIT_DATA_PATH: { - struct dentry *dentry = a->u.path.dentry; struct inode *inode; - if (a->u.path.mnt) { - audit_log_d_path(ab, "path=", &a->u.path); - } else { - audit_log_format(ab, " name="); - audit_log_untrustedstring(ab, - dentry->d_name.name); - } - inode = dentry->d_inode; + audit_log_d_path(ab, "path=", &a->u.path); + + inode = a->u.path.dentry->d_inode; + if (inode) + audit_log_format(ab, " dev=%s ino=%lu", + inode->i_sb->s_id, + inode->i_ino); + break; + } + case LSM_AUDIT_DATA_DENTRY: { + struct inode *inode; + + audit_log_format(ab, " name="); + audit_log_untrustedstring(ab, a->u.dentry->d_name.name); + + inode = a->u.dentry->d_inode; if (inode) audit_log_format(ab, " dev=%s ino=%lu", inode->i_sb->s_id, diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index ad664d3056eb..9e8078a42a94 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -1569,8 +1569,8 @@ static int may_create(struct inode *dir, sid = tsec->sid; newsid = tsec->create_sid; - COMMON_AUDIT_DATA_INIT(&ad, PATH); - ad.u.path.dentry = dentry; + COMMON_AUDIT_DATA_INIT(&ad, DENTRY); + ad.u.dentry = dentry; rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR, DIR__ADD_NAME | DIR__SEARCH, @@ -1621,8 +1621,8 @@ static int may_link(struct inode *dir, dsec = dir->i_security; isec = dentry->d_inode->i_security; - COMMON_AUDIT_DATA_INIT(&ad, PATH); - ad.u.path.dentry = dentry; + COMMON_AUDIT_DATA_INIT(&ad, DENTRY); + ad.u.dentry = dentry; av = DIR__SEARCH; av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME); @@ -1667,9 +1667,9 @@ static inline int may_rename(struct inode *old_dir, old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode); new_dsec = new_dir->i_security; - COMMON_AUDIT_DATA_INIT(&ad, PATH); + COMMON_AUDIT_DATA_INIT(&ad, DENTRY); - ad.u.path.dentry = old_dentry; + ad.u.dentry = old_dentry; rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR, DIR__REMOVE_NAME | DIR__SEARCH, &ad); if (rc) @@ -1685,7 +1685,7 @@ static inline int may_rename(struct inode *old_dir, return rc; } - ad.u.path.dentry = new_dentry; + ad.u.dentry = new_dentry; av = DIR__ADD_NAME | DIR__SEARCH; if (new_dentry->d_inode) av |= DIR__REMOVE_NAME; @@ -2468,8 +2468,8 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data) if (flags & MS_KERNMOUNT) return 0; - COMMON_AUDIT_DATA_INIT(&ad, PATH); - ad.u.path.dentry = sb->s_root; + COMMON_AUDIT_DATA_INIT(&ad, DENTRY); + ad.u.dentry = sb->s_root; return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad); } @@ -2478,8 +2478,8 @@ static int selinux_sb_statfs(struct dentry *dentry) const struct cred *cred = current_cred(); struct common_audit_data ad; - COMMON_AUDIT_DATA_INIT(&ad, PATH); - ad.u.path.dentry = dentry->d_sb->s_root; + COMMON_AUDIT_DATA_INIT(&ad, DENTRY); + ad.u.dentry = dentry->d_sb->s_root; return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad); } @@ -2732,8 +2732,8 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, if (!is_owner_or_cap(inode)) return -EPERM; - COMMON_AUDIT_DATA_INIT(&ad, PATH); - ad.u.path.dentry = dentry; + COMMON_AUDIT_DATA_INIT(&ad, DENTRY); + ad.u.dentry = dentry; rc = avc_has_perm(sid, isec->sid, isec->sclass, FILE__RELABELFROM, &ad); diff --git a/security/smack/smack.h b/security/smack/smack.h index a16925c0e91a..2b6c6a516123 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h @@ -316,12 +316,7 @@ static inline void smk_ad_setfield_u_tsk(struct smk_audit_info *a, static inline void smk_ad_setfield_u_fs_path_dentry(struct smk_audit_info *a, struct dentry *d) { - a->a.u.path.dentry = d; -} -static inline void smk_ad_setfield_u_fs_path_mnt(struct smk_audit_info *a, - struct vfsmount *m) -{ - a->a.u.path.mnt = m; + a->a.u.dentry = d; } static inline void smk_ad_setfield_u_fs_inode(struct smk_audit_info *a, struct inode *i) diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index eeb393fbf925..a3bdd1383928 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -383,7 +383,7 @@ static int smack_sb_statfs(struct dentry *dentry) int rc; struct smk_audit_info ad; - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); smk_ad_setfield_u_fs_path_dentry(&ad, dentry); rc = smk_curacc(sbp->smk_floor, MAY_READ, &ad); @@ -425,10 +425,13 @@ static int smack_sb_umount(struct vfsmount *mnt, int flags) { struct superblock_smack *sbp; struct smk_audit_info ad; + struct path path; + + path.dentry = mnt->mnt_root; + path.mnt = mnt; smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); - smk_ad_setfield_u_fs_path_dentry(&ad, mnt->mnt_root); - smk_ad_setfield_u_fs_path_mnt(&ad, mnt); + smk_ad_setfield_u_fs_path(&ad, path); sbp = mnt->mnt_sb->s_security; return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad); @@ -563,7 +566,7 @@ static int smack_inode_link(struct dentry *old_dentry, struct inode *dir, struct smk_audit_info ad; int rc; - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry); isp = smk_of_inode(old_dentry->d_inode); @@ -592,7 +595,7 @@ static int smack_inode_unlink(struct inode *dir, struct dentry *dentry) struct smk_audit_info ad; int rc; - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); smk_ad_setfield_u_fs_path_dentry(&ad, dentry); /* @@ -623,7 +626,7 @@ static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry) struct smk_audit_info ad; int rc; - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); smk_ad_setfield_u_fs_path_dentry(&ad, dentry); /* @@ -663,7 +666,7 @@ static int smack_inode_rename(struct inode *old_inode, char *isp; struct smk_audit_info ad; - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry); isp = smk_of_inode(old_dentry->d_inode); @@ -720,7 +723,7 @@ static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr) */ if (iattr->ia_valid & ATTR_FORCE) return 0; - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); smk_ad_setfield_u_fs_path_dentry(&ad, dentry); return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); @@ -736,10 +739,13 @@ static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr) static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) { struct smk_audit_info ad; + struct path path; + + path.dentry = dentry; + path.mnt = mnt; smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); - smk_ad_setfield_u_fs_path_dentry(&ad, dentry); - smk_ad_setfield_u_fs_path_mnt(&ad, mnt); + smk_ad_setfield_u_fs_path(&ad, path); return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad); } @@ -784,7 +790,7 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name, } else rc = cap_inode_setxattr(dentry, name, value, size, flags); - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); smk_ad_setfield_u_fs_path_dentry(&ad, dentry); if (rc == 0) @@ -845,7 +851,7 @@ static int smack_inode_getxattr(struct dentry *dentry, const char *name) { struct smk_audit_info ad; - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); smk_ad_setfield_u_fs_path_dentry(&ad, dentry); return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad); @@ -877,7 +883,7 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name) } else rc = cap_inode_removexattr(dentry, name); - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); smk_ad_setfield_u_fs_path_dentry(&ad, dentry); if (rc == 0) rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); @@ -1070,7 +1076,7 @@ static int smack_file_lock(struct file *file, unsigned int cmd) { struct smk_audit_info ad; - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); smk_ad_setfield_u_fs_path_dentry(&ad, file->f_path.dentry); return smk_curacc(file->f_security, MAY_WRITE, &ad); } -- cgit From ad58671cf32c74a8d6e8f51e63e9cf4e7a73bf1e Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Tue, 19 Apr 2011 12:43:45 +0100 Subject: Add a strtobool function matching semantics of existing in kernel equivalents This is a rename of the usr_strtobool proposal, which was a renamed, relocated and fixed version of previous kstrtobool RFC Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- include/linux/string.h | 1 + lib/string.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) (limited to 'include/linux') diff --git a/include/linux/string.h b/include/linux/string.h index a716ee2a8adb..a176db2f2c85 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -123,6 +123,7 @@ extern char **argv_split(gfp_t gfp, const char *str, int *argcp); extern void argv_free(char **argv); extern bool sysfs_streq(const char *s1, const char *s2); +extern int strtobool(const char *s, bool *res); #ifdef CONFIG_BINARY_PRINTF int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args); diff --git a/lib/string.c b/lib/string.c index f71bead1be3e..01fad9b203e1 100644 --- a/lib/string.c +++ b/lib/string.c @@ -535,6 +535,35 @@ bool sysfs_streq(const char *s1, const char *s2) } EXPORT_SYMBOL(sysfs_streq); +/** + * strtobool - convert common user inputs into boolean values + * @s: input string + * @res: result + * + * This routine returns 0 iff the first character is one of 'Yy1Nn0'. + * Otherwise it will return -EINVAL. Value pointed to by res is + * updated upon finding a match. + */ +int strtobool(const char *s, bool *res) +{ + switch (s[0]) { + case 'y': + case 'Y': + case '1': + *res = true; + break; + case 'n': + case 'N': + case '0': + *res = false; + break; + default: + return -EINVAL; + } + return 0; +} +EXPORT_SYMBOL(strtobool); + #ifndef __HAVE_ARCH_MEMSET /** * memset - Fill a region of memory with the given value -- cgit From 3dd2ee4824b668a635d6d2bb6bc73f33708cab9f Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 25 Apr 2011 18:10:58 -0700 Subject: bit_spinlock: don't play preemption games inside the busy loop When we are waiting for the bit-lock to be released, and are looping over the 'cpu_relax()' should not be doing anything else - otherwise we miss the point of trying to do the whole 'cpu_relax()'. Do the preemption enable/disable around the loop, rather than inside of it. Noticed when I was looking at the code generation for the dcache __d_drop usage, and the code just looked very odd. Signed-off-by: Linus Torvalds --- include/linux/bit_spinlock.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/bit_spinlock.h b/include/linux/bit_spinlock.h index e612575a2596..b4326bfa684f 100644 --- a/include/linux/bit_spinlock.h +++ b/include/linux/bit_spinlock.h @@ -23,11 +23,11 @@ static inline void bit_spin_lock(int bitnum, unsigned long *addr) preempt_disable(); #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) while (unlikely(test_and_set_bit_lock(bitnum, addr))) { - while (test_bit(bitnum, addr)) { - preempt_enable(); + preempt_enable(); + do { cpu_relax(); - preempt_disable(); - } + } while (test_bit(bitnum, addr)); + preempt_disable(); } #endif __acquire(bitlock); -- cgit From 1879fd6a26571fd4e8e1f4bb3e7537bc936b1fe7 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 25 Apr 2011 14:01:36 -0400 Subject: add hlist_bl_lock/unlock helpers Now that the whole dcache_hash_bucket crap is gone, go all the way and also remove the weird locking layering violations for locking the hash buckets. Add hlist_bl_lock/unlock helpers to move the locking into the list abstraction instead of requiring each caller to open code it. After all allowing for the bit locks is the whole point of these helpers over the plain hlist variant. Signed-off-by: Christoph Hellwig Signed-off-by: Linus Torvalds --- fs/dcache.c | 22 ++++++---------------- fs/gfs2/glock.c | 6 ++---- include/linux/list_bl.h | 11 +++++++++++ 3 files changed, 19 insertions(+), 20 deletions(-) (limited to 'include/linux') diff --git a/fs/dcache.c b/fs/dcache.c index d600a0af3b2e..22a0ef41bad1 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -109,16 +109,6 @@ static inline struct hlist_bl_head *d_hash(struct dentry *parent, return dentry_hashtable + (hash & D_HASHMASK); } -static inline void spin_lock_bucket(struct hlist_bl_head *b) -{ - bit_spin_lock(0, (unsigned long *)&b->first); -} - -static inline void spin_unlock_bucket(struct hlist_bl_head *b) -{ - __bit_spin_unlock(0, (unsigned long *)&b->first); -} - /* Statistics gathering. */ struct dentry_stat_t dentry_stat = { .age_limit = 45, @@ -334,10 +324,10 @@ void __d_drop(struct dentry *dentry) else b = d_hash(dentry->d_parent, dentry->d_name.hash); - spin_lock_bucket(b); + hlist_bl_lock(b); __hlist_bl_del(&dentry->d_hash); dentry->d_hash.pprev = NULL; - spin_unlock_bucket(b); + hlist_bl_unlock(b); dentry_rcuwalk_barrier(dentry); } @@ -1594,9 +1584,9 @@ struct dentry *d_obtain_alias(struct inode *inode) tmp->d_inode = inode; tmp->d_flags |= DCACHE_DISCONNECTED; list_add(&tmp->d_alias, &inode->i_dentry); - spin_lock_bucket(&tmp->d_sb->s_anon); + hlist_bl_lock(&tmp->d_sb->s_anon); hlist_bl_add_head(&tmp->d_hash, &tmp->d_sb->s_anon); - spin_unlock_bucket(&tmp->d_sb->s_anon); + hlist_bl_unlock(&tmp->d_sb->s_anon); spin_unlock(&tmp->d_lock); spin_unlock(&inode->i_lock); security_d_instantiate(tmp, inode); @@ -2076,10 +2066,10 @@ EXPORT_SYMBOL(d_delete); static void __d_rehash(struct dentry * entry, struct hlist_bl_head *b) { BUG_ON(!d_unhashed(entry)); - spin_lock_bucket(b); + hlist_bl_lock(b); entry->d_flags |= DCACHE_RCUACCESS; hlist_bl_add_head_rcu(&entry->d_hash, b); - spin_unlock_bucket(b); + hlist_bl_unlock(b); } static void _d_rehash(struct dentry * entry) diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index f07643e21bfa..7a4fb630a320 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -93,14 +93,12 @@ static unsigned int gl_hash(const struct gfs2_sbd *sdp, static inline void spin_lock_bucket(unsigned int hash) { - struct hlist_bl_head *bl = &gl_hash_table[hash]; - bit_spin_lock(0, (unsigned long *)bl); + hlist_bl_lock(&gl_hash_table[hash]); } static inline void spin_unlock_bucket(unsigned int hash) { - struct hlist_bl_head *bl = &gl_hash_table[hash]; - __bit_spin_unlock(0, (unsigned long *)bl); + hlist_bl_unlock(&gl_hash_table[hash]); } static void gfs2_glock_dealloc(struct rcu_head *rcu) diff --git a/include/linux/list_bl.h b/include/linux/list_bl.h index 5bad17d1acde..31f9d75adc5b 100644 --- a/include/linux/list_bl.h +++ b/include/linux/list_bl.h @@ -2,6 +2,7 @@ #define _LINUX_LIST_BL_H #include +#include /* * Special version of lists, where head of the list has a lock in the lowest @@ -114,6 +115,16 @@ static inline void hlist_bl_del_init(struct hlist_bl_node *n) } } +static inline void hlist_bl_lock(struct hlist_bl_head *b) +{ + bit_spin_lock(0, (unsigned long *)b); +} + +static inline void hlist_bl_unlock(struct hlist_bl_head *b) +{ + __bit_spin_unlock(0, (unsigned long *)b); +} + /** * hlist_bl_for_each_entry - iterate over list of given type * @tpos: the type * to use as a loop cursor. -- cgit From 94403f8863d0d1d2005291b2ef0719c2534aa303 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sun, 24 Apr 2011 08:18:31 +0200 Subject: perf events: Add stalled cycles generic event - PERF_COUNT_HW_STALLED_CYCLES The new PERF_COUNT_HW_STALLED_CYCLES event tries to approximate cycles the CPU does nothing useful, because it is stalled on a cache-miss or some other condition. Acked-by: Peter Zijlstra Acked-by: Arnaldo Carvalho de Melo Cc: Frederic Weisbecker Link: http://lkml.kernel.org/n/tip-fue11vymwqsoo5to72jxxjyl@git.kernel.org Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel.c | 3 +++ include/linux/perf_event.h | 1 + tools/perf/util/parse-events.c | 1 + tools/perf/util/python.c | 1 + 4 files changed, 6 insertions(+) (limited to 'include/linux') diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 9ae4a2aa7398..efa2704c9dfd 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -1413,6 +1413,9 @@ static __init int intel_pmu_init(void) x86_pmu.enable_all = intel_pmu_nhm_enable_all; x86_pmu.extra_regs = intel_nehalem_extra_regs; + /* Install the stalled-cycles event: 0xff: All reasons, 0xa2: Resource stalls */ + intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES] = 0xffa2; + if (ebx & 0x40) { /* * Erratum AAJ80 detected, we work it around by using diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index ee9f1e782800..ac636dd20a0c 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -52,6 +52,7 @@ enum perf_hw_id { PERF_COUNT_HW_BRANCH_INSTRUCTIONS = 4, PERF_COUNT_HW_BRANCH_MISSES = 5, PERF_COUNT_HW_BUS_CYCLES = 6, + PERF_COUNT_HW_STALLED_CYCLES = 7, PERF_COUNT_HW_MAX, /* non-ABI */ }; diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 952b4ae3d954..1869e4c646db 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -38,6 +38,7 @@ static struct event_symbol event_symbols[] = { { CHW(BRANCH_INSTRUCTIONS), "branch-instructions", "branches" }, { CHW(BRANCH_MISSES), "branch-misses", "" }, { CHW(BUS_CYCLES), "bus-cycles", "" }, + { CHW(STALLED_CYCLES), "stalled-cycles", "" }, { CSW(CPU_CLOCK), "cpu-clock", "" }, { CSW(TASK_CLOCK), "task-clock", "" }, diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index f5e38451fdc5..406f613ee619 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -798,6 +798,7 @@ static struct { { "COUNT_HW_BRANCH_INSTRUCTIONS", PERF_COUNT_HW_BRANCH_INSTRUCTIONS }, { "COUNT_HW_BRANCH_MISSES", PERF_COUNT_HW_BRANCH_MISSES }, { "COUNT_HW_BUS_CYCLES", PERF_COUNT_HW_BUS_CYCLES }, + { "COUNT_HW_STALLED_CYCLES", PERF_COUNT_HW_STALLED_CYCLES }, { "COUNT_HW_CACHE_L1D", PERF_COUNT_HW_CACHE_L1D }, { "COUNT_HW_CACHE_L1I", PERF_COUNT_HW_CACHE_L1I }, { "COUNT_HW_CACHE_LL", PERF_COUNT_HW_CACHE_LL }, -- cgit From 04ad1fb2640a4f23e99ccb705c179d64abac03f2 Mon Sep 17 00:00:00 2001 From: RafaÅ‚ MiÅ‚ecki Date: Sat, 23 Apr 2011 19:30:29 +0200 Subject: ssb: update reject bit for Target State Low MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit My 14e4:4315 is SSB_IDLOW_SSBREV_26: read32 0xfaafcff8 -> 0x600422d5 My 14e4:4328 is SSB_IDLOW_SSBREV_24: read32 0xfaafcff8 -> 0x400422c5 My 14e4:432b is SSB_IDLOW_SSBREV_26 again: read32 0xfaafcff8 -> 0x600422d5 For all of them wl driver is using 0x2 reject bit: write32(0xf98) <- 0x00010002 So it seems SSB 2.3 is the exception using another bit. Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/ssb/main.c | 15 +++++++-------- include/linux/ssb/ssb_regs.h | 2 +- 2 files changed, 8 insertions(+), 9 deletions(-) (limited to 'include/linux') diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index 74aa2cca7d8c..ad3da93a428c 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c @@ -1117,23 +1117,22 @@ static u32 ssb_tmslow_reject_bitmask(struct ssb_device *dev) { u32 rev = ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_SSBREV; - /* The REJECT bit changed position in TMSLOW between - * Backplane revisions. */ + /* The REJECT bit seems to be different for Backplane rev 2.3 */ switch (rev) { case SSB_IDLOW_SSBREV_22: - return SSB_TMSLOW_REJECT_22; + case SSB_IDLOW_SSBREV_24: + case SSB_IDLOW_SSBREV_26: + return SSB_TMSLOW_REJECT; case SSB_IDLOW_SSBREV_23: return SSB_TMSLOW_REJECT_23; - case SSB_IDLOW_SSBREV_24: /* TODO - find the proper REJECT bits */ - case SSB_IDLOW_SSBREV_25: /* same here */ - case SSB_IDLOW_SSBREV_26: /* same here */ + case SSB_IDLOW_SSBREV_25: /* TODO - find the proper REJECT bit */ case SSB_IDLOW_SSBREV_27: /* same here */ - return SSB_TMSLOW_REJECT_23; /* this is a guess */ + return SSB_TMSLOW_REJECT; /* this is a guess */ default: printk(KERN_INFO "ssb: Backplane Revision 0x%.8X\n", rev); WARN_ON(1); } - return (SSB_TMSLOW_REJECT_22 | SSB_TMSLOW_REJECT_23); + return (SSB_TMSLOW_REJECT | SSB_TMSLOW_REJECT_23); } int ssb_device_is_enabled(struct ssb_device *dev) diff --git a/include/linux/ssb/ssb_regs.h b/include/linux/ssb/ssb_regs.h index 402955ae48ce..efbf459d571c 100644 --- a/include/linux/ssb/ssb_regs.h +++ b/include/linux/ssb/ssb_regs.h @@ -97,7 +97,7 @@ #define SSB_INTVEC_ENET1 0x00000040 /* Enable interrupts for enet 1 */ #define SSB_TMSLOW 0x0F98 /* SB Target State Low */ #define SSB_TMSLOW_RESET 0x00000001 /* Reset */ -#define SSB_TMSLOW_REJECT_22 0x00000002 /* Reject (Backplane rev 2.2) */ +#define SSB_TMSLOW_REJECT 0x00000002 /* Reject (Standard Backplane) */ #define SSB_TMSLOW_REJECT_23 0x00000004 /* Reject (Backplane rev 2.3) */ #define SSB_TMSLOW_CLOCK 0x00010000 /* Clock Enable */ #define SSB_TMSLOW_FGC 0x00020000 /* Force Gated Clocks On */ -- cgit From 304529b1b6f8612ccbb4582e997051b48b94f4a4 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Fri, 1 Apr 2011 14:32:09 -0700 Subject: time: Add timekeeping_inject_sleeptime MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some platforms cannot implement read_persistent_clock, as their RTC devices are only accessible when interrupts are enabled. This keeps them from being used by the timekeeping code on resume to measure the time in suspend. The RTC layer tries to work around this, by calling do_settimeofday on resume after irqs are reenabled to set the time properly. However, this only corrects CLOCK_REALTIME, and does not properly adjust the sleep time value. This causes btime in /proc/stat to be incorrect as well as making the new CLOCK_BOTTTIME inaccurate. This patch resolves the issue by introducing a new timekeeping hook to allow the RTC layer to inject the sleep time on resume. The code also checks to make sure that read_persistent_clock is nonfunctional before setting the sleep time, so that should the RTC's HCTOSYS option be configured in on a system that does support read_persistent_clock we will not increase the total_sleep_time twice. CC: Arve HjønnevÃ¥g CC: Thomas Gleixner Acked-by: Arnd Bergmann Signed-off-by: John Stultz --- drivers/rtc/class.c | 23 ++++++++----------- include/linux/time.h | 1 + kernel/time/timekeeping.c | 56 ++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 63 insertions(+), 17 deletions(-) (limited to 'include/linux') diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 39013867cbd6..4194e59e14cd 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c @@ -41,26 +41,21 @@ static void rtc_device_release(struct device *dev) * system's wall clock; restore it on resume(). */ -static struct timespec delta; static time_t oldtime; +static struct timespec oldts; static int rtc_suspend(struct device *dev, pm_message_t mesg) { struct rtc_device *rtc = to_rtc_device(dev); struct rtc_time tm; - struct timespec ts = current_kernel_time(); if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0) return 0; rtc_read_time(rtc, &tm); + ktime_get_ts(&oldts); rtc_tm_to_time(&tm, &oldtime); - /* RTC precision is 1 second; adjust delta for avg 1/2 sec err */ - set_normalized_timespec(&delta, - ts.tv_sec - oldtime, - ts.tv_nsec - (NSEC_PER_SEC >> 1)); - return 0; } @@ -70,10 +65,12 @@ static int rtc_resume(struct device *dev) struct rtc_time tm; time_t newtime; struct timespec time; + struct timespec newts; if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0) return 0; + ktime_get_ts(&newts); rtc_read_time(rtc, &tm); if (rtc_valid_tm(&tm) != 0) { pr_debug("%s: bogus resume time\n", dev_name(&rtc->dev)); @@ -85,15 +82,13 @@ static int rtc_resume(struct device *dev) pr_debug("%s: time travel!\n", dev_name(&rtc->dev)); return 0; } + /* calculate the RTC time delta */ + set_normalized_timespec(&time, newtime - oldtime, 0); - /* restore wall clock using delta against this RTC; - * adjust again for avg 1/2 second RTC sampling error - */ - set_normalized_timespec(&time, - newtime + delta.tv_sec, - (NSEC_PER_SEC >> 1) + delta.tv_nsec); - do_settimeofday(&time); + /* subtract kernel time between rtc_suspend to rtc_resume */ + time = timespec_sub(time, timespec_sub(newts, oldts)); + timekeeping_inject_sleeptime(&time); return 0; } diff --git a/include/linux/time.h b/include/linux/time.h index 454a26205787..4ea5a75fcacd 100644 --- a/include/linux/time.h +++ b/include/linux/time.h @@ -126,6 +126,7 @@ struct timespec __current_kernel_time(void); /* does not take xtime_lock */ struct timespec get_monotonic_coarse(void); void get_xtime_and_monotonic_and_sleep_offset(struct timespec *xtim, struct timespec *wtom, struct timespec *sleep); +void timekeeping_inject_sleeptime(struct timespec *delta); #define CURRENT_TIME (current_kernel_time()) #define CURRENT_TIME_SEC ((struct timespec) { get_seconds(), 0 }) diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 8ad5d576755e..8e6a05a5915a 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -595,6 +595,58 @@ void __init timekeeping_init(void) /* time in seconds when suspend began */ static struct timespec timekeeping_suspend_time; +/** + * __timekeeping_inject_sleeptime - Internal function to add sleep interval + * @delta: pointer to a timespec delta value + * + * Takes a timespec offset measuring a suspend interval and properly + * adds the sleep offset to the timekeeping variables. + */ +static void __timekeeping_inject_sleeptime(struct timespec *delta) +{ + xtime = timespec_add(xtime, *delta); + wall_to_monotonic = timespec_sub(wall_to_monotonic, *delta); + total_sleep_time = timespec_add(total_sleep_time, *delta); +} + + +/** + * timekeeping_inject_sleeptime - Adds suspend interval to timeekeeping values + * @delta: pointer to a timespec delta value + * + * This hook is for architectures that cannot support read_persistent_clock + * because their RTC/persistent clock is only accessible when irqs are enabled. + * + * This function should only be called by rtc_resume(), and allows + * a suspend offset to be injected into the timekeeping values. + */ +void timekeeping_inject_sleeptime(struct timespec *delta) +{ + unsigned long flags; + struct timespec ts; + + /* Make sure we don't set the clock twice */ + read_persistent_clock(&ts); + if (!(ts.tv_sec == 0 && ts.tv_nsec == 0)) + return; + + write_seqlock_irqsave(&xtime_lock, flags); + timekeeping_forward_now(); + + __timekeeping_inject_sleeptime(delta); + + timekeeper.ntp_error = 0; + ntp_clear(); + update_vsyscall(&xtime, &wall_to_monotonic, timekeeper.clock, + timekeeper.mult); + + write_sequnlock_irqrestore(&xtime_lock, flags); + + /* signal hrtimers about time change */ + clock_was_set(); +} + + /** * timekeeping_resume - Resumes the generic timekeeping subsystem. * @@ -615,9 +667,7 @@ static void timekeeping_resume(void) if (timespec_compare(&ts, &timekeeping_suspend_time) > 0) { ts = timespec_sub(ts, timekeeping_suspend_time); - xtime = timespec_add(xtime, ts); - wall_to_monotonic = timespec_sub(wall_to_monotonic, ts); - total_sleep_time = timespec_add(total_sleep_time, ts); + __timekeeping_inject_sleeptime(&ts); } /* re-base the last cycle value */ timekeeper.clock->cycle_last = timekeeper.clock->read(timekeeper.clock); -- cgit From 88d19cf37952a7e1e38b2bf87a00f0e857e63180 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Mon, 3 Jan 2011 18:59:43 -0800 Subject: timers: Add rb_init_node() to allow for stack allocated rb nodes In cases where a timerqueue_node or some structure that utilizes a timerqueue_node is allocated on the stack, gcc would give warnings caused by the timerqueue_init()'s calling RB_CLEAR_NODE, which self-references the nodes uninitialized data. The solution is to create an rb_init_node() function that zeros the rb_node structure out and then calls RB_CLEAR_NODE(), and then call the new init function from timerqueue_init(). CC: Thomas Gleixner Acked-by: Arnd Bergmann Signed-off-by: John Stultz --- include/linux/rbtree.h | 8 ++++++++ include/linux/timerqueue.h | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/rbtree.h b/include/linux/rbtree.h index 7066acb2c530..033b507b33b1 100644 --- a/include/linux/rbtree.h +++ b/include/linux/rbtree.h @@ -136,6 +136,14 @@ static inline void rb_set_color(struct rb_node *rb, int color) #define RB_EMPTY_NODE(node) (rb_parent(node) == node) #define RB_CLEAR_NODE(node) (rb_set_parent(node, node)) +static inline void rb_init_node(struct rb_node *rb) +{ + rb->rb_parent_color = 0; + rb->rb_right = NULL; + rb->rb_left = NULL; + RB_CLEAR_NODE(rb); +} + extern void rb_insert_color(struct rb_node *, struct rb_root *); extern void rb_erase(struct rb_node *, struct rb_root *); diff --git a/include/linux/timerqueue.h b/include/linux/timerqueue.h index a520fd70a59f..5088727478fd 100644 --- a/include/linux/timerqueue.h +++ b/include/linux/timerqueue.h @@ -39,7 +39,7 @@ struct timerqueue_node *timerqueue_getnext(struct timerqueue_head *head) static inline void timerqueue_init(struct timerqueue_node *node) { - RB_CLEAR_NODE(&node->node); + rb_init_node(&node->node); } static inline void timerqueue_init_head(struct timerqueue_head *head) -- cgit From ff3ead96d17f47ee70c294a5cc2cce9b61e82f0f Mon Sep 17 00:00:00 2001 From: John Stultz Date: Tue, 11 Jan 2011 09:42:13 -0800 Subject: timers: Introduce in-kernel alarm-timer interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This provides the in kernel interface and infrastructure for alarm-timers. Alarm-timers are a hybrid style timer, similar to hrtimers, but when the system is suspended, the RTC device is set to fire and wake the system for when the soonest alarm-timer expires. The concept for Alarm-timers was inspired by the Android Alarm driver (by Arve HjønnevÃ¥g) found in the Android kernel tree. See: http://android.git.kernel.org/?p=kernel/common.git;a=blob;f=drivers/rtc/alarm.c;h=1250edfbdf3302f5e4ea6194847c6ef4bb7beb1c;hb=android-2.6.36 This in-kernel interface should be fairly compatible with the Android alarm driver in-kernel interface, but has the advantage of utilizing the new RTC timerqueue code instead of doing direct RTC manipulation. CC: Arve HjønnevÃ¥g CC: Thomas Gleixner CC: Alessandro Zummo Acked-by: Arnd Bergmann Signed-off-by: John Stultz --- include/linux/alarmtimer.h | 30 ++++ kernel/time/Makefile | 2 +- kernel/time/alarmtimer.c | 375 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 406 insertions(+), 1 deletion(-) create mode 100644 include/linux/alarmtimer.h create mode 100644 kernel/time/alarmtimer.c (limited to 'include/linux') diff --git a/include/linux/alarmtimer.h b/include/linux/alarmtimer.h new file mode 100644 index 000000000000..6b364b2e2074 --- /dev/null +++ b/include/linux/alarmtimer.h @@ -0,0 +1,30 @@ +#ifndef _LINUX_ALARMTIMER_H +#define _LINUX_ALARMTIMER_H + +#include +#include +#include +#include + +enum alarmtimer_type { + ALARM_REALTIME, + ALARM_BOOTTIME, + + ALARM_NUMTYPE, +}; + +struct alarm { + struct timerqueue_node node; + ktime_t period; + void (*function)(struct alarm *); + enum alarmtimer_type type; + char enabled; + void *data; +}; + +void alarm_init(struct alarm *alarm, enum alarmtimer_type type, + void (*function)(struct alarm *)); +void alarm_start(struct alarm *alarm, ktime_t start, ktime_t period); +void alarm_cancel(struct alarm *alarm); + +#endif diff --git a/kernel/time/Makefile b/kernel/time/Makefile index b0425991e9ac..e2fd74b8e8c2 100644 --- a/kernel/time/Makefile +++ b/kernel/time/Makefile @@ -1,5 +1,5 @@ obj-y += timekeeping.o ntp.o clocksource.o jiffies.o timer_list.o timecompare.o -obj-y += timeconv.o posix-clock.o +obj-y += timeconv.o posix-clock.o alarmtimer.o obj-$(CONFIG_GENERIC_CLOCKEVENTS_BUILD) += clockevents.o obj-$(CONFIG_GENERIC_CLOCKEVENTS) += tick-common.o diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c new file mode 100644 index 000000000000..48c2ee949e61 --- /dev/null +++ b/kernel/time/alarmtimer.c @@ -0,0 +1,375 @@ +/* + * Alarmtimer interface + * + * This interface provides a timer which is similarto hrtimers, + * but triggers a RTC alarm if the box is suspend. + * + * This interface is influenced by the Android RTC Alarm timer + * interface. + * + * Copyright (C) 2010 IBM Corperation + * + * Author: John Stultz + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static struct alarm_base { + spinlock_t lock; + struct timerqueue_head timerqueue; + struct hrtimer timer; + ktime_t (*gettime)(void); + clockid_t base_clockid; + struct work_struct irqwork; +} alarm_bases[ALARM_NUMTYPE]; + +static struct rtc_timer rtctimer; +static struct rtc_device *rtcdev; + +static ktime_t freezer_delta; +static DEFINE_SPINLOCK(freezer_delta_lock); + + +/************************************************************************** + * alarmtimer management code + */ + +/* + * alarmtimer_enqueue - Adds an alarm timer to an alarm_base timerqueue + * @base: pointer to the base where the timer is being run + * @alarm: pointer to alarm being enqueued. + * + * Adds alarm to a alarm_base timerqueue and if necessary sets + * an hrtimer to run. + * + * Must hold base->lock when calling. + */ +static void alarmtimer_enqueue(struct alarm_base *base, struct alarm *alarm) +{ + timerqueue_add(&base->timerqueue, &alarm->node); + if (&alarm->node == timerqueue_getnext(&base->timerqueue)) { + hrtimer_try_to_cancel(&base->timer); + hrtimer_start(&base->timer, alarm->node.expires, + HRTIMER_MODE_ABS); + } +} + +/* + * alarmtimer_remove - Removes an alarm timer from an alarm_base timerqueue + * @base: pointer to the base where the timer is running + * @alarm: pointer to alarm being removed + * + * Removes alarm to a alarm_base timerqueue and if necessary sets + * a new timer to run. + * + * Must hold base->lock when calling. + */ +static void alarmtimer_remove(struct alarm_base *base, struct alarm *alarm) +{ + struct timerqueue_node *next = timerqueue_getnext(&base->timerqueue); + + timerqueue_del(&base->timerqueue, &alarm->node); + if (next == &alarm->node) { + hrtimer_try_to_cancel(&base->timer); + next = timerqueue_getnext(&base->timerqueue); + if (!next) + return; + hrtimer_start(&base->timer, next->expires, HRTIMER_MODE_ABS); + } +} + +/* + * alarmtimer_do_work - Handles alarm being fired. + * @work: pointer to workqueue being run + * + * When a timer fires, this runs through the timerqueue to see + * which alarm timers, and run those that expired. If there are + * more alarm timers queued, we set the hrtimer to fire in the + * future. + */ +void alarmtimer_do_work(struct work_struct *work) +{ + struct alarm_base *base = container_of(work, struct alarm_base, + irqwork); + struct timerqueue_node *next; + unsigned long flags; + ktime_t now; + + spin_lock_irqsave(&base->lock, flags); + now = base->gettime(); + while ((next = timerqueue_getnext(&base->timerqueue))) { + struct alarm *alarm; + ktime_t expired = next->expires; + + if (expired.tv64 >= now.tv64) + break; + + alarm = container_of(next, struct alarm, node); + + timerqueue_del(&base->timerqueue, &alarm->node); + alarm->enabled = 0; + /* Re-add periodic timers */ + if (alarm->period.tv64) { + alarm->node.expires = ktime_add(expired, alarm->period); + timerqueue_add(&base->timerqueue, &alarm->node); + alarm->enabled = 1; + } + spin_unlock_irqrestore(&base->lock, flags); + if (alarm->function) + alarm->function(alarm); + spin_lock_irqsave(&base->lock, flags); + } + + if (next) { + hrtimer_start(&base->timer, next->expires, + HRTIMER_MODE_ABS); + } + spin_unlock_irqrestore(&base->lock, flags); +} + + +/* + * alarmtimer_fired - Handles alarm hrtimer being fired. + * @timer: pointer to hrtimer being run + * + * When a timer fires, this schedules the do_work function to + * be run. + */ +static enum hrtimer_restart alarmtimer_fired(struct hrtimer *timer) +{ + struct alarm_base *base = container_of(timer, struct alarm_base, timer); + schedule_work(&base->irqwork); + return HRTIMER_NORESTART; +} + + +/* + * alarmtimer_suspend - Suspend time callback + * @dev: unused + * @state: unused + * + * When we are going into suspend, we look through the bases + * to see which is the soonest timer to expire. We then + * set an rtc timer to fire that far into the future, which + * will wake us from suspend. + */ +static int alarmtimer_suspend(struct device *dev) +{ + struct rtc_time tm; + ktime_t min, now; + unsigned long flags; + int i; + + spin_lock_irqsave(&freezer_delta_lock, flags); + min = freezer_delta; + freezer_delta = ktime_set(0, 0); + spin_unlock_irqrestore(&freezer_delta_lock, flags); + + /* If we have no rtcdev, just return */ + if (!rtcdev) + return 0; + + /* Find the soonest timer to expire*/ + for (i = 0; i < ALARM_NUMTYPE; i++) { + struct alarm_base *base = &alarm_bases[i]; + struct timerqueue_node *next; + ktime_t delta; + + spin_lock_irqsave(&base->lock, flags); + next = timerqueue_getnext(&base->timerqueue); + spin_unlock_irqrestore(&base->lock, flags); + if (!next) + continue; + delta = ktime_sub(next->expires, base->gettime()); + if (!min.tv64 || (delta.tv64 < min.tv64)) + min = delta; + } + if (min.tv64 == 0) + return 0; + + /* XXX - Should we enforce a minimum sleep time? */ + WARN_ON(min.tv64 < NSEC_PER_SEC); + + /* Setup an rtc timer to fire that far in the future */ + rtc_timer_cancel(rtcdev, &rtctimer); + rtc_read_time(rtcdev, &tm); + now = rtc_tm_to_ktime(tm); + now = ktime_add(now, min); + + rtc_timer_start(rtcdev, &rtctimer, now, ktime_set(0, 0)); + + return 0; +} + + +/************************************************************************** + * alarm kernel interface code + */ + +/* + * alarm_init - Initialize an alarm structure + * @alarm: ptr to alarm to be initialized + * @type: the type of the alarm + * @function: callback that is run when the alarm fires + * + * In-kernel interface to initializes the alarm structure. + */ +void alarm_init(struct alarm *alarm, enum alarmtimer_type type, + void (*function)(struct alarm *)) +{ + timerqueue_init(&alarm->node); + alarm->period = ktime_set(0, 0); + alarm->function = function; + alarm->type = type; + alarm->enabled = 0; +} + +/* + * alarm_start - Sets an alarm to fire + * @alarm: ptr to alarm to set + * @start: time to run the alarm + * @period: period at which the alarm will recur + * + * In-kernel interface set an alarm timer. + */ +void alarm_start(struct alarm *alarm, ktime_t start, ktime_t period) +{ + struct alarm_base *base = &alarm_bases[alarm->type]; + unsigned long flags; + + spin_lock_irqsave(&base->lock, flags); + if (alarm->enabled) + alarmtimer_remove(base, alarm); + alarm->node.expires = start; + alarm->period = period; + alarmtimer_enqueue(base, alarm); + alarm->enabled = 1; + spin_unlock_irqrestore(&base->lock, flags); +} + +/* + * alarm_cancel - Tries to cancel an alarm timer + * @alarm: ptr to alarm to be canceled + * + * In-kernel interface to cancel an alarm timer. + */ +void alarm_cancel(struct alarm *alarm) +{ + struct alarm_base *base = &alarm_bases[alarm->type]; + unsigned long flags; + + spin_lock_irqsave(&base->lock, flags); + if (alarm->enabled) + alarmtimer_remove(base, alarm); + alarm->enabled = 0; + spin_unlock_irqrestore(&base->lock, flags); +} + + + +/************************************************************************** + * alarmtimer initialization code + */ + +/* Suspend hook structures */ +static const struct dev_pm_ops alarmtimer_pm_ops = { + .suspend = alarmtimer_suspend, +}; + +static struct platform_driver alarmtimer_driver = { + .driver = { + .name = "alarmtimer", + .pm = &alarmtimer_pm_ops, + } +}; + +/** + * alarmtimer_init - Initialize alarm timer code + * + * This function initializes the alarm bases and registers + * the posix clock ids. + */ +static int __init alarmtimer_init(void) +{ + int error = 0; + int i; + + /* Initialize alarm bases */ + alarm_bases[ALARM_REALTIME].base_clockid = CLOCK_REALTIME; + alarm_bases[ALARM_REALTIME].gettime = &ktime_get_real; + alarm_bases[ALARM_BOOTTIME].base_clockid = CLOCK_BOOTTIME; + alarm_bases[ALARM_BOOTTIME].gettime = &ktime_get_boottime; + for (i = 0; i < ALARM_NUMTYPE; i++) { + timerqueue_init_head(&alarm_bases[i].timerqueue); + spin_lock_init(&alarm_bases[i].lock); + hrtimer_init(&alarm_bases[i].timer, + alarm_bases[i].base_clockid, + HRTIMER_MODE_ABS); + alarm_bases[i].timer.function = alarmtimer_fired; + INIT_WORK(&alarm_bases[i].irqwork, alarmtimer_do_work); + } + error = platform_driver_register(&alarmtimer_driver); + platform_device_register_simple("alarmtimer", -1, NULL, 0); + + return error; +} +device_initcall(alarmtimer_init); + +/** + * has_wakealarm - check rtc device has wakealarm ability + * @dev: current device + * @name_ptr: name to be returned + * + * This helper function checks to see if the rtc device can wake + * from suspend. + */ +static int __init has_wakealarm(struct device *dev, void *name_ptr) +{ + struct rtc_device *candidate = to_rtc_device(dev); + + if (!candidate->ops->set_alarm) + return 0; + if (!device_may_wakeup(candidate->dev.parent)) + return 0; + + *(const char **)name_ptr = dev_name(dev); + return 1; +} + +/** + * alarmtimer_init_late - Late initializing of alarmtimer code + * + * This function locates a rtc device to use for wakealarms. + * Run as late_initcall to make sure rtc devices have been + * registered. + */ +static int __init alarmtimer_init_late(void) +{ + char *str; + + /* Find an rtc device and init the rtc_timer */ + class_find_device(rtc_class, NULL, &str, has_wakealarm); + if (str) + rtcdev = rtc_class_open(str); + if (!rtcdev) { + printk(KERN_WARNING "No RTC device found, ALARM timers will" + " not wake from suspend"); + } + rtc_timer_init(&rtctimer, NULL, NULL); + + return 0; +} +late_initcall(alarmtimer_init_late); -- cgit From 9a7adcf5c6dea63d2e47e6f6d2f7a6c9f48b9337 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Tue, 11 Jan 2011 09:54:33 -0800 Subject: timers: Posix interface for alarm-timers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch exposes alarm-timers to userland via the posix clock and timers interface, using two new clockids: CLOCK_REALTIME_ALARM and CLOCK_BOOTTIME_ALARM. Both clockids behave identically to CLOCK_REALTIME and CLOCK_BOOTTIME, respectively, but timers set against the _ALARM suffixed clockids will wake the system if it is suspended. Some background can be found here: https://lwn.net/Articles/429925/ The concept for Alarm-timers was inspired by the Android Alarm driver (by Arve HjønnevÃ¥g) found in the Android kernel tree. See: http://android.git.kernel.org/?p=kernel/common.git;a=blob;f=drivers/rtc/alarm.c;h=1250edfbdf3302f5e4ea6194847c6ef4bb7beb1c;hb=android-2.6.36 While the in-kernel interface is pretty similar between alarm-timers and Android alarm driver, the user-space interface for the Android alarm driver is via ioctls to a new char device. As mentioned above, I've instead chosen to export this functionality via the posix interface, as it seemed a little simpler and avoids creating duplicate interfaces to things like CLOCK_REALTIME and CLOCK_MONOTONIC under alternate names (ie:ANDROID_ALARM_RTC and ANDROID_ALARM_SYSTEMTIME). The semantics of the Android alarm driver are different from what this posix interface provides. For instance, threads other then the thread waiting on the Android alarm driver are able to modify the alarm being waited on. Also this interface does not allow the same wakelock semantics that the Android driver provides (ie: kernel takes a wakelock on RTC alarm-interupt, and holds it through process wakeup, and while the process runs, until the process either closes the char device or calls back in to wait on a new alarm). One potential way to implement similar semantics may be via the timerfd infrastructure, but this needs more research. There may also need to be some sort of sysfs system level policy hooks that allow alarm timers to be disabled to keep them from firing at inappropriate times (ie: laptop in a well insulated bag, mid-flight). CC: Arve HjønnevÃ¥g CC: Thomas Gleixner CC: Alessandro Zummo Acked-by: Arnd Bergmann Signed-off-by: John Stultz --- include/linux/capability.h | 7 +- include/linux/posix-timers.h | 2 + include/linux/time.h | 2 + kernel/time/alarmtimer.c | 330 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 340 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/capability.h b/include/linux/capability.h index 16ee8b49a200..7cb23eae693d 100644 --- a/include/linux/capability.h +++ b/include/linux/capability.h @@ -355,7 +355,12 @@ struct cpu_vfs_cap_data { #define CAP_SYSLOG 34 -#define CAP_LAST_CAP CAP_SYSLOG +/* Allow triggering something that will wake the system */ + +#define CAP_WAKE_ALARM 35 + + +#define CAP_LAST_CAP CAP_WAKE_ALARM #define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP) diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h index d51243ae0726..808227d40a64 100644 --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -5,6 +5,7 @@ #include #include #include +#include union cpu_time_count { cputime_t cpu; @@ -80,6 +81,7 @@ struct k_itimer { unsigned long incr; unsigned long expires; } mmtimer; + struct alarm alarmtimer; } it; }; diff --git a/include/linux/time.h b/include/linux/time.h index 4ea5a75fcacd..b3061782dec3 100644 --- a/include/linux/time.h +++ b/include/linux/time.h @@ -295,6 +295,8 @@ struct itimerval { #define CLOCK_REALTIME_COARSE 5 #define CLOCK_MONOTONIC_COARSE 6 #define CLOCK_BOOTTIME 7 +#define CLOCK_REALTIME_ALARM 8 +#define CLOCK_BOOTTIME_ALARM 9 /* * The IDs of various hardware clocks: diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index 48c2ee949e61..4058ad79d55f 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -215,6 +215,21 @@ static int alarmtimer_suspend(struct device *dev) } +static void alarmtimer_freezerset(ktime_t absexp, enum alarmtimer_type type) +{ + ktime_t delta; + unsigned long flags; + struct alarm_base *base = &alarm_bases[type]; + + delta = ktime_sub(absexp, base->gettime()); + + spin_lock_irqsave(&freezer_delta_lock, flags); + if (!freezer_delta.tv64 || (delta.tv64 < freezer_delta.tv64)) + freezer_delta = delta; + spin_unlock_irqrestore(&freezer_delta_lock, flags); +} + + /************************************************************************** * alarm kernel interface code */ @@ -279,6 +294,309 @@ void alarm_cancel(struct alarm *alarm) } +/************************************************************************** + * alarm posix interface code + */ + +/* + * clock2alarm - helper that converts from clockid to alarmtypes + * @clockid: clockid. + * + * Helper function that converts from clockids to alarmtypes + */ +static enum alarmtimer_type clock2alarm(clockid_t clockid) +{ + if (clockid == CLOCK_REALTIME_ALARM) + return ALARM_REALTIME; + if (clockid == CLOCK_BOOTTIME_ALARM) + return ALARM_BOOTTIME; + return -1; +} + +/* + * alarm_handle_timer - Callback for posix timers + * @alarm: alarm that fired + * + * Posix timer callback for expired alarm timers. + */ +static void alarm_handle_timer(struct alarm *alarm) +{ + struct k_itimer *ptr = container_of(alarm, struct k_itimer, + it.alarmtimer); + if (posix_timer_event(ptr, 0) != 0) + ptr->it_overrun++; +} + +/* + * alarm_clock_getres - posix getres interface + * @which_clock: clockid + * @tp: timespec to fill + * + * Returns the granularity of underlying alarm base clock + */ +static int alarm_clock_getres(const clockid_t which_clock, struct timespec *tp) +{ + clockid_t baseid = alarm_bases[clock2alarm(which_clock)].base_clockid; + + return hrtimer_get_res(baseid, tp); +} + +/** + * alarm_clock_get - posix clock_get interface + * @which_clock: clockid + * @tp: timespec to fill. + * + * Provides the underlying alarm base time. + */ +static int alarm_clock_get(clockid_t which_clock, struct timespec *tp) +{ + struct alarm_base *base = &alarm_bases[clock2alarm(which_clock)]; + + *tp = ktime_to_timespec(base->gettime()); + return 0; +} + +/** + * alarm_timer_create - posix timer_create interface + * @new_timer: k_itimer pointer to manage + * + * Initializes the k_itimer structure. + */ +static int alarm_timer_create(struct k_itimer *new_timer) +{ + enum alarmtimer_type type; + struct alarm_base *base; + + if (!capable(CAP_WAKE_ALARM)) + return -EPERM; + + type = clock2alarm(new_timer->it_clock); + base = &alarm_bases[type]; + alarm_init(&new_timer->it.alarmtimer, type, alarm_handle_timer); + return 0; +} + +/** + * alarm_timer_get - posix timer_get interface + * @new_timer: k_itimer pointer + * @cur_setting: itimerspec data to fill + * + * Copies the itimerspec data out from the k_itimer + */ +static void alarm_timer_get(struct k_itimer *timr, + struct itimerspec *cur_setting) +{ + cur_setting->it_interval = + ktime_to_timespec(timr->it.alarmtimer.period); + cur_setting->it_value = + ktime_to_timespec(timr->it.alarmtimer.node.expires); + return; +} + +/** + * alarm_timer_del - posix timer_del interface + * @timr: k_itimer pointer to be deleted + * + * Cancels any programmed alarms for the given timer. + */ +static int alarm_timer_del(struct k_itimer *timr) +{ + alarm_cancel(&timr->it.alarmtimer); + return 0; +} + +/** + * alarm_timer_set - posix timer_set interface + * @timr: k_itimer pointer to be deleted + * @flags: timer flags + * @new_setting: itimerspec to be used + * @old_setting: itimerspec being replaced + * + * Sets the timer to new_setting, and starts the timer. + */ +static int alarm_timer_set(struct k_itimer *timr, int flags, + struct itimerspec *new_setting, + struct itimerspec *old_setting) +{ + /* Save old values */ + old_setting->it_interval = + ktime_to_timespec(timr->it.alarmtimer.period); + old_setting->it_value = + ktime_to_timespec(timr->it.alarmtimer.node.expires); + + /* If the timer was already set, cancel it */ + alarm_cancel(&timr->it.alarmtimer); + + /* start the timer */ + alarm_start(&timr->it.alarmtimer, + timespec_to_ktime(new_setting->it_value), + timespec_to_ktime(new_setting->it_interval)); + return 0; +} + +/** + * alarmtimer_nsleep_wakeup - Wakeup function for alarm_timer_nsleep + * @alarm: ptr to alarm that fired + * + * Wakes up the task that set the alarmtimer + */ +static void alarmtimer_nsleep_wakeup(struct alarm *alarm) +{ + struct task_struct *task = (struct task_struct *)alarm->data; + + alarm->data = NULL; + if (task) + wake_up_process(task); +} + +/** + * alarmtimer_do_nsleep - Internal alarmtimer nsleep implementation + * @alarm: ptr to alarmtimer + * @absexp: absolute expiration time + * + * Sets the alarm timer and sleeps until it is fired or interrupted. + */ +static int alarmtimer_do_nsleep(struct alarm *alarm, ktime_t absexp) +{ + alarm->data = (void *)current; + do { + set_current_state(TASK_INTERRUPTIBLE); + alarm_start(alarm, absexp, ktime_set(0, 0)); + if (likely(alarm->data)) + schedule(); + + alarm_cancel(alarm); + } while (alarm->data && !signal_pending(current)); + + __set_current_state(TASK_RUNNING); + + return (alarm->data == NULL); +} + + +/** + * update_rmtp - Update remaining timespec value + * @exp: expiration time + * @type: timer type + * @rmtp: user pointer to remaining timepsec value + * + * Helper function that fills in rmtp value with time between + * now and the exp value + */ +static int update_rmtp(ktime_t exp, enum alarmtimer_type type, + struct timespec __user *rmtp) +{ + struct timespec rmt; + ktime_t rem; + + rem = ktime_sub(exp, alarm_bases[type].gettime()); + + if (rem.tv64 <= 0) + return 0; + rmt = ktime_to_timespec(rem); + + if (copy_to_user(rmtp, &rmt, sizeof(*rmtp))) + return -EFAULT; + + return 1; + +} + +/** + * alarm_timer_nsleep_restart - restartblock alarmtimer nsleep + * @restart: ptr to restart block + * + * Handles restarted clock_nanosleep calls + */ +static long __sched alarm_timer_nsleep_restart(struct restart_block *restart) +{ + enum alarmtimer_type type = restart->nanosleep.index; + ktime_t exp; + struct timespec __user *rmtp; + struct alarm alarm; + int ret = 0; + + exp.tv64 = restart->nanosleep.expires; + alarm_init(&alarm, type, alarmtimer_nsleep_wakeup); + + if (alarmtimer_do_nsleep(&alarm, exp)) + goto out; + + if (freezing(current)) + alarmtimer_freezerset(exp, type); + + rmtp = restart->nanosleep.rmtp; + if (rmtp) { + ret = update_rmtp(exp, type, rmtp); + if (ret <= 0) + goto out; + } + + + /* The other values in restart are already filled in */ + ret = -ERESTART_RESTARTBLOCK; +out: + return ret; +} + +/** + * alarm_timer_nsleep - alarmtimer nanosleep + * @which_clock: clockid + * @flags: determins abstime or relative + * @tsreq: requested sleep time (abs or rel) + * @rmtp: remaining sleep time saved + * + * Handles clock_nanosleep calls against _ALARM clockids + */ +static int alarm_timer_nsleep(const clockid_t which_clock, int flags, + struct timespec *tsreq, struct timespec __user *rmtp) +{ + enum alarmtimer_type type = clock2alarm(which_clock); + struct alarm alarm; + ktime_t exp; + int ret = 0; + struct restart_block *restart; + + if (!capable(CAP_WAKE_ALARM)) + return -EPERM; + + alarm_init(&alarm, type, alarmtimer_nsleep_wakeup); + + exp = timespec_to_ktime(*tsreq); + /* Convert (if necessary) to absolute time */ + if (flags != TIMER_ABSTIME) { + ktime_t now = alarm_bases[type].gettime(); + exp = ktime_add(now, exp); + } + + if (alarmtimer_do_nsleep(&alarm, exp)) + goto out; + + if (freezing(current)) + alarmtimer_freezerset(exp, type); + + /* abs timers don't set remaining time or restart */ + if (flags == TIMER_ABSTIME) { + ret = -ERESTARTNOHAND; + goto out; + } + + if (rmtp) { + ret = update_rmtp(exp, type, rmtp); + if (ret <= 0) + goto out; + } + + restart = ¤t_thread_info()->restart_block; + restart->fn = alarm_timer_nsleep_restart; + restart->nanosleep.index = type; + restart->nanosleep.expires = exp.tv64; + restart->nanosleep.rmtp = rmtp; + ret = -ERESTART_RESTARTBLOCK; + +out: + return ret; +} /************************************************************************** * alarmtimer initialization code @@ -306,6 +624,18 @@ static int __init alarmtimer_init(void) { int error = 0; int i; + struct k_clock alarm_clock = { + .clock_getres = alarm_clock_getres, + .clock_get = alarm_clock_get, + .timer_create = alarm_timer_create, + .timer_set = alarm_timer_set, + .timer_del = alarm_timer_del, + .timer_get = alarm_timer_get, + .nsleep = alarm_timer_nsleep, + }; + + posix_timers_register_clock(CLOCK_REALTIME_ALARM, &alarm_clock); + posix_timers_register_clock(CLOCK_BOOTTIME_ALARM, &alarm_clock); /* Initialize alarm bases */ alarm_bases[ALARM_REALTIME].base_clockid = CLOCK_REALTIME; -- cgit From 28331a46d88459788c8fca72dbb0415cd7f514c9 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 27 Apr 2011 13:47:52 -0400 Subject: NFSv4: Ensure we request the ordinary fileid when doing readdirplus When readdir() returns a directory entry for the root of a mounted filesystem, Linux follows the old convention of returning the inode number of the covered directory (despite newer versions of POSIX declaring that this is a bug). To ensure this continues to work, the NFSv4 readdir implementation requests the 'mounted-on-fileid' from the server. However, readdirplus also needs to instantiate an inode for this entry, and for that, we also need to request the real fileid as per this patch. Signed-off-by: Trond Myklebust --- fs/nfs/nfs4xdr.c | 31 ++++++++++++++----------------- include/linux/nfs_xdr.h | 2 ++ 2 files changed, 16 insertions(+), 17 deletions(-) (limited to 'include/linux') diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index ba952bdc4d62..7310d2ec5de8 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -1452,26 +1452,25 @@ static void encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args, static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req, struct compound_hdr *hdr) { - uint32_t attrs[2] = {0, 0}; + uint32_t attrs[2] = { + FATTR4_WORD0_RDATTR_ERROR, + FATTR4_WORD1_MOUNTED_ON_FILEID, + }; uint32_t dircount = readdir->count >> 1; __be32 *p; if (readdir->plus) { attrs[0] |= FATTR4_WORD0_TYPE|FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE| - FATTR4_WORD0_FSID|FATTR4_WORD0_FILEHANDLE; + FATTR4_WORD0_FSID|FATTR4_WORD0_FILEHANDLE|FATTR4_WORD0_FILEID; attrs[1] |= FATTR4_WORD1_MODE|FATTR4_WORD1_NUMLINKS|FATTR4_WORD1_OWNER| FATTR4_WORD1_OWNER_GROUP|FATTR4_WORD1_RAWDEV| FATTR4_WORD1_SPACE_USED|FATTR4_WORD1_TIME_ACCESS| FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY; dircount >>= 1; } - attrs[0] |= FATTR4_WORD0_RDATTR_ERROR|FATTR4_WORD0_FILEID; - attrs[1] |= FATTR4_WORD1_MOUNTED_ON_FILEID; - /* Switch to mounted_on_fileid if the server supports it */ - if (readdir->bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID) - attrs[0] &= ~FATTR4_WORD0_FILEID; - else - attrs[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID; + /* Use mounted_on_fileid only if the server supports it */ + if (!(readdir->bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID)) + attrs[0] |= FATTR4_WORD0_FILEID; p = reserve_space(xdr, 12+NFS4_VERIFIER_SIZE+20); *p++ = cpu_to_be32(OP_READDIR); @@ -3140,7 +3139,7 @@ static int decode_attr_mounted_on_fileid(struct xdr_stream *xdr, uint32_t *bitma goto out_overflow; xdr_decode_hyper(p, fileid); bitmap[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID; - ret = NFS_ATTR_FATTR_FILEID; + ret = NFS_ATTR_FATTR_MOUNTED_ON_FILEID; } dprintk("%s: fileid=%Lu\n", __func__, (unsigned long long)*fileid); return ret; @@ -4002,7 +4001,6 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, { int status; umode_t fmode = 0; - uint64_t fileid; uint32_t type; status = decode_attr_type(xdr, bitmap, &type); @@ -4101,13 +4099,10 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, goto xdr_error; fattr->valid |= status; - status = decode_attr_mounted_on_fileid(xdr, bitmap, &fileid); + status = decode_attr_mounted_on_fileid(xdr, bitmap, &fattr->mounted_on_fileid); if (status < 0) goto xdr_error; - if (status != 0 && !(fattr->valid & status)) { - fattr->fileid = fileid; - fattr->valid |= status; - } + fattr->valid |= status; xdr_error: dprintk("%s: xdr returned %d\n", __func__, -status); @@ -6411,7 +6406,9 @@ int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, if (decode_getfattr_attrs(xdr, bitmap, entry->fattr, entry->fh, entry->server, 1) < 0) goto out_overflow; - if (entry->fattr->valid & NFS_ATTR_FATTR_FILEID) + if (entry->fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) + entry->ino = entry->fattr->mounted_on_fileid; + else if (entry->fattr->valid & NFS_ATTR_FATTR_FILEID) entry->ino = entry->fattr->fileid; entry->d_type = DT_UNKNOWN; diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 78b101e487ea..890dce242639 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -50,6 +50,7 @@ struct nfs_fattr { } du; struct nfs_fsid fsid; __u64 fileid; + __u64 mounted_on_fileid; struct timespec atime; struct timespec mtime; struct timespec ctime; @@ -83,6 +84,7 @@ struct nfs_fattr { #define NFS_ATTR_FATTR_PRECHANGE (1U << 18) #define NFS_ATTR_FATTR_V4_REFERRAL (1U << 19) /* NFSv4 referral */ #define NFS_ATTR_FATTR_MOUNTPOINT (1U << 20) /* Treat as mountpoint */ +#define NFS_ATTR_FATTR_MOUNTED_ON_FILEID (1U << 21) #define NFS_ATTR_FATTR (NFS_ATTR_FATTR_TYPE \ | NFS_ATTR_FATTR_MODE \ -- cgit From 26fc8775b51484d8c0a671198639c6d5ae60533e Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 15 Apr 2011 20:08:19 +0200 Subject: mmc: fix a race between card-detect rescan and clock-gate work instances Currently there is a race in the MMC core between a card-detect rescan work and the clock-gating work, scheduled from a command completion. Fix it by removing the dedicated clock-gating mutex and using the MMC standard locking mechanism instead. Signed-off-by: Guennadi Liakhovetski Cc: Simon Horman Cc: Magnus Damm Acked-by: Linus Walleij Cc: Signed-off-by: Chris Ball --- drivers/mmc/core/host.c | 9 ++++----- include/linux/mmc/host.h | 1 - 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 461e6a17fb90..2b200c1cfbba 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c @@ -94,7 +94,7 @@ static void mmc_host_clk_gate_delayed(struct mmc_host *host) spin_unlock_irqrestore(&host->clk_lock, flags); return; } - mutex_lock(&host->clk_gate_mutex); + mmc_claim_host(host); spin_lock_irqsave(&host->clk_lock, flags); if (!host->clk_requests) { spin_unlock_irqrestore(&host->clk_lock, flags); @@ -104,7 +104,7 @@ static void mmc_host_clk_gate_delayed(struct mmc_host *host) pr_debug("%s: gated MCI clock\n", mmc_hostname(host)); } spin_unlock_irqrestore(&host->clk_lock, flags); - mutex_unlock(&host->clk_gate_mutex); + mmc_release_host(host); } /* @@ -130,7 +130,7 @@ void mmc_host_clk_ungate(struct mmc_host *host) { unsigned long flags; - mutex_lock(&host->clk_gate_mutex); + mmc_claim_host(host); spin_lock_irqsave(&host->clk_lock, flags); if (host->clk_gated) { spin_unlock_irqrestore(&host->clk_lock, flags); @@ -140,7 +140,7 @@ void mmc_host_clk_ungate(struct mmc_host *host) } host->clk_requests++; spin_unlock_irqrestore(&host->clk_lock, flags); - mutex_unlock(&host->clk_gate_mutex); + mmc_release_host(host); } /** @@ -215,7 +215,6 @@ static inline void mmc_host_clk_init(struct mmc_host *host) host->clk_gated = false; INIT_WORK(&host->clk_gate_work, mmc_host_clk_gate_work); spin_lock_init(&host->clk_lock); - mutex_init(&host->clk_gate_mutex); } /** diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index bcb793ec7374..eb792cb6d745 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -183,7 +183,6 @@ struct mmc_host { struct work_struct clk_gate_work; /* delayed clock gate */ unsigned int clk_old; /* old clock value cache */ spinlock_t clk_lock; /* lock for clk fields */ - struct mutex clk_gate_mutex; /* mutex for clock gating */ #endif /* host specific block data */ -- cgit From 0a14842f5a3c0e88a1e59fac5c3025db39721f74 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 20 Apr 2011 09:27:32 +0000 Subject: net: filter: Just In Time compiler for x86-64 In order to speedup packet filtering, here is an implementation of a JIT compiler for x86_64 It is disabled by default, and must be enabled by the admin. echo 1 >/proc/sys/net/core/bpf_jit_enable It uses module_alloc() and module_free() to get memory in the 2GB text kernel range since we call helpers functions from the generated code. EAX : BPF A accumulator EBX : BPF X accumulator RDI : pointer to skb (first argument given to JIT function) RBP : frame pointer (even if CONFIG_FRAME_POINTER=n) r9d : skb->len - skb->data_len (headlen) r8 : skb->data To get a trace of generated code, use : echo 2 >/proc/sys/net/core/bpf_jit_enable Example of generated code : # tcpdump -p -n -s 0 -i eth1 host 192.168.20.0/24 flen=18 proglen=147 pass=3 image=ffffffffa00b5000 JIT code: ffffffffa00b5000: 55 48 89 e5 48 83 ec 60 48 89 5d f8 44 8b 4f 60 JIT code: ffffffffa00b5010: 44 2b 4f 64 4c 8b 87 b8 00 00 00 be 0c 00 00 00 JIT code: ffffffffa00b5020: e8 24 7b f7 e0 3d 00 08 00 00 75 28 be 1a 00 00 JIT code: ffffffffa00b5030: 00 e8 fe 7a f7 e0 24 00 3d 00 14 a8 c0 74 49 be JIT code: ffffffffa00b5040: 1e 00 00 00 e8 eb 7a f7 e0 24 00 3d 00 14 a8 c0 JIT code: ffffffffa00b5050: 74 36 eb 3b 3d 06 08 00 00 74 07 3d 35 80 00 00 JIT code: ffffffffa00b5060: 75 2d be 1c 00 00 00 e8 c8 7a f7 e0 24 00 3d 00 JIT code: ffffffffa00b5070: 14 a8 c0 74 13 be 26 00 00 00 e8 b5 7a f7 e0 24 JIT code: ffffffffa00b5080: 00 3d 00 14 a8 c0 75 07 b8 ff ff 00 00 eb 02 31 JIT code: ffffffffa00b5090: c0 c9 c3 BPF program is 144 bytes long, so native program is almost same size ;) (000) ldh [12] (001) jeq #0x800 jt 2 jf 8 (002) ld [26] (003) and #0xffffff00 (004) jeq #0xc0a81400 jt 16 jf 5 (005) ld [30] (006) and #0xffffff00 (007) jeq #0xc0a81400 jt 16 jf 17 (008) jeq #0x806 jt 10 jf 9 (009) jeq #0x8035 jt 10 jf 17 (010) ld [28] (011) and #0xffffff00 (012) jeq #0xc0a81400 jt 16 jf 13 (013) ld [38] (014) and #0xffffff00 (015) jeq #0xc0a81400 jt 16 jf 17 (016) ret #65535 (017) ret #0 Signed-off-by: Eric Dumazet Cc: Arnaldo Carvalho de Melo Cc: Ben Hutchings Cc: Hagen Paul Pfeifer Signed-off-by: David S. Miller --- Documentation/sysctl/net.txt | 11 + MAINTAINERS | 1 + arch/x86/Kbuild | 1 + arch/x86/Kconfig | 1 + arch/x86/net/Makefile | 4 + arch/x86/net/bpf_jit.S | 140 +++++++++ arch/x86/net/bpf_jit_comp.c | 654 +++++++++++++++++++++++++++++++++++++++++++ include/linux/filter.h | 76 +++++ include/linux/netdevice.h | 1 + include/linux/skbuff.h | 2 +- net/Kconfig | 13 + net/core/filter.c | 65 +---- net/core/sysctl_net_core.c | 9 + net/packet/af_packet.c | 2 +- 14 files changed, 918 insertions(+), 62 deletions(-) create mode 100644 arch/x86/net/Makefile create mode 100644 arch/x86/net/bpf_jit.S create mode 100644 arch/x86/net/bpf_jit_comp.c (limited to 'include/linux') diff --git a/Documentation/sysctl/net.txt b/Documentation/sysctl/net.txt index cbd05ffc606b..3201a7097e4d 100644 --- a/Documentation/sysctl/net.txt +++ b/Documentation/sysctl/net.txt @@ -32,6 +32,17 @@ Table : Subdirectories in /proc/sys/net 1. /proc/sys/net/core - Network core options ------------------------------------------------------- +bpf_jit_enable +-------------- + +This enables Berkeley Packet Filter Just in Time compiler. +Currently supported on x86_64 architecture, bpf_jit provides a framework +to speed packet filtering, the one used by tcpdump/libpcap for example. +Values : + 0 - disable the JIT (default value) + 1 - enable the JIT + 2 - enable the JIT and ask the compiler to emit traces on kernel log. + rmem_default ------------ diff --git a/MAINTAINERS b/MAINTAINERS index b5266ad50167..17c0917a26ea 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4372,6 +4372,7 @@ S: Maintained F: net/ipv4/ F: net/ipv6/ F: include/net/ip* +F: arch/x86/net/* NETWORKING [LABELED] (NetLabel, CIPSO, Labeled IPsec, SECMARK) M: Paul Moore diff --git a/arch/x86/Kbuild b/arch/x86/Kbuild index 0e103236b754..0e9dec6cadd1 100644 --- a/arch/x86/Kbuild +++ b/arch/x86/Kbuild @@ -15,3 +15,4 @@ obj-y += vdso/ obj-$(CONFIG_IA32_EMULATION) += ia32/ obj-y += platform/ +obj-y += net/ diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index cc6c53a95bfd..855a1bdc437d 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -72,6 +72,7 @@ config X86 select IRQ_FORCED_THREADING select USE_GENERIC_SMP_HELPERS if SMP select ARCH_NO_SYSDEV_OPS + select HAVE_BPF_JIT if X86_64 config INSTRUCTION_DECODER def_bool (KPROBES || PERF_EVENTS) diff --git a/arch/x86/net/Makefile b/arch/x86/net/Makefile new file mode 100644 index 000000000000..90568c33ddb0 --- /dev/null +++ b/arch/x86/net/Makefile @@ -0,0 +1,4 @@ +# +# Arch-specific network modules +# +obj-$(CONFIG_BPF_JIT) += bpf_jit.o bpf_jit_comp.o diff --git a/arch/x86/net/bpf_jit.S b/arch/x86/net/bpf_jit.S new file mode 100644 index 000000000000..66870223f8c5 --- /dev/null +++ b/arch/x86/net/bpf_jit.S @@ -0,0 +1,140 @@ +/* bpf_jit.S : BPF JIT helper functions + * + * Copyright (C) 2011 Eric Dumazet (eric.dumazet@gmail.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + */ +#include +#include + +/* + * Calling convention : + * rdi : skb pointer + * esi : offset of byte(s) to fetch in skb (can be scratched) + * r8 : copy of skb->data + * r9d : hlen = skb->len - skb->data_len + */ +#define SKBDATA %r8 + +sk_load_word_ind: + .globl sk_load_word_ind + + add %ebx,%esi /* offset += X */ +# test %esi,%esi /* if (offset < 0) goto bpf_error; */ + js bpf_error + +sk_load_word: + .globl sk_load_word + + mov %r9d,%eax # hlen + sub %esi,%eax # hlen - offset + cmp $3,%eax + jle bpf_slow_path_word + mov (SKBDATA,%rsi),%eax + bswap %eax /* ntohl() */ + ret + + +sk_load_half_ind: + .globl sk_load_half_ind + + add %ebx,%esi /* offset += X */ + js bpf_error + +sk_load_half: + .globl sk_load_half + + mov %r9d,%eax + sub %esi,%eax # hlen - offset + cmp $1,%eax + jle bpf_slow_path_half + movzwl (SKBDATA,%rsi),%eax + rol $8,%ax # ntohs() + ret + +sk_load_byte_ind: + .globl sk_load_byte_ind + add %ebx,%esi /* offset += X */ + js bpf_error + +sk_load_byte: + .globl sk_load_byte + + cmp %esi,%r9d /* if (offset >= hlen) goto bpf_slow_path_byte */ + jle bpf_slow_path_byte + movzbl (SKBDATA,%rsi),%eax + ret + +/** + * sk_load_byte_msh - BPF_S_LDX_B_MSH helper + * + * Implements BPF_S_LDX_B_MSH : ldxb 4*([offset]&0xf) + * Must preserve A accumulator (%eax) + * Inputs : %esi is the offset value, already known positive + */ +ENTRY(sk_load_byte_msh) + CFI_STARTPROC + cmp %esi,%r9d /* if (offset >= hlen) goto bpf_slow_path_byte_msh */ + jle bpf_slow_path_byte_msh + movzbl (SKBDATA,%rsi),%ebx + and $15,%bl + shl $2,%bl + ret + CFI_ENDPROC +ENDPROC(sk_load_byte_msh) + +bpf_error: +# force a return 0 from jit handler + xor %eax,%eax + mov -8(%rbp),%rbx + leaveq + ret + +/* rsi contains offset and can be scratched */ +#define bpf_slow_path_common(LEN) \ + push %rdi; /* save skb */ \ + push %r9; \ + push SKBDATA; \ +/* rsi already has offset */ \ + mov $LEN,%ecx; /* len */ \ + lea -12(%rbp),%rdx; \ + call skb_copy_bits; \ + test %eax,%eax; \ + pop SKBDATA; \ + pop %r9; \ + pop %rdi + + +bpf_slow_path_word: + bpf_slow_path_common(4) + js bpf_error + mov -12(%rbp),%eax + bswap %eax + ret + +bpf_slow_path_half: + bpf_slow_path_common(2) + js bpf_error + mov -12(%rbp),%ax + rol $8,%ax + movzwl %ax,%eax + ret + +bpf_slow_path_byte: + bpf_slow_path_common(1) + js bpf_error + movzbl -12(%rbp),%eax + ret + +bpf_slow_path_byte_msh: + xchg %eax,%ebx /* dont lose A , X is about to be scratched */ + bpf_slow_path_common(1) + js bpf_error + movzbl -12(%rbp),%eax + and $15,%al + shl $2,%al + xchg %eax,%ebx + ret diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c new file mode 100644 index 000000000000..bfab3fa10edc --- /dev/null +++ b/arch/x86/net/bpf_jit_comp.c @@ -0,0 +1,654 @@ +/* bpf_jit_comp.c : BPF JIT compiler + * + * Copyright (C) 2011 Eric Dumazet (eric.dumazet@gmail.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + */ +#include +#include +#include +#include + +/* + * Conventions : + * EAX : BPF A accumulator + * EBX : BPF X accumulator + * RDI : pointer to skb (first argument given to JIT function) + * RBP : frame pointer (even if CONFIG_FRAME_POINTER=n) + * ECX,EDX,ESI : scratch registers + * r9d : skb->len - skb->data_len (headlen) + * r8 : skb->data + * -8(RBP) : saved RBX value + * -16(RBP)..-80(RBP) : BPF_MEMWORDS values + */ +int bpf_jit_enable __read_mostly; + +/* + * assembly code in arch/x86/net/bpf_jit.S + */ +extern u8 sk_load_word[], sk_load_half[], sk_load_byte[], sk_load_byte_msh[]; +extern u8 sk_load_word_ind[], sk_load_half_ind[], sk_load_byte_ind[]; + +static inline u8 *emit_code(u8 *ptr, u32 bytes, unsigned int len) +{ + if (len == 1) + *ptr = bytes; + else if (len == 2) + *(u16 *)ptr = bytes; + else { + *(u32 *)ptr = bytes; + barrier(); + } + return ptr + len; +} + +#define EMIT(bytes, len) do { prog = emit_code(prog, bytes, len); } while (0) + +#define EMIT1(b1) EMIT(b1, 1) +#define EMIT2(b1, b2) EMIT((b1) + ((b2) << 8), 2) +#define EMIT3(b1, b2, b3) EMIT((b1) + ((b2) << 8) + ((b3) << 16), 3) +#define EMIT4(b1, b2, b3, b4) EMIT((b1) + ((b2) << 8) + ((b3) << 16) + ((b4) << 24), 4) +#define EMIT1_off32(b1, off) do { EMIT1(b1); EMIT(off, 4);} while (0) + +#define CLEAR_A() EMIT2(0x31, 0xc0) /* xor %eax,%eax */ +#define CLEAR_X() EMIT2(0x31, 0xdb) /* xor %ebx,%ebx */ + +static inline bool is_imm8(int value) +{ + return value <= 127 && value >= -128; +} + +static inline bool is_near(int offset) +{ + return offset <= 127 && offset >= -128; +} + +#define EMIT_JMP(offset) \ +do { \ + if (offset) { \ + if (is_near(offset)) \ + EMIT2(0xeb, offset); /* jmp .+off8 */ \ + else \ + EMIT1_off32(0xe9, offset); /* jmp .+off32 */ \ + } \ +} while (0) + +/* list of x86 cond jumps opcodes (. + s8) + * Add 0x10 (and an extra 0x0f) to generate far jumps (. + s32) + */ +#define X86_JB 0x72 +#define X86_JAE 0x73 +#define X86_JE 0x74 +#define X86_JNE 0x75 +#define X86_JBE 0x76 +#define X86_JA 0x77 + +#define EMIT_COND_JMP(op, offset) \ +do { \ + if (is_near(offset)) \ + EMIT2(op, offset); /* jxx .+off8 */ \ + else { \ + EMIT2(0x0f, op + 0x10); \ + EMIT(offset, 4); /* jxx .+off32 */ \ + } \ +} while (0) + +#define COND_SEL(CODE, TOP, FOP) \ + case CODE: \ + t_op = TOP; \ + f_op = FOP; \ + goto cond_branch + + +#define SEEN_DATAREF 1 /* might call external helpers */ +#define SEEN_XREG 2 /* ebx is used */ +#define SEEN_MEM 4 /* use mem[] for temporary storage */ + +static inline void bpf_flush_icache(void *start, void *end) +{ + mm_segment_t old_fs = get_fs(); + + set_fs(KERNEL_DS); + smp_wmb(); + flush_icache_range((unsigned long)start, (unsigned long)end); + set_fs(old_fs); +} + + +void bpf_jit_compile(struct sk_filter *fp) +{ + u8 temp[64]; + u8 *prog; + unsigned int proglen, oldproglen = 0; + int ilen, i; + int t_offset, f_offset; + u8 t_op, f_op, seen = 0, pass; + u8 *image = NULL; + u8 *func; + int pc_ret0 = -1; /* bpf index of first RET #0 instruction (if any) */ + unsigned int cleanup_addr; /* epilogue code offset */ + unsigned int *addrs; + const struct sock_filter *filter = fp->insns; + int flen = fp->len; + + if (!bpf_jit_enable) + return; + + addrs = kmalloc(flen * sizeof(*addrs), GFP_KERNEL); + if (addrs == NULL) + return; + + /* Before first pass, make a rough estimation of addrs[] + * each bpf instruction is translated to less than 64 bytes + */ + for (proglen = 0, i = 0; i < flen; i++) { + proglen += 64; + addrs[i] = proglen; + } + cleanup_addr = proglen; /* epilogue address */ + + for (pass = 0; pass < 10; pass++) { + /* no prologue/epilogue for trivial filters (RET something) */ + proglen = 0; + prog = temp; + + if (seen) { + EMIT4(0x55, 0x48, 0x89, 0xe5); /* push %rbp; mov %rsp,%rbp */ + EMIT4(0x48, 0x83, 0xec, 96); /* subq $96,%rsp */ + /* note : must save %rbx in case bpf_error is hit */ + if (seen & (SEEN_XREG | SEEN_DATAREF)) + EMIT4(0x48, 0x89, 0x5d, 0xf8); /* mov %rbx, -8(%rbp) */ + if (seen & SEEN_XREG) + CLEAR_X(); /* make sure we dont leek kernel memory */ + + /* + * If this filter needs to access skb data, + * loads r9 and r8 with : + * r9 = skb->len - skb->data_len + * r8 = skb->data + */ + if (seen & SEEN_DATAREF) { + if (offsetof(struct sk_buff, len) <= 127) + /* mov off8(%rdi),%r9d */ + EMIT4(0x44, 0x8b, 0x4f, offsetof(struct sk_buff, len)); + else { + /* mov off32(%rdi),%r9d */ + EMIT3(0x44, 0x8b, 0x8f); + EMIT(offsetof(struct sk_buff, len), 4); + } + if (is_imm8(offsetof(struct sk_buff, data_len))) + /* sub off8(%rdi),%r9d */ + EMIT4(0x44, 0x2b, 0x4f, offsetof(struct sk_buff, data_len)); + else { + EMIT3(0x44, 0x2b, 0x8f); + EMIT(offsetof(struct sk_buff, data_len), 4); + } + + if (is_imm8(offsetof(struct sk_buff, data))) + /* mov off8(%rdi),%r8 */ + EMIT4(0x4c, 0x8b, 0x47, offsetof(struct sk_buff, data)); + else { + /* mov off32(%rdi),%r8 */ + EMIT3(0x4c, 0x8b, 0x87); + EMIT(offsetof(struct sk_buff, data), 4); + } + } + } + + switch (filter[0].code) { + case BPF_S_RET_K: + case BPF_S_LD_W_LEN: + case BPF_S_ANC_PROTOCOL: + case BPF_S_ANC_IFINDEX: + case BPF_S_ANC_MARK: + case BPF_S_ANC_RXHASH: + case BPF_S_ANC_CPU: + case BPF_S_ANC_QUEUE: + case BPF_S_LD_W_ABS: + case BPF_S_LD_H_ABS: + case BPF_S_LD_B_ABS: + /* first instruction sets A register (or is RET 'constant') */ + break; + default: + /* make sure we dont leak kernel information to user */ + CLEAR_A(); /* A = 0 */ + } + + for (i = 0; i < flen; i++) { + unsigned int K = filter[i].k; + + switch (filter[i].code) { + case BPF_S_ALU_ADD_X: /* A += X; */ + seen |= SEEN_XREG; + EMIT2(0x01, 0xd8); /* add %ebx,%eax */ + break; + case BPF_S_ALU_ADD_K: /* A += K; */ + if (!K) + break; + if (is_imm8(K)) + EMIT3(0x83, 0xc0, K); /* add imm8,%eax */ + else + EMIT1_off32(0x05, K); /* add imm32,%eax */ + break; + case BPF_S_ALU_SUB_X: /* A -= X; */ + seen |= SEEN_XREG; + EMIT2(0x29, 0xd8); /* sub %ebx,%eax */ + break; + case BPF_S_ALU_SUB_K: /* A -= K */ + if (!K) + break; + if (is_imm8(K)) + EMIT3(0x83, 0xe8, K); /* sub imm8,%eax */ + else + EMIT1_off32(0x2d, K); /* sub imm32,%eax */ + break; + case BPF_S_ALU_MUL_X: /* A *= X; */ + seen |= SEEN_XREG; + EMIT3(0x0f, 0xaf, 0xc3); /* imul %ebx,%eax */ + break; + case BPF_S_ALU_MUL_K: /* A *= K */ + if (is_imm8(K)) + EMIT3(0x6b, 0xc0, K); /* imul imm8,%eax,%eax */ + else { + EMIT2(0x69, 0xc0); /* imul imm32,%eax */ + EMIT(K, 4); + } + break; + case BPF_S_ALU_DIV_X: /* A /= X; */ + seen |= SEEN_XREG; + EMIT2(0x85, 0xdb); /* test %ebx,%ebx */ + if (pc_ret0 != -1) + EMIT_COND_JMP(X86_JE, addrs[pc_ret0] - (addrs[i] - 4)); + else { + EMIT_COND_JMP(X86_JNE, 2 + 5); + CLEAR_A(); + EMIT1_off32(0xe9, cleanup_addr - (addrs[i] - 4)); /* jmp .+off32 */ + } + EMIT4(0x31, 0xd2, 0xf7, 0xf3); /* xor %edx,%edx; div %ebx */ + break; + case BPF_S_ALU_DIV_K: /* A = reciprocal_divide(A, K); */ + EMIT3(0x48, 0x69, 0xc0); /* imul imm32,%rax,%rax */ + EMIT(K, 4); + EMIT4(0x48, 0xc1, 0xe8, 0x20); /* shr $0x20,%rax */ + break; + case BPF_S_ALU_AND_X: + seen |= SEEN_XREG; + EMIT2(0x21, 0xd8); /* and %ebx,%eax */ + break; + case BPF_S_ALU_AND_K: + if (K >= 0xFFFFFF00) { + EMIT2(0x24, K & 0xFF); /* and imm8,%al */ + } else if (K >= 0xFFFF0000) { + EMIT2(0x66, 0x25); /* and imm16,%ax */ + EMIT2(K, 2); + } else { + EMIT1_off32(0x25, K); /* and imm32,%eax */ + } + break; + case BPF_S_ALU_OR_X: + seen |= SEEN_XREG; + EMIT2(0x09, 0xd8); /* or %ebx,%eax */ + break; + case BPF_S_ALU_OR_K: + if (is_imm8(K)) + EMIT3(0x83, 0xc8, K); /* or imm8,%eax */ + else + EMIT1_off32(0x0d, K); /* or imm32,%eax */ + break; + case BPF_S_ALU_LSH_X: /* A <<= X; */ + seen |= SEEN_XREG; + EMIT4(0x89, 0xd9, 0xd3, 0xe0); /* mov %ebx,%ecx; shl %cl,%eax */ + break; + case BPF_S_ALU_LSH_K: + if (K == 0) + break; + else if (K == 1) + EMIT2(0xd1, 0xe0); /* shl %eax */ + else + EMIT3(0xc1, 0xe0, K); + break; + case BPF_S_ALU_RSH_X: /* A >>= X; */ + seen |= SEEN_XREG; + EMIT4(0x89, 0xd9, 0xd3, 0xe8); /* mov %ebx,%ecx; shr %cl,%eax */ + break; + case BPF_S_ALU_RSH_K: /* A >>= K; */ + if (K == 0) + break; + else if (K == 1) + EMIT2(0xd1, 0xe8); /* shr %eax */ + else + EMIT3(0xc1, 0xe8, K); + break; + case BPF_S_ALU_NEG: + EMIT2(0xf7, 0xd8); /* neg %eax */ + break; + case BPF_S_RET_K: + if (!K) { + if (pc_ret0 == -1) + pc_ret0 = i; + CLEAR_A(); + } else { + EMIT1_off32(0xb8, K); /* mov $imm32,%eax */ + } + /* fallinto */ + case BPF_S_RET_A: + if (seen) { + if (i != flen - 1) { + EMIT_JMP(cleanup_addr - addrs[i]); + break; + } + if (seen & SEEN_XREG) + EMIT4(0x48, 0x8b, 0x5d, 0xf8); /* mov -8(%rbp),%rbx */ + EMIT1(0xc9); /* leaveq */ + } + EMIT1(0xc3); /* ret */ + break; + case BPF_S_MISC_TAX: /* X = A */ + seen |= SEEN_XREG; + EMIT2(0x89, 0xc3); /* mov %eax,%ebx */ + break; + case BPF_S_MISC_TXA: /* A = X */ + seen |= SEEN_XREG; + EMIT2(0x89, 0xd8); /* mov %ebx,%eax */ + break; + case BPF_S_LD_IMM: /* A = K */ + if (!K) + CLEAR_A(); + else + EMIT1_off32(0xb8, K); /* mov $imm32,%eax */ + break; + case BPF_S_LDX_IMM: /* X = K */ + seen |= SEEN_XREG; + if (!K) + CLEAR_X(); + else + EMIT1_off32(0xbb, K); /* mov $imm32,%ebx */ + break; + case BPF_S_LD_MEM: /* A = mem[K] : mov off8(%rbp),%eax */ + seen |= SEEN_MEM; + EMIT3(0x8b, 0x45, 0xf0 - K*4); + break; + case BPF_S_LDX_MEM: /* X = mem[K] : mov off8(%rbp),%ebx */ + seen |= SEEN_XREG | SEEN_MEM; + EMIT3(0x8b, 0x5d, 0xf0 - K*4); + break; + case BPF_S_ST: /* mem[K] = A : mov %eax,off8(%rbp) */ + seen |= SEEN_MEM; + EMIT3(0x89, 0x45, 0xf0 - K*4); + break; + case BPF_S_STX: /* mem[K] = X : mov %ebx,off8(%rbp) */ + seen |= SEEN_XREG | SEEN_MEM; + EMIT3(0x89, 0x5d, 0xf0 - K*4); + break; + case BPF_S_LD_W_LEN: /* A = skb->len; */ + BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4); + if (is_imm8(offsetof(struct sk_buff, len))) + /* mov off8(%rdi),%eax */ + EMIT3(0x8b, 0x47, offsetof(struct sk_buff, len)); + else { + EMIT2(0x8b, 0x87); + EMIT(offsetof(struct sk_buff, len), 4); + } + break; + case BPF_S_LDX_W_LEN: /* X = skb->len; */ + seen |= SEEN_XREG; + if (is_imm8(offsetof(struct sk_buff, len))) + /* mov off8(%rdi),%ebx */ + EMIT3(0x8b, 0x5f, offsetof(struct sk_buff, len)); + else { + EMIT2(0x8b, 0x9f); + EMIT(offsetof(struct sk_buff, len), 4); + } + break; + case BPF_S_ANC_PROTOCOL: /* A = ntohs(skb->protocol); */ + BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, protocol) != 2); + if (is_imm8(offsetof(struct sk_buff, protocol))) { + /* movzwl off8(%rdi),%eax */ + EMIT4(0x0f, 0xb7, 0x47, offsetof(struct sk_buff, protocol)); + } else { + EMIT3(0x0f, 0xb7, 0x87); /* movzwl off32(%rdi),%eax */ + EMIT(offsetof(struct sk_buff, protocol), 4); + } + EMIT2(0x86, 0xc4); /* ntohs() : xchg %al,%ah */ + break; + case BPF_S_ANC_IFINDEX: + if (is_imm8(offsetof(struct sk_buff, dev))) { + /* movq off8(%rdi),%rax */ + EMIT4(0x48, 0x8b, 0x47, offsetof(struct sk_buff, dev)); + } else { + EMIT3(0x48, 0x8b, 0x87); /* movq off32(%rdi),%rax */ + EMIT(offsetof(struct sk_buff, dev), 4); + } + EMIT3(0x48, 0x85, 0xc0); /* test %rax,%rax */ + EMIT_COND_JMP(X86_JE, cleanup_addr - (addrs[i] - 6)); + BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, ifindex) != 4); + EMIT2(0x8b, 0x80); /* mov off32(%rax),%eax */ + EMIT(offsetof(struct net_device, ifindex), 4); + break; + case BPF_S_ANC_MARK: + BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4); + if (is_imm8(offsetof(struct sk_buff, mark))) { + /* mov off8(%rdi),%eax */ + EMIT3(0x8b, 0x47, offsetof(struct sk_buff, mark)); + } else { + EMIT2(0x8b, 0x87); + EMIT(offsetof(struct sk_buff, mark), 4); + } + break; + case BPF_S_ANC_RXHASH: + BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, rxhash) != 4); + if (is_imm8(offsetof(struct sk_buff, rxhash))) { + /* mov off8(%rdi),%eax */ + EMIT3(0x8b, 0x47, offsetof(struct sk_buff, rxhash)); + } else { + EMIT2(0x8b, 0x87); + EMIT(offsetof(struct sk_buff, rxhash), 4); + } + break; + case BPF_S_ANC_QUEUE: + BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, queue_mapping) != 2); + if (is_imm8(offsetof(struct sk_buff, queue_mapping))) { + /* movzwl off8(%rdi),%eax */ + EMIT4(0x0f, 0xb7, 0x47, offsetof(struct sk_buff, queue_mapping)); + } else { + EMIT3(0x0f, 0xb7, 0x87); /* movzwl off32(%rdi),%eax */ + EMIT(offsetof(struct sk_buff, queue_mapping), 4); + } + break; + case BPF_S_ANC_CPU: +#ifdef CONFIG_SMP + EMIT4(0x65, 0x8b, 0x04, 0x25); /* mov %gs:off32,%eax */ + EMIT((u32)(unsigned long)&cpu_number, 4); /* A = smp_processor_id(); */ +#else + CLEAR_A(); +#endif + break; + case BPF_S_LD_W_ABS: + func = sk_load_word; +common_load: seen |= SEEN_DATAREF; + if ((int)K < 0) + goto out; + t_offset = func - (image + addrs[i]); + EMIT1_off32(0xbe, K); /* mov imm32,%esi */ + EMIT1_off32(0xe8, t_offset); /* call */ + break; + case BPF_S_LD_H_ABS: + func = sk_load_half; + goto common_load; + case BPF_S_LD_B_ABS: + func = sk_load_byte; + goto common_load; + case BPF_S_LDX_B_MSH: + if ((int)K < 0) { + if (pc_ret0 != -1) { + EMIT_JMP(addrs[pc_ret0] - addrs[i]); + break; + } + CLEAR_A(); + EMIT_JMP(cleanup_addr - addrs[i]); + break; + } + seen |= SEEN_DATAREF | SEEN_XREG; + t_offset = sk_load_byte_msh - (image + addrs[i]); + EMIT1_off32(0xbe, K); /* mov imm32,%esi */ + EMIT1_off32(0xe8, t_offset); /* call sk_load_byte_msh */ + break; + case BPF_S_LD_W_IND: + func = sk_load_word_ind; +common_load_ind: seen |= SEEN_DATAREF | SEEN_XREG; + t_offset = func - (image + addrs[i]); + EMIT1_off32(0xbe, K); /* mov imm32,%esi */ + EMIT1_off32(0xe8, t_offset); /* call sk_load_xxx_ind */ + break; + case BPF_S_LD_H_IND: + func = sk_load_half_ind; + goto common_load_ind; + case BPF_S_LD_B_IND: + func = sk_load_byte_ind; + goto common_load_ind; + case BPF_S_JMP_JA: + t_offset = addrs[i + K] - addrs[i]; + EMIT_JMP(t_offset); + break; + COND_SEL(BPF_S_JMP_JGT_K, X86_JA, X86_JBE); + COND_SEL(BPF_S_JMP_JGE_K, X86_JAE, X86_JB); + COND_SEL(BPF_S_JMP_JEQ_K, X86_JE, X86_JNE); + COND_SEL(BPF_S_JMP_JSET_K,X86_JNE, X86_JE); + COND_SEL(BPF_S_JMP_JGT_X, X86_JA, X86_JBE); + COND_SEL(BPF_S_JMP_JGE_X, X86_JAE, X86_JB); + COND_SEL(BPF_S_JMP_JEQ_X, X86_JE, X86_JNE); + COND_SEL(BPF_S_JMP_JSET_X,X86_JNE, X86_JE); + +cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i]; + t_offset = addrs[i + filter[i].jt] - addrs[i]; + + /* same targets, can avoid doing the test :) */ + if (filter[i].jt == filter[i].jf) { + EMIT_JMP(t_offset); + break; + } + + switch (filter[i].code) { + case BPF_S_JMP_JGT_X: + case BPF_S_JMP_JGE_X: + case BPF_S_JMP_JEQ_X: + seen |= SEEN_XREG; + EMIT2(0x39, 0xd8); /* cmp %ebx,%eax */ + break; + case BPF_S_JMP_JSET_X: + seen |= SEEN_XREG; + EMIT2(0x85, 0xd8); /* test %ebx,%eax */ + break; + case BPF_S_JMP_JEQ_K: + if (K == 0) { + EMIT2(0x85, 0xc0); /* test %eax,%eax */ + break; + } + case BPF_S_JMP_JGT_K: + case BPF_S_JMP_JGE_K: + if (K <= 127) + EMIT3(0x83, 0xf8, K); /* cmp imm8,%eax */ + else + EMIT1_off32(0x3d, K); /* cmp imm32,%eax */ + break; + case BPF_S_JMP_JSET_K: + if (K <= 0xFF) + EMIT2(0xa8, K); /* test imm8,%al */ + else if (!(K & 0xFFFF00FF)) + EMIT3(0xf6, 0xc4, K >> 8); /* test imm8,%ah */ + else if (K <= 0xFFFF) { + EMIT2(0x66, 0xa9); /* test imm16,%ax */ + EMIT(K, 2); + } else { + EMIT1_off32(0xa9, K); /* test imm32,%eax */ + } + break; + } + if (filter[i].jt != 0) { + if (filter[i].jf) + t_offset += is_near(f_offset) ? 2 : 6; + EMIT_COND_JMP(t_op, t_offset); + if (filter[i].jf) + EMIT_JMP(f_offset); + break; + } + EMIT_COND_JMP(f_op, f_offset); + break; + default: + /* hmm, too complex filter, give up with jit compiler */ + goto out; + } + ilen = prog - temp; + if (image) { + if (unlikely(proglen + ilen > oldproglen)) { + pr_err("bpb_jit_compile fatal error\n"); + kfree(addrs); + module_free(NULL, image); + return; + } + memcpy(image + proglen, temp, ilen); + } + proglen += ilen; + addrs[i] = proglen; + prog = temp; + } + /* last bpf instruction is always a RET : + * use it to give the cleanup instruction(s) addr + */ + cleanup_addr = proglen - 1; /* ret */ + if (seen) + cleanup_addr -= 1; /* leaveq */ + if (seen & SEEN_XREG) + cleanup_addr -= 4; /* mov -8(%rbp),%rbx */ + + if (image) { + WARN_ON(proglen != oldproglen); + break; + } + if (proglen == oldproglen) { + image = module_alloc(max_t(unsigned int, + proglen, + sizeof(struct work_struct))); + if (!image) + goto out; + } + oldproglen = proglen; + } + if (bpf_jit_enable > 1) + pr_err("flen=%d proglen=%u pass=%d image=%p\n", + flen, proglen, pass, image); + + if (image) { + if (bpf_jit_enable > 1) + print_hex_dump(KERN_ERR, "JIT code: ", DUMP_PREFIX_ADDRESS, + 16, 1, image, proglen, false); + + bpf_flush_icache(image, image + proglen); + + fp->bpf_func = (void *)image; + } +out: + kfree(addrs); + return; +} + +static void jit_free_defer(struct work_struct *arg) +{ + module_free(NULL, arg); +} + +/* run from softirq, we must use a work_struct to call + * module_free() from process context + */ +void bpf_jit_free(struct sk_filter *fp) +{ + if (fp->bpf_func != sk_run_filter) { + struct work_struct *work = (struct work_struct *)fp->bpf_func; + + INIT_WORK(work, jit_free_defer); + schedule_work(work); + } +} diff --git a/include/linux/filter.h b/include/linux/filter.h index 45266b75409a..4609b85e559d 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -135,6 +135,8 @@ struct sk_filter { atomic_t refcnt; unsigned int len; /* Number of filter blocks */ + unsigned int (*bpf_func)(const struct sk_buff *skb, + const struct sock_filter *filter); struct rcu_head rcu; struct sock_filter insns[0]; }; @@ -153,6 +155,80 @@ extern unsigned int sk_run_filter(const struct sk_buff *skb, extern int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk); extern int sk_detach_filter(struct sock *sk); extern int sk_chk_filter(struct sock_filter *filter, int flen); + +#ifdef CONFIG_BPF_JIT +extern void bpf_jit_compile(struct sk_filter *fp); +extern void bpf_jit_free(struct sk_filter *fp); +#define SK_RUN_FILTER(FILTER, SKB) (*FILTER->bpf_func)(SKB, FILTER->insns) +#else +static inline void bpf_jit_compile(struct sk_filter *fp) +{ +} +static inline void bpf_jit_free(struct sk_filter *fp) +{ +} +#define SK_RUN_FILTER(FILTER, SKB) sk_run_filter(SKB, FILTER->insns) +#endif + +enum { + BPF_S_RET_K = 1, + BPF_S_RET_A, + BPF_S_ALU_ADD_K, + BPF_S_ALU_ADD_X, + BPF_S_ALU_SUB_K, + BPF_S_ALU_SUB_X, + BPF_S_ALU_MUL_K, + BPF_S_ALU_MUL_X, + BPF_S_ALU_DIV_X, + BPF_S_ALU_AND_K, + BPF_S_ALU_AND_X, + BPF_S_ALU_OR_K, + BPF_S_ALU_OR_X, + BPF_S_ALU_LSH_K, + BPF_S_ALU_LSH_X, + BPF_S_ALU_RSH_K, + BPF_S_ALU_RSH_X, + BPF_S_ALU_NEG, + BPF_S_LD_W_ABS, + BPF_S_LD_H_ABS, + BPF_S_LD_B_ABS, + BPF_S_LD_W_LEN, + BPF_S_LD_W_IND, + BPF_S_LD_H_IND, + BPF_S_LD_B_IND, + BPF_S_LD_IMM, + BPF_S_LDX_W_LEN, + BPF_S_LDX_B_MSH, + BPF_S_LDX_IMM, + BPF_S_MISC_TAX, + BPF_S_MISC_TXA, + BPF_S_ALU_DIV_K, + BPF_S_LD_MEM, + BPF_S_LDX_MEM, + BPF_S_ST, + BPF_S_STX, + BPF_S_JMP_JA, + BPF_S_JMP_JEQ_K, + BPF_S_JMP_JEQ_X, + BPF_S_JMP_JGE_K, + BPF_S_JMP_JGE_X, + BPF_S_JMP_JGT_K, + BPF_S_JMP_JGT_X, + BPF_S_JMP_JSET_K, + BPF_S_JMP_JSET_X, + /* Ancillary data */ + BPF_S_ANC_PROTOCOL, + BPF_S_ANC_PKTTYPE, + BPF_S_ANC_IFINDEX, + BPF_S_ANC_NLATTR, + BPF_S_ANC_NLATTR_NEST, + BPF_S_ANC_MARK, + BPF_S_ANC_QUEUE, + BPF_S_ANC_HATYPE, + BPF_S_ANC_RXHASH, + BPF_S_ANC_CPU, +}; + #endif /* __KERNEL__ */ #endif /* __LINUX_FILTER_H__ */ diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index cb8178ab3c52..364bcf212f71 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2514,6 +2514,7 @@ extern struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev, extern int netdev_max_backlog; extern int netdev_tstamp_prequeue; extern int weight_p; +extern int bpf_jit_enable; extern int netdev_set_master(struct net_device *dev, struct net_device *master); extern int netdev_set_bond_master(struct net_device *dev, struct net_device *master); diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index d0ae90af0b40..79aafbbf430a 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -391,8 +391,8 @@ struct sk_buff { __u32 rxhash; + __u16 queue_mapping; kmemcheck_bitfield_begin(flags2); - __u16 queue_mapping:16; #ifdef CONFIG_IPV6_NDISC_NODETYPE __u8 ndisc_nodetype:2; #endif diff --git a/net/Kconfig b/net/Kconfig index 79cabf1ee68b..745fb02d2fda 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -232,6 +232,19 @@ config XPS depends on SMP && SYSFS && USE_GENERIC_SMP_HELPERS default y +config HAVE_BPF_JIT + bool + +config BPF_JIT + bool "enable BPF Just In Time compiler" + depends on HAVE_BPF_JIT + ---help--- + Berkeley Packet Filter filtering capabilities are normally handled + by an interpreter. This option allows kernel to generate a native + code when filter is loaded in memory. This should speedup + packet sniffing (libpcap/tcpdump). Note : Admin should enable + this feature changing /proc/sys/net/core/bpf_jit_enable + menu "Network testing" config NET_PKTGEN diff --git a/net/core/filter.c b/net/core/filter.c index afb8afb066bb..0eb8c4466eaa 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -39,65 +39,6 @@ #include #include -enum { - BPF_S_RET_K = 1, - BPF_S_RET_A, - BPF_S_ALU_ADD_K, - BPF_S_ALU_ADD_X, - BPF_S_ALU_SUB_K, - BPF_S_ALU_SUB_X, - BPF_S_ALU_MUL_K, - BPF_S_ALU_MUL_X, - BPF_S_ALU_DIV_X, - BPF_S_ALU_AND_K, - BPF_S_ALU_AND_X, - BPF_S_ALU_OR_K, - BPF_S_ALU_OR_X, - BPF_S_ALU_LSH_K, - BPF_S_ALU_LSH_X, - BPF_S_ALU_RSH_K, - BPF_S_ALU_RSH_X, - BPF_S_ALU_NEG, - BPF_S_LD_W_ABS, - BPF_S_LD_H_ABS, - BPF_S_LD_B_ABS, - BPF_S_LD_W_LEN, - BPF_S_LD_W_IND, - BPF_S_LD_H_IND, - BPF_S_LD_B_IND, - BPF_S_LD_IMM, - BPF_S_LDX_W_LEN, - BPF_S_LDX_B_MSH, - BPF_S_LDX_IMM, - BPF_S_MISC_TAX, - BPF_S_MISC_TXA, - BPF_S_ALU_DIV_K, - BPF_S_LD_MEM, - BPF_S_LDX_MEM, - BPF_S_ST, - BPF_S_STX, - BPF_S_JMP_JA, - BPF_S_JMP_JEQ_K, - BPF_S_JMP_JEQ_X, - BPF_S_JMP_JGE_K, - BPF_S_JMP_JGE_X, - BPF_S_JMP_JGT_K, - BPF_S_JMP_JGT_X, - BPF_S_JMP_JSET_K, - BPF_S_JMP_JSET_X, - /* Ancillary data */ - BPF_S_ANC_PROTOCOL, - BPF_S_ANC_PKTTYPE, - BPF_S_ANC_IFINDEX, - BPF_S_ANC_NLATTR, - BPF_S_ANC_NLATTR_NEST, - BPF_S_ANC_MARK, - BPF_S_ANC_QUEUE, - BPF_S_ANC_HATYPE, - BPF_S_ANC_RXHASH, - BPF_S_ANC_CPU, -}; - /* No hurry in this branch */ static void *__load_pointer(const struct sk_buff *skb, int k, unsigned int size) { @@ -145,7 +86,7 @@ int sk_filter(struct sock *sk, struct sk_buff *skb) rcu_read_lock(); filter = rcu_dereference(sk->sk_filter); if (filter) { - unsigned int pkt_len = sk_run_filter(skb, filter->insns); + unsigned int pkt_len = SK_RUN_FILTER(filter, skb); err = pkt_len ? pskb_trim(skb, pkt_len) : -EPERM; } @@ -638,6 +579,7 @@ void sk_filter_release_rcu(struct rcu_head *rcu) { struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu); + bpf_jit_free(fp); kfree(fp); } EXPORT_SYMBOL(sk_filter_release_rcu); @@ -672,6 +614,7 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) atomic_set(&fp->refcnt, 1); fp->len = fprog->len; + fp->bpf_func = sk_run_filter; err = sk_chk_filter(fp->insns, fp->len); if (err) { @@ -679,6 +622,8 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) return err; } + bpf_jit_compile(fp); + old_fp = rcu_dereference_protected(sk->sk_filter, sock_owned_by_user(sk)); rcu_assign_pointer(sk->sk_filter, fp); diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c index 385b6095fdc4..a829e3f60aeb 100644 --- a/net/core/sysctl_net_core.c +++ b/net/core/sysctl_net_core.c @@ -122,6 +122,15 @@ static struct ctl_table net_core_table[] = { .mode = 0644, .proc_handler = proc_dointvec }, +#ifdef CONFIG_BPF_JIT + { + .procname = "bpf_jit_enable", + .data = &bpf_jit_enable, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec + }, +#endif { .procname = "netdev_tstamp_prequeue", .data = &netdev_tstamp_prequeue, diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index b5362e96022b..549527bca87a 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -538,7 +538,7 @@ static inline unsigned int run_filter(const struct sk_buff *skb, rcu_read_lock(); filter = rcu_dereference(sk->sk_filter); if (filter != NULL) - res = sk_run_filter(skb, filter->insns); + res = SK_RUN_FILTER(filter, skb); rcu_read_unlock(); return res; -- cgit From acad9853b95df6a3887f52e0ec88e4a77119ee28 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 27 Apr 2011 23:08:51 -0700 Subject: Input: wm831x-ts - allow IRQ flags to be specified This allows maximum flexibility for configuring the direct GPIO based interrupts. Signed-off-by: Mark Brown Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/wm831x-ts.c | 16 +++++++++++++--- include/linux/mfd/wm831x/pdata.h | 2 ++ 2 files changed, 15 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/drivers/input/touchscreen/wm831x-ts.c b/drivers/input/touchscreen/wm831x-ts.c index b9373012b3e6..78e8705df20d 100644 --- a/drivers/input/touchscreen/wm831x-ts.c +++ b/drivers/input/touchscreen/wm831x-ts.c @@ -241,7 +241,7 @@ static __devinit int wm831x_ts_probe(struct platform_device *pdev) struct wm831x_pdata *core_pdata = dev_get_platdata(pdev->dev.parent); struct wm831x_touch_pdata *pdata = NULL; struct input_dev *input_dev; - int error; + int error, irqf; if (core_pdata) pdata = core_pdata->touch; @@ -314,9 +314,14 @@ static __devinit int wm831x_ts_probe(struct platform_device *pdev) wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1, WM831X_TCH_RATE_MASK, 6); + if (pdata && pdata->data_irqf) + irqf = pdata->data_irqf; + else + irqf = IRQF_TRIGGER_HIGH; + error = request_threaded_irq(wm831x_ts->data_irq, NULL, wm831x_ts_data_irq, - IRQF_ONESHOT, + irqf | IRQF_ONESHOT, "Touchscreen data", wm831x_ts); if (error) { dev_err(&pdev->dev, "Failed to request data IRQ %d: %d\n", @@ -325,9 +330,14 @@ static __devinit int wm831x_ts_probe(struct platform_device *pdev) } disable_irq(wm831x_ts->data_irq); + if (pdata && pdata->pd_irqf) + irqf = pdata->pd_irqf; + else + irqf = IRQF_TRIGGER_HIGH; + error = request_threaded_irq(wm831x_ts->pd_irq, NULL, wm831x_ts_pen_down_irq, - IRQF_ONESHOT, + irqf | IRQF_ONESHOT, "Touchscreen pen down", wm831x_ts); if (error) { dev_err(&pdev->dev, "Failed to request pen down IRQ %d: %d\n", diff --git a/include/linux/mfd/wm831x/pdata.h b/include/linux/mfd/wm831x/pdata.h index 173086d42af4..6b0eb130efb8 100644 --- a/include/linux/mfd/wm831x/pdata.h +++ b/include/linux/mfd/wm831x/pdata.h @@ -81,7 +81,9 @@ struct wm831x_touch_pdata { int rpu; /** Pen down sensitivity resistor divider */ int pressure; /** Report pressure (boolean) */ unsigned int data_irq; /** Touch data ready IRQ */ + int data_irqf; /** IRQ flags for data ready IRQ */ unsigned int pd_irq; /** Touch pendown detect IRQ */ + int pd_irqf; /** IRQ flags for pen down IRQ */ }; enum wm831x_watchdog_action { -- cgit From e6fa16ab9c1e9b344428e6fea4d29e3cc4b28fb0 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Wed, 27 Apr 2011 20:59:41 +0200 Subject: signal: sigprocmask() should do retarget_shared_pending() In short, almost every changing of current->blocked is wrong, or at least can lead to the unexpected results. For example. Two threads T1 and T2, T1 sleeps in sigtimedwait/pause/etc. kill(tgid, SIG) can pick T2 for TIF_SIGPENDING. If T2 calls sigprocmask() and blocks SIG before it notices the pending signal, nobody else can handle this pending shared signal. I am not sure this is bug, but at least this looks strange imho. T1 should not sleep forever, there is a signal which should wake it up. This patch moves the code which actually changes ->blocked into the new helper, set_current_blocked() and changes this code to call retarget_shared_pending() as exit_signals() does. We should only care about the signals we just blocked, we use "newset & ~current->blocked" as a mask. We do not check !sigisemptyset(newblocked), retarget_shared_pending() is cheap unless mask & shared_pending. Note: for this particular case we could simply change sigprocmask() to return -EINTR if signal_pending(), but then we should change other callers and, more importantly, if we need this fix then set_current_blocked() will have more callers and some of them can't restart. See the next patch as a random example. Signed-off-by: Oleg Nesterov Reviewed-by: Matt Fleming Acked-by: Tejun Heo --- include/linux/signal.h | 1 + kernel/signal.c | 29 ++++++++++++++++++++++++----- 2 files changed, 25 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/signal.h b/include/linux/signal.h index fcd2b14b1932..ba009c167275 100644 --- a/include/linux/signal.h +++ b/include/linux/signal.h @@ -243,6 +243,7 @@ extern long do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig, siginfo_t *info); extern long do_sigpending(void __user *, unsigned long); extern int sigprocmask(int, sigset_t *, sigset_t *); +extern void set_current_blocked(const sigset_t *); extern int show_unhandled_signals; struct pt_regs; diff --git a/kernel/signal.c b/kernel/signal.c index e8308e3238c1..8aa3a2e226af 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -2299,6 +2299,29 @@ long do_no_restart_syscall(struct restart_block *param) return -EINTR; } +/** + * set_current_blocked - change current->blocked mask + * @newset: new mask + * + * It is wrong to change ->blocked directly, this helper should be used + * to ensure the process can't miss a shared signal we are going to block. + */ +void set_current_blocked(const sigset_t *newset) +{ + struct task_struct *tsk = current; + + spin_lock_irq(&tsk->sighand->siglock); + if (signal_pending(tsk) && !thread_group_empty(tsk)) { + sigset_t newblocked; + /* A set of now blocked but previously unblocked signals. */ + signandsets(&newblocked, newset, ¤t->blocked); + retarget_shared_pending(tsk, &newblocked); + } + tsk->blocked = *newset; + recalc_sigpending(); + spin_unlock_irq(&tsk->sighand->siglock); +} + /* * This is also useful for kernel threads that want to temporarily * (or permanently) block certain signals. @@ -2330,11 +2353,7 @@ int sigprocmask(int how, sigset_t *set, sigset_t *oldset) return -EINVAL; } - spin_lock_irq(&tsk->sighand->siglock); - tsk->blocked = newset; - recalc_sigpending(); - spin_unlock_irq(&tsk->sighand->siglock); - + set_current_blocked(&newset); return 0; } -- cgit From 943df1485a8ff0e600729e082e568ece04d4de9e Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Wed, 27 Apr 2011 21:44:14 +0200 Subject: signal: introduce do_sigtimedwait() to factor out compat/native code Factor out the common code in sys_rt_sigtimedwait/compat_sys_rt_sigtimedwait to the new helper, do_sigtimedwait(). Add the comment to document the extra tick we add to timespec_to_jiffies(ts), thanks to Linus who explained this to me. Perhaps it would be better to move compat_sys_rt_sigtimedwait() into signal.c under CONFIG_COMPAT, then we can make do_sigtimedwait() static. Signed-off-by: Oleg Nesterov Acked-by: Tejun Heo Reviewed-by: Matt Fleming --- include/linux/signal.h | 2 + kernel/compat.c | 41 ++++-------------- kernel/signal.c | 110 +++++++++++++++++++++++++++++-------------------- 3 files changed, 74 insertions(+), 79 deletions(-) (limited to 'include/linux') diff --git a/include/linux/signal.h b/include/linux/signal.h index ba009c167275..782546d661ba 100644 --- a/include/linux/signal.h +++ b/include/linux/signal.h @@ -242,6 +242,8 @@ extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *); extern long do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig, siginfo_t *info); extern long do_sigpending(void __user *, unsigned long); +extern int do_sigtimedwait(const sigset_t *, siginfo_t *, + const struct timespec *); extern int sigprocmask(int, sigset_t *, sigset_t *); extern void set_current_blocked(const sigset_t *); extern int show_unhandled_signals; diff --git a/kernel/compat.c b/kernel/compat.c index 06cbb0619531..9214dcd087b7 100644 --- a/kernel/compat.c +++ b/kernel/compat.c @@ -890,10 +890,9 @@ compat_sys_rt_sigtimedwait (compat_sigset_t __user *uthese, { compat_sigset_t s32; sigset_t s; - int sig; struct timespec t; siginfo_t info; - long ret, timeout; + long ret; if (sigsetsize != sizeof(sigset_t)) return -EINVAL; @@ -901,45 +900,19 @@ compat_sys_rt_sigtimedwait (compat_sigset_t __user *uthese, if (copy_from_user(&s32, uthese, sizeof(compat_sigset_t))) return -EFAULT; sigset_from_compat(&s, &s32); - sigdelsetmask(&s,sigmask(SIGKILL)|sigmask(SIGSTOP)); - signotset(&s); - timeout = MAX_SCHEDULE_TIMEOUT; if (uts) { - if (get_compat_timespec (&t, uts)) + if (get_compat_timespec(&t, uts)) return -EFAULT; - if (!timespec_valid(&t)) - return -EINVAL; - timeout = timespec_to_jiffies(&t) + (t.tv_sec || t.tv_nsec); } - spin_lock_irq(¤t->sighand->siglock); - sig = dequeue_signal(current, &s, &info); - if (!sig && timeout) { - current->real_blocked = current->blocked; - sigandsets(¤t->blocked, ¤t->blocked, &s); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - - timeout = schedule_timeout_interruptible(timeout); - - spin_lock_irq(¤t->sighand->siglock); - sig = dequeue_signal(current, &s, &info); - current->blocked = current->real_blocked; - siginitset(¤t->real_blocked, 0); - recalc_sigpending(); - } - spin_unlock_irq(¤t->sighand->siglock); + ret = do_sigtimedwait(&s, &info, uts ? &t : NULL); - if (sig) { - ret = sig; - if (uinfo) { - if (copy_siginfo_to_user32(uinfo, &info)) - ret = -EFAULT; - } - } else { - ret = timeout?-EINTR:-EAGAIN; + if (ret > 0 && uinfo) { + if (copy_siginfo_to_user32(uinfo, &info)) + ret = -EFAULT; } + return ret; } diff --git a/kernel/signal.c b/kernel/signal.c index c734619554f6..1ab89f677424 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -2503,6 +2503,66 @@ int copy_siginfo_to_user(siginfo_t __user *to, siginfo_t *from) #endif +/** + * do_sigtimedwait - wait for queued signals specified in @which + * @which: queued signals to wait for + * @info: if non-null, the signal's siginfo is returned here + * @ts: upper bound on process time suspension + */ +int do_sigtimedwait(const sigset_t *which, siginfo_t *info, + const struct timespec *ts) +{ + struct task_struct *tsk = current; + long timeout = MAX_SCHEDULE_TIMEOUT; + sigset_t mask = *which; + int sig; + + if (ts) { + if (!timespec_valid(ts)) + return -EINVAL; + timeout = timespec_to_jiffies(ts); + /* + * We can be close to the next tick, add another one + * to ensure we will wait at least the time asked for. + */ + if (ts->tv_sec || ts->tv_nsec) + timeout++; + } + + /* + * Invert the set of allowed signals to get those we want to block. + */ + sigdelsetmask(&mask, sigmask(SIGKILL) | sigmask(SIGSTOP)); + signotset(&mask); + + spin_lock_irq(&tsk->sighand->siglock); + sig = dequeue_signal(tsk, &mask, info); + if (!sig && timeout) { + /* + * None ready, temporarily unblock those we're interested + * while we are sleeping in so that we'll be awakened when + * they arrive. + */ + tsk->real_blocked = tsk->blocked; + sigandsets(&tsk->blocked, &tsk->blocked, &mask); + recalc_sigpending(); + spin_unlock_irq(&tsk->sighand->siglock); + + timeout = schedule_timeout_interruptible(timeout); + + spin_lock_irq(&tsk->sighand->siglock); + sig = dequeue_signal(tsk, &mask, info); + tsk->blocked = tsk->real_blocked; + siginitset(&tsk->real_blocked, 0); + recalc_sigpending(); + } + spin_unlock_irq(&tsk->sighand->siglock); + + if (sig) + return sig; + return timeout ? -EINTR : -EAGAIN; +} + /** * sys_rt_sigtimedwait - synchronously wait for queued signals specified * in @uthese @@ -2515,11 +2575,10 @@ SYSCALL_DEFINE4(rt_sigtimedwait, const sigset_t __user *, uthese, siginfo_t __user *, uinfo, const struct timespec __user *, uts, size_t, sigsetsize) { - int ret, sig; sigset_t these; struct timespec ts; siginfo_t info; - long timeout; + int ret; /* XXX: Don't preclude handling different sized sigset_t's. */ if (sigsetsize != sizeof(sigset_t)) @@ -2528,55 +2587,16 @@ SYSCALL_DEFINE4(rt_sigtimedwait, const sigset_t __user *, uthese, if (copy_from_user(&these, uthese, sizeof(these))) return -EFAULT; - /* - * Invert the set of allowed signals to get those we - * want to block. - */ - sigdelsetmask(&these, sigmask(SIGKILL)|sigmask(SIGSTOP)); - signotset(&these); - - timeout = MAX_SCHEDULE_TIMEOUT; if (uts) { if (copy_from_user(&ts, uts, sizeof(ts))) return -EFAULT; - if (!timespec_valid(&ts)) - return -EINVAL; - timeout = timespec_to_jiffies(&ts) + (ts.tv_sec || ts.tv_nsec); } - spin_lock_irq(¤t->sighand->siglock); - sig = dequeue_signal(current, &these, &info); - if (!sig && timeout) { - /* - * None ready -- temporarily unblock those we're - * interested while we are sleeping in so that we'll - * be awakened when they arrive. - */ - current->real_blocked = current->blocked; - sigandsets(¤t->blocked, ¤t->blocked, &these); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - - timeout = schedule_timeout_interruptible(timeout); - - spin_lock_irq(¤t->sighand->siglock); - sig = dequeue_signal(current, &these, &info); - current->blocked = current->real_blocked; - siginitset(¤t->real_blocked, 0); - recalc_sigpending(); - } - spin_unlock_irq(¤t->sighand->siglock); + ret = do_sigtimedwait(&these, &info, uts ? &ts : NULL); - if (sig) { - ret = sig; - if (uinfo) { - if (copy_siginfo_to_user(uinfo, &info)) - ret = -EFAULT; - } - } else { - ret = -EAGAIN; - if (timeout) - ret = -EINTR; + if (ret > 0 && uinfo) { + if (copy_siginfo_to_user(uinfo, &info)) + ret = -EFAULT; } return ret; -- cgit From 702a5073fdb71eb29cd4912575289fb5044c1894 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Wed, 27 Apr 2011 22:01:27 +0200 Subject: signal: rename signandsets() to sigandnsets() As Tejun and Linus pointed out, "nand" is the wrong name for "x & ~y", it should be "andn". Rename signandsets() as suggested. Suggested-by: Tejun Heo Signed-off-by: Oleg Nesterov Acked-by: Tejun Heo --- include/linux/signal.h | 6 +++--- kernel/signal.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/signal.h b/include/linux/signal.h index 782546d661ba..7e2526374fd7 100644 --- a/include/linux/signal.h +++ b/include/linux/signal.h @@ -123,13 +123,13 @@ _SIG_SET_BINOP(sigorsets, _sig_or) #define _sig_and(x,y) ((x) & (y)) _SIG_SET_BINOP(sigandsets, _sig_and) -#define _sig_nand(x,y) ((x) & ~(y)) -_SIG_SET_BINOP(signandsets, _sig_nand) +#define _sig_andn(x,y) ((x) & ~(y)) +_SIG_SET_BINOP(sigandnsets, _sig_andn) #undef _SIG_SET_BINOP #undef _sig_or #undef _sig_and -#undef _sig_nand +#undef _sig_andn #define _SIG_SET_OP(name, op) \ static inline void name(sigset_t *set) \ diff --git a/kernel/signal.c b/kernel/signal.c index 4d97e11d7672..e7ee4e642c5a 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -669,7 +669,7 @@ static int rm_from_queue_full(sigset_t *mask, struct sigpending *s) if (sigisemptyset(&m)) return 0; - signandsets(&s->signal, &s->signal, mask); + sigandnsets(&s->signal, &s->signal, mask); list_for_each_entry_safe(q, n, &s->list, list) { if (sigismember(mask, q->info.si_signo)) { list_del_init(&q->list); @@ -2304,7 +2304,7 @@ static void __set_task_blocked(struct task_struct *tsk, const sigset_t *newset) if (signal_pending(tsk) && !thread_group_empty(tsk)) { sigset_t newblocked; /* A set of now blocked but previously unblocked signals. */ - signandsets(&newblocked, newset, ¤t->blocked); + sigandnsets(&newblocked, newset, ¤t->blocked); retarget_shared_pending(tsk, &newblocked); } tsk->blocked = *newset; @@ -2349,7 +2349,7 @@ int sigprocmask(int how, sigset_t *set, sigset_t *oldset) sigorsets(&newset, &tsk->blocked, set); break; case SIG_UNBLOCK: - signandsets(&newset, &tsk->blocked, set); + sigandnsets(&newset, &tsk->blocked, set); break; case SIG_SETMASK: newset = *set; -- cgit From 78f11a255749d09025f54d4e2df4fbcb031530e2 Mon Sep 17 00:00:00 2001 From: Andrea Arcangeli Date: Wed, 27 Apr 2011 15:26:45 -0700 Subject: mm: thp: fix /dev/zero MAP_PRIVATE and vm_flags cleanups The huge_memory.c THP page fault was allowed to run if vm_ops was null (which would succeed for /dev/zero MAP_PRIVATE, as the f_op->mmap wouldn't setup a special vma->vm_ops and it would fallback to regular anonymous memory) but other THP logics weren't fully activated for vmas with vm_file not NULL (/dev/zero has a not NULL vma->vm_file). So this removes the vm_file checks so that /dev/zero also can safely use THP (the other albeit safer approach to fix this bug would have been to prevent the THP initial page fault to run if vm_file was set). After removing the vm_file checks, this also makes huge_memory.c stricter in khugepaged for the DEBUG_VM=y case. It doesn't replace the vm_file check with a is_pfn_mapping check (but it keeps checking for VM_PFNMAP under VM_BUG_ON) because for a is_cow_mapping() mapping VM_PFNMAP should only be allowed to exist before the first page fault, and in turn when vma->anon_vma is null (so preventing khugepaged registration). So I tend to think the previous comment saying if vm_file was set, VM_PFNMAP might have been set and we could still be registered in khugepaged (despite anon_vma was not NULL to be registered in khugepaged) was too paranoid. The is_linear_pfn_mapping check is also I think superfluous (as described by comment) but under DEBUG_VM it is safe to stay. Addresses https://bugzilla.kernel.org/show_bug.cgi?id=33682 Signed-off-by: Andrea Arcangeli Reported-by: Caspar Zhang Acked-by: Mel Gorman Acked-by: Rik van Riel Cc: [2.6.38.x] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/huge_mm.h | 2 +- include/linux/mm.h | 3 ++- mm/huge_memory.c | 43 ++++++++++++++++++++++++------------------- 3 files changed, 27 insertions(+), 21 deletions(-) (limited to 'include/linux') diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h index df29c8fde36b..8847c8c29791 100644 --- a/include/linux/huge_mm.h +++ b/include/linux/huge_mm.h @@ -117,7 +117,7 @@ static inline void vma_adjust_trans_huge(struct vm_area_struct *vma, unsigned long end, long adjust_next) { - if (!vma->anon_vma || vma->vm_ops || vma->vm_file) + if (!vma->anon_vma || vma->vm_ops) return; __vma_adjust_trans_huge(vma, start, end, adjust_next); } diff --git a/include/linux/mm.h b/include/linux/mm.h index 692dbae6ffa7..2348db26bc3d 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -137,7 +137,8 @@ extern unsigned int kobjsize(const void *objp); #define VM_RandomReadHint(v) ((v)->vm_flags & VM_RAND_READ) /* - * special vmas that are non-mergable, non-mlock()able + * Special vmas that are non-mergable, non-mlock()able. + * Note: mm/huge_memory.c VM_NO_THP depends on this definition. */ #define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_RESERVED | VM_PFNMAP) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 470dcda10add..83326ad66d9b 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -1408,6 +1408,9 @@ out: return ret; } +#define VM_NO_THP (VM_SPECIAL|VM_INSERTPAGE|VM_MIXEDMAP|VM_SAO| \ + VM_HUGETLB|VM_SHARED|VM_MAYSHARE) + int hugepage_madvise(struct vm_area_struct *vma, unsigned long *vm_flags, int advice) { @@ -1416,11 +1419,7 @@ int hugepage_madvise(struct vm_area_struct *vma, /* * Be somewhat over-protective like KSM for now! */ - if (*vm_flags & (VM_HUGEPAGE | - VM_SHARED | VM_MAYSHARE | - VM_PFNMAP | VM_IO | VM_DONTEXPAND | - VM_RESERVED | VM_HUGETLB | VM_INSERTPAGE | - VM_MIXEDMAP | VM_SAO)) + if (*vm_flags & (VM_HUGEPAGE | VM_NO_THP)) return -EINVAL; *vm_flags &= ~VM_NOHUGEPAGE; *vm_flags |= VM_HUGEPAGE; @@ -1436,11 +1435,7 @@ int hugepage_madvise(struct vm_area_struct *vma, /* * Be somewhat over-protective like KSM for now! */ - if (*vm_flags & (VM_NOHUGEPAGE | - VM_SHARED | VM_MAYSHARE | - VM_PFNMAP | VM_IO | VM_DONTEXPAND | - VM_RESERVED | VM_HUGETLB | VM_INSERTPAGE | - VM_MIXEDMAP | VM_SAO)) + if (*vm_flags & (VM_NOHUGEPAGE | VM_NO_THP)) return -EINVAL; *vm_flags &= ~VM_HUGEPAGE; *vm_flags |= VM_NOHUGEPAGE; @@ -1574,10 +1569,14 @@ int khugepaged_enter_vma_merge(struct vm_area_struct *vma) * page fault if needed. */ return 0; - if (vma->vm_file || vma->vm_ops) + if (vma->vm_ops) /* khugepaged not yet working on file or special mappings */ return 0; - VM_BUG_ON(is_linear_pfn_mapping(vma) || is_pfn_mapping(vma)); + /* + * If is_pfn_mapping() is true is_learn_pfn_mapping() must be + * true too, verify it here. + */ + VM_BUG_ON(is_linear_pfn_mapping(vma) || vma->vm_flags & VM_NO_THP); hstart = (vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK; hend = vma->vm_end & HPAGE_PMD_MASK; if (hstart < hend) @@ -1828,12 +1827,15 @@ static void collapse_huge_page(struct mm_struct *mm, (vma->vm_flags & VM_NOHUGEPAGE)) goto out; - /* VM_PFNMAP vmas may have vm_ops null but vm_file set */ - if (!vma->anon_vma || vma->vm_ops || vma->vm_file) + if (!vma->anon_vma || vma->vm_ops) goto out; if (is_vma_temporary_stack(vma)) goto out; - VM_BUG_ON(is_linear_pfn_mapping(vma) || is_pfn_mapping(vma)); + /* + * If is_pfn_mapping() is true is_learn_pfn_mapping() must be + * true too, verify it here. + */ + VM_BUG_ON(is_linear_pfn_mapping(vma) || vma->vm_flags & VM_NO_THP); pgd = pgd_offset(mm, address); if (!pgd_present(*pgd)) @@ -2066,13 +2068,16 @@ static unsigned int khugepaged_scan_mm_slot(unsigned int pages, progress++; continue; } - /* VM_PFNMAP vmas may have vm_ops null but vm_file set */ - if (!vma->anon_vma || vma->vm_ops || vma->vm_file) + if (!vma->anon_vma || vma->vm_ops) goto skip; if (is_vma_temporary_stack(vma)) goto skip; - - VM_BUG_ON(is_linear_pfn_mapping(vma) || is_pfn_mapping(vma)); + /* + * If is_pfn_mapping() is true is_learn_pfn_mapping() + * must be true too, verify it here. + */ + VM_BUG_ON(is_linear_pfn_mapping(vma) || + vma->vm_flags & VM_NO_THP); hstart = (vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK; hend = vma->vm_end & HPAGE_PMD_MASK; -- cgit From 5a3ea8782c63d3501cb764c176f153c0d9a400e1 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Thu, 28 Apr 2011 15:55:52 -0400 Subject: flex_array: flex_array_prealloc takes a number of elements, not an end Change flex_array_prealloc to take the number of elements for which space should be allocated instead of the last (inclusive) element. Users and documentation are updated accordingly. flex_arrays got introduced before they had users. When folks started using it, they ended up needing a different API than was coded up originally. This swaps over to the API that folks apparently need. Based-on-patch-by: Steffen Klassert Signed-off-by: Eric Paris Tested-by: Chris Richards Acked-by: Dave Hansen Cc: stable@kernel.org [2.6.38+] --- Documentation/flexible-arrays.txt | 4 ++-- include/linux/flex_array.h | 2 +- lib/flex_array.c | 13 ++++++++----- security/selinux/ss/policydb.c | 6 +++--- 4 files changed, 14 insertions(+), 11 deletions(-) (limited to 'include/linux') diff --git a/Documentation/flexible-arrays.txt b/Documentation/flexible-arrays.txt index cb8a3a00cc92..df904aec9904 100644 --- a/Documentation/flexible-arrays.txt +++ b/Documentation/flexible-arrays.txt @@ -66,10 +66,10 @@ trick is to ensure that any needed memory allocations are done before entering atomic context, using: int flex_array_prealloc(struct flex_array *array, unsigned int start, - unsigned int end, gfp_t flags); + unsigned int nr_elements, gfp_t flags); This function will ensure that memory for the elements indexed in the range -defined by start and end has been allocated. Thereafter, a +defined by start and nr_elements has been allocated. Thereafter, a flex_array_put() call on an element in that range is guaranteed not to block. diff --git a/include/linux/flex_array.h b/include/linux/flex_array.h index 70e4efabe0fb..ebeb2f3ad068 100644 --- a/include/linux/flex_array.h +++ b/include/linux/flex_array.h @@ -61,7 +61,7 @@ struct flex_array { struct flex_array *flex_array_alloc(int element_size, unsigned int total, gfp_t flags); int flex_array_prealloc(struct flex_array *fa, unsigned int start, - unsigned int end, gfp_t flags); + unsigned int nr_elements, gfp_t flags); void flex_array_free(struct flex_array *fa); void flex_array_free_parts(struct flex_array *fa); int flex_array_put(struct flex_array *fa, unsigned int element_nr, void *src, diff --git a/lib/flex_array.c b/lib/flex_array.c index c0ea40ba2082..0c33b24498ba 100644 --- a/lib/flex_array.c +++ b/lib/flex_array.c @@ -232,10 +232,10 @@ EXPORT_SYMBOL(flex_array_clear); /** * flex_array_prealloc - guarantee that array space exists - * @fa: the flex array for which to preallocate parts - * @start: index of first array element for which space is allocated - * @end: index of last (inclusive) element for which space is allocated - * @flags: page allocation flags + * @fa: the flex array for which to preallocate parts + * @start: index of first array element for which space is allocated + * @nr_elements: number of elements for which space is allocated + * @flags: page allocation flags * * This will guarantee that no future calls to flex_array_put() * will allocate memory. It can be used if you are expecting to @@ -245,13 +245,16 @@ EXPORT_SYMBOL(flex_array_clear); * Locking must be provided by the caller. */ int flex_array_prealloc(struct flex_array *fa, unsigned int start, - unsigned int end, gfp_t flags) + unsigned int nr_elements, gfp_t flags) { int start_part; int end_part; int part_nr; + unsigned int end; struct flex_array_part *part; + end = start + nr_elements - 1; + if (start >= fa->total_nr_elements || end >= fa->total_nr_elements) return -ENOSPC; if (elements_fit_in_base(fa)) diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index 549120c56edd..102e9ec1b77a 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c @@ -545,7 +545,7 @@ static int policydb_index(struct policydb *p) goto out; rc = flex_array_prealloc(p->type_val_to_struct_array, 0, - p->p_types.nprim - 1, GFP_KERNEL | __GFP_ZERO); + p->p_types.nprim, GFP_KERNEL | __GFP_ZERO); if (rc) goto out; @@ -562,7 +562,7 @@ static int policydb_index(struct policydb *p) goto out; rc = flex_array_prealloc(p->sym_val_to_name[i], - 0, p->symtab[i].nprim - 1, + 0, p->symtab[i].nprim, GFP_KERNEL | __GFP_ZERO); if (rc) goto out; @@ -2439,7 +2439,7 @@ int policydb_read(struct policydb *p, void *fp) goto bad; /* preallocate so we don't have to worry about the put ever failing */ - rc = flex_array_prealloc(p->type_attr_map_array, 0, p->p_types.nprim - 1, + rc = flex_array_prealloc(p->type_attr_map_array, 0, p->p_types.nprim, GFP_KERNEL | __GFP_ZERO); if (rc) goto bad; -- cgit From 68972efa657040f891c7eda07c7da8c8dd576788 Mon Sep 17 00:00:00 2001 From: Paul Stewart Date: Thu, 28 Apr 2011 05:43:37 +0000 Subject: usbnet: Resubmit interrupt URB if device is open Resubmit interrupt URB if device is open. Use a flag set in usbnet_open() to determine this state. Also kill and free interrupt URB in usbnet_disconnect(). [Rebased off git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git] Signed-off-by: Paul Stewart Signed-off-by: David S. Miller --- drivers/net/usb/usbnet.c | 8 ++++++++ include/linux/usb/usbnet.h | 1 + 2 files changed, 9 insertions(+) (limited to 'include/linux') diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 069c1cf0fdf7..009bba3d753e 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -736,6 +736,7 @@ int usbnet_open (struct net_device *net) } } + set_bit(EVENT_DEV_OPEN, &dev->flags); netif_start_queue (net); netif_info(dev, ifup, dev->net, "open: enable queueing (rx %d, tx %d) mtu %d %s framing\n", @@ -1259,6 +1260,9 @@ void usbnet_disconnect (struct usb_interface *intf) if (dev->driver_info->unbind) dev->driver_info->unbind (dev, intf); + usb_kill_urb(dev->interrupt); + usb_free_urb(dev->interrupt); + free_netdev(net); usb_put_dev (xdev); } @@ -1498,6 +1502,10 @@ int usbnet_resume (struct usb_interface *intf) int retval; if (!--dev->suspend_count) { + /* resume interrupt URBs */ + if (dev->interrupt && test_bit(EVENT_DEV_OPEN, &dev->flags)) + usb_submit_urb(dev->interrupt, GFP_NOIO); + spin_lock_irq(&dev->txq.lock); while ((res = usb_get_from_anchor(&dev->deferred))) { diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h index 0e1855079fbb..605b0aa8d852 100644 --- a/include/linux/usb/usbnet.h +++ b/include/linux/usb/usbnet.h @@ -68,6 +68,7 @@ struct usbnet { # define EVENT_RX_PAUSED 5 # define EVENT_DEV_WAKING 6 # define EVENT_DEV_ASLEEP 7 +# define EVENT_DEV_OPEN 8 }; static inline struct usb_driver *driver_of(struct usb_interface *intf) -- cgit From 5d30b10bd68df007e7ae21e77d1e0ce184b53040 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Thu, 28 Apr 2011 15:55:52 -0400 Subject: flex_array: flex_array_prealloc takes a number of elements, not an end Change flex_array_prealloc to take the number of elements for which space should be allocated instead of the last (inclusive) element. Users and documentation are updated accordingly. flex_arrays got introduced before they had users. When folks started using it, they ended up needing a different API than was coded up originally. This swaps over to the API that folks apparently need. Based-on-patch-by: Steffen Klassert Signed-off-by: Eric Paris Tested-by: Chris Richards Acked-by: Dave Hansen Cc: stable@kernel.org [2.6.38+] --- Documentation/flexible-arrays.txt | 4 ++-- include/linux/flex_array.h | 2 +- lib/flex_array.c | 13 ++++++++----- security/selinux/ss/policydb.c | 6 +++--- 4 files changed, 14 insertions(+), 11 deletions(-) (limited to 'include/linux') diff --git a/Documentation/flexible-arrays.txt b/Documentation/flexible-arrays.txt index cb8a3a00cc92..df904aec9904 100644 --- a/Documentation/flexible-arrays.txt +++ b/Documentation/flexible-arrays.txt @@ -66,10 +66,10 @@ trick is to ensure that any needed memory allocations are done before entering atomic context, using: int flex_array_prealloc(struct flex_array *array, unsigned int start, - unsigned int end, gfp_t flags); + unsigned int nr_elements, gfp_t flags); This function will ensure that memory for the elements indexed in the range -defined by start and end has been allocated. Thereafter, a +defined by start and nr_elements has been allocated. Thereafter, a flex_array_put() call on an element in that range is guaranteed not to block. diff --git a/include/linux/flex_array.h b/include/linux/flex_array.h index 70e4efabe0fb..ebeb2f3ad068 100644 --- a/include/linux/flex_array.h +++ b/include/linux/flex_array.h @@ -61,7 +61,7 @@ struct flex_array { struct flex_array *flex_array_alloc(int element_size, unsigned int total, gfp_t flags); int flex_array_prealloc(struct flex_array *fa, unsigned int start, - unsigned int end, gfp_t flags); + unsigned int nr_elements, gfp_t flags); void flex_array_free(struct flex_array *fa); void flex_array_free_parts(struct flex_array *fa); int flex_array_put(struct flex_array *fa, unsigned int element_nr, void *src, diff --git a/lib/flex_array.c b/lib/flex_array.c index c0ea40ba2082..0c33b24498ba 100644 --- a/lib/flex_array.c +++ b/lib/flex_array.c @@ -232,10 +232,10 @@ EXPORT_SYMBOL(flex_array_clear); /** * flex_array_prealloc - guarantee that array space exists - * @fa: the flex array for which to preallocate parts - * @start: index of first array element for which space is allocated - * @end: index of last (inclusive) element for which space is allocated - * @flags: page allocation flags + * @fa: the flex array for which to preallocate parts + * @start: index of first array element for which space is allocated + * @nr_elements: number of elements for which space is allocated + * @flags: page allocation flags * * This will guarantee that no future calls to flex_array_put() * will allocate memory. It can be used if you are expecting to @@ -245,13 +245,16 @@ EXPORT_SYMBOL(flex_array_clear); * Locking must be provided by the caller. */ int flex_array_prealloc(struct flex_array *fa, unsigned int start, - unsigned int end, gfp_t flags) + unsigned int nr_elements, gfp_t flags) { int start_part; int end_part; int part_nr; + unsigned int end; struct flex_array_part *part; + end = start + nr_elements - 1; + if (start >= fa->total_nr_elements || end >= fa->total_nr_elements) return -ENOSPC; if (elements_fit_in_base(fa)) diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index e7b850ad57ee..e6e7ce0d3d55 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c @@ -502,7 +502,7 @@ static int policydb_index(struct policydb *p) goto out; rc = flex_array_prealloc(p->type_val_to_struct_array, 0, - p->p_types.nprim - 1, GFP_KERNEL | __GFP_ZERO); + p->p_types.nprim, GFP_KERNEL | __GFP_ZERO); if (rc) goto out; @@ -519,7 +519,7 @@ static int policydb_index(struct policydb *p) goto out; rc = flex_array_prealloc(p->sym_val_to_name[i], - 0, p->symtab[i].nprim - 1, + 0, p->symtab[i].nprim, GFP_KERNEL | __GFP_ZERO); if (rc) goto out; @@ -2375,7 +2375,7 @@ int policydb_read(struct policydb *p, void *fp) goto bad; /* preallocate so we don't have to worry about the put ever failing */ - rc = flex_array_prealloc(p->type_attr_map_array, 0, p->p_types.nprim - 1, + rc = flex_array_prealloc(p->type_attr_map_array, 0, p->p_types.nprim, GFP_KERNEL | __GFP_ZERO); if (rc) goto bad; -- cgit From 1742f183fc218798dab6fcf0ded25b6608fc0a48 Mon Sep 17 00:00:00 2001 From: MichaÅ‚ MirosÅ‚aw Date: Fri, 22 Apr 2011 06:31:16 +0000 Subject: net: fix netdev_increment_features() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Simplify and fix netdev_increment_features() to conform to what is stated in netdevice.h comments about NETIF_F_ONE_FOR_ALL. Include FCoE segmentation and VLAN-challedged flags in computation. Signed-off-by: MichaÅ‚ MirosÅ‚aw Signed-off-by: David S. Miller --- include/linux/netdevice.h | 7 ++++++- net/core/dev.c | 35 +++++++++++------------------------ 2 files changed, 17 insertions(+), 25 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 364bcf212f71..b7d0304762aa 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1106,7 +1106,12 @@ struct net_device { */ #define NETIF_F_ONE_FOR_ALL (NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ROBUST | \ NETIF_F_SG | NETIF_F_HIGHDMA | \ - NETIF_F_FRAGLIST) + NETIF_F_FRAGLIST | NETIF_F_VLAN_CHALLENGED) + /* + * If one device doesn't support one of these features, then disable it + * for all in netdev_increment_features. + */ +#define NETIF_F_ALL_FOR_ALL (NETIF_F_NOCACHE_COPY | NETIF_F_FSO) /* changeable features with no special hardware requirements */ #define NETIF_F_SOFT_FEATURES (NETIF_F_GSO | NETIF_F_GRO) diff --git a/net/core/dev.c b/net/core/dev.c index 3bbb4c2ce92e..7db99b52679f 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -6164,33 +6164,20 @@ static int dev_cpu_callback(struct notifier_block *nfb, */ u32 netdev_increment_features(u32 all, u32 one, u32 mask) { - /* If device needs checksumming, downgrade to it. */ - if (all & NETIF_F_NO_CSUM && !(one & NETIF_F_NO_CSUM)) - all ^= NETIF_F_NO_CSUM | (one & NETIF_F_ALL_CSUM); - else if (mask & NETIF_F_ALL_CSUM) { - /* If one device supports v4/v6 checksumming, set for all. */ - if (one & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM) && - !(all & NETIF_F_GEN_CSUM)) { - all &= ~NETIF_F_ALL_CSUM; - all |= one & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); - } - - /* If one device supports hw checksumming, set for all. */ - if (one & NETIF_F_GEN_CSUM && !(all & NETIF_F_GEN_CSUM)) { - all &= ~NETIF_F_ALL_CSUM; - all |= NETIF_F_HW_CSUM; - } - } + if (mask & NETIF_F_GEN_CSUM) + mask |= NETIF_F_ALL_CSUM; + mask |= NETIF_F_VLAN_CHALLENGED; - /* If device can't no cache copy, don't do for all */ - if (!(one & NETIF_F_NOCACHE_COPY)) - all &= ~NETIF_F_NOCACHE_COPY; + all |= one & (NETIF_F_ONE_FOR_ALL|NETIF_F_ALL_CSUM) & mask; + all &= one | ~NETIF_F_ALL_FOR_ALL; - one |= NETIF_F_ALL_CSUM; + /* If device needs checksumming, downgrade to it. */ + if (all & (NETIF_F_ALL_CSUM & ~NETIF_F_NO_CSUM)) + all &= ~NETIF_F_NO_CSUM; - one |= all & NETIF_F_ONE_FOR_ALL; - all &= one | NETIF_F_LLTX | NETIF_F_GSO | NETIF_F_UFO; - all |= one & mask & NETIF_F_ONE_FOR_ALL; + /* If one device supports hw checksumming, set for all. */ + if (all & NETIF_F_GEN_CSUM) + all &= ~(NETIF_F_ALL_CSUM & ~NETIF_F_GEN_CSUM); return all; } -- cgit From fa2bd7ff9247f4218dfc907db14d000cd7edd862 Mon Sep 17 00:00:00 2001 From: MichaÅ‚ MirosÅ‚aw Date: Fri, 22 Apr 2011 06:31:16 +0000 Subject: net: allow user to change NETIF_F_HIGHDMA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NETIF_F_HIGHDMA is like any other TX offloads, so allow user to toggle it. This is needed later for bridge and bonding convertsion to hw_features. Signed-off-by: MichaÅ‚ MirosÅ‚aw Signed-off-by: David S. Miller --- include/linux/netdevice.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index b7d0304762aa..e03af35843bc 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1080,7 +1080,7 @@ struct net_device { /* Features valid for ethtool to change */ /* = all defined minus driver/device-class-related */ -#define NETIF_F_NEVER_CHANGE (NETIF_F_HIGHDMA | NETIF_F_VLAN_CHALLENGED | \ +#define NETIF_F_NEVER_CHANGE (NETIF_F_VLAN_CHALLENGED | \ NETIF_F_LLTX | NETIF_F_NETNS_LOCAL) #define NETIF_F_ETHTOOL_BITS (0x7f3fffff & ~NETIF_F_NEVER_CHANGE) @@ -1098,6 +1098,7 @@ struct net_device { #define NETIF_F_ALL_TX_OFFLOADS (NETIF_F_ALL_CSUM | NETIF_F_SG | \ NETIF_F_FRAGLIST | NETIF_F_ALL_TSO | \ + NETIF_F_HIGHDMA | \ NETIF_F_SCTP_CSUM | NETIF_F_FCOE_CRC) /* -- cgit From 180bf812ceaf01eb8ac69b86f3be0bd57f697668 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Thu, 28 Apr 2011 12:58:11 -0700 Subject: timers: Improve alarmtimer comments and minor fixes This patch addresses a number of minor comment improvements and other minor issues from Thomas' review of the alarmtimers code. CC: Thomas Gleixner Signed-off-by: John Stultz --- include/linux/alarmtimer.h | 12 ++++++++- kernel/time/alarmtimer.c | 67 +++++++++++++++++++--------------------------- 2 files changed, 38 insertions(+), 41 deletions(-) (limited to 'include/linux') diff --git a/include/linux/alarmtimer.h b/include/linux/alarmtimer.h index 6b364b2e2074..c5d6095b46f8 100644 --- a/include/linux/alarmtimer.h +++ b/include/linux/alarmtimer.h @@ -13,12 +13,22 @@ enum alarmtimer_type { ALARM_NUMTYPE, }; +/** + * struct alarm - Alarm timer structure + * @node: timerqueue node for adding to the event list this value + * also includes the expiration time. + * @period: Period for recuring alarms + * @function: Function pointer to be executed when the timer fires. + * @type: Alarm type (BOOTTIME/REALTIME) + * @enabled: Flag that represents if the alarm is set to fire or not + * @data: Internal data value. + */ struct alarm { struct timerqueue_node node; ktime_t period; void (*function)(struct alarm *); enum alarmtimer_type type; - char enabled; + bool enabled; void *data; }; diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index 4058ad79d55f..bed98004ae1a 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -26,7 +26,15 @@ #include #include - +/** + * struct alarm_base - Alarm timer bases + * @lock: Lock for syncrhonized access to the base + * @timerqueue: Timerqueue head managing the list of events + * @timer: hrtimer used to schedule events while running + * @gettime: Function to read the time correlating to the base + * @base_clockid: clockid for the base + * @irqwork Delayed work structure for expiring timers + */ static struct alarm_base { spinlock_t lock; struct timerqueue_head timerqueue; @@ -36,18 +44,16 @@ static struct alarm_base { struct work_struct irqwork; } alarm_bases[ALARM_NUMTYPE]; +/* rtc timer and device for setting alarm wakeups at suspend */ static struct rtc_timer rtctimer; static struct rtc_device *rtcdev; +/* freezer delta & lock used to handle clock_nanosleep triggered wakeups */ static ktime_t freezer_delta; static DEFINE_SPINLOCK(freezer_delta_lock); -/************************************************************************** - * alarmtimer management code - */ - -/* +/** * alarmtimer_enqueue - Adds an alarm timer to an alarm_base timerqueue * @base: pointer to the base where the timer is being run * @alarm: pointer to alarm being enqueued. @@ -67,7 +73,7 @@ static void alarmtimer_enqueue(struct alarm_base *base, struct alarm *alarm) } } -/* +/** * alarmtimer_remove - Removes an alarm timer from an alarm_base timerqueue * @base: pointer to the base where the timer is running * @alarm: pointer to alarm being removed @@ -91,16 +97,16 @@ static void alarmtimer_remove(struct alarm_base *base, struct alarm *alarm) } } -/* +/** * alarmtimer_do_work - Handles alarm being fired. * @work: pointer to workqueue being run * - * When a timer fires, this runs through the timerqueue to see - * which alarm timers, and run those that expired. If there are - * more alarm timers queued, we set the hrtimer to fire in the - * future. + * When a alarm timer fires, this runs through the timerqueue to + * see which alarms expired, and runs those. If there are more alarm + * timers queued for the future, we set the hrtimer to fire when + * when the next future alarm timer expires. */ -void alarmtimer_do_work(struct work_struct *work) +static void alarmtimer_do_work(struct work_struct *work) { struct alarm_base *base = container_of(work, struct alarm_base, irqwork); @@ -141,7 +147,7 @@ void alarmtimer_do_work(struct work_struct *work) } -/* +/** * alarmtimer_fired - Handles alarm hrtimer being fired. * @timer: pointer to hrtimer being run * @@ -156,7 +162,7 @@ static enum hrtimer_restart alarmtimer_fired(struct hrtimer *timer) } -/* +/** * alarmtimer_suspend - Suspend time callback * @dev: unused * @state: unused @@ -230,17 +236,11 @@ static void alarmtimer_freezerset(ktime_t absexp, enum alarmtimer_type type) } -/************************************************************************** - * alarm kernel interface code - */ - -/* +/** * alarm_init - Initialize an alarm structure * @alarm: ptr to alarm to be initialized * @type: the type of the alarm * @function: callback that is run when the alarm fires - * - * In-kernel interface to initializes the alarm structure. */ void alarm_init(struct alarm *alarm, enum alarmtimer_type type, void (*function)(struct alarm *)) @@ -252,13 +252,11 @@ void alarm_init(struct alarm *alarm, enum alarmtimer_type type, alarm->enabled = 0; } -/* +/** * alarm_start - Sets an alarm to fire * @alarm: ptr to alarm to set * @start: time to run the alarm * @period: period at which the alarm will recur - * - * In-kernel interface set an alarm timer. */ void alarm_start(struct alarm *alarm, ktime_t start, ktime_t period) { @@ -275,11 +273,9 @@ void alarm_start(struct alarm *alarm, ktime_t start, ktime_t period) spin_unlock_irqrestore(&base->lock, flags); } -/* +/** * alarm_cancel - Tries to cancel an alarm timer * @alarm: ptr to alarm to be canceled - * - * In-kernel interface to cancel an alarm timer. */ void alarm_cancel(struct alarm *alarm) { @@ -294,15 +290,9 @@ void alarm_cancel(struct alarm *alarm) } -/************************************************************************** - * alarm posix interface code - */ - -/* +/** * clock2alarm - helper that converts from clockid to alarmtypes * @clockid: clockid. - * - * Helper function that converts from clockids to alarmtypes */ static enum alarmtimer_type clock2alarm(clockid_t clockid) { @@ -313,7 +303,7 @@ static enum alarmtimer_type clock2alarm(clockid_t clockid) return -1; } -/* +/** * alarm_handle_timer - Callback for posix timers * @alarm: alarm that fired * @@ -327,7 +317,7 @@ static void alarm_handle_timer(struct alarm *alarm) ptr->it_overrun++; } -/* +/** * alarm_clock_getres - posix getres interface * @which_clock: clockid * @tp: timespec to fill @@ -598,9 +588,6 @@ out: return ret; } -/************************************************************************** - * alarmtimer initialization code - */ /* Suspend hook structures */ static const struct dev_pm_ops alarmtimer_pm_ops = { -- cgit From 69c9dd1ecf446ad8a830e4afc539a2a1adc85b78 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 29 Apr 2011 00:36:05 +0200 Subject: PM: Export platform bus type's default PM callbacks Export the default PM callbacks defined for the platform bus type so that they can be used by power domains for suspending and resuming platform devices in the future. Signed-off-by: Rafael J. Wysocki --- drivers/base/platform.c | 72 +++++++++++------------------------------ include/linux/platform_device.h | 60 ++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 54 deletions(-) (limited to 'include/linux') diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 9e0e4fc24c46..313556f28c9e 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -667,7 +667,7 @@ static int platform_legacy_resume(struct device *dev) return ret; } -static int platform_pm_prepare(struct device *dev) +int platform_pm_prepare(struct device *dev) { struct device_driver *drv = dev->driver; int ret = 0; @@ -678,7 +678,7 @@ static int platform_pm_prepare(struct device *dev) return ret; } -static void platform_pm_complete(struct device *dev) +void platform_pm_complete(struct device *dev) { struct device_driver *drv = dev->driver; @@ -686,16 +686,11 @@ static void platform_pm_complete(struct device *dev) drv->pm->complete(dev); } -#else /* !CONFIG_PM_SLEEP */ - -#define platform_pm_prepare NULL -#define platform_pm_complete NULL - -#endif /* !CONFIG_PM_SLEEP */ +#endif /* CONFIG_PM_SLEEP */ #ifdef CONFIG_SUSPEND -int __weak platform_pm_suspend(struct device *dev) +int platform_pm_suspend(struct device *dev) { struct device_driver *drv = dev->driver; int ret = 0; @@ -713,7 +708,7 @@ int __weak platform_pm_suspend(struct device *dev) return ret; } -int __weak platform_pm_suspend_noirq(struct device *dev) +int platform_pm_suspend_noirq(struct device *dev) { struct device_driver *drv = dev->driver; int ret = 0; @@ -729,7 +724,7 @@ int __weak platform_pm_suspend_noirq(struct device *dev) return ret; } -int __weak platform_pm_resume(struct device *dev) +int platform_pm_resume(struct device *dev) { struct device_driver *drv = dev->driver; int ret = 0; @@ -747,7 +742,7 @@ int __weak platform_pm_resume(struct device *dev) return ret; } -int __weak platform_pm_resume_noirq(struct device *dev) +int platform_pm_resume_noirq(struct device *dev) { struct device_driver *drv = dev->driver; int ret = 0; @@ -763,18 +758,11 @@ int __weak platform_pm_resume_noirq(struct device *dev) return ret; } -#else /* !CONFIG_SUSPEND */ - -#define platform_pm_suspend NULL -#define platform_pm_resume NULL -#define platform_pm_suspend_noirq NULL -#define platform_pm_resume_noirq NULL - -#endif /* !CONFIG_SUSPEND */ +#endif /* CONFIG_SUSPEND */ #ifdef CONFIG_HIBERNATE_CALLBACKS -static int platform_pm_freeze(struct device *dev) +int platform_pm_freeze(struct device *dev) { struct device_driver *drv = dev->driver; int ret = 0; @@ -792,7 +780,7 @@ static int platform_pm_freeze(struct device *dev) return ret; } -static int platform_pm_freeze_noirq(struct device *dev) +int platform_pm_freeze_noirq(struct device *dev) { struct device_driver *drv = dev->driver; int ret = 0; @@ -808,7 +796,7 @@ static int platform_pm_freeze_noirq(struct device *dev) return ret; } -static int platform_pm_thaw(struct device *dev) +int platform_pm_thaw(struct device *dev) { struct device_driver *drv = dev->driver; int ret = 0; @@ -826,7 +814,7 @@ static int platform_pm_thaw(struct device *dev) return ret; } -static int platform_pm_thaw_noirq(struct device *dev) +int platform_pm_thaw_noirq(struct device *dev) { struct device_driver *drv = dev->driver; int ret = 0; @@ -842,7 +830,7 @@ static int platform_pm_thaw_noirq(struct device *dev) return ret; } -static int platform_pm_poweroff(struct device *dev) +int platform_pm_poweroff(struct device *dev) { struct device_driver *drv = dev->driver; int ret = 0; @@ -860,7 +848,7 @@ static int platform_pm_poweroff(struct device *dev) return ret; } -static int platform_pm_poweroff_noirq(struct device *dev) +int platform_pm_poweroff_noirq(struct device *dev) { struct device_driver *drv = dev->driver; int ret = 0; @@ -876,7 +864,7 @@ static int platform_pm_poweroff_noirq(struct device *dev) return ret; } -static int platform_pm_restore(struct device *dev) +int platform_pm_restore(struct device *dev) { struct device_driver *drv = dev->driver; int ret = 0; @@ -894,7 +882,7 @@ static int platform_pm_restore(struct device *dev) return ret; } -static int platform_pm_restore_noirq(struct device *dev) +int platform_pm_restore_noirq(struct device *dev) { struct device_driver *drv = dev->driver; int ret = 0; @@ -910,18 +898,7 @@ static int platform_pm_restore_noirq(struct device *dev) return ret; } -#else /* !CONFIG_HIBERNATE_CALLBACKS */ - -#define platform_pm_freeze NULL -#define platform_pm_thaw NULL -#define platform_pm_poweroff NULL -#define platform_pm_restore NULL -#define platform_pm_freeze_noirq NULL -#define platform_pm_thaw_noirq NULL -#define platform_pm_poweroff_noirq NULL -#define platform_pm_restore_noirq NULL - -#endif /* !CONFIG_HIBERNATE_CALLBACKS */ +#endif /* CONFIG_HIBERNATE_CALLBACKS */ #ifdef CONFIG_PM_RUNTIME @@ -949,23 +926,10 @@ int __weak platform_pm_runtime_idle(struct device *dev) #endif /* !CONFIG_PM_RUNTIME */ static const struct dev_pm_ops platform_dev_pm_ops = { - .prepare = platform_pm_prepare, - .complete = platform_pm_complete, - .suspend = platform_pm_suspend, - .resume = platform_pm_resume, - .freeze = platform_pm_freeze, - .thaw = platform_pm_thaw, - .poweroff = platform_pm_poweroff, - .restore = platform_pm_restore, - .suspend_noirq = platform_pm_suspend_noirq, - .resume_noirq = platform_pm_resume_noirq, - .freeze_noirq = platform_pm_freeze_noirq, - .thaw_noirq = platform_pm_thaw_noirq, - .poweroff_noirq = platform_pm_poweroff_noirq, - .restore_noirq = platform_pm_restore_noirq, .runtime_suspend = platform_pm_runtime_suspend, .runtime_resume = platform_pm_runtime_resume, .runtime_idle = platform_pm_runtime_idle, + USE_PLATFORM_PM_SLEEP_OPS }; struct bus_type platform_bus_type = { diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index 744942c95fec..e0093e061b08 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h @@ -205,4 +205,64 @@ static inline char *early_platform_driver_setup_func(void) \ } #endif /* MODULE */ +#ifdef CONFIG_PM_SLEEP +extern int platform_pm_prepare(struct device *dev); +extern void platform_pm_complete(struct device *dev); +#else +#define platform_pm_prepare NULL +#define platform_pm_complete NULL +#endif + +#ifdef CONFIG_SUSPEND +extern int platform_pm_suspend(struct device *dev); +extern int platform_pm_suspend_noirq(struct device *dev); +extern int platform_pm_resume(struct device *dev); +extern int platform_pm_resume_noirq(struct device *dev); +#else +#define platform_pm_suspend NULL +#define platform_pm_resume NULL +#define platform_pm_suspend_noirq NULL +#define platform_pm_resume_noirq NULL +#endif + +#ifdef CONFIG_HIBERNATE_CALLBACKS +extern int platform_pm_freeze(struct device *dev); +extern int platform_pm_freeze_noirq(struct device *dev); +extern int platform_pm_thaw(struct device *dev); +extern int platform_pm_thaw_noirq(struct device *dev); +extern int platform_pm_poweroff(struct device *dev); +extern int platform_pm_poweroff_noirq(struct device *dev); +extern int platform_pm_restore(struct device *dev); +extern int platform_pm_restore_noirq(struct device *dev); +#else +#define platform_pm_freeze NULL +#define platform_pm_thaw NULL +#define platform_pm_poweroff NULL +#define platform_pm_restore NULL +#define platform_pm_freeze_noirq NULL +#define platform_pm_thaw_noirq NULL +#define platform_pm_poweroff_noirq NULL +#define platform_pm_restore_noirq NULL +#endif + +#ifdef CONFIG_PM_SLEEP +#define USE_PLATFORM_PM_SLEEP_OPS \ + .prepare = platform_pm_prepare, \ + .complete = platform_pm_complete, \ + .suspend = platform_pm_suspend, \ + .resume = platform_pm_resume, \ + .freeze = platform_pm_freeze, \ + .thaw = platform_pm_thaw, \ + .poweroff = platform_pm_poweroff, \ + .restore = platform_pm_restore, \ + .suspend_noirq = platform_pm_suspend_noirq, \ + .resume_noirq = platform_pm_resume_noirq, \ + .freeze_noirq = platform_pm_freeze_noirq, \ + .thaw_noirq = platform_pm_thaw_noirq, \ + .poweroff_noirq = platform_pm_poweroff_noirq, \ + .restore_noirq = platform_pm_restore_noirq, +#else +#define USE_PLATFORM_PM_SLEEP_OPS +#endif + #endif /* _PLATFORM_DEVICE_H_ */ -- cgit From 1d2b71f61b6a10216274e27b717becf9ae101fc7 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 29 Apr 2011 00:36:53 +0200 Subject: PM / Runtime: Add subsystem data field to struct dev_pm_info Some subsystems need to attach PM-related data to struct device and they need to use devres for this purpose. For their convenience and to make code more straightforward, add a new field called subsys_data to struct dev_pm_info and let subsystems use it for attaching PM-related information to devices. Convert the ARM shmobile platform to using the new field. Signed-off-by: Rafael J. Wysocki --- arch/arm/mach-shmobile/pm_runtime.c | 34 +++++++++++++++++----------------- include/linux/pm.h | 1 + 2 files changed, 18 insertions(+), 17 deletions(-) (limited to 'include/linux') diff --git a/arch/arm/mach-shmobile/pm_runtime.c b/arch/arm/mach-shmobile/pm_runtime.c index 12bb504c7f49..30bbe9a99ae1 100644 --- a/arch/arm/mach-shmobile/pm_runtime.c +++ b/arch/arm/mach-shmobile/pm_runtime.c @@ -18,6 +18,7 @@ #include #include #include +#include #ifdef CONFIG_PM_RUNTIME #define BIT_ONCE 0 @@ -29,22 +30,9 @@ struct pm_runtime_data { struct clk *clk; }; -static void __devres_release(struct device *dev, void *res) -{ - struct pm_runtime_data *prd = res; - - dev_dbg(dev, "__devres_release()\n"); - - if (test_bit(BIT_CLK_ENABLED, &prd->flags)) - clk_disable(prd->clk); - - if (test_bit(BIT_ACTIVE, &prd->flags)) - clk_put(prd->clk); -} - static struct pm_runtime_data *__to_prd(struct device *dev) { - return devres_find(dev, __devres_release, NULL, NULL); + return dev ? dev->power.subsys_data : NULL; } static void platform_pm_runtime_init(struct device *dev, @@ -121,14 +109,26 @@ static int platform_bus_notify(struct notifier_block *nb, dev_dbg(dev, "platform_bus_notify() %ld !\n", action); - if (action == BUS_NOTIFY_BIND_DRIVER) { - prd = devres_alloc(__devres_release, sizeof(*prd), GFP_KERNEL); + switch (action) { + case BUS_NOTIFY_BIND_DRIVER: + prd = kzalloc(sizeof(*prd), GFP_KERNEL); if (prd) { - devres_add(dev, prd); + dev->power.subsys_data = prd; dev->pwr_domain = &default_power_domain; } else { dev_err(dev, "unable to alloc memory for runtime pm\n"); } + break; + case BUS_NOTIFY_UNBOUND_DRIVER: + prd = __to_prd(dev); + if (prd) { + if (test_bit(BIT_CLK_ENABLED, &prd->flags)) + clk_disable(prd->clk); + + if (test_bit(BIT_ACTIVE, &prd->flags)) + clk_put(prd->clk); + } + break; } return 0; diff --git a/include/linux/pm.h b/include/linux/pm.h index 512e09177e57..f4167d0faa67 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -460,6 +460,7 @@ struct dev_pm_info { unsigned long active_jiffies; unsigned long suspended_jiffies; unsigned long accounting_timestamp; + void *subsys_data; /* Owned by the subsystem. */ #endif }; -- cgit From 8f62242246351b5a4bc0c1f00c0c7003edea128a Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 29 Apr 2011 13:19:47 +0200 Subject: perf events: Add generic front-end and back-end stalled cycle event definitions Add two generic hardware events: front-end and back-end stalled cycles. These events measure conditions when the CPU is executing code but its capabilities are not fully utilized. Understanding such situations and analyzing them is an important sub-task of code optimization workflows. Both events limit performance: most front end stalls tend to be caused by branch misprediction or instruction fetch cachemisses, backend stalls can be caused by various resource shortages or inefficient instruction scheduling. Front-end stalls are the more important ones: code cannot run fast if the instruction stream is not being kept up. An over-utilized back-end can cause front-end stalls and thus has to be kept an eye on as well. The exact composition is very program logic and instruction mix dependent. We use the terms 'stall', 'front-end' and 'back-end' loosely and try to use the best available events from specific CPUs that approximate these concepts. Cc: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: Frederic Weisbecker Link: http://lkml.kernel.org/n/tip-7y40wib8n000io7hjpn1dsrm@git.kernel.org Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel.c | 2 +- include/linux/perf_event.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 1ea94224f62e..393085b87a2c 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -1414,7 +1414,7 @@ static __init int intel_pmu_init(void) x86_pmu.extra_regs = intel_nehalem_extra_regs; /* Install the stalled-cycles event: UOPS_EXECUTED.CORE_ACTIVE_CYCLES,c=1,i=1 */ - intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES] = 0x1803fb1; + intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = 0x1803fb1; if (ebx & 0x40) { /* diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index ac636dd20a0c..4e2d7ae71499 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -52,7 +52,8 @@ enum perf_hw_id { PERF_COUNT_HW_BRANCH_INSTRUCTIONS = 4, PERF_COUNT_HW_BRANCH_MISSES = 5, PERF_COUNT_HW_BUS_CYCLES = 6, - PERF_COUNT_HW_STALLED_CYCLES = 7, + PERF_COUNT_HW_STALLED_CYCLES_FRONTEND = 7, + PERF_COUNT_HW_STALLED_CYCLES_BACKEND = 8, PERF_COUNT_HW_MAX, /* non-ABI */ }; -- cgit From 36504605432996590f889e33d47e2d9c581f7569 Mon Sep 17 00:00:00 2001 From: David Decotigny Date: Wed, 27 Apr 2011 18:32:37 +0000 Subject: ethtool: cosmetics: enforce const-ness in ethtool_cmd_speed The 'ep' argument of ethtool_cmd_speed is not altered: advertise it in protoype. +Indentation fix. Also add comments to advise using the ethtool_cmd_speed API to get/set the link speed. Signed-off-by: David Decotigny Signed-off-by: David S. Miller --- include/linux/ethtool.h | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 9de31274341d..7e6e0a89ca26 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -24,7 +24,10 @@ struct ethtool_cmd { __u32 cmd; __u32 supported; /* Features this interface supports */ __u32 advertising; /* Features this interface advertises */ - __u16 speed; /* The forced speed, 10Mb, 100Mb, gigabit */ + __u16 speed; /* The forced speed (lower bits) in + * Mbps. Please use + * ethtool_cmd_speed()/_set() to + * access it */ __u8 duplex; /* Duplex, half or full */ __u8 port; /* Which connector port */ __u8 phy_address; @@ -33,7 +36,10 @@ struct ethtool_cmd { __u8 mdio_support; __u32 maxtxpkt; /* Tx pkts before generating tx int */ __u32 maxrxpkt; /* Rx pkts before generating rx int */ - __u16 speed_hi; + __u16 speed_hi; /* The forced speed (upper + * bits) in Mbps. Please use + * ethtool_cmd_speed()/_set() to + * access it */ __u8 eth_tp_mdix; __u8 reserved2; __u32 lp_advertising; /* Features the link partner advertises */ @@ -41,14 +47,14 @@ struct ethtool_cmd { }; static inline void ethtool_cmd_speed_set(struct ethtool_cmd *ep, - __u32 speed) + __u32 speed) { ep->speed = (__u16)speed; ep->speed_hi = (__u16)(speed >> 16); } -static inline __u32 ethtool_cmd_speed(struct ethtool_cmd *ep) +static inline __u32 ethtool_cmd_speed(const struct ethtool_cmd *ep) { return (ep->speed_hi << 16) | ep->speed; } -- cgit From 8ae6daca85c8bbd6a32c382db5e2a2a989f8bed2 Mon Sep 17 00:00:00 2001 From: David Decotigny Date: Wed, 27 Apr 2011 18:32:38 +0000 Subject: ethtool: Call ethtool's get/set_settings callbacks with cleaned data This makes sure that when a driver calls the ethtool's get/set_settings() callback of another driver, the data passed to it is clean. This guarantees that speed_hi will be zeroed correctly if the called callback doesn't explicitely set it: we are sure we don't get a corrupted speed from the underlying driver. We also take care of setting the cmd field appropriately (ETHTOOL_GSET/SSET). This applies to dev_ethtool_get_settings(), which now makes sure it sets up that ethtool command parameter correctly before passing it to drivers. This also means that whoever calls dev_ethtool_get_settings() does not have to clean the ethtool command parameter. This function also becomes an exported symbol instead of an inline. All drivers visible to make allyesconfig under x86_64 have been updated. Signed-off-by: David Decotigny Signed-off-by: David S. Miller --- arch/mips/txx9/generic/setup_tx4939.c | 21 ++++++++------------- drivers/net/e100.c | 2 +- drivers/net/mdio.c | 3 +++ drivers/net/mii.c | 3 +++ drivers/net/pch_gbe/pch_gbe_main.c | 6 +++--- drivers/net/pch_gbe/pch_gbe_phy.c | 2 +- drivers/net/pcnet32.c | 16 ++++++++-------- drivers/net/sfc/mdio_10g.c | 4 ++-- drivers/net/stmmac/stmmac_ethtool.c | 5 ++--- drivers/net/usb/asix.c | 28 +++++++++++++++------------- drivers/net/usb/dm9601.c | 6 +++--- drivers/net/usb/smsc75xx.c | 7 ++++--- drivers/net/usb/smsc95xx.c | 7 ++++--- drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 11 +++++++---- drivers/scsi/fcoe/fcoe.c | 11 +++++++---- include/linux/ethtool.h | 4 +++- include/linux/netdevice.h | 9 ++------- include/rdma/ib_addr.h | 13 +++++++------ net/core/dev.c | 24 ++++++++++++++++++++++++ net/core/net-sysfs.c | 24 ++++++++++-------------- 20 files changed, 117 insertions(+), 89 deletions(-) (limited to 'include/linux') diff --git a/arch/mips/txx9/generic/setup_tx4939.c b/arch/mips/txx9/generic/setup_tx4939.c index 3dc19f482959..e9f95dcde379 100644 --- a/arch/mips/txx9/generic/setup_tx4939.c +++ b/arch/mips/txx9/generic/setup_tx4939.c @@ -318,19 +318,15 @@ void __init tx4939_sio_init(unsigned int sclk, unsigned int cts_mask) } #if defined(CONFIG_TC35815) || defined(CONFIG_TC35815_MODULE) -static int tx4939_get_eth_speed(struct net_device *dev) +static u32 tx4939_get_eth_speed(struct net_device *dev) { - struct ethtool_cmd cmd = { ETHTOOL_GSET }; - int speed = 100; /* default 100Mbps */ - int err; - if (!dev->ethtool_ops || !dev->ethtool_ops->get_settings) - return speed; - err = dev->ethtool_ops->get_settings(dev, &cmd); - if (err < 0) - return speed; - speed = cmd.speed == SPEED_100 ? 100 : 10; - return speed; + struct ethtool_cmd cmd; + if (dev_ethtool_get_settings(dev, &cmd)) + return 100; /* default 100Mbps */ + + return ethtool_cmd_speed(&cmd); } + static int tx4939_netdev_event(struct notifier_block *this, unsigned long event, void *ptr) @@ -343,8 +339,7 @@ static int tx4939_netdev_event(struct notifier_block *this, else if (dev->irq == TXX9_IRQ_BASE + TX4939_IR_ETH(1)) bit = TX4939_PCFG_SPEED1; if (bit) { - int speed = tx4939_get_eth_speed(dev); - if (speed == 100) + if (tx4939_get_eth_speed(dev) == 100) txx9_set64(&tx4939_ccfgptr->pcfg, bit); else txx9_clear64(&tx4939_ccfgptr->pcfg, bit); diff --git a/drivers/net/e100.c b/drivers/net/e100.c index b0aa9e68990a..66ba596a4d37 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -1668,7 +1668,7 @@ static void e100_adjust_adaptive_ifs(struct nic *nic, int speed, int duplex) static void e100_watchdog(unsigned long data) { struct nic *nic = (struct nic *)data; - struct ethtool_cmd cmd; + struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET }; netif_printk(nic, timer, KERN_DEBUG, nic->netdev, "right now = %ld\n", jiffies); diff --git a/drivers/net/mdio.c b/drivers/net/mdio.c index e85bf04cf813..f2d10abd0403 100644 --- a/drivers/net/mdio.c +++ b/drivers/net/mdio.c @@ -176,6 +176,9 @@ static u32 mdio45_get_an(const struct mdio_if_info *mdio, u16 addr) * @npage_adv: Modes currently advertised on next pages * @npage_lpa: Modes advertised by link partner on next pages * + * The @ecmd parameter is expected to have been cleared before calling + * mdio45_ethtool_gset_npage(). + * * Since the CSRs for auto-negotiation using next pages are not fully * standardised, this function does not attempt to decode them. The * caller must pass them in. diff --git a/drivers/net/mii.c b/drivers/net/mii.c index 0a6c6a2e7550..05acca78f63a 100644 --- a/drivers/net/mii.c +++ b/drivers/net/mii.c @@ -58,6 +58,9 @@ static u32 mii_get_an(struct mii_if_info *mii, u16 addr) * @mii: MII interface * @ecmd: requested ethtool_cmd * + * The @ecmd parameter is expected to have been cleared before calling + * mii_ethtool_gset(). + * * Returns 0 for success, negative on error. */ int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd) diff --git a/drivers/net/pch_gbe/pch_gbe_main.c b/drivers/net/pch_gbe/pch_gbe_main.c index 4cc9872f5ec4..f3e4b0adae93 100644 --- a/drivers/net/pch_gbe/pch_gbe_main.c +++ b/drivers/net/pch_gbe/pch_gbe_main.c @@ -888,12 +888,12 @@ static void pch_gbe_watchdog(unsigned long data) struct pch_gbe_adapter *adapter = (struct pch_gbe_adapter *)data; struct net_device *netdev = adapter->netdev; struct pch_gbe_hw *hw = &adapter->hw; - struct ethtool_cmd cmd; pr_debug("right now = %ld\n", jiffies); pch_gbe_update_stats(adapter); if ((mii_link_ok(&adapter->mii)) && (!netif_carrier_ok(netdev))) { + struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET }; netdev->tx_queue_len = adapter->tx_queue_len; /* mii library handles link maintenance tasks */ if (mii_ethtool_gset(&adapter->mii, &cmd)) { @@ -903,7 +903,7 @@ static void pch_gbe_watchdog(unsigned long data) PCH_GBE_WATCHDOG_PERIOD)); return; } - hw->mac.link_speed = cmd.speed; + hw->mac.link_speed = ethtool_cmd_speed(&cmd); hw->mac.link_duplex = cmd.duplex; /* Set the RGMII control. */ pch_gbe_set_rgmii_ctrl(adapter, hw->mac.link_speed, @@ -913,7 +913,7 @@ static void pch_gbe_watchdog(unsigned long data) hw->mac.link_duplex); netdev_dbg(netdev, "Link is Up %d Mbps %s-Duplex\n", - cmd.speed, + hw->mac.link_speed, cmd.duplex == DUPLEX_FULL ? "Full" : "Half"); netif_carrier_on(netdev); netif_wake_queue(netdev); diff --git a/drivers/net/pch_gbe/pch_gbe_phy.c b/drivers/net/pch_gbe/pch_gbe_phy.c index 923a687acd30..9a8207f686fd 100644 --- a/drivers/net/pch_gbe/pch_gbe_phy.c +++ b/drivers/net/pch_gbe/pch_gbe_phy.c @@ -247,7 +247,7 @@ inline void pch_gbe_phy_set_rgmii(struct pch_gbe_hw *hw) void pch_gbe_phy_init_setting(struct pch_gbe_hw *hw) { struct pch_gbe_adapter *adapter; - struct ethtool_cmd cmd; + struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET }; int ret; u16 mii_reg; diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index 0a1efbae1bc0..b48aba9e4227 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c @@ -2099,7 +2099,7 @@ static int pcnet32_open(struct net_device *dev) int first_phy = -1; u16 bmcr; u32 bcr9; - struct ethtool_cmd ecmd; + struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET }; /* * There is really no good other way to handle multiple PHYs @@ -2115,9 +2115,9 @@ static int pcnet32_open(struct net_device *dev) ecmd.port = PORT_MII; ecmd.transceiver = XCVR_INTERNAL; ecmd.autoneg = AUTONEG_DISABLE; - ecmd.speed = - lp-> - options & PCNET32_PORT_100 ? SPEED_100 : SPEED_10; + ethtool_cmd_speed_set(&ecmd, + (lp->options & PCNET32_PORT_100) ? + SPEED_100 : SPEED_10); bcr9 = lp->a.read_bcr(ioaddr, 9); if (lp->options & PCNET32_PORT_FD) { @@ -2763,11 +2763,11 @@ static void pcnet32_check_media(struct net_device *dev, int verbose) netif_carrier_on(dev); if (lp->mii) { if (netif_msg_link(lp)) { - struct ethtool_cmd ecmd; + struct ethtool_cmd ecmd = { + .cmd = ETHTOOL_GSET }; mii_ethtool_gset(&lp->mii_if, &ecmd); - netdev_info(dev, "link up, %sMbps, %s-duplex\n", - (ecmd.speed == SPEED_100) - ? "100" : "10", + netdev_info(dev, "link up, %uMbps, %s-duplex\n", + ethtool_cmd_speed(&ecmd), (ecmd.duplex == DUPLEX_FULL) ? "full" : "half"); } diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c index 19e68c26d103..71159145b4bf 100644 --- a/drivers/net/sfc/mdio_10g.c +++ b/drivers/net/sfc/mdio_10g.c @@ -232,12 +232,12 @@ void efx_mdio_set_mmds_lpower(struct efx_nic *efx, */ int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) { - struct ethtool_cmd prev; + struct ethtool_cmd prev = { .cmd = ETHTOOL_GSET }; efx->phy_op->get_settings(efx, &prev); if (ecmd->advertising == prev.advertising && - ecmd->speed == prev.speed && + ethtool_cmd_speed(ecmd) == ethtool_cmd_speed(&prev) && ecmd->duplex == prev.duplex && ecmd->port == prev.port && ecmd->autoneg == prev.autoneg) diff --git a/drivers/net/stmmac/stmmac_ethtool.c b/drivers/net/stmmac/stmmac_ethtool.c index 0e61ac8707cb..6f5aaeb986ff 100644 --- a/drivers/net/stmmac/stmmac_ethtool.c +++ b/drivers/net/stmmac/stmmac_ethtool.c @@ -237,13 +237,12 @@ stmmac_set_pauseparam(struct net_device *netdev, if (phy->autoneg) { if (netif_running(netdev)) { - struct ethtool_cmd cmd; + struct ethtool_cmd cmd = { .cmd = ETHTOOL_SSET }; /* auto-negotiation automatically restarted */ - cmd.cmd = ETHTOOL_NWAY_RST; cmd.supported = phy->supported; cmd.advertising = phy->advertising; cmd.autoneg = phy->autoneg; - cmd.speed = phy->speed; + ethtool_cmd_speed_set(&cmd, phy->speed); cmd.duplex = phy->duplex; cmd.phy_address = phy->addr; ret = phy_ethtool_sset(phy, &cmd); diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 6140b56cce53..6998aa6b7bb7 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -847,7 +847,7 @@ static void ax88172_set_multicast(struct net_device *net) static int ax88172_link_reset(struct usbnet *dev) { u8 mode; - struct ethtool_cmd ecmd; + struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET }; mii_check_media(&dev->mii, 1, 1); mii_ethtool_gset(&dev->mii, &ecmd); @@ -856,8 +856,8 @@ static int ax88172_link_reset(struct usbnet *dev) if (ecmd.duplex != DUPLEX_FULL) mode |= ~AX88172_MEDIUM_FD; - netdev_dbg(dev->net, "ax88172_link_reset() speed: %d duplex: %d setting mode to 0x%04x\n", - ecmd.speed, ecmd.duplex, mode); + netdev_dbg(dev->net, "ax88172_link_reset() speed: %u duplex: %d setting mode to 0x%04x\n", + ethtool_cmd_speed(&ecmd), ecmd.duplex, mode); asix_write_medium_mode(dev, mode); @@ -947,20 +947,20 @@ static const struct ethtool_ops ax88772_ethtool_ops = { static int ax88772_link_reset(struct usbnet *dev) { u16 mode; - struct ethtool_cmd ecmd; + struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET }; mii_check_media(&dev->mii, 1, 1); mii_ethtool_gset(&dev->mii, &ecmd); mode = AX88772_MEDIUM_DEFAULT; - if (ecmd.speed != SPEED_100) + if (ethtool_cmd_speed(&ecmd) != SPEED_100) mode &= ~AX_MEDIUM_PS; if (ecmd.duplex != DUPLEX_FULL) mode &= ~AX_MEDIUM_FD; - netdev_dbg(dev->net, "ax88772_link_reset() speed: %d duplex: %d setting mode to 0x%04x\n", - ecmd.speed, ecmd.duplex, mode); + netdev_dbg(dev->net, "ax88772_link_reset() speed: %u duplex: %d setting mode to 0x%04x\n", + ethtool_cmd_speed(&ecmd), ecmd.duplex, mode); asix_write_medium_mode(dev, mode); @@ -1173,18 +1173,20 @@ static int marvell_led_status(struct usbnet *dev, u16 speed) static int ax88178_link_reset(struct usbnet *dev) { u16 mode; - struct ethtool_cmd ecmd; + struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET }; struct asix_data *data = (struct asix_data *)&dev->data; + u32 speed; netdev_dbg(dev->net, "ax88178_link_reset()\n"); mii_check_media(&dev->mii, 1, 1); mii_ethtool_gset(&dev->mii, &ecmd); mode = AX88178_MEDIUM_DEFAULT; + speed = ethtool_cmd_speed(&ecmd); - if (ecmd.speed == SPEED_1000) + if (speed == SPEED_1000) mode |= AX_MEDIUM_GM; - else if (ecmd.speed == SPEED_100) + else if (speed == SPEED_100) mode |= AX_MEDIUM_PS; else mode &= ~(AX_MEDIUM_PS | AX_MEDIUM_GM); @@ -1196,13 +1198,13 @@ static int ax88178_link_reset(struct usbnet *dev) else mode &= ~AX_MEDIUM_FD; - netdev_dbg(dev->net, "ax88178_link_reset() speed: %d duplex: %d setting mode to 0x%04x\n", - ecmd.speed, ecmd.duplex, mode); + netdev_dbg(dev->net, "ax88178_link_reset() speed: %u duplex: %d setting mode to 0x%04x\n", + speed, ecmd.duplex, mode); asix_write_medium_mode(dev, mode); if (data->phymode == PHY_MODE_MARVELL && data->ledmode) - marvell_led_status(dev, ecmd.speed); + marvell_led_status(dev, speed); return 0; } diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c index 5002f5be47be..1d93133e9b74 100644 --- a/drivers/net/usb/dm9601.c +++ b/drivers/net/usb/dm9601.c @@ -599,13 +599,13 @@ static void dm9601_status(struct usbnet *dev, struct urb *urb) static int dm9601_link_reset(struct usbnet *dev) { - struct ethtool_cmd ecmd; + struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET }; mii_check_media(&dev->mii, 1, 1); mii_ethtool_gset(&dev->mii, &ecmd); - netdev_dbg(dev->net, "link_reset() speed: %d duplex: %d\n", - ecmd.speed, ecmd.duplex); + netdev_dbg(dev->net, "link_reset() speed: %u duplex: %d\n", + ethtool_cmd_speed(&ecmd), ecmd.duplex); return 0; } diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c index 860a20c938b4..15b3d6888ae9 100644 --- a/drivers/net/usb/smsc75xx.c +++ b/drivers/net/usb/smsc75xx.c @@ -503,7 +503,7 @@ static int smsc75xx_update_flowcontrol(struct usbnet *dev, u8 duplex, static int smsc75xx_link_reset(struct usbnet *dev) { struct mii_if_info *mii = &dev->mii; - struct ethtool_cmd ecmd; + struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET }; u16 lcladv, rmtadv; int ret; @@ -519,8 +519,9 @@ static int smsc75xx_link_reset(struct usbnet *dev) lcladv = smsc75xx_mdio_read(dev->net, mii->phy_id, MII_ADVERTISE); rmtadv = smsc75xx_mdio_read(dev->net, mii->phy_id, MII_LPA); - netif_dbg(dev, link, dev->net, "speed: %d duplex: %d lcladv: %04x" - " rmtadv: %04x", ecmd.speed, ecmd.duplex, lcladv, rmtadv); + netif_dbg(dev, link, dev->net, "speed: %u duplex: %d lcladv: %04x" + " rmtadv: %04x", ethtool_cmd_speed(&ecmd), + ecmd.duplex, lcladv, rmtadv); return smsc75xx_update_flowcontrol(dev, ecmd.duplex, lcladv, rmtadv); } diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index 24f4b3739dd2..b374a9997908 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -457,7 +457,7 @@ static int smsc95xx_link_reset(struct usbnet *dev) { struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); struct mii_if_info *mii = &dev->mii; - struct ethtool_cmd ecmd; + struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET }; unsigned long flags; u16 lcladv, rmtadv; u32 intdata; @@ -472,8 +472,9 @@ static int smsc95xx_link_reset(struct usbnet *dev) lcladv = smsc95xx_mdio_read(dev->net, mii->phy_id, MII_ADVERTISE); rmtadv = smsc95xx_mdio_read(dev->net, mii->phy_id, MII_LPA); - netif_dbg(dev, link, dev->net, "speed: %d duplex: %d lcladv: %04x rmtadv: %04x\n", - ecmd.speed, ecmd.duplex, lcladv, rmtadv); + netif_dbg(dev, link, dev->net, + "speed: %u duplex: %d lcladv: %04x rmtadv: %04x\n", + ethtool_cmd_speed(&ecmd), ecmd.duplex, lcladv, rmtadv); spin_lock_irqsave(&pdata->mac_cr_lock, flags); if (ecmd.duplex != DUPLEX_FULL) { diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c index e2e647509a73..cd050196a163 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c @@ -664,7 +664,7 @@ static void bnx2fc_link_speed_update(struct fc_lport *lport) struct fcoe_port *port = lport_priv(lport); struct bnx2fc_hba *hba = port->priv; struct net_device *netdev = hba->netdev; - struct ethtool_cmd ecmd = { ETHTOOL_GSET }; + struct ethtool_cmd ecmd; if (!dev_ethtool_get_settings(netdev, &ecmd)) { lport->link_supported_speeds &= @@ -675,12 +675,15 @@ static void bnx2fc_link_speed_update(struct fc_lport *lport) if (ecmd.supported & SUPPORTED_10000baseT_Full) lport->link_supported_speeds |= FC_PORTSPEED_10GBIT; - if (ecmd.speed == SPEED_1000) + switch (ethtool_cmd_speed(&ecmd)) { + case SPEED_1000: lport->link_speed = FC_PORTSPEED_1GBIT; - if (ecmd.speed == SPEED_10000) + break; + case SPEED_10000: lport->link_speed = FC_PORTSPEED_10GBIT; + break; + } } - return; } static int bnx2fc_link_ok(struct fc_lport *lport) { diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index bde6ee5333eb..04f346b562da 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -2026,7 +2026,7 @@ out_nodev: int fcoe_link_speed_update(struct fc_lport *lport) { struct net_device *netdev = fcoe_netdev(lport); - struct ethtool_cmd ecmd = { ETHTOOL_GSET }; + struct ethtool_cmd ecmd; if (!dev_ethtool_get_settings(netdev, &ecmd)) { lport->link_supported_speeds &= @@ -2037,11 +2037,14 @@ int fcoe_link_speed_update(struct fc_lport *lport) if (ecmd.supported & SUPPORTED_10000baseT_Full) lport->link_supported_speeds |= FC_PORTSPEED_10GBIT; - if (ecmd.speed == SPEED_1000) + switch (ethtool_cmd_speed(&ecmd)) { + case SPEED_1000: lport->link_speed = FC_PORTSPEED_1GBIT; - if (ecmd.speed == SPEED_10000) + break; + case SPEED_10000: lport->link_speed = FC_PORTSPEED_10GBIT; - + break; + } return 0; } return -1; diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 7e6e0a89ca26..4194a2067a14 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -744,7 +744,9 @@ bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported); /** * struct ethtool_ops - optional netdev operations * @get_settings: Get various device settings including Ethernet link - * settings. Returns a negative error code or zero. + * settings. The @cmd parameter is expected to have been cleared + * before get_settings is called. Returns a negative error code or + * zero. * @set_settings: Set various device settings including Ethernet link * settings. Returns a negative error code or zero. * @get_drvinfo: Report driver/device information. Should only set the diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index e03af35843bc..d5de66af46f9 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2597,13 +2597,8 @@ static inline int netif_is_bond_slave(struct net_device *dev) extern struct pernet_operations __net_initdata loopback_net_ops; -static inline int dev_ethtool_get_settings(struct net_device *dev, - struct ethtool_cmd *cmd) -{ - if (!dev->ethtool_ops || !dev->ethtool_ops->get_settings) - return -EOPNOTSUPP; - return dev->ethtool_ops->get_settings(dev, cmd); -} +int dev_ethtool_get_settings(struct net_device *dev, + struct ethtool_cmd *cmd); static inline u32 dev_ethtool_get_rx_csum(struct net_device *dev) { diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h index b5fc9f39122b..ae8c68f30f1b 100644 --- a/include/rdma/ib_addr.h +++ b/include/rdma/ib_addr.h @@ -217,18 +217,19 @@ static inline enum ib_mtu iboe_get_mtu(int mtu) static inline int iboe_get_rate(struct net_device *dev) { struct ethtool_cmd cmd; + u32 speed; - if (!dev->ethtool_ops || !dev->ethtool_ops->get_settings || - dev->ethtool_ops->get_settings(dev, &cmd)) + if (dev_ethtool_get_settings(dev, &cmd)) return IB_RATE_PORT_CURRENT; - if (cmd.speed >= 40000) + speed = ethtool_cmd_speed(&cmd); + if (speed >= 40000) return IB_RATE_40_GBPS; - else if (cmd.speed >= 30000) + else if (speed >= 30000) return IB_RATE_30_GBPS; - else if (cmd.speed >= 20000) + else if (speed >= 20000) return IB_RATE_20_GBPS; - else if (cmd.speed >= 10000) + else if (speed >= 10000) return IB_RATE_10_GBPS; else return IB_RATE_PORT_CURRENT; diff --git a/net/core/dev.c b/net/core/dev.c index 7db99b52679f..e95dc30110eb 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -4495,6 +4495,30 @@ void dev_set_rx_mode(struct net_device *dev) netif_addr_unlock_bh(dev); } +/** + * dev_ethtool_get_settings - call device's ethtool_ops::get_settings() + * @dev: device + * @cmd: memory area for ethtool_ops::get_settings() result + * + * The cmd arg is initialized properly (cleared and + * ethtool_cmd::cmd field set to ETHTOOL_GSET). + * + * Return device's ethtool_ops::get_settings() result value or + * -EOPNOTSUPP when device doesn't expose + * ethtool_ops::get_settings() operation. + */ +int dev_ethtool_get_settings(struct net_device *dev, + struct ethtool_cmd *cmd) +{ + if (!dev->ethtool_ops || !dev->ethtool_ops->get_settings) + return -EOPNOTSUPP; + + memset(cmd, 0, sizeof(struct ethtool_cmd)); + cmd->cmd = ETHTOOL_GSET; + return dev->ethtool_ops->get_settings(dev, cmd); +} +EXPORT_SYMBOL(dev_ethtool_get_settings); + /** * dev_get_flags - get flags reported to userspace * @dev: device diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 5ceb257e860c..381813eae46c 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -28,6 +28,7 @@ static const char fmt_hex[] = "%#x\n"; static const char fmt_long_hex[] = "%#lx\n"; static const char fmt_dec[] = "%d\n"; +static const char fmt_udec[] = "%u\n"; static const char fmt_ulong[] = "%lu\n"; static const char fmt_u64[] = "%llu\n"; @@ -145,13 +146,10 @@ static ssize_t show_speed(struct device *dev, if (!rtnl_trylock()) return restart_syscall(); - if (netif_running(netdev) && - netdev->ethtool_ops && - netdev->ethtool_ops->get_settings) { - struct ethtool_cmd cmd = { ETHTOOL_GSET }; - - if (!netdev->ethtool_ops->get_settings(netdev, &cmd)) - ret = sprintf(buf, fmt_dec, ethtool_cmd_speed(&cmd)); + if (netif_running(netdev)) { + struct ethtool_cmd cmd; + if (!dev_ethtool_get_settings(netdev, &cmd)) + ret = sprintf(buf, fmt_udec, ethtool_cmd_speed(&cmd)); } rtnl_unlock(); return ret; @@ -166,13 +164,11 @@ static ssize_t show_duplex(struct device *dev, if (!rtnl_trylock()) return restart_syscall(); - if (netif_running(netdev) && - netdev->ethtool_ops && - netdev->ethtool_ops->get_settings) { - struct ethtool_cmd cmd = { ETHTOOL_GSET }; - - if (!netdev->ethtool_ops->get_settings(netdev, &cmd)) - ret = sprintf(buf, "%s\n", cmd.duplex ? "full" : "half"); + if (netif_running(netdev)) { + struct ethtool_cmd cmd; + if (!dev_ethtool_get_settings(netdev, &cmd)) + ret = sprintf(buf, "%s\n", + cmd.duplex ? "full" : "half"); } rtnl_unlock(); return ret; -- cgit From 85eb8c8d0b0900c073b0e6f89979ac9c439ade1a Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sat, 30 Apr 2011 00:25:44 +0200 Subject: PM / Runtime: Generic clock manipulation rountines for runtime PM (v6) Many different platforms and subsystems may want to disable device clocks during suspend and enable them during resume which is going to be done in a very similar way in all those cases. For this reason, provide generic routines for the manipulation of device clocks during suspend and resume. Convert the ARM shmobile platform to using the new routines. Signed-off-by: Rafael J. Wysocki --- arch/arm/mach-shmobile/pm_runtime.c | 140 +----------- drivers/base/power/Makefile | 1 + drivers/base/power/clock_ops.c | 430 ++++++++++++++++++++++++++++++++++++ include/linux/pm_runtime.h | 42 ++++ kernel/power/Kconfig | 4 + 5 files changed, 486 insertions(+), 131 deletions(-) create mode 100644 drivers/base/power/clock_ops.c (limited to 'include/linux') diff --git a/arch/arm/mach-shmobile/pm_runtime.c b/arch/arm/mach-shmobile/pm_runtime.c index 30bbe9a99ae1..2d1b67a59e4a 100644 --- a/arch/arm/mach-shmobile/pm_runtime.c +++ b/arch/arm/mach-shmobile/pm_runtime.c @@ -21,70 +21,6 @@ #include #ifdef CONFIG_PM_RUNTIME -#define BIT_ONCE 0 -#define BIT_ACTIVE 1 -#define BIT_CLK_ENABLED 2 - -struct pm_runtime_data { - unsigned long flags; - struct clk *clk; -}; - -static struct pm_runtime_data *__to_prd(struct device *dev) -{ - return dev ? dev->power.subsys_data : NULL; -} - -static void platform_pm_runtime_init(struct device *dev, - struct pm_runtime_data *prd) -{ - if (prd && !test_and_set_bit(BIT_ONCE, &prd->flags)) { - prd->clk = clk_get(dev, NULL); - if (!IS_ERR(prd->clk)) { - set_bit(BIT_ACTIVE, &prd->flags); - dev_info(dev, "clocks managed by runtime pm\n"); - } - } -} - -static void platform_pm_runtime_bug(struct device *dev, - struct pm_runtime_data *prd) -{ - if (prd && !test_and_set_bit(BIT_ONCE, &prd->flags)) - dev_err(dev, "runtime pm suspend before resume\n"); -} - -static int default_platform_runtime_suspend(struct device *dev) -{ - struct pm_runtime_data *prd = __to_prd(dev); - - dev_dbg(dev, "%s()\n", __func__); - - platform_pm_runtime_bug(dev, prd); - - if (prd && test_bit(BIT_ACTIVE, &prd->flags)) { - clk_disable(prd->clk); - clear_bit(BIT_CLK_ENABLED, &prd->flags); - } - - return 0; -} - -static int default_platform_runtime_resume(struct device *dev) -{ - struct pm_runtime_data *prd = __to_prd(dev); - - dev_dbg(dev, "%s()\n", __func__); - - platform_pm_runtime_init(dev, prd); - - if (prd && test_bit(BIT_ACTIVE, &prd->flags)) { - clk_enable(prd->clk); - set_bit(BIT_CLK_ENABLED, &prd->flags); - } - - return 0; -} static int default_platform_runtime_idle(struct device *dev) { @@ -94,87 +30,29 @@ static int default_platform_runtime_idle(struct device *dev) static struct dev_power_domain default_power_domain = { .ops = { - .runtime_suspend = default_platform_runtime_suspend, - .runtime_resume = default_platform_runtime_resume, + .runtime_suspend = pm_runtime_clk_suspend, + .runtime_resume = pm_runtime_clk_resume, .runtime_idle = default_platform_runtime_idle, USE_PLATFORM_PM_SLEEP_OPS }, }; -static int platform_bus_notify(struct notifier_block *nb, - unsigned long action, void *data) -{ - struct device *dev = data; - struct pm_runtime_data *prd; - - dev_dbg(dev, "platform_bus_notify() %ld !\n", action); - - switch (action) { - case BUS_NOTIFY_BIND_DRIVER: - prd = kzalloc(sizeof(*prd), GFP_KERNEL); - if (prd) { - dev->power.subsys_data = prd; - dev->pwr_domain = &default_power_domain; - } else { - dev_err(dev, "unable to alloc memory for runtime pm\n"); - } - break; - case BUS_NOTIFY_UNBOUND_DRIVER: - prd = __to_prd(dev); - if (prd) { - if (test_bit(BIT_CLK_ENABLED, &prd->flags)) - clk_disable(prd->clk); +#define DEFAULT_PWR_DOMAIN_PTR (&default_power_domain) - if (test_bit(BIT_ACTIVE, &prd->flags)) - clk_put(prd->clk); - } - break; - } +#else - return 0; -} - -#else /* CONFIG_PM_RUNTIME */ - -static int platform_bus_notify(struct notifier_block *nb, - unsigned long action, void *data) -{ - struct device *dev = data; - struct clk *clk; - - dev_dbg(dev, "platform_bus_notify() %ld !\n", action); - - switch (action) { - case BUS_NOTIFY_BIND_DRIVER: - clk = clk_get(dev, NULL); - if (!IS_ERR(clk)) { - clk_enable(clk); - clk_put(clk); - dev_info(dev, "runtime pm disabled, clock forced on\n"); - } - break; - case BUS_NOTIFY_UNBOUND_DRIVER: - clk = clk_get(dev, NULL); - if (!IS_ERR(clk)) { - clk_disable(clk); - clk_put(clk); - dev_info(dev, "runtime pm disabled, clock forced off\n"); - } - break; - } - - return 0; -} +#define DEFAULT_PWR_DOMAIN_PTR NULL #endif /* CONFIG_PM_RUNTIME */ -static struct notifier_block platform_bus_notifier = { - .notifier_call = platform_bus_notify +static struct pm_clk_notifier_block platform_bus_notifier = { + .pwr_domain = DEFAULT_PWR_DOMAIN_PTR, + .con_ids = { NULL, }, }; static int __init sh_pm_runtime_init(void) { - bus_register_notifier(&platform_bus_type, &platform_bus_notifier); + pm_runtime_clk_add_notifier(&platform_bus_type, &platform_bus_notifier); return 0; } core_initcall(sh_pm_runtime_init); diff --git a/drivers/base/power/Makefile b/drivers/base/power/Makefile index 118c1b92a511..06a7073f9027 100644 --- a/drivers/base/power/Makefile +++ b/drivers/base/power/Makefile @@ -3,6 +3,7 @@ obj-$(CONFIG_PM_SLEEP) += main.o wakeup.o obj-$(CONFIG_PM_RUNTIME) += runtime.o obj-$(CONFIG_PM_TRACE_RTC) += trace.o obj-$(CONFIG_PM_OPP) += opp.o +obj-$(CONFIG_HAVE_CLK) += clock_ops.o ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG ccflags-$(CONFIG_PM_VERBOSE) += -DDEBUG diff --git a/drivers/base/power/clock_ops.c b/drivers/base/power/clock_ops.c new file mode 100644 index 000000000000..d74abf334391 --- /dev/null +++ b/drivers/base/power/clock_ops.c @@ -0,0 +1,430 @@ +/* + * drivers/base/power/clock_ops.c - Generic clock manipulation PM callbacks + * + * Copyright (c) 2011 Rafael J. Wysocki , Renesas Electronics Corp. + * + * This file is released under the GPLv2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_PM_RUNTIME + +struct pm_runtime_clk_data { + struct list_head clock_list; + struct mutex lock; +}; + +enum pce_status { + PCE_STATUS_NONE = 0, + PCE_STATUS_ACQUIRED, + PCE_STATUS_ENABLED, + PCE_STATUS_ERROR, +}; + +struct pm_clock_entry { + struct list_head node; + char *con_id; + struct clk *clk; + enum pce_status status; +}; + +static struct pm_runtime_clk_data *__to_prd(struct device *dev) +{ + return dev ? dev->power.subsys_data : NULL; +} + +/** + * pm_runtime_clk_add - Start using a device clock for runtime PM. + * @dev: Device whose clock is going to be used for runtime PM. + * @con_id: Connection ID of the clock. + * + * Add the clock represented by @con_id to the list of clocks used for + * the runtime PM of @dev. + */ +int pm_runtime_clk_add(struct device *dev, const char *con_id) +{ + struct pm_runtime_clk_data *prd = __to_prd(dev); + struct pm_clock_entry *ce; + + if (!prd) + return -EINVAL; + + ce = kzalloc(sizeof(*ce), GFP_KERNEL); + if (!ce) { + dev_err(dev, "Not enough memory for clock entry.\n"); + return -ENOMEM; + } + + if (con_id) { + ce->con_id = kstrdup(con_id, GFP_KERNEL); + if (!ce->con_id) { + dev_err(dev, + "Not enough memory for clock connection ID.\n"); + kfree(ce); + return -ENOMEM; + } + } + + mutex_lock(&prd->lock); + list_add_tail(&ce->node, &prd->clock_list); + mutex_unlock(&prd->lock); + return 0; +} + +/** + * __pm_runtime_clk_remove - Destroy runtime PM clock entry. + * @ce: Runtime PM clock entry to destroy. + * + * This routine must be called under the mutex protecting the runtime PM list + * of clocks corresponding the the @ce's device. + */ +static void __pm_runtime_clk_remove(struct pm_clock_entry *ce) +{ + if (!ce) + return; + + list_del(&ce->node); + + if (ce->status < PCE_STATUS_ERROR) { + if (ce->status == PCE_STATUS_ENABLED) + clk_disable(ce->clk); + + if (ce->status >= PCE_STATUS_ACQUIRED) + clk_put(ce->clk); + } + + if (ce->con_id) + kfree(ce->con_id); + + kfree(ce); +} + +/** + * pm_runtime_clk_remove - Stop using a device clock for runtime PM. + * @dev: Device whose clock should not be used for runtime PM any more. + * @con_id: Connection ID of the clock. + * + * Remove the clock represented by @con_id from the list of clocks used for + * the runtime PM of @dev. + */ +void pm_runtime_clk_remove(struct device *dev, const char *con_id) +{ + struct pm_runtime_clk_data *prd = __to_prd(dev); + struct pm_clock_entry *ce; + + if (!prd) + return; + + mutex_lock(&prd->lock); + + list_for_each_entry(ce, &prd->clock_list, node) { + if (!con_id && !ce->con_id) { + __pm_runtime_clk_remove(ce); + break; + } else if (!con_id || !ce->con_id) { + continue; + } else if (!strcmp(con_id, ce->con_id)) { + __pm_runtime_clk_remove(ce); + break; + } + } + + mutex_unlock(&prd->lock); +} + +/** + * pm_runtime_clk_init - Initialize a device's list of runtime PM clocks. + * @dev: Device to initialize the list of runtime PM clocks for. + * + * Allocate a struct pm_runtime_clk_data object, initialize its lock member and + * make the @dev's power.subsys_data field point to it. + */ +int pm_runtime_clk_init(struct device *dev) +{ + struct pm_runtime_clk_data *prd; + + prd = kzalloc(sizeof(*prd), GFP_KERNEL); + if (!prd) { + dev_err(dev, "Not enough memory fo runtime PM data.\n"); + return -ENOMEM; + } + + INIT_LIST_HEAD(&prd->clock_list); + mutex_init(&prd->lock); + dev->power.subsys_data = prd; + return 0; +} + +/** + * pm_runtime_clk_destroy - Destroy a device's list of runtime PM clocks. + * @dev: Device to destroy the list of runtime PM clocks for. + * + * Clear the @dev's power.subsys_data field, remove the list of clock entries + * from the struct pm_runtime_clk_data object pointed to by it before and free + * that object. + */ +void pm_runtime_clk_destroy(struct device *dev) +{ + struct pm_runtime_clk_data *prd = __to_prd(dev); + struct pm_clock_entry *ce, *c; + + if (!prd) + return; + + dev->power.subsys_data = NULL; + + mutex_lock(&prd->lock); + + list_for_each_entry_safe_reverse(ce, c, &prd->clock_list, node) + __pm_runtime_clk_remove(ce); + + mutex_unlock(&prd->lock); + + kfree(prd); +} + +/** + * pm_runtime_clk_acquire - Acquire a device clock. + * @dev: Device whose clock is to be acquired. + * @con_id: Connection ID of the clock. + */ +static void pm_runtime_clk_acquire(struct device *dev, + struct pm_clock_entry *ce) +{ + ce->clk = clk_get(dev, ce->con_id); + if (IS_ERR(ce->clk)) { + ce->status = PCE_STATUS_ERROR; + } else { + ce->status = PCE_STATUS_ACQUIRED; + dev_dbg(dev, "Clock %s managed by runtime PM.\n", ce->con_id); + } +} + +/** + * pm_runtime_clk_suspend - Disable clocks in a device's runtime PM clock list. + * @dev: Device to disable the clocks for. + */ +int pm_runtime_clk_suspend(struct device *dev) +{ + struct pm_runtime_clk_data *prd = __to_prd(dev); + struct pm_clock_entry *ce; + + dev_dbg(dev, "%s()\n", __func__); + + if (!prd) + return 0; + + mutex_lock(&prd->lock); + + list_for_each_entry_reverse(ce, &prd->clock_list, node) { + if (ce->status == PCE_STATUS_NONE) + pm_runtime_clk_acquire(dev, ce); + + if (ce->status < PCE_STATUS_ERROR) { + clk_disable(ce->clk); + ce->status = PCE_STATUS_ACQUIRED; + } + } + + mutex_unlock(&prd->lock); + + return 0; +} + +/** + * pm_runtime_clk_resume - Enable clocks in a device's runtime PM clock list. + * @dev: Device to enable the clocks for. + */ +int pm_runtime_clk_resume(struct device *dev) +{ + struct pm_runtime_clk_data *prd = __to_prd(dev); + struct pm_clock_entry *ce; + + dev_dbg(dev, "%s()\n", __func__); + + if (!prd) + return 0; + + mutex_lock(&prd->lock); + + list_for_each_entry(ce, &prd->clock_list, node) { + if (ce->status == PCE_STATUS_NONE) + pm_runtime_clk_acquire(dev, ce); + + if (ce->status < PCE_STATUS_ERROR) { + clk_enable(ce->clk); + ce->status = PCE_STATUS_ENABLED; + } + } + + mutex_unlock(&prd->lock); + + return 0; +} + +/** + * pm_runtime_clk_notify - Notify routine for device addition and removal. + * @nb: Notifier block object this function is a member of. + * @action: Operation being carried out by the caller. + * @data: Device the routine is being run for. + * + * For this function to work, @nb must be a member of an object of type + * struct pm_clk_notifier_block containing all of the requisite data. + * Specifically, the pwr_domain member of that object is copied to the device's + * pwr_domain field and its con_ids member is used to populate the device's list + * of runtime PM clocks, depending on @action. + * + * If the device's pwr_domain field is already populated with a value different + * from the one stored in the struct pm_clk_notifier_block object, the function + * does nothing. + */ +static int pm_runtime_clk_notify(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct pm_clk_notifier_block *clknb; + struct device *dev = data; + char *con_id; + int error; + + dev_dbg(dev, "%s() %ld\n", __func__, action); + + clknb = container_of(nb, struct pm_clk_notifier_block, nb); + + switch (action) { + case BUS_NOTIFY_ADD_DEVICE: + if (dev->pwr_domain) + break; + + error = pm_runtime_clk_init(dev); + if (error) + break; + + dev->pwr_domain = clknb->pwr_domain; + if (clknb->con_ids[0]) { + for (con_id = clknb->con_ids[0]; *con_id; con_id++) + pm_runtime_clk_add(dev, con_id); + } else { + pm_runtime_clk_add(dev, NULL); + } + + break; + case BUS_NOTIFY_DEL_DEVICE: + if (dev->pwr_domain != clknb->pwr_domain) + break; + + dev->pwr_domain = NULL; + pm_runtime_clk_destroy(dev); + break; + } + + return 0; +} + +#else /* !CONFIG_PM_RUNTIME */ + +/** + * enable_clock - Enable a device clock. + * @dev: Device whose clock is to be enabled. + * @con_id: Connection ID of the clock. + */ +static void enable_clock(struct device *dev, const char *con_id) +{ + struct clk *clk; + + clk = clk_get(dev, con_id); + if (!IS_ERR(clk)) { + clk_enable(clk); + clk_put(clk); + dev_info(dev, "Runtime PM disabled, clock forced on.\n"); + } +} + +/** + * disable_clock - Disable a device clock. + * @dev: Device whose clock is to be disabled. + * @con_id: Connection ID of the clock. + */ +static void disable_clock(struct device *dev, const char *con_id) +{ + struct clk *clk; + + clk = clk_get(dev, con_id); + if (!IS_ERR(clk)) { + clk_disable(clk); + clk_put(clk); + dev_info(dev, "Runtime PM disabled, clock forced off.\n"); + } +} + +/** + * pm_runtime_clk_notify - Notify routine for device addition and removal. + * @nb: Notifier block object this function is a member of. + * @action: Operation being carried out by the caller. + * @data: Device the routine is being run for. + * + * For this function to work, @nb must be a member of an object of type + * struct pm_clk_notifier_block containing all of the requisite data. + * Specifically, the con_ids member of that object is used to enable or disable + * the device's clocks, depending on @action. + */ +static int pm_runtime_clk_notify(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct pm_clk_notifier_block *clknb; + struct device *dev = data; + + dev_dbg(dev, "%s() %ld\n", __func__, action); + + clknb = container_of(nb, struct pm_clk_notifier_block, nb); + + switch (action) { + case BUS_NOTIFY_ADD_DEVICE: + if (clknb->con_ids[0]) { + for (con_id = clknb->con_ids[0]; *con_id; con_id++) + enable_clock(dev, con_id); + } else { + enable_clock(dev, NULL); + } + break; + case BUS_NOTIFY_DEL_DEVICE: + if (clknb->con_ids[0]) { + for (con_id = clknb->con_ids[0]; *con_id; con_id++) + disable_clock(dev, con_id); + } else { + disable_clock(dev, NULL); + } + break; + } + + return 0; +} + +#endif /* !CONFIG_PM_RUNTIME */ + +/** + * pm_runtime_clk_add_notifier - Add bus type notifier for runtime PM clocks. + * @bus: Bus type to add the notifier to. + * @clknb: Notifier to be added to the given bus type. + * + * The nb member of @clknb is not expected to be initialized and its + * notifier_call member will be replaced with pm_runtime_clk_notify(). However, + * the remaining members of @clknb should be populated prior to calling this + * routine. + */ +void pm_runtime_clk_add_notifier(struct bus_type *bus, + struct pm_clk_notifier_block *clknb) +{ + if (!bus || !clknb) + return; + + clknb->nb.notifier_call = pm_runtime_clk_notify; + bus_register_notifier(bus, &clknb->nb); +} diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h index 8de9aa6e7def..878cf84baeb1 100644 --- a/include/linux/pm_runtime.h +++ b/include/linux/pm_runtime.h @@ -245,4 +245,46 @@ static inline void pm_runtime_dont_use_autosuspend(struct device *dev) __pm_runtime_use_autosuspend(dev, false); } +struct pm_clk_notifier_block { + struct notifier_block nb; + struct dev_power_domain *pwr_domain; + char *con_ids[]; +}; + +#ifdef CONFIG_PM_RUNTIME_CLK +extern int pm_runtime_clk_init(struct device *dev); +extern void pm_runtime_clk_destroy(struct device *dev); +extern int pm_runtime_clk_add(struct device *dev, const char *con_id); +extern void pm_runtime_clk_remove(struct device *dev, const char *con_id); +extern int pm_runtime_clk_suspend(struct device *dev); +extern int pm_runtime_clk_resume(struct device *dev); +#else +static inline int pm_runtime_clk_init(struct device *dev) +{ + return -EINVAL; +} +static inline void pm_runtime_clk_destroy(struct device *dev) +{ +} +static inline int pm_runtime_clk_add(struct device *dev, const char *con_id) +{ + return -EINVAL; +} +static inline void pm_runtime_clk_remove(struct device *dev, const char *con_id) +{ +} +#define pm_runtime_clock_suspend NULL +#define pm_runtime_clock_resume NULL +#endif + +#ifdef CONFIG_HAVE_CLK +extern void pm_runtime_clk_add_notifier(struct bus_type *bus, + struct pm_clk_notifier_block *clknb); +#else +static inline void pm_runtime_clk_add_notifier(struct bus_type *bus, + struct pm_clk_notifier_block *clknb) +{ +} +#endif + #endif diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig index 6de9a8fc3417..d74ad4a90695 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig @@ -229,3 +229,7 @@ config PM_OPP representing individual voltage domains and provides SOC implementations a ready to use framework to manage OPPs. For more information, read + +config PM_RUNTIME_CLK + def_bool y + depends on PM_RUNTIME && HAVE_CLK -- cgit From 6498d9db6d2dad4cf5deb2dd09e0816904f41ca5 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 28 Apr 2011 10:45:24 -0400 Subject: USB: documentation update for the pre_reset method This patch (as1459) updates the documentation for the pre_reset method in struct usb_driver. When a driver is notified of an impending reset, it must cancel all outstanding I/O and not start any new I/O until it has been notified that the reset is complete. As far as I know, most existing drivers that implement pre_reset do this now. The major exceptions appear to be the SpeedTouch and CDC-WDM drivers. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- Documentation/usb/callbacks.txt | 8 +++++--- include/linux/usb.h | 6 ++++-- 2 files changed, 9 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/Documentation/usb/callbacks.txt b/Documentation/usb/callbacks.txt index bfb36b34b79e..9e85846bdb98 100644 --- a/Documentation/usb/callbacks.txt +++ b/Documentation/usb/callbacks.txt @@ -95,9 +95,11 @@ pre_reset int (*pre_reset)(struct usb_interface *intf); -Another driver or user space is triggering a reset on the device which -contains the interface passed as an argument. Cease IO and save any -device state you need to restore. +A driver or user space is triggering a reset on the device which +contains the interface passed as an argument. Cease IO, wait for all +outstanding URBs to complete, and save any device state you need to +restore. No more URBs may be submitted until the post_reset method +is called. If you need to allocate memory here, use GFP_NOIO or GFP_ATOMIC, if you are in atomic context. diff --git a/include/linux/usb.h b/include/linux/usb.h index 65f78ca5d88e..73c7df489607 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -806,8 +806,10 @@ struct usbdrv_wrap { * @resume: Called when the device is being resumed by the system. * @reset_resume: Called when the suspended device has been reset instead * of being resumed. - * @pre_reset: Called by usb_reset_device() when the device - * is about to be reset. + * @pre_reset: Called by usb_reset_device() when the device is about to be + * reset. This routine must not return until the driver has no active + * URBs for the device, and no more URBs may be submitted until the + * post_reset method is called. * @post_reset: Called by usb_reset_device() after the device * has been reset * @id_table: USB drivers use ID table to support hotplugging. -- cgit From af32fe511374f17feb137d7fbfe2f4c73a8f531c Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Apr 2011 14:10:16 +0900 Subject: usb: renesas_usbhs: remove callback when module removed. The callback function which is called from platform must be removed if module removed. Signed-off-by: Kuninori Morimoto Signed-off-by: Greg Kroah-Hartman --- drivers/usb/renesas_usbhs/common.c | 4 ++++ include/linux/usb/renesas_usbhs.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index d9ad60d1c156..fda586d1f7d8 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c @@ -352,9 +352,13 @@ probe_end_kfree: static int __devexit usbhs_remove(struct platform_device *pdev) { struct usbhs_priv *priv = usbhsc_pdev_to_priv(pdev); + struct renesas_usbhs_platform_info *info = pdev->dev.platform_data; + struct renesas_usbhs_driver_callback *dfunc = &info->driver_callback; dev_dbg(&pdev->dev, "usb remove\n"); + dfunc->notify_hotplug = NULL; + pm_runtime_disable(&pdev->dev); usbhsc_bus_ctrl(priv, 0); diff --git a/include/linux/usb/renesas_usbhs.h b/include/linux/usb/renesas_usbhs.h index 565bca3aa440..66bbdd12d153 100644 --- a/include/linux/usb/renesas_usbhs.h +++ b/include/linux/usb/renesas_usbhs.h @@ -143,7 +143,7 @@ struct renesas_usbhs_platform_info { ({ \ struct renesas_usbhs_driver_callback *dc; \ dc = &(renesas_usbhs_get_info(pdev)->driver_callback); \ - if (dc) \ + if (dc && dc->notify_hotplug) \ dc->notify_hotplug(pdev); \ }) #endif /* RENESAS_USB_H */ -- cgit From bc57381e634782009b1cb2e86b18013699ada576 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 28 Apr 2011 16:41:14 +0900 Subject: usb: renesas_usbhs: use delayed_work instead of work_struct This delay is used to overjump debounce. And, this patch also move usbhsc_drvcllbck_notify_hotplug to global, because it will be called from other files. Signed-off-by: Kuninori Morimoto Signed-off-by: Greg Kroah-Hartman --- drivers/usb/renesas_usbhs/common.c | 9 +++++---- drivers/usb/renesas_usbhs/common.h | 3 ++- include/linux/usb/renesas_usbhs.h | 7 +++++++ 3 files changed, 14 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index db13cef9effe..9a75a45687bb 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c @@ -178,7 +178,7 @@ static void usbhsc_notify_hotplug(struct work_struct *work) { struct usbhs_priv *priv = container_of(work, struct usbhs_priv, - notify_hotplug_work); + notify_hotplug_work.work); struct platform_device *pdev = usbhs_priv_to_pdev(priv); struct usbhs_mod *mod = usbhs_mod_get_current(priv); int id; @@ -224,16 +224,17 @@ static void usbhsc_notify_hotplug(struct work_struct *work) } } -static int usbhsc_drvcllbck_notify_hotplug(struct platform_device *pdev) +int usbhsc_drvcllbck_notify_hotplug(struct platform_device *pdev) { struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev); + int delay = usbhs_get_dparam(priv, detection_delay); /* * This functions will be called in interrupt. * To make sure safety context, * use workqueue for usbhs_notify_hotplug */ - schedule_work(&priv->notify_hotplug_work); + schedule_delayed_work(&priv->notify_hotplug_work, delay); return 0; } @@ -300,7 +301,7 @@ static int __devinit usbhs_probe(struct platform_device *pdev) */ priv->irq = irq; priv->pdev = pdev; - INIT_WORK(&priv->notify_hotplug_work, usbhsc_notify_hotplug); + INIT_DELAYED_WORK(&priv->notify_hotplug_work, usbhsc_notify_hotplug); spin_lock_init(usbhs_priv_to_lock(priv)); /* call pipe and module init */ diff --git a/drivers/usb/renesas_usbhs/common.h b/drivers/usb/renesas_usbhs/common.h index f3b907d26082..0157eb805cf6 100644 --- a/drivers/usb/renesas_usbhs/common.h +++ b/drivers/usb/renesas_usbhs/common.h @@ -177,7 +177,7 @@ struct usbhs_priv { struct renesas_usbhs_platform_callback *pfunc; struct renesas_usbhs_driver_param *dparam; - struct work_struct notify_hotplug_work; + struct delayed_work notify_hotplug_work; struct platform_device *pdev; spinlock_t lock; @@ -200,6 +200,7 @@ u16 usbhs_read(struct usbhs_priv *priv, u32 reg); void usbhs_write(struct usbhs_priv *priv, u32 reg, u16 data); void usbhs_bset(struct usbhs_priv *priv, u32 reg, u16 mask, u16 data); +int usbhsc_drvcllbck_notify_hotplug(struct platform_device *pdev); /* * sysconfig */ diff --git a/include/linux/usb/renesas_usbhs.h b/include/linux/usb/renesas_usbhs.h index 66bbdd12d153..3a7f1d982dd6 100644 --- a/include/linux/usb/renesas_usbhs.h +++ b/include/linux/usb/renesas_usbhs.h @@ -103,6 +103,13 @@ struct renesas_usbhs_driver_param { * for BUSWAIT :: BWAIT * */ int buswait_bwait; + + /* + * option: + * + * delay time from notify_hotplug callback + */ + int detection_delay; }; /* -- cgit From a62573dc353b255dbbc8520bfdcb1c8a8c1ada87 Mon Sep 17 00:00:00 2001 From: Mi Jinlong Date: Wed, 23 Mar 2011 17:57:07 +0800 Subject: nfsd41: add flag checking for create_session Teach the NFS server to reject invalid create_session flags. Also do some minor formatting adjustments. Signed-off-by: Mi Jinlong Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4state.c | 3 +++ include/linux/nfs4.h | 8 +++++--- 2 files changed, 8 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index fbde6f79922e..6dbaa379c863 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -1515,6 +1515,9 @@ nfsd4_create_session(struct svc_rqst *rqstp, bool confirm_me = false; int status = 0; + if (cr_ses->flags & ~SESSION4_FLAG_MASK_A) + return nfserr_inval; + nfs4_lock_state(); unconf = find_unconfirmed_client(&cr_ses->clientid); conf = find_confirmed_client(&cr_ses->clientid); diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index b528f6d4b860..8937727e7039 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h @@ -570,9 +570,11 @@ struct nfs4_sessionid { }; /* Create Session Flags */ -#define SESSION4_PERSIST 0x001 -#define SESSION4_BACK_CHAN 0x002 -#define SESSION4_RDMA 0x004 +#define SESSION4_PERSIST 0x001 +#define SESSION4_BACK_CHAN 0x002 +#define SESSION4_RDMA 0x004 + +#define SESSION4_FLAG_MASK_A 0x007 enum state_protect_how4 { SP4_NONE = 0, -- cgit From 45a4a2372b364107cabea79f255b333236626416 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 21 Apr 2011 23:16:46 -0400 Subject: ftrace: Remove FTRACE_FL_FAILED flag Since we disable all function tracer processing if we detect that a modification of a instruction had failed, we do not need to track that the record has failed. No more ftrace processing is allowed, and the FTRACE_FL_FAILED flag is pointless. Removing this flag simplifies some of the code, but some ftrace_disabled checks needed to be added or move around a little. Signed-off-by: Steven Rostedt --- include/linux/ftrace.h | 9 +++--- kernel/trace/ftrace.c | 76 +++++++++++++++++++++++++++++++------------------- 2 files changed, 51 insertions(+), 34 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index ca29e03c1fac..2a195ffd4269 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -147,11 +147,10 @@ extern int ftrace_text_reserved(void *start, void *end); enum { FTRACE_FL_FREE = (1 << 0), - FTRACE_FL_FAILED = (1 << 1), - FTRACE_FL_FILTER = (1 << 2), - FTRACE_FL_ENABLED = (1 << 3), - FTRACE_FL_NOTRACE = (1 << 4), - FTRACE_FL_CONVERTED = (1 << 5), + FTRACE_FL_FILTER = (1 << 1), + FTRACE_FL_ENABLED = (1 << 2), + FTRACE_FL_NOTRACE = (1 << 3), + FTRACE_FL_CONVERTED = (1 << 4), }; struct dyn_ftrace { diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 97b30f818642..eb19fae2c54a 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -1083,19 +1083,20 @@ static void ftrace_replace_code(int enable) struct ftrace_page *pg; int failed; + if (unlikely(ftrace_disabled)) + return; + do_for_each_ftrace_rec(pg, rec) { /* * Skip over free records, records that have * failed and not converted. */ if (rec->flags & FTRACE_FL_FREE || - rec->flags & FTRACE_FL_FAILED || !(rec->flags & FTRACE_FL_CONVERTED)) continue; failed = __ftrace_replace_code(rec, enable); if (failed) { - rec->flags |= FTRACE_FL_FAILED; ftrace_bug(failed, rec->ip); /* Stop processing */ return; @@ -1111,10 +1112,12 @@ ftrace_code_disable(struct module *mod, struct dyn_ftrace *rec) ip = rec->ip; + if (unlikely(ftrace_disabled)) + return 0; + ret = ftrace_make_nop(mod, rec, MCOUNT_ADDR); if (ret) { ftrace_bug(ret, ip); - rec->flags |= FTRACE_FL_FAILED; return 0; } return 1; @@ -1466,6 +1469,9 @@ t_next(struct seq_file *m, void *v, loff_t *pos) struct ftrace_iterator *iter = m->private; struct dyn_ftrace *rec = NULL; + if (unlikely(ftrace_disabled)) + return NULL; + if (iter->flags & FTRACE_ITER_HASH) return t_hash_next(m, pos); @@ -1518,6 +1524,10 @@ static void *t_start(struct seq_file *m, loff_t *pos) loff_t l; mutex_lock(&ftrace_lock); + + if (unlikely(ftrace_disabled)) + return NULL; + /* * If an lseek was done, then reset and start from beginning. */ @@ -1636,8 +1646,6 @@ static void ftrace_filter_reset(int enable) if (enable) ftrace_filtered = 0; do_for_each_ftrace_rec(pg, rec) { - if (rec->flags & FTRACE_FL_FAILED) - continue; rec->flags &= ~type; } while_for_each_ftrace_rec(); mutex_unlock(&ftrace_lock); @@ -1767,9 +1775,6 @@ static int ftrace_match_records(char *buff, int len, int enable) mutex_lock(&ftrace_lock); do_for_each_ftrace_rec(pg, rec) { - if (rec->flags & FTRACE_FL_FAILED) - continue; - if (ftrace_match_record(rec, search, search_len, type)) { if (not) rec->flags &= ~flag; @@ -1837,10 +1842,11 @@ static int ftrace_match_module_records(char *buff, char *mod, int enable) } mutex_lock(&ftrace_lock); - do_for_each_ftrace_rec(pg, rec) { - if (rec->flags & FTRACE_FL_FAILED) - continue; + if (unlikely(ftrace_disabled)) + goto out_unlock; + + do_for_each_ftrace_rec(pg, rec) { if (ftrace_match_module_record(rec, mod, search, search_len, type)) { @@ -1854,6 +1860,7 @@ static int ftrace_match_module_records(char *buff, char *mod, int enable) ftrace_filtered = 1; } while_for_each_ftrace_rec(); + out_unlock: mutex_unlock(&ftrace_lock); return found; @@ -2008,10 +2015,11 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops, return -EINVAL; mutex_lock(&ftrace_lock); - do_for_each_ftrace_rec(pg, rec) { - if (rec->flags & FTRACE_FL_FAILED) - continue; + if (unlikely(ftrace_disabled)) + goto out_unlock; + + do_for_each_ftrace_rec(pg, rec) { if (!ftrace_match_record(rec, search, len, type)) continue; @@ -2218,6 +2226,10 @@ ftrace_regex_write(struct file *file, const char __user *ubuf, mutex_lock(&ftrace_regex_lock); + ret = -ENODEV; + if (unlikely(ftrace_disabled)) + goto out_unlock; + if (file->f_mode & FMODE_READ) { struct seq_file *m = file->private_data; iter = m->private; @@ -2545,9 +2557,6 @@ ftrace_set_func(unsigned long *array, int *idx, char *buffer) bool exists; int i; - if (ftrace_disabled) - return -ENODEV; - /* decode regex */ type = filter_parse_regex(buffer, strlen(buffer), &search, ¬); if (!not && *idx >= FTRACE_GRAPH_MAX_FUNCS) @@ -2556,9 +2565,15 @@ ftrace_set_func(unsigned long *array, int *idx, char *buffer) search_len = strlen(search); mutex_lock(&ftrace_lock); + + if (unlikely(ftrace_disabled)) { + mutex_unlock(&ftrace_lock); + return -ENODEV; + } + do_for_each_ftrace_rec(pg, rec) { - if (rec->flags & (FTRACE_FL_FAILED | FTRACE_FL_FREE)) + if (rec->flags & FTRACE_FL_FREE) continue; if (ftrace_match_record(rec, search, search_len, type)) { @@ -2700,10 +2715,11 @@ void ftrace_release_mod(struct module *mod) struct dyn_ftrace *rec; struct ftrace_page *pg; + mutex_lock(&ftrace_lock); + if (ftrace_disabled) - return; + goto out_unlock; - mutex_lock(&ftrace_lock); do_for_each_ftrace_rec(pg, rec) { if (within_module_core(rec->ip, mod)) { /* @@ -2714,6 +2730,7 @@ void ftrace_release_mod(struct module *mod) ftrace_free_rec(rec); } } while_for_each_ftrace_rec(); + out_unlock: mutex_unlock(&ftrace_lock); } @@ -3108,16 +3125,17 @@ void ftrace_kill(void) */ int register_ftrace_function(struct ftrace_ops *ops) { - int ret; - - if (unlikely(ftrace_disabled)) - return -1; + int ret = -1; mutex_lock(&ftrace_lock); + if (unlikely(ftrace_disabled)) + goto out_unlock; + ret = __register_ftrace_function(ops); ftrace_startup(0); + out_unlock: mutex_unlock(&ftrace_lock); return ret; } @@ -3145,14 +3163,14 @@ ftrace_enable_sysctl(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { - int ret; - - if (unlikely(ftrace_disabled)) - return -ENODEV; + int ret = -ENODEV; mutex_lock(&ftrace_lock); - ret = proc_dointvec(table, write, buffer, lenp, ppos); + if (unlikely(ftrace_disabled)) + goto out; + + ret = proc_dointvec(table, write, buffer, lenp, ppos); if (ret || !write || (last_ftrace_enabled == !!ftrace_enabled)) goto out; -- cgit From d2c8c3eafbf715306ec891e7ca52d3d999acbe31 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 25 Apr 2011 14:32:42 -0400 Subject: ftrace: Remove FTRACE_FL_CONVERTED flag Since we disable all function tracer processing if we detect that a modification of a instruction had failed, we do not need to track that the record has failed. No more ftrace processing is allowed, and the FTRACE_FL_CONVERTED flag is pointless. The FTRACE_FL_CONVERTED flag was used to denote records that were successfully converted from mcount calls into nops. But if a single record fails, all of ftrace is disabled. Signed-off-by: Steven Rostedt --- include/linux/ftrace.h | 1 - kernel/trace/ftrace.c | 12 ++++-------- 2 files changed, 4 insertions(+), 9 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 2a195ffd4269..32047449b309 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -150,7 +150,6 @@ enum { FTRACE_FL_FILTER = (1 << 1), FTRACE_FL_ENABLED = (1 << 2), FTRACE_FL_NOTRACE = (1 << 3), - FTRACE_FL_CONVERTED = (1 << 4), }; struct dyn_ftrace { diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index eb19fae2c54a..9abaaf46f212 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -1087,12 +1087,8 @@ static void ftrace_replace_code(int enable) return; do_for_each_ftrace_rec(pg, rec) { - /* - * Skip over free records, records that have - * failed and not converted. - */ - if (rec->flags & FTRACE_FL_FREE || - !(rec->flags & FTRACE_FL_CONVERTED)) + /* Skip over free records */ + if (rec->flags & FTRACE_FL_FREE) continue; failed = __ftrace_replace_code(rec, enable); @@ -1280,10 +1276,10 @@ static int ftrace_update_code(struct module *mod) */ if (!ftrace_code_disable(mod, p)) { ftrace_free_rec(p); - continue; + /* Game over */ + break; } - p->flags |= FTRACE_FL_CONVERTED; ftrace_update_cnt++; /* -- cgit From a6e5e2be44616c8400f9ec2f635b10f8e579217c Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 1 May 2011 18:18:49 +0200 Subject: i2c-i801: Move device ID definitions to driver Move the SMBus device ID definitions of recent devices from pci_ids.h to the i2c-i801.c driver file. They don't have to be shared, as they are clearly identified and only used in this driver. In the future, such IDs will go to i2c-i801 directly. This will make adding support for new devices much faster and easier, as it will avoid cross- subsystem patch sets and merge conflicts. Signed-off-by: Jean Delvare Cc: Seth Heasley Acked-by: Jesse Barnes --- drivers/i2c/busses/i2c-i801.c | 5 +++++ include/linux/pci_ids.h | 4 ---- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 72c0415f6f94..455e909bc768 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -134,10 +134,15 @@ SMBHSTSTS_BUS_ERR | SMBHSTSTS_DEV_ERR | \ SMBHSTSTS_INTR) +/* Older devices have their ID defined in */ +#define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS 0x1c22 +#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22 /* Patsburg also has three 'Integrated Device Function' SMBus controllers */ #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0 0x1d70 #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1 0x1d71 #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2 0x1d72 +#define PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS 0x2330 +#define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS 0x3b30 struct i801_priv { struct i2c_adapter adapter; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 4e2c9150a785..8abe8d78c4bf 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2477,15 +2477,12 @@ #define PCI_DEVICE_ID_INTEL_82840_HB 0x1a21 #define PCI_DEVICE_ID_INTEL_82845_HB 0x1a30 #define PCI_DEVICE_ID_INTEL_IOAT 0x1a38 -#define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS 0x1c22 #define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MIN 0x1c41 #define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX 0x1c5f -#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22 #define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_0 0x1d40 #define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_1 0x1d41 #define PCI_DEVICE_ID_INTEL_DH89XXCC_LPC_MIN 0x2310 #define PCI_DEVICE_ID_INTEL_DH89XXCC_LPC_MAX 0x231f -#define PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS 0x2330 #define PCI_DEVICE_ID_INTEL_82801AA_0 0x2410 #define PCI_DEVICE_ID_INTEL_82801AA_1 0x2411 #define PCI_DEVICE_ID_INTEL_82801AA_3 0x2413 @@ -2696,7 +2693,6 @@ #define PCI_DEVICE_ID_INTEL_ICH10_5 0x3a60 #define PCI_DEVICE_ID_INTEL_5_3400_SERIES_LPC_MIN 0x3b00 #define PCI_DEVICE_ID_INTEL_5_3400_SERIES_LPC_MAX 0x3b1f -#define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS 0x3b30 #define PCI_DEVICE_ID_INTEL_IOAT_SNB 0x402f #define PCI_DEVICE_ID_INTEL_5100_16 0x65f0 #define PCI_DEVICE_ID_INTEL_5100_21 0x65f5 -- cgit From b12a03ce4880bd13786a98db6de494a3e0123129 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Mon, 2 May 2011 16:48:57 +0200 Subject: hrtimers: Prepare for cancel on clock was set timers Make clock_was_set() unconditional and rename hres_timers_resume to hrtimers_resume. This is a preparatory patch for hrtimers which are cancelled when clock realtime was set. Signed-off-by: Thomas Gleixner --- include/linux/hrtimer.h | 16 ++---- kernel/hrtimer.c | 125 ++++++++++++++++++++++------------------------ kernel/time/timekeeping.c | 2 +- 3 files changed, 65 insertions(+), 78 deletions(-) (limited to 'include/linux') diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 62f500c724f9..4135c88fe4fa 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -148,9 +148,7 @@ struct hrtimer_clock_base { ktime_t resolution; ktime_t (*get_time)(void); ktime_t softirq_time; -#ifdef CONFIG_HIGH_RES_TIMERS ktime_t offset; -#endif }; enum hrtimer_base_type { @@ -256,8 +254,6 @@ static inline ktime_t hrtimer_expires_remaining(const struct hrtimer *timer) #ifdef CONFIG_HIGH_RES_TIMERS struct clock_event_device; -extern void clock_was_set(void); -extern void hres_timers_resume(void); extern void hrtimer_interrupt(struct clock_event_device *dev); /* @@ -291,16 +287,8 @@ extern void hrtimer_peek_ahead_timers(void); # define MONOTONIC_RES_NSEC LOW_RES_NSEC # define KTIME_MONOTONIC_RES KTIME_LOW_RES -/* - * clock_was_set() is a NOP for non- high-resolution systems. The - * time-sorted order guarantees that a timer does not expire early and - * is expired in the next softirq when the clock was advanced. - */ -static inline void clock_was_set(void) { } static inline void hrtimer_peek_ahead_timers(void) { } -static inline void hres_timers_resume(void) { } - /* * In non high resolution mode the time reference is taken from * the base softirq time variable. @@ -316,11 +304,13 @@ static inline int hrtimer_is_hres_active(struct hrtimer *timer) } #endif +extern void clock_was_set(void); +extern void hrtimers_resume(void); + extern ktime_t ktime_get(void); extern ktime_t ktime_get_real(void); extern ktime_t ktime_get_boottime(void); - DECLARE_PER_CPU(struct tick_device, tick_cpu_device); diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index dbbbf7d43080..c145ed643bca 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -621,66 +621,6 @@ static int hrtimer_reprogram(struct hrtimer *timer, return res; } - -/* - * Retrigger next event is called after clock was set - * - * Called with interrupts disabled via on_each_cpu() - */ -static void retrigger_next_event(void *arg) -{ - struct hrtimer_cpu_base *base; - struct timespec realtime_offset, wtm, sleep; - - if (!hrtimer_hres_active()) - return; - - get_xtime_and_monotonic_and_sleep_offset(&realtime_offset, &wtm, - &sleep); - set_normalized_timespec(&realtime_offset, -wtm.tv_sec, -wtm.tv_nsec); - - base = &__get_cpu_var(hrtimer_bases); - - /* Adjust CLOCK_REALTIME offset */ - raw_spin_lock(&base->lock); - base->clock_base[HRTIMER_BASE_REALTIME].offset = - timespec_to_ktime(realtime_offset); - base->clock_base[HRTIMER_BASE_BOOTTIME].offset = - timespec_to_ktime(sleep); - - hrtimer_force_reprogram(base, 0); - raw_spin_unlock(&base->lock); -} - -/* - * Clock realtime was set - * - * Change the offset of the realtime clock vs. the monotonic - * clock. - * - * We might have to reprogram the high resolution timer interrupt. On - * SMP we call the architecture specific code to retrigger _all_ high - * resolution timer interrupts. On UP we just disable interrupts and - * call the high resolution interrupt code. - */ -void clock_was_set(void) -{ - /* Retrigger the CPU local events everywhere */ - on_each_cpu(retrigger_next_event, NULL, 1); -} - -/* - * During resume we might have to reprogram the high resolution timer - * interrupt (on the local CPU): - */ -void hres_timers_resume(void) -{ - WARN_ONCE(!irqs_disabled(), - KERN_INFO "hres_timers_resume() called with IRQs enabled!"); - - retrigger_next_event(NULL); -} - /* * Initialize the high resolution related parts of cpu_base */ @@ -714,12 +654,14 @@ static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer, return 0; } +static void retrigger_next_event(void *arg); + /* * Switch to high resolution mode */ static int hrtimer_switch_to_hres(void) { - int cpu = smp_processor_id(); + int i, cpu = smp_processor_id(); struct hrtimer_cpu_base *base = &per_cpu(hrtimer_bases, cpu); unsigned long flags; @@ -735,9 +677,8 @@ static int hrtimer_switch_to_hres(void) return 0; } base->hres_active = 1; - base->clock_base[HRTIMER_BASE_REALTIME].resolution = KTIME_HIGH_RES; - base->clock_base[HRTIMER_BASE_MONOTONIC].resolution = KTIME_HIGH_RES; - base->clock_base[HRTIMER_BASE_BOOTTIME].resolution = KTIME_HIGH_RES; + for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) + base->clock_base[i].resolution = KTIME_HIGH_RES; tick_setup_sched_timer(); @@ -764,6 +705,62 @@ static inline void hrtimer_init_hres(struct hrtimer_cpu_base *base) { } #endif /* CONFIG_HIGH_RES_TIMERS */ +/* + * Retrigger next event is called after clock was set + * + * Called with interrupts disabled via on_each_cpu() + */ +static void retrigger_next_event(void *arg) +{ + struct hrtimer_cpu_base *base = &__get_cpu_var(hrtimer_bases); + struct timespec realtime_offset, xtim, wtm, sleep; + + if (!hrtimer_hres_active()) + return; + + get_xtime_and_monotonic_and_sleep_offset(&xtim, &wtm, &sleep); + set_normalized_timespec(&realtime_offset, -wtm.tv_sec, -wtm.tv_nsec); + + /* Adjust CLOCK_REALTIME offset */ + raw_spin_lock(&base->lock); + base->clock_base[HRTIMER_BASE_REALTIME].offset = + timespec_to_ktime(realtime_offset); + base->clock_base[HRTIMER_BASE_BOOTTIME].offset = + timespec_to_ktime(sleep); + + hrtimer_force_reprogram(base, 0); + raw_spin_unlock(&base->lock); +} + +/* + * Clock realtime was set + * + * Change the offset of the realtime clock vs. the monotonic + * clock. + * + * We might have to reprogram the high resolution timer interrupt. On + * SMP we call the architecture specific code to retrigger _all_ high + * resolution timer interrupts. On UP we just disable interrupts and + * call the high resolution interrupt code. + */ +void clock_was_set(void) +{ + /* Retrigger the CPU local events everywhere */ + on_each_cpu(retrigger_next_event, NULL, 1); +} + +/* + * During resume we might have to reprogram the high resolution timer + * interrupt (on the local CPU): + */ +void hrtimers_resume(void) +{ + WARN_ONCE(!irqs_disabled(), + KERN_INFO "hrtimers_resume() called with IRQs enabled!"); + + retrigger_next_event(NULL); +} + static inline void timer_stats_hrtimer_set_start_info(struct hrtimer *timer) { #ifdef CONFIG_TIMER_STATS diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 8e6a05a5915a..a61b8fa2d39a 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -680,7 +680,7 @@ static void timekeeping_resume(void) clockevents_notify(CLOCK_EVT_NOTIFY_RESUME, NULL); /* Resume hrtimers */ - hres_timers_resume(); + hrtimers_resume(); } static int timekeeping_suspend(void) -- cgit From 99ee5315dac6211e972fa3f23bcc9a0343ff58c4 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 27 Apr 2011 14:16:42 +0200 Subject: timerfd: Allow timers to be cancelled when clock was set Some applications must be aware of clock realtime being set backward. A simple example is a clock applet which arms a timer for the next minute display. If clock realtime is set backward then the applet displays a stale time for the amount of time which the clock was set backwards. Due to that applications poll the time because we don't have an interface. Extend the timerfd interface by adding a flag which puts the timer onto a different internal realtime clock. All timers on this clock are expired whenever the clock was set. The timerfd core records the monotonic offset when the timer is created. When the timer is armed, then the current offset is compared to the previous recorded offset. When it has changed, then timerfd_settime returns -ECANCELED. When a timer is read the offset is compared and if it changed -ECANCELED returned to user space. Periodic timers are not rearmed in the cancelation case. Signed-off-by: Thomas Gleixner Acked-by: John Stultz Cc: Chris Friesen Tested-by: Kay Sievers Cc: "Kirill A. Shutemov" Cc: Peter Zijlstra Cc: Davide Libenzi Reviewed-by: Alexander Shishkin Link: http://lkml.kernel.org/r/%3Calpine.LFD.2.02.1104271359580.3323%40ionos%3E Signed-off-by: Thomas Gleixner --- fs/timerfd.c | 57 ++++++++++++++++++++++++++++++++++++++++++----- include/linux/hrtimer.h | 2 ++ include/linux/time.h | 6 +++++ include/linux/timerfd.h | 3 ++- kernel/hrtimer.c | 36 +++++++++++++++++++++++++++++- kernel/time/timekeeping.c | 15 +++++++++++++ 6 files changed, 111 insertions(+), 8 deletions(-) (limited to 'include/linux') diff --git a/fs/timerfd.c b/fs/timerfd.c index 8c4fc1425b3e..7e14c9e7c4ee 100644 --- a/fs/timerfd.c +++ b/fs/timerfd.c @@ -26,10 +26,12 @@ struct timerfd_ctx { struct hrtimer tmr; ktime_t tintv; + ktime_t moffs; wait_queue_head_t wqh; u64 ticks; int expired; int clockid; + bool might_cancel; }; /* @@ -59,24 +61,52 @@ static ktime_t timerfd_get_remaining(struct timerfd_ctx *ctx) return remaining.tv64 < 0 ? ktime_set(0, 0): remaining; } -static void timerfd_setup(struct timerfd_ctx *ctx, int flags, - const struct itimerspec *ktmr) +static bool timerfd_canceled(struct timerfd_ctx *ctx) +{ + ktime_t moffs; + + if (!ctx->might_cancel) + return false; + + moffs = ktime_get_monotonic_offset(); + + if (moffs.tv64 == ctx->moffs.tv64) + return false; + + ctx->moffs = moffs; + return true; +} + +static int timerfd_setup(struct timerfd_ctx *ctx, int flags, + const struct itimerspec *ktmr) { enum hrtimer_mode htmode; ktime_t texp; + int clockid = ctx->clockid; htmode = (flags & TFD_TIMER_ABSTIME) ? HRTIMER_MODE_ABS: HRTIMER_MODE_REL; + ctx->might_cancel = false; + if (htmode == HRTIMER_MODE_ABS && ctx->clockid == CLOCK_REALTIME && + (flags & TFD_TIMER_CANCELON_SET)) { + clockid = CLOCK_REALTIME_COS; + ctx->might_cancel = true; + } + texp = timespec_to_ktime(ktmr->it_value); ctx->expired = 0; ctx->ticks = 0; ctx->tintv = timespec_to_ktime(ktmr->it_interval); - hrtimer_init(&ctx->tmr, ctx->clockid, htmode); + hrtimer_init(&ctx->tmr, clockid, htmode); hrtimer_set_expires(&ctx->tmr, texp); ctx->tmr.function = timerfd_tmrproc; - if (texp.tv64 != 0) + if (texp.tv64 != 0) { hrtimer_start(&ctx->tmr, texp, htmode); + if (timerfd_canceled(ctx)) + return -ECANCELED; + } + return 0; } static int timerfd_release(struct inode *inode, struct file *file) @@ -118,8 +148,21 @@ static ssize_t timerfd_read(struct file *file, char __user *buf, size_t count, res = -EAGAIN; else res = wait_event_interruptible_locked_irq(ctx->wqh, ctx->ticks); + if (ctx->ticks) { ticks = ctx->ticks; + + /* + * If clock has changed, we do not care about the + * ticks and we do not rearm the timer. Userspace must + * reevaluate anyway. + */ + if (timerfd_canceled(ctx)) { + ticks = 0; + ctx->expired = 0; + res = -ECANCELED; + } + if (ctx->expired && ctx->tintv.tv64) { /* * If tintv.tv64 != 0, this is a periodic timer that @@ -183,6 +226,7 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags) init_waitqueue_head(&ctx->wqh); ctx->clockid = clockid; hrtimer_init(&ctx->tmr, clockid, HRTIMER_MODE_ABS); + ctx->moffs = ktime_get_monotonic_offset(); ufd = anon_inode_getfd("[timerfd]", &timerfd_fops, ctx, O_RDWR | (flags & TFD_SHARED_FCNTL_FLAGS)); @@ -199,6 +243,7 @@ SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags, struct file *file; struct timerfd_ctx *ctx; struct itimerspec ktmr, kotmr; + int ret; if (copy_from_user(&ktmr, utmr, sizeof(ktmr))) return -EFAULT; @@ -240,14 +285,14 @@ SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags, /* * Re-program the timer to the new value ... */ - timerfd_setup(ctx, flags, &ktmr); + ret = timerfd_setup(ctx, flags, &ktmr); spin_unlock_irq(&ctx->wqh.lock); fput(file); if (otmr && copy_to_user(otmr, &kotmr, sizeof(kotmr))) return -EFAULT; - return 0; + return ret; } SYSCALL_DEFINE2(timerfd_gettime, int, ufd, struct itimerspec __user *, otmr) diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 4135c88fe4fa..eda4ccde0730 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -155,6 +155,7 @@ enum hrtimer_base_type { HRTIMER_BASE_REALTIME, HRTIMER_BASE_MONOTONIC, HRTIMER_BASE_BOOTTIME, + HRTIMER_BASE_REALTIME_COS, HRTIMER_MAX_CLOCK_BASES, }; @@ -310,6 +311,7 @@ extern void hrtimers_resume(void); extern ktime_t ktime_get(void); extern ktime_t ktime_get_real(void); extern ktime_t ktime_get_boottime(void); +extern ktime_t ktime_get_monotonic_offset(void); DECLARE_PER_CPU(struct tick_device, tick_cpu_device); diff --git a/include/linux/time.h b/include/linux/time.h index b3061782dec3..a9242773eb24 100644 --- a/include/linux/time.h +++ b/include/linux/time.h @@ -302,6 +302,12 @@ struct itimerval { * The IDs of various hardware clocks: */ #define CLOCK_SGI_CYCLE 10 + +#ifdef __KERNEL__ +/* This clock is not exposed to user space */ +#define CLOCK_REALTIME_COS 15 +#endif + #define MAX_CLOCKS 16 #define CLOCKS_MASK (CLOCK_REALTIME | CLOCK_MONOTONIC) #define CLOCKS_MONO CLOCK_MONOTONIC diff --git a/include/linux/timerfd.h b/include/linux/timerfd.h index 2d0792983f8c..e9571fc8f1a0 100644 --- a/include/linux/timerfd.h +++ b/include/linux/timerfd.h @@ -19,6 +19,7 @@ * shared O_* flags. */ #define TFD_TIMER_ABSTIME (1 << 0) +#define TFD_TIMER_CANCELON_SET (1 << 1) #define TFD_CLOEXEC O_CLOEXEC #define TFD_NONBLOCK O_NONBLOCK @@ -26,6 +27,6 @@ /* Flags for timerfd_create. */ #define TFD_CREATE_FLAGS TFD_SHARED_FCNTL_FLAGS /* Flags for timerfd_settime. */ -#define TFD_SETTIME_FLAGS TFD_TIMER_ABSTIME +#define TFD_SETTIME_FLAGS (TFD_TIMER_ABSTIME | TFD_TIMER_CANCELON_SET) #endif /* _LINUX_TIMERFD_H */ diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index c145ed643bca..eabcbd781433 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -78,6 +78,11 @@ DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) = .get_time = &ktime_get_boottime, .resolution = KTIME_LOW_RES, }, + { + .index = CLOCK_REALTIME_COS, + .get_time = &ktime_get_real, + .resolution = KTIME_LOW_RES, + }, } }; @@ -85,6 +90,7 @@ static const int hrtimer_clock_to_base_table[MAX_CLOCKS] = { [CLOCK_REALTIME] = HRTIMER_BASE_REALTIME, [CLOCK_MONOTONIC] = HRTIMER_BASE_MONOTONIC, [CLOCK_BOOTTIME] = HRTIMER_BASE_BOOTTIME, + [CLOCK_REALTIME_COS] = HRTIMER_BASE_REALTIME_COS, }; static inline int hrtimer_clockid_to_base(clockid_t clock_id) @@ -110,6 +116,7 @@ static void hrtimer_get_softirq_time(struct hrtimer_cpu_base *base) base->clock_base[HRTIMER_BASE_REALTIME].softirq_time = xtim; base->clock_base[HRTIMER_BASE_MONOTONIC].softirq_time = mono; base->clock_base[HRTIMER_BASE_BOOTTIME].softirq_time = boot; + base->clock_base[HRTIMER_BASE_REALTIME_COS].softirq_time = xtim; } /* @@ -479,6 +486,8 @@ static inline void debug_deactivate(struct hrtimer *timer) trace_hrtimer_cancel(timer); } +static void hrtimer_expire_cancelable(struct hrtimer_cpu_base *cpu_base); + /* High resolution timer related functions */ #ifdef CONFIG_HIGH_RES_TIMERS @@ -715,9 +724,14 @@ static void retrigger_next_event(void *arg) struct hrtimer_cpu_base *base = &__get_cpu_var(hrtimer_bases); struct timespec realtime_offset, xtim, wtm, sleep; - if (!hrtimer_hres_active()) + if (!hrtimer_hres_active()) { + raw_spin_lock(&base->lock); + hrtimer_expire_cancelable(base); + raw_spin_unlock(&base->lock); return; + } + /* Optimized out for !HIGH_RES */ get_xtime_and_monotonic_and_sleep_offset(&xtim, &wtm, &sleep); set_normalized_timespec(&realtime_offset, -wtm.tv_sec, -wtm.tv_nsec); @@ -727,6 +741,10 @@ static void retrigger_next_event(void *arg) timespec_to_ktime(realtime_offset); base->clock_base[HRTIMER_BASE_BOOTTIME].offset = timespec_to_ktime(sleep); + base->clock_base[HRTIMER_BASE_REALTIME_COS].offset = + timespec_to_ktime(realtime_offset); + + hrtimer_expire_cancelable(base); hrtimer_force_reprogram(base, 0); raw_spin_unlock(&base->lock); @@ -1222,6 +1240,22 @@ static void __run_hrtimer(struct hrtimer *timer, ktime_t *now) timer->state &= ~HRTIMER_STATE_CALLBACK; } +static void hrtimer_expire_cancelable(struct hrtimer_cpu_base *cpu_base) +{ + struct timerqueue_node *node; + struct hrtimer_clock_base *base; + ktime_t now = ktime_get_real(); + + base = &cpu_base->clock_base[HRTIMER_BASE_REALTIME_COS]; + + while ((node = timerqueue_getnext(&base->active))) { + struct hrtimer *timer; + + timer = container_of(node, struct hrtimer, node); + __run_hrtimer(timer, &now); + } +} + #ifdef CONFIG_HIGH_RES_TIMERS /* diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index a61b8fa2d39a..342408cf68dd 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -1098,6 +1098,21 @@ void get_xtime_and_monotonic_and_sleep_offset(struct timespec *xtim, } while (read_seqretry(&xtime_lock, seq)); } +/** + * ktime_get_monotonic_offset() - get wall_to_monotonic in ktime_t format + */ +ktime_t ktime_get_monotonic_offset(void) +{ + unsigned long seq; + struct timespec wtom; + + do { + seq = read_seqbegin(&xtime_lock); + wtom = wall_to_monotonic; + } while (read_seqretry(&xtime_lock, seq)); + return timespec_to_ktime(wtom); +} + /** * xtime_update() - advances the timekeeping infrastructure * @ticks: number of ticks, that have elapsed since the last call. -- cgit From 3dacdf11f1f82b98d301d5e1d42cdaea9a39968a Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Fri, 15 Apr 2011 16:18:38 +0200 Subject: usb: factor out state_string() on otg drivers Provide common otg_state_string() and use it in drivers. Signed-off-by: Anatolij Gustschin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/otg/isp1301_omap.c | 26 +++----------------------- drivers/usb/otg/langwell_otg.c | 40 +++------------------------------------- drivers/usb/otg/otg.c | 35 +++++++++++++++++++++++++++++++++++ include/linux/usb/otg.h | 1 + 4 files changed, 42 insertions(+), 60 deletions(-) (limited to 'include/linux') diff --git a/drivers/usb/otg/isp1301_omap.c b/drivers/usb/otg/isp1301_omap.c index e25700f44b6f..8c282258e1bd 100644 --- a/drivers/usb/otg/isp1301_omap.c +++ b/drivers/usb/otg/isp1301_omap.c @@ -234,29 +234,9 @@ isp1301_clear_bits(struct isp1301 *isp, u8 reg, u8 bits) /*-------------------------------------------------------------------------*/ -static const char *state_string(enum usb_otg_state state) -{ - switch (state) { - case OTG_STATE_A_IDLE: return "a_idle"; - case OTG_STATE_A_WAIT_VRISE: return "a_wait_vrise"; - case OTG_STATE_A_WAIT_BCON: return "a_wait_bcon"; - case OTG_STATE_A_HOST: return "a_host"; - case OTG_STATE_A_SUSPEND: return "a_suspend"; - case OTG_STATE_A_PERIPHERAL: return "a_peripheral"; - case OTG_STATE_A_WAIT_VFALL: return "a_wait_vfall"; - case OTG_STATE_A_VBUS_ERR: return "a_vbus_err"; - case OTG_STATE_B_IDLE: return "b_idle"; - case OTG_STATE_B_SRP_INIT: return "b_srp_init"; - case OTG_STATE_B_PERIPHERAL: return "b_peripheral"; - case OTG_STATE_B_WAIT_ACON: return "b_wait_acon"; - case OTG_STATE_B_HOST: return "b_host"; - default: return "UNDEFINED"; - } -} - static inline const char *state_name(struct isp1301 *isp) { - return state_string(isp->otg.state); + return otg_state_string(isp->otg.state); } /*-------------------------------------------------------------------------*/ @@ -501,7 +481,7 @@ static void check_state(struct isp1301 *isp, const char *tag) if (isp->otg.state == state && !extra) return; pr_debug("otg: %s FSM %s/%02x, %s, %06x\n", tag, - state_string(state), fsm, state_name(isp), + otg_state_string(state), fsm, state_name(isp), omap_readl(OTG_CTRL)); } @@ -1095,7 +1075,7 @@ static void isp_update_otg(struct isp1301 *isp, u8 stat) if (state != isp->otg.state) pr_debug(" isp, %s -> %s\n", - state_string(state), state_name(isp)); + otg_state_string(state), state_name(isp)); #ifdef CONFIG_USB_OTG /* update the OTG controller state to match the isp1301; may diff --git a/drivers/usb/otg/langwell_otg.c b/drivers/usb/otg/langwell_otg.c index e973ff19c55a..f08f784086f7 100644 --- a/drivers/usb/otg/langwell_otg.c +++ b/drivers/usb/otg/langwell_otg.c @@ -82,40 +82,6 @@ static struct pci_driver otg_pci_driver = { .resume = langwell_otg_resume, }; -static const char *state_string(enum usb_otg_state state) -{ - switch (state) { - case OTG_STATE_A_IDLE: - return "a_idle"; - case OTG_STATE_A_WAIT_VRISE: - return "a_wait_vrise"; - case OTG_STATE_A_WAIT_BCON: - return "a_wait_bcon"; - case OTG_STATE_A_HOST: - return "a_host"; - case OTG_STATE_A_SUSPEND: - return "a_suspend"; - case OTG_STATE_A_PERIPHERAL: - return "a_peripheral"; - case OTG_STATE_A_WAIT_VFALL: - return "a_wait_vfall"; - case OTG_STATE_A_VBUS_ERR: - return "a_vbus_err"; - case OTG_STATE_B_IDLE: - return "b_idle"; - case OTG_STATE_B_SRP_INIT: - return "b_srp_init"; - case OTG_STATE_B_PERIPHERAL: - return "b_peripheral"; - case OTG_STATE_B_WAIT_ACON: - return "b_wait_acon"; - case OTG_STATE_B_HOST: - return "b_host"; - default: - return "UNDEFINED"; - } -} - /* HSM timers */ static inline struct langwell_otg_timer *otg_timer_initializer (void (*function)(unsigned long), unsigned long expires, unsigned long data) @@ -968,7 +934,7 @@ static void langwell_otg_work(struct work_struct *work) pdev = to_pci_dev(lnw->dev); dev_dbg(lnw->dev, "%s: old state = %s\n", __func__, - state_string(iotg->otg.state)); + otg_state_string(iotg->otg.state)); switch (iotg->otg.state) { case OTG_STATE_UNDEFINED: @@ -1703,7 +1669,7 @@ static void langwell_otg_work(struct work_struct *work) } dev_dbg(lnw->dev, "%s: new state = %s\n", __func__, - state_string(iotg->otg.state)); + otg_state_string(iotg->otg.state)); } static ssize_t @@ -1789,7 +1755,7 @@ show_hsm(struct device *_dev, struct device_attribute *attr, char *buf) "b_bus_req = \t%d\n" "b_bus_suspend_tmout = \t%d\n" "b_bus_suspend_vld = \t%d\n", - state_string(iotg->otg.state), + otg_state_string(iotg->otg.state), iotg->hsm.a_bus_resume, iotg->hsm.a_bus_suspend, iotg->hsm.a_conn, diff --git a/drivers/usb/otg/otg.c b/drivers/usb/otg/otg.c index 0a43a7db750f..fb7adeff9ffa 100644 --- a/drivers/usb/otg/otg.c +++ b/drivers/usb/otg/otg.c @@ -64,3 +64,38 @@ int otg_set_transceiver(struct otg_transceiver *x) return 0; } EXPORT_SYMBOL(otg_set_transceiver); + +const char *otg_state_string(enum usb_otg_state state) +{ + switch (state) { + case OTG_STATE_A_IDLE: + return "a_idle"; + case OTG_STATE_A_WAIT_VRISE: + return "a_wait_vrise"; + case OTG_STATE_A_WAIT_BCON: + return "a_wait_bcon"; + case OTG_STATE_A_HOST: + return "a_host"; + case OTG_STATE_A_SUSPEND: + return "a_suspend"; + case OTG_STATE_A_PERIPHERAL: + return "a_peripheral"; + case OTG_STATE_A_WAIT_VFALL: + return "a_wait_vfall"; + case OTG_STATE_A_VBUS_ERR: + return "a_vbus_err"; + case OTG_STATE_B_IDLE: + return "b_idle"; + case OTG_STATE_B_SRP_INIT: + return "b_srp_init"; + case OTG_STATE_B_PERIPHERAL: + return "b_peripheral"; + case OTG_STATE_B_WAIT_ACON: + return "b_wait_acon"; + case OTG_STATE_B_HOST: + return "b_host"; + default: + return "UNDEFINED"; + } +} +EXPORT_SYMBOL(otg_state_string); diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h index 6e40718f5abe..bc84858b3a4d 100644 --- a/include/linux/usb/otg.h +++ b/include/linux/usb/otg.h @@ -246,5 +246,6 @@ otg_unregister_notifier(struct otg_transceiver *otg, struct notifier_block *nb) /* for OTG controller drivers (and maybe other stuff) */ extern int usb_bus_start_enum(struct usb_bus *bus, unsigned port_num); +extern const char *otg_state_string(enum usb_otg_state state); #endif /* __LINUX_USB_OTG_H */ -- cgit From 64b3c304bed25388fed48dbdc098dfcad7063d9c Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 11 Apr 2011 20:19:12 +0200 Subject: usb/ch9: use proper endianess for wBytesPerInterval while going through Tatyana's changes for the gadget framework I noticed that this type is not defined as __le16. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Sarah Sharp --- drivers/usb/core/config.c | 2 +- drivers/usb/host/xhci-mem.c | 2 +- include/linux/usb/ch9.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 83126b03e7cf..c962608b4b9a 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -129,7 +129,7 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, max_tx = ep->desc.wMaxPacketSize * (desc->bMaxBurst + 1); else max_tx = 999999; - if (desc->wBytesPerInterval > max_tx) { + if (le16_to_cpu(desc->wBytesPerInterval) > max_tx) { dev_warn(ddev, "%s endpoint with wBytesPerInterval of %d in " "config %d interface %d altsetting %d ep %d: " "setting to %d\n", diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 500ec7a9eb8a..a4fc4d929385 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1130,7 +1130,7 @@ static u32 xhci_get_max_esit_payload(struct xhci_hcd *xhci, return 0; if (udev->speed == USB_SPEED_SUPER) - return ep->ss_ep_comp.wBytesPerInterval; + return le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval); max_packet = GET_MAX_PACKET(le16_to_cpu(ep->desc.wMaxPacketSize)); max_burst = (le16_to_cpu(ep->desc.wMaxPacketSize) & 0x1800) >> 11; diff --git a/include/linux/usb/ch9.h b/include/linux/usb/ch9.h index b72f305ce6bd..0fd3fbdd8283 100644 --- a/include/linux/usb/ch9.h +++ b/include/linux/usb/ch9.h @@ -579,7 +579,7 @@ struct usb_ss_ep_comp_descriptor { __u8 bMaxBurst; __u8 bmAttributes; - __u16 wBytesPerInterval; + __le16 wBytesPerInterval; } __attribute__ ((packed)); #define USB_DT_SS_EP_COMP_SIZE 6 -- cgit From 13b7ee2a953f07d994b6bc3439cdd4a718de6f80 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Mon, 18 Apr 2011 22:01:55 +0200 Subject: USB: ehci-fsl: add MPC5121E specific suspend and resume Signed-off-by: Anatolij Gustschin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-fsl.c | 153 ++++++++++++++++++++++++++++++++++++++++++++ drivers/usb/host/ehci-fsl.h | 4 ++ include/linux/fsl_devices.h | 15 +++++ 3 files changed, 172 insertions(+) (limited to 'include/linux') diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 5c761df7fa83..caf3d4ac42bd 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -328,6 +328,149 @@ struct ehci_fsl { #ifdef CONFIG_PM +#ifdef CONFIG_PPC_MPC512x +static int ehci_fsl_mpc512x_drv_suspend(struct device *dev) +{ + struct usb_hcd *hcd = dev_get_drvdata(dev); + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + struct fsl_usb2_platform_data *pdata = dev->platform_data; + u32 tmp; + +#ifdef DEBUG + u32 mode = ehci_readl(ehci, hcd->regs + FSL_SOC_USB_USBMODE); + mode &= USBMODE_CM_MASK; + tmp = ehci_readl(ehci, hcd->regs + 0x140); /* usbcmd */ + + dev_dbg(dev, "suspend=%d already_suspended=%d " + "mode=%d usbcmd %08x\n", pdata->suspended, + pdata->already_suspended, mode, tmp); +#endif + + /* + * If the controller is already suspended, then this must be a + * PM suspend. Remember this fact, so that we will leave the + * controller suspended at PM resume time. + */ + if (pdata->suspended) { + dev_dbg(dev, "already suspended, leaving early\n"); + pdata->already_suspended = 1; + return 0; + } + + dev_dbg(dev, "suspending...\n"); + + hcd->state = HC_STATE_SUSPENDED; + dev->power.power_state = PMSG_SUSPEND; + + /* ignore non-host interrupts */ + clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + + /* stop the controller */ + tmp = ehci_readl(ehci, &ehci->regs->command); + tmp &= ~CMD_RUN; + ehci_writel(ehci, tmp, &ehci->regs->command); + + /* save EHCI registers */ + pdata->pm_command = ehci_readl(ehci, &ehci->regs->command); + pdata->pm_command &= ~CMD_RUN; + pdata->pm_status = ehci_readl(ehci, &ehci->regs->status); + pdata->pm_intr_enable = ehci_readl(ehci, &ehci->regs->intr_enable); + pdata->pm_frame_index = ehci_readl(ehci, &ehci->regs->frame_index); + pdata->pm_segment = ehci_readl(ehci, &ehci->regs->segment); + pdata->pm_frame_list = ehci_readl(ehci, &ehci->regs->frame_list); + pdata->pm_async_next = ehci_readl(ehci, &ehci->regs->async_next); + pdata->pm_configured_flag = + ehci_readl(ehci, &ehci->regs->configured_flag); + pdata->pm_portsc = ehci_readl(ehci, &ehci->regs->port_status[0]); + pdata->pm_usbgenctrl = ehci_readl(ehci, + hcd->regs + FSL_SOC_USB_USBGENCTRL); + + /* clear the W1C bits */ + pdata->pm_portsc &= cpu_to_hc32(ehci, ~PORT_RWC_BITS); + + pdata->suspended = 1; + + /* clear PP to cut power to the port */ + tmp = ehci_readl(ehci, &ehci->regs->port_status[0]); + tmp &= ~PORT_POWER; + ehci_writel(ehci, tmp, &ehci->regs->port_status[0]); + + return 0; +} + +static int ehci_fsl_mpc512x_drv_resume(struct device *dev) +{ + struct usb_hcd *hcd = dev_get_drvdata(dev); + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + struct fsl_usb2_platform_data *pdata = dev->platform_data; + u32 tmp; + + dev_dbg(dev, "suspend=%d already_suspended=%d\n", + pdata->suspended, pdata->already_suspended); + + /* + * If the controller was already suspended at suspend time, + * then don't resume it now. + */ + if (pdata->already_suspended) { + dev_dbg(dev, "already suspended, leaving early\n"); + pdata->already_suspended = 0; + return 0; + } + + if (!pdata->suspended) { + dev_dbg(dev, "not suspended, leaving early\n"); + return 0; + } + + pdata->suspended = 0; + + dev_dbg(dev, "resuming...\n"); + + /* set host mode */ + tmp = USBMODE_CM_HOST | (pdata->es ? USBMODE_ES : 0); + ehci_writel(ehci, tmp, hcd->regs + FSL_SOC_USB_USBMODE); + + ehci_writel(ehci, pdata->pm_usbgenctrl, + hcd->regs + FSL_SOC_USB_USBGENCTRL); + ehci_writel(ehci, ISIPHYCTRL_PXE | ISIPHYCTRL_PHYE, + hcd->regs + FSL_SOC_USB_ISIPHYCTRL); + + /* restore EHCI registers */ + ehci_writel(ehci, pdata->pm_command, &ehci->regs->command); + ehci_writel(ehci, pdata->pm_intr_enable, &ehci->regs->intr_enable); + ehci_writel(ehci, pdata->pm_frame_index, &ehci->regs->frame_index); + ehci_writel(ehci, pdata->pm_segment, &ehci->regs->segment); + ehci_writel(ehci, pdata->pm_frame_list, &ehci->regs->frame_list); + ehci_writel(ehci, pdata->pm_async_next, &ehci->regs->async_next); + ehci_writel(ehci, pdata->pm_configured_flag, + &ehci->regs->configured_flag); + ehci_writel(ehci, pdata->pm_portsc, &ehci->regs->port_status[0]); + + set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + hcd->state = HC_STATE_RUNNING; + dev->power.power_state = PMSG_ON; + + tmp = ehci_readl(ehci, &ehci->regs->command); + tmp |= CMD_RUN; + ehci_writel(ehci, tmp, &ehci->regs->command); + + usb_hcd_resume_root_hub(hcd); + + return 0; +} +#else +static inline int ehci_fsl_mpc512x_drv_suspend(struct device *dev) +{ + return 0; +} + +static inline int ehci_fsl_mpc512x_drv_resume(struct device *dev) +{ + return 0; +} +#endif /* CONFIG_PPC_MPC512x */ + static struct ehci_fsl *hcd_to_ehci_fsl(struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); @@ -341,6 +484,11 @@ static int ehci_fsl_drv_suspend(struct device *dev) struct ehci_fsl *ehci_fsl = hcd_to_ehci_fsl(hcd); void __iomem *non_ehci = hcd->regs; + if (of_device_is_compatible(dev->parent->of_node, + "fsl,mpc5121-usb2-dr")) { + return ehci_fsl_mpc512x_drv_suspend(dev); + } + ehci_prepare_ports_for_controller_suspend(hcd_to_ehci(hcd), device_may_wakeup(dev)); if (!fsl_deep_sleep()) @@ -357,6 +505,11 @@ static int ehci_fsl_drv_resume(struct device *dev) struct ehci_hcd *ehci = hcd_to_ehci(hcd); void __iomem *non_ehci = hcd->regs; + if (of_device_is_compatible(dev->parent->of_node, + "fsl,mpc5121-usb2-dr")) { + return ehci_fsl_mpc512x_drv_resume(dev); + } + ehci_prepare_ports_for_controller_resume(ehci); if (!fsl_deep_sleep()) return 0; diff --git a/drivers/usb/host/ehci-fsl.h b/drivers/usb/host/ehci-fsl.h index 3fabed33d940..491806221165 100644 --- a/drivers/usb/host/ehci-fsl.h +++ b/drivers/usb/host/ehci-fsl.h @@ -27,6 +27,10 @@ #define PORT_PTS_SERIAL (3<<30) #define PORT_PTS_PTW (1<<28) #define FSL_SOC_USB_PORTSC2 0x188 +#define FSL_SOC_USB_USBMODE 0x1a8 +#define USBMODE_CM_MASK (3 << 0) /* controller mode mask */ +#define USBMODE_CM_HOST (3 << 0) /* controller mode: host */ +#define USBMODE_ES (1 << 2) /* (Big) Endian Select */ #define FSL_SOC_USB_USBGENCTRL 0x200 #define USBGENCTRL_PPP (1 << 3) diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h index 4eb56ed75fbc..3773c5dab8f5 100644 --- a/include/linux/fsl_devices.h +++ b/include/linux/fsl_devices.h @@ -79,6 +79,21 @@ struct fsl_usb2_platform_data { unsigned have_sysif_regs:1; unsigned invert_drvvbus:1; unsigned invert_pwr_fault:1; + + unsigned suspended:1; + unsigned already_suspended:1; + + /* register save area for suspend/resume */ + u32 pm_command; + u32 pm_status; + u32 pm_intr_enable; + u32 pm_frame_index; + u32 pm_segment; + u32 pm_frame_list; + u32 pm_async_next; + u32 pm_configured_flag; + u32 pm_portsc; + u32 pm_usbgenctrl; }; /* Flags in fsl_usb2_mph_platform_data */ -- cgit From 83722bc9430424de1614ff31696f73a40b3d81a9 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Mon, 18 Apr 2011 22:02:00 +0200 Subject: USB: extend ehci-fsl and fsl_udc_core driver for OTG operation Signed-off-by: Anatolij Gustschin Cc: Li Yang Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/fsl_udc_core.c | 147 ++++++++++++++++++++++++++++++++++---- drivers/usb/gadget/fsl_usb2_udc.h | 2 + drivers/usb/host/ehci-fsl.c | 66 +++++++++++++++++ drivers/usb/host/ehci-hub.c | 8 +++ drivers/usb/host/ehci.h | 4 ++ include/linux/fsl_devices.h | 1 + 6 files changed, 213 insertions(+), 15 deletions(-) (limited to 'include/linux') diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index 28b3a9f25f3b..999eafe89653 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -353,6 +353,19 @@ static void dr_controller_stop(struct fsl_udc *udc) { unsigned int tmp; + pr_debug("%s\n", __func__); + + /* if we're in OTG mode, and the Host is currently using the port, + * stop now and don't rip the controller out from under the + * ehci driver + */ + if (udc->gadget.is_otg) { + if (!(fsl_readl(&dr_regs->otgsc) & OTGSC_STS_USB_ID)) { + pr_debug("udc: Leaving early\n"); + return; + } + } + /* disable all INTR */ fsl_writel(0, &dr_regs->usbintr); @@ -1668,6 +1681,9 @@ static void port_change_irq(struct fsl_udc *udc) { u32 speed; + if (udc->bus_reset) + udc->bus_reset = 0; + /* Bus resetting is finished */ if (!(fsl_readl(&dr_regs->portsc1) & PORTSCX_PORT_RESET)) { /* Get the speed */ @@ -1775,6 +1791,8 @@ static void reset_irq(struct fsl_udc *udc) if (fsl_readl(&dr_regs->portsc1) & PORTSCX_PORT_RESET) { VDBG("Bus reset"); + /* Bus is reseting */ + udc->bus_reset = 1; /* Reset all the queues, include XD, dTD, EP queue * head and TR Queue */ reset_queues(udc); @@ -1852,6 +1870,7 @@ static irqreturn_t fsl_udc_irq(int irq, void *_udc) /* Reset Received */ if (irq_src & USB_STS_RESET) { + VDBG("reset int"); reset_irq(udc); status = IRQ_HANDLED; } @@ -1909,11 +1928,30 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, goto out; } - /* Enable DR IRQ reg and Set usbcmd reg Run bit */ - dr_controller_run(udc_controller); - udc_controller->usb_state = USB_STATE_ATTACHED; - udc_controller->ep0_state = WAIT_FOR_SETUP; - udc_controller->ep0_dir = 0; + if (udc_controller->transceiver) { + /* Suspend the controller until OTG enable it */ + udc_controller->stopped = 1; + printk(KERN_INFO "Suspend udc for OTG auto detect\n"); + + /* connect to bus through transceiver */ + if (udc_controller->transceiver) { + retval = otg_set_peripheral(udc_controller->transceiver, + &udc_controller->gadget); + if (retval < 0) { + ERR("can't bind to transceiver\n"); + driver->unbind(&udc_controller->gadget); + udc_controller->gadget.dev.driver = 0; + udc_controller->driver = 0; + return retval; + } + } + } else { + /* Enable DR IRQ reg and set USBCMD reg Run bit */ + dr_controller_run(udc_controller); + udc_controller->usb_state = USB_STATE_ATTACHED; + udc_controller->ep0_state = WAIT_FOR_SETUP; + udc_controller->ep0_dir = 0; + } printk(KERN_INFO "%s: bind to driver %s\n", udc_controller->gadget.name, driver->driver.name); @@ -2374,17 +2412,30 @@ static int __init fsl_udc_probe(struct platform_device *pdev) spin_lock_init(&udc_controller->lock); udc_controller->stopped = 1; +#ifdef CONFIG_USB_OTG + if (pdata->operating_mode == FSL_USB2_DR_OTG) { + udc_controller->transceiver = otg_get_transceiver(); + if (!udc_controller->transceiver) { + ERR("Can't find OTG driver!\n"); + ret = -ENODEV; + goto err_kfree; + } + } +#endif + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { ret = -ENXIO; goto err_kfree; } - if (!request_mem_region(res->start, res->end - res->start + 1, - driver_name)) { - ERR("request mem region for %s failed\n", pdev->name); - ret = -EBUSY; - goto err_kfree; + if (pdata->operating_mode == FSL_USB2_DR_DEVICE) { + if (!request_mem_region(res->start, res->end - res->start + 1, + driver_name)) { + ERR("request mem region for %s failed\n", pdev->name); + ret = -EBUSY; + goto err_kfree; + } } dr_regs = ioremap(res->start, resource_size(res)); @@ -2455,9 +2506,11 @@ static int __init fsl_udc_probe(struct platform_device *pdev) goto err_free_irq; } - /* initialize usb hw reg except for regs for EP, - * leave usbintr reg untouched */ - dr_controller_setup(udc_controller); + if (!udc_controller->transceiver) { + /* initialize usb hw reg except for regs for EP, + * leave usbintr reg untouched */ + dr_controller_setup(udc_controller); + } fsl_udc_clk_finalize(pdev); @@ -2477,6 +2530,9 @@ static int __init fsl_udc_probe(struct platform_device *pdev) if (ret < 0) goto err_free_irq; + if (udc_controller->transceiver) + udc_controller->gadget.is_otg = 1; + /* setup QH and epctrl for ep0 */ ep0_setup(udc_controller); @@ -2521,7 +2577,8 @@ err_iounmap: err_iounmap_noclk: iounmap(dr_regs); err_release_mem_region: - release_mem_region(res->start, res->end - res->start + 1); + if (pdata->operating_mode == FSL_USB2_DR_DEVICE) + release_mem_region(res->start, res->end - res->start + 1); err_kfree: kfree(udc_controller); udc_controller = NULL; @@ -2555,7 +2612,8 @@ static int __exit fsl_udc_remove(struct platform_device *pdev) dma_pool_destroy(udc_controller->td_pool); free_irq(udc_controller->irq, udc_controller); iounmap(dr_regs); - release_mem_region(res->start, res->end - res->start + 1); + if (pdata->operating_mode == FSL_USB2_DR_DEVICE) + release_mem_region(res->start, res->end - res->start + 1); device_unregister(&udc_controller->gadget.dev); /* free udc --wait for the release() finished */ @@ -2598,6 +2656,62 @@ static int fsl_udc_resume(struct platform_device *pdev) return 0; } +static int fsl_udc_otg_suspend(struct device *dev, pm_message_t state) +{ + struct fsl_udc *udc = udc_controller; + u32 mode, usbcmd; + + mode = fsl_readl(&dr_regs->usbmode) & USB_MODE_CTRL_MODE_MASK; + + pr_debug("%s(): mode 0x%x stopped %d\n", __func__, mode, udc->stopped); + + /* + * If the controller is already stopped, then this must be a + * PM suspend. Remember this fact, so that we will leave the + * controller stopped at PM resume time. + */ + if (udc->stopped) { + pr_debug("gadget already stopped, leaving early\n"); + udc->already_stopped = 1; + return 0; + } + + if (mode != USB_MODE_CTRL_MODE_DEVICE) { + pr_debug("gadget not in device mode, leaving early\n"); + return 0; + } + + /* stop the controller */ + usbcmd = fsl_readl(&dr_regs->usbcmd) & ~USB_CMD_RUN_STOP; + fsl_writel(usbcmd, &dr_regs->usbcmd); + + udc->stopped = 1; + + pr_info("USB Gadget suspended\n"); + + return 0; +} + +static int fsl_udc_otg_resume(struct device *dev) +{ + pr_debug("%s(): stopped %d already_stopped %d\n", __func__, + udc_controller->stopped, udc_controller->already_stopped); + + /* + * If the controller was stopped at suspend time, then + * don't resume it now. + */ + if (udc_controller->already_stopped) { + udc_controller->already_stopped = 0; + pr_debug("gadget was already stopped, leaving early\n"); + return 0; + } + + pr_info("USB Gadget resume\n"); + + return fsl_udc_resume(NULL); +} + /*------------------------------------------------------------------------- Register entry point for the peripheral controller driver --------------------------------------------------------------------------*/ @@ -2610,6 +2724,9 @@ static struct platform_driver udc_driver = { .driver = { .name = (char *)driver_name, .owner = THIS_MODULE, + /* udc suspend/resume called from OTG driver */ + .suspend = fsl_udc_otg_suspend, + .resume = fsl_udc_otg_resume, }, }; diff --git a/drivers/usb/gadget/fsl_usb2_udc.h b/drivers/usb/gadget/fsl_usb2_udc.h index 5647cc21b84c..1d51be83fda8 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.h +++ b/drivers/usb/gadget/fsl_usb2_udc.h @@ -476,6 +476,7 @@ struct fsl_udc { unsigned vbus_active:1; unsigned stopped:1; unsigned remote_wakeup:1; + unsigned already_stopped:1; unsigned big_endian_desc:1; struct ep_queue_head *ep_qh; /* Endpoints Queue-Head */ @@ -487,6 +488,7 @@ struct fsl_udc { dma_addr_t ep_qh_dma; /* dma address of QH */ u32 max_pipes; /* Device max pipes */ + u32 bus_reset; /* Device is bus resetting */ u32 resume_state; /* USB state to resume */ u32 usb_state; /* USB current state */ u32 ep0_state; /* Endpoint zero state */ diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index caf3d4ac42bd..623732a312dd 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -117,6 +117,9 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver, pdata->regs = hcd->regs; + if (pdata->power_budget) + hcd->power_budget = pdata->power_budget; + /* * do platform specific init: check the clock, grab/config pins, etc. */ @@ -134,6 +137,30 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver, retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); if (retval != 0) goto err4; + +#ifdef CONFIG_USB_OTG + if (pdata->operating_mode == FSL_USB2_DR_OTG) { + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + + ehci->transceiver = otg_get_transceiver(); + dev_dbg(&pdev->dev, "hcd=0x%p ehci=0x%p, transceiver=0x%p\n", + hcd, ehci, ehci->transceiver); + + if (ehci->transceiver) { + retval = otg_set_host(ehci->transceiver, + &ehci_to_hcd(ehci)->self); + if (retval) { + if (ehci->transceiver) + put_device(ehci->transceiver->dev); + goto err4; + } + } else { + dev_err(&pdev->dev, "can't find transceiver\n"); + retval = -ENODEV; + goto err4; + } + } +#endif return retval; err4: @@ -164,6 +191,12 @@ static void usb_hcd_fsl_remove(struct usb_hcd *hcd, struct platform_device *pdev) { struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + + if (ehci->transceiver) { + otg_set_host(ehci->transceiver, NULL); + put_device(ehci->transceiver->dev); + } usb_remove_hcd(hcd); @@ -544,6 +577,38 @@ static struct dev_pm_ops ehci_fsl_pm_ops = { #define EHCI_FSL_PM_OPS NULL #endif /* CONFIG_PM */ +#ifdef CONFIG_USB_OTG +static int ehci_start_port_reset(struct usb_hcd *hcd, unsigned port) +{ + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + u32 status; + + if (!port) + return -EINVAL; + + port--; + + /* start port reset before HNP protocol time out */ + status = readl(&ehci->regs->port_status[port]); + if (!(status & PORT_CONNECT)) + return -ENODEV; + + /* khubd will finish the reset later */ + if (ehci_is_TDI(ehci)) { + writel(PORT_RESET | + (status & ~(PORT_CSC | PORT_PEC | PORT_OCC)), + &ehci->regs->port_status[port]); + } else { + writel(PORT_RESET, &ehci->regs->port_status[port]); + } + + return 0; +} +#else +#define ehci_start_port_reset NULL +#endif /* CONFIG_USB_OTG */ + + static const struct hc_driver ehci_fsl_hc_driver = { .description = hcd_name, .product_desc = "Freescale On-Chip EHCI Host Controller", @@ -583,6 +648,7 @@ static const struct hc_driver ehci_fsl_hc_driver = { .hub_control = ehci_hub_control, .bus_suspend = ehci_bus_suspend, .bus_resume = ehci_bus_resume, + .start_port_reset = ehci_start_port_reset, .relinquish_port = ehci_relinquish_port, .port_handed_over = ehci_port_handed_over, diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 1a21799195af..ea6184bf48d0 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -27,6 +27,7 @@ */ /*-------------------------------------------------------------------------*/ +#include #define PORT_WAKE_BITS (PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E) @@ -801,6 +802,13 @@ static int ehci_hub_control ( goto error; if (ehci->no_selective_suspend) break; +#ifdef CONFIG_USB_OTG + if ((hcd->self.otg_port == (wIndex + 1)) + && hcd->self.b_hnp_enable) { + otg_start_hnp(ehci->transceiver); + break; + } +#endif if (!(temp & PORT_SUSPEND)) break; if ((temp & PORT_PE) == 0) diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 168f1a88c4d0..e9ba8e252489 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -161,6 +161,10 @@ struct ehci_hcd { /* one per controller */ #ifdef DEBUG struct dentry *debug_dir; #endif + /* + * OTG controllers and transceivers need software interaction + */ + struct otg_transceiver *transceiver; }; /* convert between an HCD pointer and the corresponding EHCI_HCD */ diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h index 3773c5dab8f5..fffdf00f87b9 100644 --- a/include/linux/fsl_devices.h +++ b/include/linux/fsl_devices.h @@ -72,6 +72,7 @@ struct fsl_usb2_platform_data { void (*exit)(struct platform_device *); void __iomem *regs; /* ioremap'd register base */ struct clk *clk; + unsigned power_budget; /* hcd->power_budget */ unsigned big_endian_mmio:1; unsigned big_endian_desc:1; unsigned es:1; /* need USBMODE:ES */ -- cgit From 139540170d9d9b7ead3caaf540f161756b356d56 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Wed, 27 Apr 2011 21:07:28 +0530 Subject: USB: ehci: remove structure packing from ehci_def As pointed out by Arnd Bergmann, in include/linux/usb/ehci_def.h, struct ehci_caps is defined with __attribute__((packed)) for no good reason, and this triggers undefined behaviour when using ARM's readl() on pointers to elements of this structure: http://lkml.kernel.org/r/201102021700.20683.arnd@arndb.de The same problem exists with the other two structures in ehci_def.h too, so remove the __attribute__((packed)) from all of them. Cc: Arnd Bergmann Signed-off-by: Rabin Vincent Signed-off-by: Greg Kroah-Hartman --- include/linux/usb/ehci_def.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/usb/ehci_def.h b/include/linux/usb/ehci_def.h index e49dfd45baa4..78799432008e 100644 --- a/include/linux/usb/ehci_def.h +++ b/include/linux/usb/ehci_def.h @@ -52,7 +52,7 @@ struct ehci_caps { #define HCC_PGM_FRAMELISTLEN(p) ((p)&(1 << 1)) /* true: periodic_size changes*/ #define HCC_64BIT_ADDR(p) ((p)&(1)) /* true: can use 64-bit addr */ u8 portroute[8]; /* nibbles for routing - offset 0xC */ -} __attribute__ ((packed)); +}; /* Section 2.3 Host Controller Operational Registers */ @@ -150,7 +150,7 @@ struct ehci_regs { #define PORT_CSC (1<<1) /* connect status change */ #define PORT_CONNECT (1<<0) /* device connected */ #define PORT_RWC_BITS (PORT_CSC | PORT_PEC | PORT_OCC) -} __attribute__ ((packed)); +}; #define USBMODE 0x68 /* USB Device mode */ #define USBMODE_SDIS (1<<3) /* Stream disable */ @@ -194,7 +194,7 @@ struct ehci_dbg_port { u32 data47; u32 address; #define DBGP_EPADDR(dev, ep) (((dev)<<8)|(ep)) -} __attribute__ ((packed)); +}; #ifdef CONFIG_EARLY_PRINTK_DBGP #include -- cgit From 61ec9016988f5c030e96e3c8a42ee9e11b8517aa Mon Sep 17 00:00:00 2001 From: John Linn Date: Sat, 30 Apr 2011 00:07:43 -0400 Subject: tty/serial: add support for Xilinx PS UART The Xilinx PS Uart is used on the new ARM based SoC. This UART is not compatible with others such that a seperate driver is required. Signed-off-by: John Linn Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/Kconfig | 13 + drivers/tty/serial/Makefile | 1 + drivers/tty/serial/xilinx_uartps.c | 1113 ++++++++++++++++++++++++++++++++++++ include/linux/serial_core.h | 3 + 4 files changed, 1130 insertions(+) create mode 100644 drivers/tty/serial/xilinx_uartps.c (limited to 'include/linux') diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 80484af781e1..84876ec2ed97 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1612,4 +1612,17 @@ config SERIAL_MXS_AUART_CONSOLE help Enable a MXS AUART port to be the system console. +config SERIAL_XILINX_PS_UART + tristate "Xilinx PS UART support" + select SERIAL_CORE + help + This driver supports the Xilinx PS UART port. + +config SERIAL_XILINX_PS_UART_CONSOLE + bool "Xilinx PS UART console support" + depends on SERIAL_XILINX_PS_UART=y + select SERIAL_CORE_CONSOLE + help + Enable a Xilinx PS UART port to be the system console. + endmenu diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index fee0690ef8e3..aafddf15992f 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile @@ -94,3 +94,4 @@ obj-$(CONFIG_SERIAL_IFX6X60) += ifx6x60.o obj-$(CONFIG_SERIAL_PCH_UART) += pch_uart.o obj-$(CONFIG_SERIAL_MSM_SMD) += msm_smd_tty.o obj-$(CONFIG_SERIAL_MXS_AUART) += mxs-auart.o +obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c new file mode 100644 index 000000000000..19cc1e8149dd --- /dev/null +++ b/drivers/tty/serial/xilinx_uartps.c @@ -0,0 +1,1113 @@ +/* + * Xilinx PS UART driver + * + * 2011 (c) Xilinx Inc. + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; + * either version 2 of the License, or (at your option) any + * later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#define XUARTPS_TTY_NAME "ttyPS" +#define XUARTPS_NAME "xuartps" +#define XUARTPS_MAJOR 0 /* use dynamic node allocation */ +#define XUARTPS_MINOR 0 /* works best with devtmpfs */ +#define XUARTPS_NR_PORTS 2 +#define XUARTPS_FIFO_SIZE 16 /* FIFO size */ +#define XUARTPS_REGISTER_SPACE 0xFFF + +#define xuartps_readl(offset) ioread32(port->membase + offset) +#define xuartps_writel(val, offset) iowrite32(val, port->membase + offset) + +/********************************Register Map********************************/ +/** UART + * + * Register offsets for the UART. + * + */ +#define XUARTPS_CR_OFFSET 0x00 /* Control Register [8:0] */ +#define XUARTPS_MR_OFFSET 0x04 /* Mode Register [10:0] */ +#define XUARTPS_IER_OFFSET 0x08 /* Interrupt Enable [10:0] */ +#define XUARTPS_IDR_OFFSET 0x0C /* Interrupt Disable [10:0] */ +#define XUARTPS_IMR_OFFSET 0x10 /* Interrupt Mask [10:0] */ +#define XUARTPS_ISR_OFFSET 0x14 /* Interrupt Status [10:0]*/ +#define XUARTPS_BAUDGEN_OFFSET 0x18 /* Baud Rate Generator [15:0] */ +#define XUARTPS_RXTOUT_OFFSET 0x1C /* RX Timeout [7:0] */ +#define XUARTPS_RXWM_OFFSET 0x20 /* RX FIFO Trigger Level [5:0] */ +#define XUARTPS_MODEMCR_OFFSET 0x24 /* Modem Control [5:0] */ +#define XUARTPS_MODEMSR_OFFSET 0x28 /* Modem Status [8:0] */ +#define XUARTPS_SR_OFFSET 0x2C /* Channel Status [11:0] */ +#define XUARTPS_FIFO_OFFSET 0x30 /* FIFO [15:0] or [7:0] */ +#define XUARTPS_BAUDDIV_OFFSET 0x34 /* Baud Rate Divider [7:0] */ +#define XUARTPS_FLOWDEL_OFFSET 0x38 /* Flow Delay [15:0] */ +#define XUARTPS_IRRX_PWIDTH_OFFSET 0x3C /* IR Minimum Received Pulse + Width [15:0] */ +#define XUARTPS_IRTX_PWIDTH_OFFSET 0x40 /* IR Transmitted pulse + Width [7:0] */ +#define XUARTPS_TXWM_OFFSET 0x44 /* TX FIFO Trigger Level [5:0] */ + +/** Control Register + * + * The Control register (CR) controls the major functions of the device. + * + * Control Register Bit Definitions + */ +#define XUARTPS_CR_STOPBRK 0x00000100 /* Stop TX break */ +#define XUARTPS_CR_STARTBRK 0x00000080 /* Set TX break */ +#define XUARTPS_CR_TX_DIS 0x00000020 /* TX disabled. */ +#define XUARTPS_CR_TX_EN 0x00000010 /* TX enabled */ +#define XUARTPS_CR_RX_DIS 0x00000008 /* RX disabled. */ +#define XUARTPS_CR_RX_EN 0x00000004 /* RX enabled */ +#define XUARTPS_CR_TXRST 0x00000002 /* TX logic reset */ +#define XUARTPS_CR_RXRST 0x00000001 /* RX logic reset */ +#define XUARTPS_CR_RST_TO 0x00000040 /* Restart Timeout Counter */ + +/** Mode Register + * + * The mode register (MR) defines the mode of transfer as well as the data + * format. If this register is modified during transmission or reception, + * data validity cannot be guaranteed. + * + * Mode Register Bit Definitions + * + */ +#define XUARTPS_MR_CLKSEL 0x00000001 /* Pre-scalar selection */ +#define XUARTPS_MR_CHMODE_L_LOOP 0x00000200 /* Local loop back mode */ +#define XUARTPS_MR_CHMODE_NORM 0x00000000 /* Normal mode */ + +#define XUARTPS_MR_STOPMODE_2_BIT 0x00000080 /* 2 stop bits */ +#define XUARTPS_MR_STOPMODE_1_BIT 0x00000000 /* 1 stop bit */ + +#define XUARTPS_MR_PARITY_NONE 0x00000020 /* No parity mode */ +#define XUARTPS_MR_PARITY_MARK 0x00000018 /* Mark parity mode */ +#define XUARTPS_MR_PARITY_SPACE 0x00000010 /* Space parity mode */ +#define XUARTPS_MR_PARITY_ODD 0x00000008 /* Odd parity mode */ +#define XUARTPS_MR_PARITY_EVEN 0x00000000 /* Even parity mode */ + +#define XUARTPS_MR_CHARLEN_6_BIT 0x00000006 /* 6 bits data */ +#define XUARTPS_MR_CHARLEN_7_BIT 0x00000004 /* 7 bits data */ +#define XUARTPS_MR_CHARLEN_8_BIT 0x00000000 /* 8 bits data */ + +/** Interrupt Registers + * + * Interrupt control logic uses the interrupt enable register (IER) and the + * interrupt disable register (IDR) to set the value of the bits in the + * interrupt mask register (IMR). The IMR determines whether to pass an + * interrupt to the interrupt status register (ISR). + * Writing a 1 to IER Enables an interrupt, writing a 1 to IDR disables an + * interrupt. IMR and ISR are read only, and IER and IDR are write only. + * Reading either IER or IDR returns 0x00. + * + * All four registers have the same bit definitions. + */ +#define XUARTPS_IXR_TOUT 0x00000100 /* RX Timeout error interrupt */ +#define XUARTPS_IXR_PARITY 0x00000080 /* Parity error interrupt */ +#define XUARTPS_IXR_FRAMING 0x00000040 /* Framing error interrupt */ +#define XUARTPS_IXR_OVERRUN 0x00000020 /* Overrun error interrupt */ +#define XUARTPS_IXR_TXFULL 0x00000010 /* TX FIFO Full interrupt */ +#define XUARTPS_IXR_TXEMPTY 0x00000008 /* TX FIFO empty interrupt */ +#define XUARTPS_ISR_RXEMPTY 0x00000002 /* RX FIFO empty interrupt */ +#define XUARTPS_IXR_RXTRIG 0x00000001 /* RX FIFO trigger interrupt */ +#define XUARTPS_IXR_RXFULL 0x00000004 /* RX FIFO full interrupt. */ +#define XUARTPS_IXR_RXEMPTY 0x00000002 /* RX FIFO empty interrupt. */ +#define XUARTPS_IXR_MASK 0x00001FFF /* Valid bit mask */ + +/** Channel Status Register + * + * The channel status register (CSR) is provided to enable the control logic + * to monitor the status of bits in the channel interrupt status register, + * even if these are masked out by the interrupt mask register. + */ +#define XUARTPS_SR_RXEMPTY 0x00000002 /* RX FIFO empty */ +#define XUARTPS_SR_TXEMPTY 0x00000008 /* TX FIFO empty */ +#define XUARTPS_SR_TXFULL 0x00000010 /* TX FIFO full */ +#define XUARTPS_SR_RXTRIG 0x00000001 /* Rx Trigger */ + +/** + * xuartps_isr - Interrupt handler + * @irq: Irq number + * @dev_id: Id of the port + * + * Returns IRQHANDLED + **/ +static irqreturn_t xuartps_isr(int irq, void *dev_id) +{ + struct uart_port *port = (struct uart_port *)dev_id; + struct tty_struct *tty; + unsigned long flags; + unsigned int isrstatus, numbytes; + unsigned int data; + char status = TTY_NORMAL; + + /* Get the tty which could be NULL so don't assume it's valid */ + tty = tty_port_tty_get(&port->state->port); + + spin_lock_irqsave(&port->lock, flags); + + /* Read the interrupt status register to determine which + * interrupt(s) is/are active. + */ + isrstatus = xuartps_readl(XUARTPS_ISR_OFFSET); + + /* drop byte with parity error if IGNPAR specified */ + if (isrstatus & port->ignore_status_mask & XUARTPS_IXR_PARITY) + isrstatus &= ~(XUARTPS_IXR_RXTRIG | XUARTPS_IXR_TOUT); + + isrstatus &= port->read_status_mask; + isrstatus &= ~port->ignore_status_mask; + + if ((isrstatus & XUARTPS_IXR_TOUT) || + (isrstatus & XUARTPS_IXR_RXTRIG)) { + /* Receive Timeout Interrupt */ + while ((xuartps_readl(XUARTPS_SR_OFFSET) & + XUARTPS_SR_RXEMPTY) != XUARTPS_SR_RXEMPTY) { + data = xuartps_readl(XUARTPS_FIFO_OFFSET); + port->icount.rx++; + + if (isrstatus & XUARTPS_IXR_PARITY) { + port->icount.parity++; + status = TTY_PARITY; + } else if (isrstatus & XUARTPS_IXR_FRAMING) { + port->icount.frame++; + status = TTY_FRAME; + } else if (isrstatus & XUARTPS_IXR_OVERRUN) + port->icount.overrun++; + + if (tty) + uart_insert_char(port, isrstatus, + XUARTPS_IXR_OVERRUN, data, + status); + } + spin_unlock(&port->lock); + if (tty) + tty_flip_buffer_push(tty); + spin_lock(&port->lock); + } + + /* Dispatch an appropriate handler */ + if ((isrstatus & XUARTPS_IXR_TXEMPTY) == XUARTPS_IXR_TXEMPTY) { + if (uart_circ_empty(&port->state->xmit)) { + xuartps_writel(XUARTPS_IXR_TXEMPTY, + XUARTPS_IDR_OFFSET); + } else { + numbytes = port->fifosize; + /* Break if no more data available in the UART buffer */ + while (numbytes--) { + if (uart_circ_empty(&port->state->xmit)) + break; + /* Get the data from the UART circular buffer + * and write it to the xuartps's TX_FIFO + * register. + */ + xuartps_writel( + port->state->xmit.buf[port->state->xmit. + tail], XUARTPS_FIFO_OFFSET); + + port->icount.tx++; + + /* Adjust the tail of the UART buffer and wrap + * the buffer if it reaches limit. + */ + port->state->xmit.tail = + (port->state->xmit.tail + 1) & \ + (UART_XMIT_SIZE - 1); + } + + if (uart_circ_chars_pending( + &port->state->xmit) < WAKEUP_CHARS) + uart_write_wakeup(port); + } + } + + xuartps_writel(isrstatus, XUARTPS_ISR_OFFSET); + + /* be sure to release the lock and tty before leaving */ + spin_unlock_irqrestore(&port->lock, flags); + tty_kref_put(tty); + + return IRQ_HANDLED; +} + +/** + * xuartps_set_baud_rate - Calculate and set the baud rate + * @port: Handle to the uart port structure + * @baud: Baud rate to set + * + * Returns baud rate, requested baud when possible, or actual baud when there + * was too much error + **/ +static unsigned int xuartps_set_baud_rate(struct uart_port *port, + unsigned int baud) +{ + unsigned int sel_clk; + unsigned int calc_baud = 0; + unsigned int brgr_val, brdiv_val; + unsigned int bauderror; + + /* Formula to obtain baud rate is + * baud_tx/rx rate = sel_clk/CD * (BDIV + 1) + * input_clk = (Uart User Defined Clock or Apb Clock) + * depends on UCLKEN in MR Reg + * sel_clk = input_clk or input_clk/8; + * depends on CLKS in MR reg + * CD and BDIV depends on values in + * baud rate generate register + * baud rate clock divisor register + */ + sel_clk = port->uartclk; + if (xuartps_readl(XUARTPS_MR_OFFSET) & XUARTPS_MR_CLKSEL) + sel_clk = sel_clk / 8; + + /* Find the best values for baud generation */ + for (brdiv_val = 4; brdiv_val < 255; brdiv_val++) { + + brgr_val = sel_clk / (baud * (brdiv_val + 1)); + if (brgr_val < 2 || brgr_val > 65535) + continue; + + calc_baud = sel_clk / (brgr_val * (brdiv_val + 1)); + + if (baud > calc_baud) + bauderror = baud - calc_baud; + else + bauderror = calc_baud - baud; + + /* use the values when percent error is acceptable */ + if (((bauderror * 100) / baud) < 3) { + calc_baud = baud; + break; + } + } + + /* Set the values for the new baud rate */ + xuartps_writel(brgr_val, XUARTPS_BAUDGEN_OFFSET); + xuartps_writel(brdiv_val, XUARTPS_BAUDDIV_OFFSET); + + return calc_baud; +} + +/*----------------------Uart Operations---------------------------*/ + +/** + * xuartps_start_tx - Start transmitting bytes + * @port: Handle to the uart port structure + * + **/ +static void xuartps_start_tx(struct uart_port *port) +{ + unsigned int status, numbytes = port->fifosize; + + if (uart_circ_empty(&port->state->xmit) || uart_tx_stopped(port)) + return; + + status = xuartps_readl(XUARTPS_CR_OFFSET); + /* Set the TX enable bit and clear the TX disable bit to enable the + * transmitter. + */ + xuartps_writel((status & ~XUARTPS_CR_TX_DIS) | XUARTPS_CR_TX_EN, + XUARTPS_CR_OFFSET); + + while (numbytes-- && ((xuartps_readl(XUARTPS_SR_OFFSET) + & XUARTPS_SR_TXFULL)) != XUARTPS_SR_TXFULL) { + + /* Break if no more data available in the UART buffer */ + if (uart_circ_empty(&port->state->xmit)) + break; + + /* Get the data from the UART circular buffer and + * write it to the xuartps's TX_FIFO register. + */ + xuartps_writel( + port->state->xmit.buf[port->state->xmit.tail], + XUARTPS_FIFO_OFFSET); + port->icount.tx++; + + /* Adjust the tail of the UART buffer and wrap + * the buffer if it reaches limit. + */ + port->state->xmit.tail = (port->state->xmit.tail + 1) & + (UART_XMIT_SIZE - 1); + } + + /* Enable the TX Empty interrupt */ + xuartps_writel(XUARTPS_IXR_TXEMPTY, XUARTPS_IER_OFFSET); + + if (uart_circ_chars_pending(&port->state->xmit) < WAKEUP_CHARS) + uart_write_wakeup(port); +} + +/** + * xuartps_stop_tx - Stop TX + * @port: Handle to the uart port structure + * + **/ +static void xuartps_stop_tx(struct uart_port *port) +{ + unsigned int regval; + + regval = xuartps_readl(XUARTPS_CR_OFFSET); + regval |= XUARTPS_CR_TX_DIS; + /* Disable the transmitter */ + xuartps_writel(regval, XUARTPS_CR_OFFSET); +} + +/** + * xuartps_stop_rx - Stop RX + * @port: Handle to the uart port structure + * + **/ +static void xuartps_stop_rx(struct uart_port *port) +{ + unsigned int regval; + + regval = xuartps_readl(XUARTPS_CR_OFFSET); + regval |= XUARTPS_CR_RX_DIS; + /* Disable the receiver */ + xuartps_writel(regval, XUARTPS_CR_OFFSET); +} + +/** + * xuartps_tx_empty - Check whether TX is empty + * @port: Handle to the uart port structure + * + * Returns TIOCSER_TEMT on success, 0 otherwise + **/ +static unsigned int xuartps_tx_empty(struct uart_port *port) +{ + unsigned int status; + + status = xuartps_readl(XUARTPS_ISR_OFFSET) & XUARTPS_IXR_TXEMPTY; + return status ? TIOCSER_TEMT : 0; +} + +/** + * xuartps_break_ctl - Based on the input ctl we have to start or stop + * transmitting char breaks + * @port: Handle to the uart port structure + * @ctl: Value based on which start or stop decision is taken + * + **/ +static void xuartps_break_ctl(struct uart_port *port, int ctl) +{ + unsigned int status; + unsigned long flags; + + spin_lock_irqsave(&port->lock, flags); + + status = xuartps_readl(XUARTPS_CR_OFFSET); + + if (ctl == -1) + xuartps_writel(XUARTPS_CR_STARTBRK | status, + XUARTPS_CR_OFFSET); + else { + if ((status & XUARTPS_CR_STOPBRK) == 0) + xuartps_writel(XUARTPS_CR_STOPBRK | status, + XUARTPS_CR_OFFSET); + } + spin_unlock_irqrestore(&port->lock, flags); +} + +/** + * xuartps_set_termios - termios operations, handling data length, parity, + * stop bits, flow control, baud rate + * @port: Handle to the uart port structure + * @termios: Handle to the input termios structure + * @old: Values of the previously saved termios structure + * + **/ +static void xuartps_set_termios(struct uart_port *port, + struct ktermios *termios, struct ktermios *old) +{ + unsigned int cval = 0; + unsigned int baud; + unsigned long flags; + unsigned int ctrl_reg, mode_reg; + + spin_lock_irqsave(&port->lock, flags); + + /* Empty the receive FIFO 1st before making changes */ + while ((xuartps_readl(XUARTPS_SR_OFFSET) & + XUARTPS_SR_RXEMPTY) != XUARTPS_SR_RXEMPTY) { + xuartps_readl(XUARTPS_FIFO_OFFSET); + } + + /* Disable the TX and RX to set baud rate */ + xuartps_writel(xuartps_readl(XUARTPS_CR_OFFSET) | + (XUARTPS_CR_TX_DIS | XUARTPS_CR_RX_DIS), + XUARTPS_CR_OFFSET); + + /* Min baud rate = 6bps and Max Baud Rate is 10Mbps for 100Mhz clk */ + baud = uart_get_baud_rate(port, termios, old, 0, 10000000); + baud = xuartps_set_baud_rate(port, baud); + if (tty_termios_baud_rate(termios)) + tty_termios_encode_baud_rate(termios, baud, baud); + + /* + * Update the per-port timeout. + */ + uart_update_timeout(port, termios->c_cflag, baud); + + /* Set TX/RX Reset */ + xuartps_writel(xuartps_readl(XUARTPS_CR_OFFSET) | + (XUARTPS_CR_TXRST | XUARTPS_CR_RXRST), + XUARTPS_CR_OFFSET); + + ctrl_reg = xuartps_readl(XUARTPS_CR_OFFSET); + + /* Clear the RX disable and TX disable bits and then set the TX enable + * bit and RX enable bit to enable the transmitter and receiver. + */ + xuartps_writel( + (ctrl_reg & ~(XUARTPS_CR_TX_DIS | XUARTPS_CR_RX_DIS)) + | (XUARTPS_CR_TX_EN | XUARTPS_CR_RX_EN), + XUARTPS_CR_OFFSET); + + xuartps_writel(10, XUARTPS_RXTOUT_OFFSET); + + port->read_status_mask = XUARTPS_IXR_TXEMPTY | XUARTPS_IXR_RXTRIG | + XUARTPS_IXR_OVERRUN | XUARTPS_IXR_TOUT; + port->ignore_status_mask = 0; + + if (termios->c_iflag & INPCK) + port->read_status_mask |= XUARTPS_IXR_PARITY | + XUARTPS_IXR_FRAMING; + + if (termios->c_iflag & IGNPAR) + port->ignore_status_mask |= XUARTPS_IXR_PARITY | + XUARTPS_IXR_FRAMING | XUARTPS_IXR_OVERRUN; + + /* ignore all characters if CREAD is not set */ + if ((termios->c_cflag & CREAD) == 0) + port->ignore_status_mask |= XUARTPS_IXR_RXTRIG | + XUARTPS_IXR_TOUT | XUARTPS_IXR_PARITY | + XUARTPS_IXR_FRAMING | XUARTPS_IXR_OVERRUN; + + mode_reg = xuartps_readl(XUARTPS_MR_OFFSET); + + /* Handling Data Size */ + switch (termios->c_cflag & CSIZE) { + case CS6: + cval |= XUARTPS_MR_CHARLEN_6_BIT; + break; + case CS7: + cval |= XUARTPS_MR_CHARLEN_7_BIT; + break; + default: + case CS8: + cval |= XUARTPS_MR_CHARLEN_8_BIT; + termios->c_cflag &= ~CSIZE; + termios->c_cflag |= CS8; + break; + } + + /* Handling Parity and Stop Bits length */ + if (termios->c_cflag & CSTOPB) + cval |= XUARTPS_MR_STOPMODE_2_BIT; /* 2 STOP bits */ + else + cval |= XUARTPS_MR_STOPMODE_1_BIT; /* 1 STOP bit */ + + if (termios->c_cflag & PARENB) { + /* Mark or Space parity */ + if (termios->c_cflag & CMSPAR) { + if (termios->c_cflag & PARODD) + cval |= XUARTPS_MR_PARITY_MARK; + else + cval |= XUARTPS_MR_PARITY_SPACE; + } else if (termios->c_cflag & PARODD) + cval |= XUARTPS_MR_PARITY_ODD; + else + cval |= XUARTPS_MR_PARITY_EVEN; + } else + cval |= XUARTPS_MR_PARITY_NONE; + xuartps_writel(cval , XUARTPS_MR_OFFSET); + + spin_unlock_irqrestore(&port->lock, flags); +} + +/** + * xuartps_startup - Called when an application opens a xuartps port + * @port: Handle to the uart port structure + * + * Returns 0 on success, negative error otherwise + **/ +static int xuartps_startup(struct uart_port *port) +{ + unsigned int retval = 0, status = 0; + + retval = request_irq(port->irq, xuartps_isr, 0, XUARTPS_NAME, + (void *)port); + if (retval) + return retval; + + /* Disable the TX and RX */ + xuartps_writel(XUARTPS_CR_TX_DIS | XUARTPS_CR_RX_DIS, + XUARTPS_CR_OFFSET); + + /* Set the Control Register with TX/RX Enable, TX/RX Reset, + * no break chars. + */ + xuartps_writel(XUARTPS_CR_TXRST | XUARTPS_CR_RXRST, + XUARTPS_CR_OFFSET); + + status = xuartps_readl(XUARTPS_CR_OFFSET); + + /* Clear the RX disable and TX disable bits and then set the TX enable + * bit and RX enable bit to enable the transmitter and receiver. + */ + xuartps_writel((status & ~(XUARTPS_CR_TX_DIS | XUARTPS_CR_RX_DIS)) + | (XUARTPS_CR_TX_EN | XUARTPS_CR_RX_EN | + XUARTPS_CR_STOPBRK), XUARTPS_CR_OFFSET); + + /* Set the Mode Register with normal mode,8 data bits,1 stop bit, + * no parity. + */ + xuartps_writel(XUARTPS_MR_CHMODE_NORM | XUARTPS_MR_STOPMODE_1_BIT + | XUARTPS_MR_PARITY_NONE | XUARTPS_MR_CHARLEN_8_BIT, + XUARTPS_MR_OFFSET); + + /* Set the RX FIFO Trigger level to 14 assuming FIFO size as 16 */ + xuartps_writel(14, XUARTPS_RXWM_OFFSET); + + /* Receive Timeout register is enabled with value of 10 */ + xuartps_writel(10, XUARTPS_RXTOUT_OFFSET); + + + /* Set the Interrupt Registers with desired interrupts */ + xuartps_writel(XUARTPS_IXR_TXEMPTY | XUARTPS_IXR_PARITY | + XUARTPS_IXR_FRAMING | XUARTPS_IXR_OVERRUN | + XUARTPS_IXR_RXTRIG | XUARTPS_IXR_TOUT, XUARTPS_IER_OFFSET); + xuartps_writel(~(XUARTPS_IXR_TXEMPTY | XUARTPS_IXR_PARITY | + XUARTPS_IXR_FRAMING | XUARTPS_IXR_OVERRUN | + XUARTPS_IXR_RXTRIG | XUARTPS_IXR_TOUT), XUARTPS_IDR_OFFSET); + + return retval; +} + +/** + * xuartps_shutdown - Called when an application closes a xuartps port + * @port: Handle to the uart port structure + * + **/ +static void xuartps_shutdown(struct uart_port *port) +{ + int status; + + /* Disable interrupts */ + status = xuartps_readl(XUARTPS_IMR_OFFSET); + xuartps_writel(status, XUARTPS_IDR_OFFSET); + + /* Disable the TX and RX */ + xuartps_writel(XUARTPS_CR_TX_DIS | XUARTPS_CR_RX_DIS, + XUARTPS_CR_OFFSET); + free_irq(port->irq, port); +} + +/** + * xuartps_type - Set UART type to xuartps port + * @port: Handle to the uart port structure + * + * Returns string on success, NULL otherwise + **/ +static const char *xuartps_type(struct uart_port *port) +{ + return port->type == PORT_XUARTPS ? XUARTPS_NAME : NULL; +} + +/** + * xuartps_verify_port - Verify the port params + * @port: Handle to the uart port structure + * @ser: Handle to the structure whose members are compared + * + * Returns 0 if success otherwise -EINVAL + **/ +static int xuartps_verify_port(struct uart_port *port, + struct serial_struct *ser) +{ + if (ser->type != PORT_UNKNOWN && ser->type != PORT_XUARTPS) + return -EINVAL; + if (port->irq != ser->irq) + return -EINVAL; + if (ser->io_type != UPIO_MEM) + return -EINVAL; + if (port->iobase != ser->port) + return -EINVAL; + if (ser->hub6 != 0) + return -EINVAL; + return 0; +} + +/** + * xuartps_request_port - Claim the memory region attached to xuartps port, + * called when the driver adds a xuartps port via + * uart_add_one_port() + * @port: Handle to the uart port structure + * + * Returns 0, -ENOMEM if request fails + **/ +static int xuartps_request_port(struct uart_port *port) +{ + if (!request_mem_region(port->mapbase, XUARTPS_REGISTER_SPACE, + XUARTPS_NAME)) { + return -ENOMEM; + } + + port->membase = ioremap(port->mapbase, XUARTPS_REGISTER_SPACE); + if (!port->membase) { + dev_err(port->dev, "Unable to map registers\n"); + release_mem_region(port->mapbase, XUARTPS_REGISTER_SPACE); + return -ENOMEM; + } + return 0; +} + +/** + * xuartps_release_port - Release the memory region attached to a xuartps + * port, called when the driver removes a xuartps + * port via uart_remove_one_port(). + * @port: Handle to the uart port structure + * + **/ +static void xuartps_release_port(struct uart_port *port) +{ + release_mem_region(port->mapbase, XUARTPS_REGISTER_SPACE); + iounmap(port->membase); + port->membase = NULL; +} + +/** + * xuartps_config_port - Configure xuartps, called when the driver adds a + * xuartps port + * @port: Handle to the uart port structure + * @flags: If any + * + **/ +static void xuartps_config_port(struct uart_port *port, int flags) +{ + if (flags & UART_CONFIG_TYPE && xuartps_request_port(port) == 0) + port->type = PORT_XUARTPS; +} + +/** + * xuartps_get_mctrl - Get the modem control state + * + * @port: Handle to the uart port structure + * + * Returns the modem control state + * + **/ +static unsigned int xuartps_get_mctrl(struct uart_port *port) +{ + return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; +} + +static void xuartps_set_mctrl(struct uart_port *port, unsigned int mctrl) +{ + /* N/A */ +} + +static void xuartps_enable_ms(struct uart_port *port) +{ + /* N/A */ +} + +/** The UART operations structure + */ +static struct uart_ops xuartps_ops = { + .set_mctrl = xuartps_set_mctrl, + .get_mctrl = xuartps_get_mctrl, + .enable_ms = xuartps_enable_ms, + + .start_tx = xuartps_start_tx, /* Start transmitting */ + .stop_tx = xuartps_stop_tx, /* Stop transmission */ + .stop_rx = xuartps_stop_rx, /* Stop reception */ + .tx_empty = xuartps_tx_empty, /* Transmitter busy? */ + .break_ctl = xuartps_break_ctl, /* Start/stop + * transmitting break + */ + .set_termios = xuartps_set_termios, /* Set termios */ + .startup = xuartps_startup, /* App opens xuartps */ + .shutdown = xuartps_shutdown, /* App closes xuartps */ + .type = xuartps_type, /* Set UART type */ + .verify_port = xuartps_verify_port, /* Verification of port + * params + */ + .request_port = xuartps_request_port, /* Claim resources + * associated with a + * xuartps port + */ + .release_port = xuartps_release_port, /* Release resources + * associated with a + * xuartps port + */ + .config_port = xuartps_config_port, /* Configure when driver + * adds a xuartps port + */ +}; + +static struct uart_port xuartps_port[2]; + +/** + * xuartps_get_port - Configure the port from the platform device resource + * info + * + * Returns a pointer to a uart_port or NULL for failure + **/ +static struct uart_port *xuartps_get_port(void) +{ + struct uart_port *port; + int id; + + /* Find the next unused port */ + for (id = 0; id < XUARTPS_NR_PORTS; id++) + if (xuartps_port[id].mapbase == 0) + break; + + if (id >= XUARTPS_NR_PORTS) + return NULL; + + port = &xuartps_port[id]; + + /* At this point, we've got an empty uart_port struct, initialize it */ + spin_lock_init(&port->lock); + port->membase = NULL; + port->iobase = 1; /* mark port in use */ + port->irq = 0; + port->type = PORT_UNKNOWN; + port->iotype = UPIO_MEM32; + port->flags = UPF_BOOT_AUTOCONF; + port->ops = &xuartps_ops; + port->fifosize = XUARTPS_FIFO_SIZE; + port->line = id; + port->dev = NULL; + return port; +} + +/*-----------------------Console driver operations--------------------------*/ + +#ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE +/** + * xuartps_console_wait_tx - Wait for the TX to be full + * @port: Handle to the uart port structure + * + **/ +static void xuartps_console_wait_tx(struct uart_port *port) +{ + while ((xuartps_readl(XUARTPS_SR_OFFSET) & XUARTPS_SR_TXEMPTY) + != XUARTPS_SR_TXEMPTY) + barrier(); +} + +/** + * xuartps_console_putchar - write the character to the FIFO buffer + * @port: Handle to the uart port structure + * @ch: Character to be written + * + **/ +static void xuartps_console_putchar(struct uart_port *port, int ch) +{ + xuartps_console_wait_tx(port); + xuartps_writel(ch, XUARTPS_FIFO_OFFSET); +} + +/** + * xuartps_console_write - perform write operation + * @port: Handle to the uart port structure + * @s: Pointer to character array + * @count: No of characters + **/ +static void xuartps_console_write(struct console *co, const char *s, + unsigned int count) +{ + struct uart_port *port = &xuartps_port[co->index]; + unsigned long flags; + unsigned int imr; + int locked = 1; + + if (oops_in_progress) + locked = spin_trylock_irqsave(&port->lock, flags); + else + spin_lock_irqsave(&port->lock, flags); + + /* save and disable interrupt */ + imr = xuartps_readl(XUARTPS_IMR_OFFSET); + xuartps_writel(imr, XUARTPS_IDR_OFFSET); + + uart_console_write(port, s, count, xuartps_console_putchar); + xuartps_console_wait_tx(port); + + /* restore interrupt state, it seems like there may be a h/w bug + * in that the interrupt enable register should not need to be + * written based on the data sheet + */ + xuartps_writel(~imr, XUARTPS_IDR_OFFSET); + xuartps_writel(imr, XUARTPS_IER_OFFSET); + + if (locked) + spin_unlock_irqrestore(&port->lock, flags); +} + +/** + * xuartps_console_setup - Initialize the uart to default config + * @co: Console handle + * @options: Initial settings of uart + * + * Returns 0, -ENODEV if no device + **/ +static int __init xuartps_console_setup(struct console *co, char *options) +{ + struct uart_port *port = &xuartps_port[co->index]; + int baud = 9600; + int bits = 8; + int parity = 'n'; + int flow = 'n'; + + if (co->index < 0 || co->index >= XUARTPS_NR_PORTS) + return -EINVAL; + + if (!port->mapbase) { + pr_debug("console on ttyPS%i not present\n", co->index); + return -ENODEV; + } + + if (options) + uart_parse_options(options, &baud, &parity, &bits, &flow); + + return uart_set_options(port, co, baud, parity, bits, flow); +} + +static struct uart_driver xuartps_uart_driver; + +static struct console xuartps_console = { + .name = XUARTPS_TTY_NAME, + .write = xuartps_console_write, + .device = uart_console_device, + .setup = xuartps_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, /* Specified on the cmdline (e.g. console=ttyPS ) */ + .data = &xuartps_uart_driver, +}; + +/** + * xuartps_console_init - Initialization call + * + * Returns 0 on success, negative error otherwise + **/ +static int __init xuartps_console_init(void) +{ + register_console(&xuartps_console); + return 0; +} + +console_initcall(xuartps_console_init); + +#endif /* CONFIG_SERIAL_XILINX_PS_UART_CONSOLE */ + +/** Structure Definitions + */ +static struct uart_driver xuartps_uart_driver = { + .owner = THIS_MODULE, /* Owner */ + .driver_name = XUARTPS_NAME, /* Driver name */ + .dev_name = XUARTPS_TTY_NAME, /* Node name */ + .major = XUARTPS_MAJOR, /* Major number */ + .minor = XUARTPS_MINOR, /* Minor number */ + .nr = XUARTPS_NR_PORTS, /* Number of UART ports */ +#ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE + .cons = &xuartps_console, /* Console */ +#endif +}; + +/* --------------------------------------------------------------------- + * Platform bus binding + */ +/** + * xuartps_probe - Platform driver probe + * @pdev: Pointer to the platform device structure + * + * Returns 0 on success, negative error otherwise + **/ +static int __devinit xuartps_probe(struct platform_device *pdev) +{ + int rc; + struct uart_port *port; + struct resource *res, *res2; + int clk = 0; + +#ifdef CONFIG_OF + const unsigned int *prop; + + prop = of_get_property(pdev->dev.of_node, "clock", NULL); + if (prop) + clk = be32_to_cpup(prop); +#else + clk = *((unsigned int *)(pdev->dev.platform_data)); +#endif + if (!clk) { + dev_err(&pdev->dev, "no clock specified\n"); + return -ENODEV; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + + res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!res2) + return -ENODEV; + + /* Initialize the port structure */ + port = xuartps_get_port(); + + if (!port) { + dev_err(&pdev->dev, "Cannot get uart_port structure\n"); + return -ENODEV; + } else { + /* Register the port. + * This function also registers this device with the tty layer + * and triggers invocation of the config_port() entry point. + */ + port->mapbase = res->start; + port->irq = res2->start; + port->dev = &pdev->dev; + port->uartclk = clk; + dev_set_drvdata(&pdev->dev, port); + rc = uart_add_one_port(&xuartps_uart_driver, port); + if (rc) { + dev_err(&pdev->dev, + "uart_add_one_port() failed; err=%i\n", rc); + dev_set_drvdata(&pdev->dev, NULL); + return rc; + } + return 0; + } +} + +/** + * xuartps_remove - called when the platform driver is unregistered + * @pdev: Pointer to the platform device structure + * + * Returns 0 on success, negative error otherwise + **/ +static int __devexit xuartps_remove(struct platform_device *pdev) +{ + struct uart_port *port = dev_get_drvdata(&pdev->dev); + int rc = 0; + + /* Remove the xuartps port from the serial core */ + if (port) { + rc = uart_remove_one_port(&xuartps_uart_driver, port); + dev_set_drvdata(&pdev->dev, NULL); + port->mapbase = 0; + } + return rc; +} + +/** + * xuartps_suspend - suspend event + * @pdev: Pointer to the platform device structure + * @state: State of the device + * + * Returns 0 + **/ +static int xuartps_suspend(struct platform_device *pdev, pm_message_t state) +{ + /* Call the API provided in serial_core.c file which handles + * the suspend. + */ + uart_suspend_port(&xuartps_uart_driver, &xuartps_port[pdev->id]); + return 0; +} + +/** + * xuartps_resume - Resume after a previous suspend + * @pdev: Pointer to the platform device structure + * + * Returns 0 + **/ +static int xuartps_resume(struct platform_device *pdev) +{ + uart_resume_port(&xuartps_uart_driver, &xuartps_port[pdev->id]); + return 0; +} + +/* Match table for of_platform binding */ + +#ifdef CONFIG_OF +static struct of_device_id xuartps_of_match[] __devinitdata = { + { .compatible = "xlnx,xuartps", }, + {} +}; +MODULE_DEVICE_TABLE(of, xuartps_of_match); +#else +#define xuartps_of_match NULL +#endif + +static struct platform_driver xuartps_platform_driver = { + .probe = xuartps_probe, /* Probe method */ + .remove = __exit_p(xuartps_remove), /* Detach method */ + .suspend = xuartps_suspend, /* Suspend */ + .resume = xuartps_resume, /* Resume after a suspend */ + .driver = { + .owner = THIS_MODULE, + .name = XUARTPS_NAME, /* Driver name */ + .of_match_table = xuartps_of_match, + }, +}; + +/* --------------------------------------------------------------------- + * Module Init and Exit + */ +/** + * xuartps_init - Initial driver registration call + * + * Returns whether the registration was successful or not + **/ +static int __init xuartps_init(void) +{ + int retval = 0; + + /* Register the xuartps driver with the serial core */ + retval = uart_register_driver(&xuartps_uart_driver); + if (retval) + return retval; + + /* Register the platform driver */ + retval = platform_driver_register(&xuartps_platform_driver); + if (retval) + uart_unregister_driver(&xuartps_uart_driver); + + return retval; +} + +/** + * xuartps_exit - Driver unregistration call + **/ +static void __exit xuartps_exit(void) +{ + /* The order of unregistration is important. Unregister the + * UART driver before the platform driver crashes the system. + */ + + /* Unregister the platform driver */ + platform_driver_unregister(&xuartps_platform_driver); + + /* Unregister the xuartps driver */ + uart_unregister_driver(&xuartps_uart_driver); +} + +module_init(xuartps_init); +module_exit(xuartps_exit); + +MODULE_DESCRIPTION("Driver for PS UART"); +MODULE_AUTHOR("Xilinx Inc."); +MODULE_LICENSE("GPL"); diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 758c5b0c6fd3..95d479ba514e 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -202,6 +202,9 @@ /* VIA VT8500 SoC */ #define PORT_VT8500 97 +/* Xilinx PSS UART */ +#define PORT_XUARTPS 98 + #ifdef __KERNEL__ #include -- cgit From c430131a02d677aa708f56342c1565edfdacb3c0 Mon Sep 17 00:00:00 2001 From: Jan Andersson Date: Tue, 3 May 2011 20:11:57 +0200 Subject: USB: EHCI: Support controllers with big endian capability regs The two first HC capability registers (CAPLENGTH and HCIVERSION) are defined as one 8-bit and one 16-bit register. Most HC implementations have selected to treat these registers as part of a 32-bit register, giving the same layout for both big and small endian systems. This patch adds a new quirk, big_endian_capbase, to support controllers with big endian register interfaces that treat HCIVERSION and CAPLENGTH as individual registers. Signed-off-by: Jan Andersson Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/early/ehci-dbgp.c | 5 ++++- drivers/usb/host/ehci-ath79.c | 8 ++++---- drivers/usb/host/ehci-atmel.c | 2 +- drivers/usb/host/ehci-au1xxx.c | 3 ++- drivers/usb/host/ehci-cns3xxx.c | 2 +- drivers/usb/host/ehci-dbg.c | 2 +- drivers/usb/host/ehci-fsl.c | 2 +- drivers/usb/host/ehci-hcd.c | 2 +- drivers/usb/host/ehci-ixp4xx.c | 2 +- drivers/usb/host/ehci-msm.c | 2 +- drivers/usb/host/ehci-mxc.c | 2 +- drivers/usb/host/ehci-octeon.c | 2 +- drivers/usb/host/ehci-omap.c | 2 +- drivers/usb/host/ehci-orion.c | 2 +- drivers/usb/host/ehci-pci.c | 2 +- drivers/usb/host/ehci-pmcmsp.c | 2 +- drivers/usb/host/ehci-ppc-of.c | 2 +- drivers/usb/host/ehci-ps3.c | 2 +- drivers/usb/host/ehci-s5p.c | 3 ++- drivers/usb/host/ehci-sh.c | 2 +- drivers/usb/host/ehci-spear.c | 2 +- drivers/usb/host/ehci-tegra.c | 2 +- drivers/usb/host/ehci-vt8500.c | 3 ++- drivers/usb/host/ehci-w90x900.c | 2 +- drivers/usb/host/ehci-xilinx-of.c | 2 +- drivers/usb/host/ehci.h | 7 +++++++ include/linux/usb/ehci_def.h | 9 +++++++-- 27 files changed, 48 insertions(+), 30 deletions(-) (limited to 'include/linux') diff --git a/drivers/usb/early/ehci-dbgp.c b/drivers/usb/early/ehci-dbgp.c index a6a350f5827b..1fc8f1249806 100644 --- a/drivers/usb/early/ehci-dbgp.c +++ b/drivers/usb/early/ehci-dbgp.c @@ -102,6 +102,9 @@ static struct kgdb_io kgdbdbgp_io_ops; #define dbgp_kgdb_mode (0) #endif +/* Local version of HC_LENGTH macro as ehci struct is not available here */ +#define EARLY_HC_LENGTH(p) (0x00ff & (p)) /* bits 7 : 0 */ + /* * USB Packet IDs (PIDs) */ @@ -892,7 +895,7 @@ int __init early_dbgp_init(char *s) dbgp_printk("ehci_bar: %p\n", ehci_bar); ehci_caps = ehci_bar; - ehci_regs = ehci_bar + HC_LENGTH(readl(&ehci_caps->hc_capbase)); + ehci_regs = ehci_bar + EARLY_HC_LENGTH(readl(&ehci_caps->hc_capbase)); ehci_debug = ehci_bar + offset; ehci_dev.bus = bus; ehci_dev.slot = slot; diff --git a/drivers/usb/host/ehci-ath79.c b/drivers/usb/host/ehci-ath79.c index 7ea23b50f5d8..98cc8a13169c 100644 --- a/drivers/usb/host/ehci-ath79.c +++ b/drivers/usb/host/ehci-ath79.c @@ -44,6 +44,7 @@ static int ehci_ath79_init(struct usb_hcd *hcd) struct ehci_hcd *ehci = hcd_to_ehci(hcd); struct platform_device *pdev = to_platform_device(hcd->self.controller); const struct platform_device_id *id; + int hclength; int ret; id = platform_get_device_id(pdev); @@ -52,21 +53,20 @@ static int ehci_ath79_init(struct usb_hcd *hcd) return -EINVAL; } + hclength = HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); switch (id->driver_data) { case EHCI_ATH79_IP_V1: ehci->has_synopsys_hc_bug = 1; ehci->caps = hcd->regs; - ehci->regs = hcd->regs + - HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); + ehci->regs = hcd->regs + hclength; break; case EHCI_ATH79_IP_V2: hcd->has_tt = 1; ehci->caps = hcd->regs + 0x100; - ehci->regs = hcd->regs + 0x100 + - HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); + ehci->regs = hcd->regs + 0x100 + hclength; break; default: diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c index b2ed55cb811d..a5a3ef1f0096 100644 --- a/drivers/usb/host/ehci-atmel.c +++ b/drivers/usb/host/ehci-atmel.c @@ -56,7 +56,7 @@ static int ehci_atmel_setup(struct usb_hcd *hcd) /* registers start at offset 0x0 */ ehci->caps = hcd->regs; ehci->regs = hcd->regs + - HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); + HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); dbg_hcs_params(ehci, "reset"); dbg_hcc_params(ehci, "reset"); diff --git a/drivers/usb/host/ehci-au1xxx.c b/drivers/usb/host/ehci-au1xxx.c index a869e3c103d3..40b002869ac2 100644 --- a/drivers/usb/host/ehci-au1xxx.c +++ b/drivers/usb/host/ehci-au1xxx.c @@ -175,7 +175,8 @@ static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev) ehci = hcd_to_ehci(hcd); ehci->caps = hcd->regs; - ehci->regs = hcd->regs + HC_LENGTH(readl(&ehci->caps->hc_capbase)); + ehci->regs = hcd->regs + + HC_LENGTH(ehci, readl(&ehci->caps->hc_capbase)); /* cache this readonly data; minimize chip reads */ ehci->hcs_params = readl(&ehci->caps->hcs_params); diff --git a/drivers/usb/host/ehci-cns3xxx.c b/drivers/usb/host/ehci-cns3xxx.c index 708a05b5d258..d41745c6f0c4 100644 --- a/drivers/usb/host/ehci-cns3xxx.c +++ b/drivers/usb/host/ehci-cns3xxx.c @@ -34,7 +34,7 @@ static int cns3xxx_ehci_init(struct usb_hcd *hcd) ehci->caps = hcd->regs; ehci->regs = hcd->regs - + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); + + HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); hcd->has_tt = 0; diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c index 693c29b30521..40a844c1dbb4 100644 --- a/drivers/usb/host/ehci-dbg.c +++ b/drivers/usb/host/ehci-dbg.c @@ -726,7 +726,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf) } /* Capability Registers */ - i = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase)); + i = HC_VERSION(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); temp = scnprintf (next, size, "bus %s, device %s\n" "%s\n" diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 623732a312dd..f380bf97e5af 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -324,7 +324,7 @@ static int ehci_fsl_setup(struct usb_hcd *hcd) /* EHCI registers start at offset 0x100 */ ehci->caps = hcd->regs + 0x100; ehci->regs = hcd->regs + 0x100 + - HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); + HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); dbg_hcs_params(ehci, "reset"); dbg_hcc_params(ehci, "reset"); diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 83b7d5f02a15..8164ffafd10a 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -739,7 +739,7 @@ static int ehci_run (struct usb_hcd *hcd) up_write(&ehci_cf_port_reset_rwsem); ehci->last_periodic_enable = ktime_get_real(); - temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase)); + temp = HC_VERSION(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); ehci_info (ehci, "USB %x.%x started, EHCI %x.%02x%s\n", ((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f), diff --git a/drivers/usb/host/ehci-ixp4xx.c b/drivers/usb/host/ehci-ixp4xx.c index 89b7c70c6ed6..50e600d26e28 100644 --- a/drivers/usb/host/ehci-ixp4xx.c +++ b/drivers/usb/host/ehci-ixp4xx.c @@ -23,7 +23,7 @@ static int ixp4xx_ehci_init(struct usb_hcd *hcd) ehci->caps = hcd->regs + 0x100; ehci->regs = hcd->regs + 0x100 - + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); + + HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); hcd->has_tt = 1; diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c index 9ce1b0bc186d..b5a0bf649c95 100644 --- a/drivers/usb/host/ehci-msm.c +++ b/drivers/usb/host/ehci-msm.c @@ -41,7 +41,7 @@ static int ehci_msm_reset(struct usb_hcd *hcd) ehci->caps = USB_CAPLENGTH; ehci->regs = USB_CAPLENGTH + - HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); + HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); dbg_hcs_params(ehci, "reset"); dbg_hcc_params(ehci, "reset"); diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c index 25c8c10bb689..0c058be35a38 100644 --- a/drivers/usb/host/ehci-mxc.c +++ b/drivers/usb/host/ehci-mxc.c @@ -208,7 +208,7 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) /* EHCI registers start at offset 0x100 */ ehci->caps = hcd->regs + 0x100; ehci->regs = hcd->regs + 0x100 + - HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); + HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); /* set up the PORTSCx register */ ehci_writel(ehci, pdata->portsc, &ehci->regs->port_status[0]); diff --git a/drivers/usb/host/ehci-octeon.c b/drivers/usb/host/ehci-octeon.c index a31a031178a8..ff55757ba7d8 100644 --- a/drivers/usb/host/ehci-octeon.c +++ b/drivers/usb/host/ehci-octeon.c @@ -151,7 +151,7 @@ static int ehci_octeon_drv_probe(struct platform_device *pdev) ehci->caps = hcd->regs; ehci->regs = hcd->regs + - HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); + HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); /* cache this readonly data; minimize chip reads */ ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index 7e41a95c5ceb..3c482dc99ece 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -188,7 +188,7 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) /* we know this is the memory we want, no need to ioremap again */ omap_ehci->caps = hcd->regs; omap_ehci->regs = hcd->regs - + HC_LENGTH(readl(&omap_ehci->caps->hc_capbase)); + + HC_LENGTH(ehci, readl(&omap_ehci->caps->hc_capbase)); dbg_hcs_params(omap_ehci, "reset"); dbg_hcc_params(omap_ehci, "reset"); diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c index 281e094e1c18..395bdb0248d5 100644 --- a/drivers/usb/host/ehci-orion.c +++ b/drivers/usb/host/ehci-orion.c @@ -251,7 +251,7 @@ static int __devinit ehci_orion_drv_probe(struct platform_device *pdev) ehci = hcd_to_ehci(hcd); ehci->caps = hcd->regs + 0x100; ehci->regs = hcd->regs + 0x100 + - HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); + HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); hcd->has_tt = 1; ehci->sbrn = 0x20; diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index d5eaea7caf89..660b80a75cac 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -70,7 +70,7 @@ static int ehci_pci_setup(struct usb_hcd *hcd) ehci->caps = hcd->regs; ehci->regs = hcd->regs + - HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); + HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); dbg_hcs_params(ehci, "reset"); dbg_hcc_params(ehci, "reset"); diff --git a/drivers/usb/host/ehci-pmcmsp.c b/drivers/usb/host/ehci-pmcmsp.c index a2168642175b..cd69099cda19 100644 --- a/drivers/usb/host/ehci-pmcmsp.c +++ b/drivers/usb/host/ehci-pmcmsp.c @@ -83,7 +83,7 @@ static int ehci_msp_setup(struct usb_hcd *hcd) ehci->caps = hcd->regs; ehci->regs = hcd->regs + - HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); + HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); dbg_hcs_params(ehci, "reset"); dbg_hcc_params(ehci, "reset"); diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c index 1f09f253697e..8552db6c29c9 100644 --- a/drivers/usb/host/ehci-ppc-of.c +++ b/drivers/usb/host/ehci-ppc-of.c @@ -179,7 +179,7 @@ static int __devinit ehci_hcd_ppc_of_probe(struct platform_device *op) ehci->caps = hcd->regs; ehci->regs = hcd->regs + - HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); + HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); /* cache this readonly data; minimize chip reads */ ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c index 1dee33b9139e..64626a777d61 100644 --- a/drivers/usb/host/ehci-ps3.c +++ b/drivers/usb/host/ehci-ps3.c @@ -29,7 +29,7 @@ static int ps3_ehci_hc_reset(struct usb_hcd *hcd) ehci->big_endian_mmio = 1; ehci->caps = hcd->regs; - ehci->regs = hcd->regs + HC_LENGTH(ehci_readl(ehci, + ehci->regs = hcd->regs + HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); dbg_hcs_params(ehci, "reset"); diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c index 0c18f280bf4c..321a03301ad2 100644 --- a/drivers/usb/host/ehci-s5p.c +++ b/drivers/usb/host/ehci-s5p.c @@ -126,7 +126,8 @@ static int s5p_ehci_probe(struct platform_device *pdev) ehci = hcd_to_ehci(hcd); ehci->caps = hcd->regs; - ehci->regs = hcd->regs + HC_LENGTH(readl(&ehci->caps->hc_capbase)); + ehci->regs = hcd->regs + + HC_LENGTH(ehci, readl(&ehci->caps->hc_capbase)); dbg_hcs_params(ehci, "reset"); dbg_hcc_params(ehci, "reset"); diff --git a/drivers/usb/host/ehci-sh.c b/drivers/usb/host/ehci-sh.c index 595f70f42b52..86a95bb80a61 100644 --- a/drivers/usb/host/ehci-sh.c +++ b/drivers/usb/host/ehci-sh.c @@ -23,7 +23,7 @@ static int ehci_sh_reset(struct usb_hcd *hcd) int ret; ehci->caps = hcd->regs; - ehci->regs = hcd->regs + HC_LENGTH(ehci_readl(ehci, + ehci->regs = hcd->regs + HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); dbg_hcs_params(ehci, "reset"); diff --git a/drivers/usb/host/ehci-spear.c b/drivers/usb/host/ehci-spear.c index 75c00873443d..dbf1e4ef3c17 100644 --- a/drivers/usb/host/ehci-spear.c +++ b/drivers/usb/host/ehci-spear.c @@ -38,7 +38,7 @@ static int ehci_spear_setup(struct usb_hcd *hcd) /* registers start at offset 0x0 */ ehci->caps = hcd->regs; - ehci->regs = hcd->regs + HC_LENGTH(ehci_readl(ehci, + ehci->regs = hcd->regs + HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); /* cache this readonly data; minimize chip reads */ ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 7359bcbe4176..02b2bfd49a10 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -400,7 +400,7 @@ static int tegra_ehci_setup(struct usb_hcd *hcd) /* EHCI registers start at offset 0x100 */ ehci->caps = hcd->regs + 0x100; ehci->regs = hcd->regs + 0x100 + - HC_LENGTH(readl(&ehci->caps->hc_capbase)); + HC_LENGTH(ehci, readl(&ehci->caps->hc_capbase)); dbg_hcs_params(ehci, "reset"); dbg_hcc_params(ehci, "reset"); diff --git a/drivers/usb/host/ehci-vt8500.c b/drivers/usb/host/ehci-vt8500.c index 20168062035a..47d749631bc7 100644 --- a/drivers/usb/host/ehci-vt8500.c +++ b/drivers/usb/host/ehci-vt8500.c @@ -121,7 +121,8 @@ static int vt8500_ehci_drv_probe(struct platform_device *pdev) ehci = hcd_to_ehci(hcd); ehci->caps = hcd->regs; - ehci->regs = hcd->regs + HC_LENGTH(readl(&ehci->caps->hc_capbase)); + ehci->regs = hcd->regs + + HC_LENGTH(ehci, readl(&ehci->caps->hc_capbase)); dbg_hcs_params(ehci, "reset"); dbg_hcc_params(ehci, "reset"); diff --git a/drivers/usb/host/ehci-w90x900.c b/drivers/usb/host/ehci-w90x900.c index 6bc35809a5c6..52a027aaa370 100644 --- a/drivers/usb/host/ehci-w90x900.c +++ b/drivers/usb/host/ehci-w90x900.c @@ -57,7 +57,7 @@ static int __devinit usb_w90x900_probe(const struct hc_driver *driver, ehci = hcd_to_ehci(hcd); ehci->caps = hcd->regs; ehci->regs = hcd->regs + - HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); + HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); /* enable PHY 0,1,the regs only apply to w90p910 * 0xA4,0xA8 were offsets of PHY0 and PHY1 controller of diff --git a/drivers/usb/host/ehci-xilinx-of.c b/drivers/usb/host/ehci-xilinx-of.c index effc58d7af8b..a64d6d66d760 100644 --- a/drivers/usb/host/ehci-xilinx-of.c +++ b/drivers/usb/host/ehci-xilinx-of.c @@ -220,7 +220,7 @@ static int __devinit ehci_hcd_xilinx_of_probe(struct platform_device *op) */ ehci->caps = hcd->regs + 0x100; ehci->regs = hcd->regs + 0x100 + - HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); + HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); /* cache this readonly data; minimize chip reads */ ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index e9ba8e252489..d0792f591590 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -128,6 +128,7 @@ struct ehci_hcd { /* one per controller */ unsigned has_fsl_port_bug:1; /* FreeScale */ unsigned big_endian_mmio:1; unsigned big_endian_desc:1; + unsigned big_endian_capbase:1; unsigned has_amcc_usb23:1; unsigned need_io_watchdog:1; unsigned broken_periodic:1; @@ -605,12 +606,18 @@ ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc) * This attempts to support either format at compile time without a * runtime penalty, or both formats with the additional overhead * of checking a flag bit. + * + * ehci_big_endian_capbase is a special quirk for controllers that + * implement the HC capability registers as separate registers and not + * as fields of a 32-bit register. */ #ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO #define ehci_big_endian_mmio(e) ((e)->big_endian_mmio) +#define ehci_big_endian_capbase(e) ((e)->big_endian_capbase) #else #define ehci_big_endian_mmio(e) 0 +#define ehci_big_endian_capbase(e) 0 #endif /* diff --git a/include/linux/usb/ehci_def.h b/include/linux/usb/ehci_def.h index 78799432008e..7cc95ee3606b 100644 --- a/include/linux/usb/ehci_def.h +++ b/include/linux/usb/ehci_def.h @@ -25,10 +25,15 @@ struct ehci_caps { /* these fields are specified as 8 and 16 bit registers, * but some hosts can't perform 8 or 16 bit PCI accesses. + * some hosts treat caplength and hciversion as parts of a 32-bit + * register, others treat them as two separate registers, this + * affects the memory map for big endian controllers. */ u32 hc_capbase; -#define HC_LENGTH(p) (((p)>>00)&0x00ff) /* bits 7:0 */ -#define HC_VERSION(p) (((p)>>16)&0xffff) /* bits 31:16 */ +#define HC_LENGTH(ehci, p) (0x00ff&((p) >> /* bits 7:0 / offset 00h */ \ + (ehci_big_endian_capbase(ehci) ? 24 : 0))) +#define HC_VERSION(ehci, p) (0xffff&((p) >> /* bits 31:16 / offset 02h */ \ + (ehci_big_endian_capbase(ehci) ? 0 : 16))) u32 hcs_params; /* HCSPARAMS - offset 0x4 */ #define HCS_DEBUG_PORT(p) (((p)>>20)&0xf) /* bits 23:20, debug port? */ #define HCS_INDICATOR(p) ((p)&(1 << 16)) /* true: has port indicators */ -- cgit From 57a503c61db077b923e23f36050c02166a4a1db2 Mon Sep 17 00:00:00 2001 From: Viresh KUMAR Date: Mon, 2 May 2011 18:36:45 +0000 Subject: net/stmmac: Move "#include " to linux/stmmac.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit stmmac.h uses struct platform_device and doesn't include . Whereas drivers/net/stmmac/stmmac.h includes it, but doesn't directly use it. And so we get following compilation warning while using this file: warning: ‘struct platform_device’ declared inside parameter list This patch includes in linux/stmmac.h and removes it from drivers/net/stmmac/stmmac.h Signed-off-by: Viresh Kumar Acked-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- drivers/net/stmmac/stmmac.h | 1 - include/linux/stmmac.h | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/drivers/net/stmmac/stmmac.h b/drivers/net/stmmac/stmmac.h index 5f06c4706abe..2b076b313622 100644 --- a/drivers/net/stmmac/stmmac.h +++ b/drivers/net/stmmac/stmmac.h @@ -21,7 +21,6 @@ *******************************************************************************/ #define DRV_MODULE_VERSION "Nov_2010" -#include #include #include "common.h" diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h index f29197a4b227..9529e49b0385 100644 --- a/include/linux/stmmac.h +++ b/include/linux/stmmac.h @@ -26,6 +26,8 @@ #ifndef __STMMAC_PLATFORM_DATA #define __STMMAC_PLATFORM_DATA +#include + /* platform data for platform device structure's platform_data field */ /* Private data for the STM on-board ethernet driver */ -- cgit From 99b38b4acc0d7dbbab443273577cff60080fcfad Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 6 Dec 2010 12:43:33 +1000 Subject: platform/x86: add MXM WMI driver. MXM is a laptop graphics card form-factor + interface specification, this adds an initial stub driver to talk to the MXM WMI interface. The only method used is the MUX switching method needed to do switchable graphics on the nvidia chipsets. Signed-off-by: Dave Airlie Acked-by: Matthew Garrett --- drivers/platform/x86/Kconfig | 7 ++++ drivers/platform/x86/Makefile | 1 + drivers/platform/x86/mxm-wmi.c | 85 ++++++++++++++++++++++++++++++++++++++++++ include/linux/mxm-wmi.h | 32 ++++++++++++++++ 4 files changed, 125 insertions(+) create mode 100644 drivers/platform/x86/mxm-wmi.c create mode 100644 include/linux/mxm-wmi.h (limited to 'include/linux') diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 0485e394712a..94914572dd7f 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -753,4 +753,11 @@ config SAMSUNG_LAPTOP To compile this driver as a module, choose M here: the module will be called samsung-laptop. +config MXM_WMI + tristate "WMI support for MXM Laptop Graphics" + depends on WMI + ---help--- + MXM is a standard for laptop graphics cards, the WMI interface + is required for switchable nvidia graphics machines + endif # X86_PLATFORM_DEVICES diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index 029e8861d086..a7ab3bc7b3a1 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile @@ -42,3 +42,4 @@ obj-$(CONFIG_XO15_EBOOK) += xo15-ebook.o obj-$(CONFIG_IBM_RTL) += ibm_rtl.o obj-$(CONFIG_SAMSUNG_LAPTOP) += samsung-laptop.o obj-$(CONFIG_INTEL_MFLD_THERMAL) += intel_mid_thermal.o +obj-$(CONFIG_MXM_WMI) += mxm-wmi.o diff --git a/drivers/platform/x86/mxm-wmi.c b/drivers/platform/x86/mxm-wmi.c new file mode 100644 index 000000000000..12b6f341e72b --- /dev/null +++ b/drivers/platform/x86/mxm-wmi.c @@ -0,0 +1,85 @@ +/* + * MXM WMI driver + * + * Copyright(C) 2010 Red Hat. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include + +MODULE_AUTHOR("Dave Airlie"); +MODULE_DESCRIPTION("MXM WMI Driver"); +MODULE_LICENSE("GPL"); + +#define MXM_WMMX_GUID "F6CB5C3C-9CAE-4EBD-B577-931EA32A2CC0" + +MODULE_ALIAS("wmi:"MXM_WMMX_GUID); + +#define MXM_WMMX_FUNC_MXDS 0x5344584D /* "MXDS" */ + +struct mxds_args { + u32 func; + u32 args; + u32 xarg; +}; + +int mxm_wmi_call_mxds(int adapter) +{ + struct mxds_args args = { + .func = MXM_WMMX_FUNC_MXDS, + .args = 0, + .xarg = 1, + }; + struct acpi_buffer input = { (acpi_size)sizeof(args), &args }; + struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; + acpi_status status; + + printk("calling mux switch %d\n", adapter); + + status = wmi_evaluate_method(MXM_WMMX_GUID, 0x1, adapter, &input, + &output); + + if (ACPI_FAILURE(status)) + return status; + + printk("mux switched %d\n", status); + return 0; + +} +EXPORT_SYMBOL_GPL(mxm_wmi_call_mxds); + +bool mxm_wmi_supported(void) +{ + bool guid_valid; + guid_valid = wmi_has_guid(MXM_WMMX_GUID); + return guid_valid; +} +EXPORT_SYMBOL_GPL(mxm_wmi_supported); + +static int __init mxm_wmi_init(void) +{ + return 0; +} + +static void __exit mxm_wmi_exit(void) +{ +} + +module_init(mxm_wmi_init); +module_exit(mxm_wmi_exit); diff --git a/include/linux/mxm-wmi.h b/include/linux/mxm-wmi.h new file mode 100644 index 000000000000..51359c0718bf --- /dev/null +++ b/include/linux/mxm-wmi.h @@ -0,0 +1,32 @@ +/* + * MXM WMI driver + * + * Copyright(C) 2010 Red Hat. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MXM_WMI_H +#define MXM_WMI_H + +/* discrete adapters */ +#define MXM_MXDS_ADAPTER_0 0x0 +#define MXM_MXDS_ADAPTER_1 0x0 +/* integrated adapter */ +#define MXM_MXDS_ADAPTER_IGD 0x10 +int mxm_wmi_call_mxds(int adapter); +bool mxm_wmi_supported(void); + +#endif -- cgit From 3448a19da479b6bd1e28e2a2be9fa16c6a6feb39 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 1 Jun 2010 15:32:24 +1000 Subject: vgaarb: use bridges to control VGA routing where possible. So in a lot of modern systems, a GPU will always be below a parent bridge that won't share with any other GPUs. This means VGA arbitration on those GPUs can be controlled by using the bridge routing instead of io/mem decodes. The problem is locating which GPUs share which upstream bridges. This patch attempts to identify all the GPUs which can be controlled via bridges, and ones that can't. This patch endeavours to work out the bridge sharing semantics. When disabling GPUs via a bridge, it doesn't do irq callbacks or touch the io/mem decodes for the gpu. Signed-off-by: Dave Airlie --- drivers/gpu/vga/vgaarb.c | 113 +++++++++++++++++++++++++++++++++++++++++------ drivers/pci/pci.c | 25 ++++++----- include/linux/pci.h | 7 ++- 3 files changed, 118 insertions(+), 27 deletions(-) (limited to 'include/linux') diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c index be8d4cb5861c..8a1021f2e319 100644 --- a/drivers/gpu/vga/vgaarb.c +++ b/drivers/gpu/vga/vgaarb.c @@ -61,7 +61,7 @@ struct vga_device { unsigned int mem_lock_cnt; /* legacy MEM lock count */ unsigned int io_norm_cnt; /* normal IO count */ unsigned int mem_norm_cnt; /* normal MEM count */ - + bool bridge_has_one_vga; /* allow IRQ enable/disable hook */ void *cookie; void (*irq_set_state)(void *cookie, bool enable); @@ -165,6 +165,8 @@ static struct vga_device *__vga_tryget(struct vga_device *vgadev, unsigned int wants, legacy_wants, match; struct vga_device *conflict; unsigned int pci_bits; + u32 flags = 0; + /* Account for "normal" resources to lock. If we decode the legacy, * counterpart, we need to request it as well */ @@ -237,16 +239,23 @@ static struct vga_device *__vga_tryget(struct vga_device *vgadev, /* looks like he doesn't have a lock, we can steal * them from him */ - vga_irq_set_state(conflict, false); + flags = 0; pci_bits = 0; - if (lwants & (VGA_RSRC_LEGACY_MEM|VGA_RSRC_NORMAL_MEM)) - pci_bits |= PCI_COMMAND_MEMORY; - if (lwants & (VGA_RSRC_LEGACY_IO|VGA_RSRC_NORMAL_IO)) - pci_bits |= PCI_COMMAND_IO; - pci_set_vga_state(conflict->pdev, false, pci_bits, - change_bridge); + if (!conflict->bridge_has_one_vga) { + vga_irq_set_state(conflict, false); + flags |= PCI_VGA_STATE_CHANGE_DECODES; + if (lwants & (VGA_RSRC_LEGACY_MEM|VGA_RSRC_NORMAL_MEM)) + pci_bits |= PCI_COMMAND_MEMORY; + if (lwants & (VGA_RSRC_LEGACY_IO|VGA_RSRC_NORMAL_IO)) + pci_bits |= PCI_COMMAND_IO; + } + + if (change_bridge) + flags |= PCI_VGA_STATE_CHANGE_BRIDGE; + + pci_set_vga_state(conflict->pdev, false, pci_bits, flags); conflict->owns &= ~lwants; /* If he also owned non-legacy, that is no longer the case */ if (lwants & VGA_RSRC_LEGACY_MEM) @@ -261,14 +270,24 @@ enable_them: * also have in "decodes". We can lock resources we don't decode but * not own them. */ + flags = 0; pci_bits = 0; - if (wants & (VGA_RSRC_LEGACY_MEM|VGA_RSRC_NORMAL_MEM)) - pci_bits |= PCI_COMMAND_MEMORY; - if (wants & (VGA_RSRC_LEGACY_IO|VGA_RSRC_NORMAL_IO)) - pci_bits |= PCI_COMMAND_IO; - pci_set_vga_state(vgadev->pdev, true, pci_bits, !!(wants & VGA_RSRC_LEGACY_MASK)); - vga_irq_set_state(vgadev, true); + if (!vgadev->bridge_has_one_vga) { + flags |= PCI_VGA_STATE_CHANGE_DECODES; + if (wants & (VGA_RSRC_LEGACY_MEM|VGA_RSRC_NORMAL_MEM)) + pci_bits |= PCI_COMMAND_MEMORY; + if (wants & (VGA_RSRC_LEGACY_IO|VGA_RSRC_NORMAL_IO)) + pci_bits |= PCI_COMMAND_IO; + } + if (!!(wants & VGA_RSRC_LEGACY_MASK)) + flags |= PCI_VGA_STATE_CHANGE_BRIDGE; + + pci_set_vga_state(vgadev->pdev, true, pci_bits, flags); + + if (!vgadev->bridge_has_one_vga) { + vga_irq_set_state(vgadev, true); + } vgadev->owns |= (wants & vgadev->decodes); lock_them: vgadev->locks |= (rsrc & VGA_RSRC_LEGACY_MASK); @@ -421,6 +440,62 @@ bail: } EXPORT_SYMBOL(vga_put); +/* Rules for using a bridge to control a VGA descendant decoding: + if a bridge has only one VGA descendant then it can be used + to control the VGA routing for that device. + It should always use the bridge closest to the device to control it. + If a bridge has a direct VGA descendant, but also have a sub-bridge + VGA descendant then we cannot use that bridge to control the direct VGA descendant. + So for every device we register, we need to iterate all its parent bridges + so we can invalidate any devices using them properly. +*/ +static void vga_arbiter_check_bridge_sharing(struct vga_device *vgadev) +{ + struct vga_device *same_bridge_vgadev; + struct pci_bus *new_bus, *bus; + struct pci_dev *new_bridge, *bridge; + + vgadev->bridge_has_one_vga = true; + + if (list_empty(&vga_list)) + return; + + /* okay iterate the new devices bridge hierarachy */ + new_bus = vgadev->pdev->bus; + while (new_bus) { + new_bridge = new_bus->self; + + if (new_bridge) { + /* go through list of devices already registered */ + list_for_each_entry(same_bridge_vgadev, &vga_list, list) { + bus = same_bridge_vgadev->pdev->bus; + bridge = bus->self; + + /* see if the share a bridge with this device */ + if (new_bridge == bridge) { + /* if their direct parent bridge is the same + as any bridge of this device then it can't be used + for that device */ + same_bridge_vgadev->bridge_has_one_vga = false; + } + + /* now iterate the previous devices bridge hierarchy */ + /* if the new devices parent bridge is in the other devices + hierarchy then we can't use it to control this device */ + while (bus) { + bridge = bus->self; + if (bridge) { + if (bridge == vgadev->pdev->bus->self) + vgadev->bridge_has_one_vga = false; + } + bus = bus->parent; + } + } + } + new_bus = new_bus->parent; + } +} + /* * Currently, we assume that the "initial" setup of the system is * not sane, that is we come up with conflicting devices and let @@ -500,6 +575,8 @@ static bool vga_arbiter_add_pci_device(struct pci_dev *pdev) vga_default = pci_dev_get(pdev); #endif + vga_arbiter_check_bridge_sharing(vgadev); + /* Add to the list */ list_add(&vgadev->list, &vga_list); vga_count++; @@ -1222,6 +1299,7 @@ static int __init vga_arb_device_init(void) { int rc; struct pci_dev *pdev; + struct vga_device *vgadev; rc = misc_register(&vga_arb_device); if (rc < 0) @@ -1238,6 +1316,13 @@ static int __init vga_arb_device_init(void) vga_arbiter_add_pci_device(pdev); pr_info("vgaarb: loaded\n"); + + list_for_each_entry(vgadev, &vga_list, list) { + if (vgadev->bridge_has_one_vga) + pr_info("vgaarb: bridge control possible %s\n", pci_name(vgadev->pdev)); + else + pr_info("vgaarb: no bridge control possible %s\n", pci_name(vgadev->pdev)); + } return rc; } subsys_initcall(vga_arb_device_init); diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 2472e7177b4b..a339237f4f96 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -2875,31 +2875,34 @@ static int pci_set_vga_state_arch(struct pci_dev *dev, bool decode, * @dev: the PCI device * @decode: true = enable decoding, false = disable decoding * @command_bits: PCI_COMMAND_IO and/or PCI_COMMAND_MEMORY - * @change_bridge: traverse ancestors and change bridges + * @change_bridge_flags: traverse ancestors and change bridges + * CHANGE_BRIDGE_ONLY / CHANGE_BRIDGE */ int pci_set_vga_state(struct pci_dev *dev, bool decode, - unsigned int command_bits, bool change_bridge) + unsigned int command_bits, u32 flags) { struct pci_bus *bus; struct pci_dev *bridge; u16 cmd; int rc; - WARN_ON(command_bits & ~(PCI_COMMAND_IO|PCI_COMMAND_MEMORY)); + WARN_ON((flags & PCI_VGA_STATE_CHANGE_DECODES) & (command_bits & ~(PCI_COMMAND_IO|PCI_COMMAND_MEMORY))); /* ARCH specific VGA enables */ - rc = pci_set_vga_state_arch(dev, decode, command_bits, change_bridge); + rc = pci_set_vga_state_arch(dev, decode, command_bits, flags); if (rc) return rc; - pci_read_config_word(dev, PCI_COMMAND, &cmd); - if (decode == true) - cmd |= command_bits; - else - cmd &= ~command_bits; - pci_write_config_word(dev, PCI_COMMAND, cmd); + if (flags & PCI_VGA_STATE_CHANGE_DECODES) { + pci_read_config_word(dev, PCI_COMMAND, &cmd); + if (decode == true) + cmd |= command_bits; + else + cmd &= ~command_bits; + pci_write_config_word(dev, PCI_COMMAND, cmd); + } - if (change_bridge == false) + if (!(flags & PCI_VGA_STATE_CHANGE_BRIDGE)) return 0; bus = dev->bus; diff --git a/include/linux/pci.h b/include/linux/pci.h index 96f70d7e058d..f2e57b2e6a81 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -915,8 +915,11 @@ int pci_cfg_space_size_ext(struct pci_dev *dev); int pci_cfg_space_size(struct pci_dev *dev); unsigned char pci_bus_max_busnr(struct pci_bus *bus); +#define PCI_VGA_STATE_CHANGE_BRIDGE (1 << 0) +#define PCI_VGA_STATE_CHANGE_DECODES (1 << 1) + int pci_set_vga_state(struct pci_dev *pdev, bool decode, - unsigned int command_bits, bool change_bridge); + unsigned int command_bits, u32 flags); /* kmem_cache style wrapper around pci_alloc_consistent() */ #include @@ -1061,7 +1064,7 @@ static inline int pci_proc_domain(struct pci_bus *bus) /* some architectures require additional setup to direct VGA traffic */ typedef int (*arch_set_vga_state_t)(struct pci_dev *pdev, bool decode, - unsigned int command_bits, bool change_bridge); + unsigned int command_bits, u32 flags); extern void pci_register_set_vga_state(arch_set_vga_state_t func); #else /* CONFIG_PCI is not enabled */ -- cgit From e7e7ee2eab2080248084d71fe0a115ab745eb2aa Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 4 May 2011 08:42:29 +0200 Subject: perf events: Clean up definitions and initializers, update copyrights Fix a few inconsistent style bits that were added over the past few months. Cc: Peter Zijlstra Link: http://lkml.kernel.org/n/tip-yv4hwf9yhnzoada8pcpb3a97@git.kernel.org Signed-off-by: Ingo Molnar --- include/linux/perf_event.h | 96 +++++++++++++++++++++------------------------- kernel/events/core.c | 40 +++++++++---------- 2 files changed, 64 insertions(+), 72 deletions(-) (limited to 'include/linux') diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 9eec53d97370..207c16976a17 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -2,8 +2,8 @@ * Performance events: * * Copyright (C) 2008-2009, Thomas Gleixner - * Copyright (C) 2008-2009, Red Hat, Inc., Ingo Molnar - * Copyright (C) 2008-2009, Red Hat, Inc., Peter Zijlstra + * Copyright (C) 2008-2011, Red Hat, Inc., Ingo Molnar + * Copyright (C) 2008-2011, Red Hat, Inc., Peter Zijlstra * * Data type definitions, declarations, prototypes. * @@ -468,9 +468,9 @@ enum perf_callchain_context { PERF_CONTEXT_MAX = (__u64)-4095, }; -#define PERF_FLAG_FD_NO_GROUP (1U << 0) -#define PERF_FLAG_FD_OUTPUT (1U << 1) -#define PERF_FLAG_PID_CGROUP (1U << 2) /* pid=cgroup id, per-cpu mode only */ +#define PERF_FLAG_FD_NO_GROUP (1U << 0) +#define PERF_FLAG_FD_OUTPUT (1U << 1) +#define PERF_FLAG_PID_CGROUP (1U << 2) /* pid=cgroup id, per-cpu mode only */ #ifdef __KERNEL__ /* @@ -484,9 +484,9 @@ enum perf_callchain_context { #endif struct perf_guest_info_callbacks { - int (*is_in_guest) (void); - int (*is_user_mode) (void); - unsigned long (*get_guest_ip) (void); + int (*is_in_guest)(void); + int (*is_user_mode)(void); + unsigned long (*get_guest_ip)(void); }; #ifdef CONFIG_HAVE_HW_BREAKPOINT @@ -652,19 +652,19 @@ struct pmu { * Start the transaction, after this ->add() doesn't need to * do schedulability tests. */ - void (*start_txn) (struct pmu *pmu); /* optional */ + void (*start_txn) (struct pmu *pmu); /* optional */ /* * If ->start_txn() disabled the ->add() schedulability test * then ->commit_txn() is required to perform one. On success * the transaction is closed. On error the transaction is kept * open until ->cancel_txn() is called. */ - int (*commit_txn) (struct pmu *pmu); /* optional */ + int (*commit_txn) (struct pmu *pmu); /* optional */ /* * Will cancel the transaction, assumes ->del() is called * for each successful ->add() during the transaction. */ - void (*cancel_txn) (struct pmu *pmu); /* optional */ + void (*cancel_txn) (struct pmu *pmu); /* optional */ }; /** @@ -712,15 +712,15 @@ typedef void (*perf_overflow_handler_t)(struct perf_event *, int, struct pt_regs *regs); enum perf_group_flag { - PERF_GROUP_SOFTWARE = 0x1, + PERF_GROUP_SOFTWARE = 0x1, }; -#define SWEVENT_HLIST_BITS 8 -#define SWEVENT_HLIST_SIZE (1 << SWEVENT_HLIST_BITS) +#define SWEVENT_HLIST_BITS 8 +#define SWEVENT_HLIST_SIZE (1 << SWEVENT_HLIST_BITS) struct swevent_hlist { - struct hlist_head heads[SWEVENT_HLIST_SIZE]; - struct rcu_head rcu_head; + struct hlist_head heads[SWEVENT_HLIST_SIZE]; + struct rcu_head rcu_head; }; #define PERF_ATTACH_CONTEXT 0x01 @@ -733,13 +733,13 @@ struct swevent_hlist { * This is a per-cpu dynamically allocated data structure. */ struct perf_cgroup_info { - u64 time; - u64 timestamp; + u64 time; + u64 timestamp; }; struct perf_cgroup { - struct cgroup_subsys_state css; - struct perf_cgroup_info *info; /* timing info, one per cpu */ + struct cgroup_subsys_state css; + struct perf_cgroup_info *info; /* timing info, one per cpu */ }; #endif @@ -923,7 +923,7 @@ struct perf_event_context { /* * Number of contexts where an event can trigger: - * task, softirq, hardirq, nmi. + * task, softirq, hardirq, nmi. */ #define PERF_NR_CONTEXTS 4 @@ -1001,8 +1001,7 @@ struct perf_sample_data { struct perf_raw_record *raw; }; -static inline -void perf_sample_data_init(struct perf_sample_data *data, u64 addr) +static inline void perf_sample_data_init(struct perf_sample_data *data, u64 addr) { data->addr = addr; data->raw = NULL; @@ -1039,8 +1038,7 @@ extern struct jump_label_key perf_swevent_enabled[PERF_COUNT_SW_MAX]; extern void __perf_sw_event(u32, u64, int, struct pt_regs *, u64); #ifndef perf_arch_fetch_caller_regs -static inline void -perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip) { } +static inline void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip) { } #endif /* @@ -1080,8 +1078,7 @@ static inline void perf_event_task_sched_in(struct task_struct *task) __perf_event_task_sched_in(task); } -static inline -void perf_event_task_sched_out(struct task_struct *task, struct task_struct *next) +static inline void perf_event_task_sched_out(struct task_struct *task, struct task_struct *next) { perf_sw_event(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, 1, NULL, 0); @@ -1099,14 +1096,10 @@ extern void perf_event_fork(struct task_struct *tsk); /* Callchains */ DECLARE_PER_CPU(struct perf_callchain_entry, perf_callchain_entry); -extern void perf_callchain_user(struct perf_callchain_entry *entry, - struct pt_regs *regs); -extern void perf_callchain_kernel(struct perf_callchain_entry *entry, - struct pt_regs *regs); - +extern void perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs); +extern void perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs); -static inline void -perf_callchain_store(struct perf_callchain_entry *entry, u64 ip) +static inline void perf_callchain_store(struct perf_callchain_entry *entry, u64 ip) { if (entry->nr < PERF_MAX_STACK_DEPTH) entry->ip[entry->nr++] = ip; @@ -1142,9 +1135,9 @@ extern void perf_tp_event(u64 addr, u64 count, void *record, extern void perf_bp_event(struct perf_event *event, void *data); #ifndef perf_misc_flags -#define perf_misc_flags(regs) (user_mode(regs) ? PERF_RECORD_MISC_USER : \ - PERF_RECORD_MISC_KERNEL) -#define perf_instruction_pointer(regs) instruction_pointer(regs) +# define perf_misc_flags(regs) \ + (user_mode(regs) ? PERF_RECORD_MISC_USER : PERF_RECORD_MISC_KERNEL) +# define perf_instruction_pointer(regs) instruction_pointer(regs) #endif extern int perf_output_begin(struct perf_output_handle *handle, @@ -1179,9 +1172,9 @@ static inline void perf_bp_event(struct perf_event *event, void *data) { } static inline int perf_register_guest_info_callbacks -(struct perf_guest_info_callbacks *callbacks) { return 0; } +(struct perf_guest_info_callbacks *callbacks) { return 0; } static inline int perf_unregister_guest_info_callbacks -(struct perf_guest_info_callbacks *callbacks) { return 0; } +(struct perf_guest_info_callbacks *callbacks) { return 0; } static inline void perf_event_mmap(struct vm_area_struct *vma) { } static inline void perf_event_comm(struct task_struct *tsk) { } @@ -1194,23 +1187,22 @@ static inline void perf_event_disable(struct perf_event *event) { } static inline void perf_event_task_tick(void) { } #endif -#define perf_output_put(handle, x) \ - perf_output_copy((handle), &(x), sizeof(x)) +#define perf_output_put(handle, x) perf_output_copy((handle), &(x), sizeof(x)) /* * This has to have a higher priority than migration_notifier in sched.c. */ -#define perf_cpu_notifier(fn) \ -do { \ - static struct notifier_block fn##_nb __cpuinitdata = \ - { .notifier_call = fn, .priority = CPU_PRI_PERF }; \ - fn(&fn##_nb, (unsigned long)CPU_UP_PREPARE, \ - (void *)(unsigned long)smp_processor_id()); \ - fn(&fn##_nb, (unsigned long)CPU_STARTING, \ - (void *)(unsigned long)smp_processor_id()); \ - fn(&fn##_nb, (unsigned long)CPU_ONLINE, \ - (void *)(unsigned long)smp_processor_id()); \ - register_cpu_notifier(&fn##_nb); \ +#define perf_cpu_notifier(fn) \ +do { \ + static struct notifier_block fn##_nb __cpuinitdata = \ + { .notifier_call = fn, .priority = CPU_PRI_PERF }; \ + fn(&fn##_nb, (unsigned long)CPU_UP_PREPARE, \ + (void *)(unsigned long)smp_processor_id()); \ + fn(&fn##_nb, (unsigned long)CPU_STARTING, \ + (void *)(unsigned long)smp_processor_id()); \ + fn(&fn##_nb, (unsigned long)CPU_ONLINE, \ + (void *)(unsigned long)smp_processor_id()); \ + register_cpu_notifier(&fn##_nb); \ } while (0) #endif /* __KERNEL__ */ diff --git a/kernel/events/core.c b/kernel/events/core.c index 440bc485bbff..0fc34a370ba4 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -2,8 +2,8 @@ * Performance events core code: * * Copyright (C) 2008 Thomas Gleixner - * Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar - * Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra + * Copyright (C) 2008-2011 Red Hat, Inc., Ingo Molnar + * Copyright (C) 2008-2011 Red Hat, Inc., Peter Zijlstra * Copyright © 2009 Paul Mackerras, IBM Corp. * * For licensing details see kernel-base/COPYING @@ -39,10 +39,10 @@ #include struct remote_function_call { - struct task_struct *p; - int (*func)(void *info); - void *info; - int ret; + struct task_struct *p; + int (*func)(void *info); + void *info; + int ret; }; static void remote_function(void *data) @@ -76,10 +76,10 @@ static int task_function_call(struct task_struct *p, int (*func) (void *info), void *info) { struct remote_function_call data = { - .p = p, - .func = func, - .info = info, - .ret = -ESRCH, /* No such (running) process */ + .p = p, + .func = func, + .info = info, + .ret = -ESRCH, /* No such (running) process */ }; if (task_curr(p)) @@ -100,10 +100,10 @@ task_function_call(struct task_struct *p, int (*func) (void *info), void *info) static int cpu_function_call(int cpu, int (*func) (void *info), void *info) { struct remote_function_call data = { - .p = NULL, - .func = func, - .info = info, - .ret = -ENXIO, /* No such CPU */ + .p = NULL, + .func = func, + .info = info, + .ret = -ENXIO, /* No such CPU */ }; smp_call_function_single(cpu, remote_function, &data, 1); @@ -7445,11 +7445,11 @@ static void perf_cgroup_exit(struct cgroup_subsys *ss, struct cgroup *cgrp, } struct cgroup_subsys perf_subsys = { - .name = "perf_event", - .subsys_id = perf_subsys_id, - .create = perf_cgroup_create, - .destroy = perf_cgroup_destroy, - .exit = perf_cgroup_exit, - .attach = perf_cgroup_attach, + .name = "perf_event", + .subsys_id = perf_subsys_id, + .create = perf_cgroup_create, + .destroy = perf_cgroup_destroy, + .exit = perf_cgroup_exit, + .attach = perf_cgroup_attach, }; #endif /* CONFIG_CGROUP_PERF */ -- cgit From 2d06d8c49afdcc9bb35a85039fa50f0fe35bd40e Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 27 Mar 2011 15:04:46 +0200 Subject: [CPUFREQ] use dynamic debug instead of custom infrastructure With dynamic debug having gained the capability to report debug messages also during the boot process, it offers a far superior interface for debug messages than the custom cpufreq infrastructure. As a first step, remove the old cpufreq_debug_printk() function and replace it with a call to the generic pr_debug() function. How can dynamic debug be used on cpufreq? You need a kernel which has CONFIG_DYNAMIC_DEBUG enabled. To enabled debugging during runtime, mount debugfs and $ echo -n 'module cpufreq +p' > /sys/kernel/debug/dynamic_debug/control for debugging the complete "cpufreq" module. To achieve the same goal during boot, append ddebug_query="module cpufreq +p" as a boot parameter to the kernel of your choice. For more detailled instructions, please see Documentation/dynamic-debug-howto.txt Signed-off-by: Dominik Brodowski Signed-off-by: Dave Jones --- arch/arm/mach-davinci/cpufreq.c | 4 +- arch/blackfin/mach-common/dpmc.c | 3 - arch/ia64/kernel/cpufreq/acpi-cpufreq.c | 44 +++--- arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | 45 +++--- arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c | 6 +- arch/x86/kernel/cpu/cpufreq/gx-suspmod.c | 21 ++- arch/x86/kernel/cpu/cpufreq/longhaul.c | 11 +- arch/x86/kernel/cpu/cpufreq/longrun.c | 17 +-- arch/x86/kernel/cpu/cpufreq/p4-clockmod.c | 10 +- arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c | 47 +++--- arch/x86/kernel/cpu/cpufreq/powernow-k7.c | 33 ++--- arch/x86/kernel/cpu/cpufreq/powernow-k8.c | 100 ++++++------- arch/x86/kernel/cpu/cpufreq/powernow-k8.h | 2 - arch/x86/kernel/cpu/cpufreq/sc520_freq.c | 6 +- arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c | 23 ++- arch/x86/kernel/cpu/cpufreq/speedstep-ich.c | 28 ++-- arch/x86/kernel/cpu/cpufreq/speedstep-lib.c | 43 +++--- arch/x86/kernel/cpu/cpufreq/speedstep-smi.c | 41 +++--- drivers/acpi/processor_perflib.c | 6 +- drivers/cpufreq/Kconfig | 13 -- drivers/cpufreq/cpufreq.c | 180 +++++------------------ drivers/cpufreq/cpufreq_performance.c | 5 +- drivers/cpufreq/cpufreq_powersave.c | 5 +- drivers/cpufreq/cpufreq_userspace.c | 13 +- drivers/cpufreq/freq_table.c | 19 +-- include/linux/cpufreq.h | 19 --- 26 files changed, 270 insertions(+), 474 deletions(-) (limited to 'include/linux') diff --git a/arch/arm/mach-davinci/cpufreq.c b/arch/arm/mach-davinci/cpufreq.c index 0a95be1512bb..41669ecc1f91 100644 --- a/arch/arm/mach-davinci/cpufreq.c +++ b/arch/arm/mach-davinci/cpufreq.c @@ -94,9 +94,7 @@ static int davinci_target(struct cpufreq_policy *policy, if (freqs.old == freqs.new) return ret; - cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, - dev_driver_string(cpufreq.dev), - "transition: %u --> %u\n", freqs.old, freqs.new); + dev_dbg(&cpufreq.dev, "transition: %u --> %u\n", freqs.old, freqs.new); ret = cpufreq_frequency_table_target(policy, pdata->freq_table, freqs.new, relation, &idx); diff --git a/arch/blackfin/mach-common/dpmc.c b/arch/blackfin/mach-common/dpmc.c index 382099fd5561..5e4112e518a9 100644 --- a/arch/blackfin/mach-common/dpmc.c +++ b/arch/blackfin/mach-common/dpmc.c @@ -19,9 +19,6 @@ #define DRIVER_NAME "bfin dpmc" -#define dprintk(msg...) \ - cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, DRIVER_NAME, msg) - struct bfin_dpmc_platform_data *pdata; /** diff --git a/arch/ia64/kernel/cpufreq/acpi-cpufreq.c b/arch/ia64/kernel/cpufreq/acpi-cpufreq.c index 22f61526a8e1..f09b174244d5 100644 --- a/arch/ia64/kernel/cpufreq/acpi-cpufreq.c +++ b/arch/ia64/kernel/cpufreq/acpi-cpufreq.c @@ -23,8 +23,6 @@ #include #include -#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "acpi-cpufreq", msg) - MODULE_AUTHOR("Venkatesh Pallipadi"); MODULE_DESCRIPTION("ACPI Processor P-States Driver"); MODULE_LICENSE("GPL"); @@ -47,12 +45,12 @@ processor_set_pstate ( { s64 retval; - dprintk("processor_set_pstate\n"); + pr_debug("processor_set_pstate\n"); retval = ia64_pal_set_pstate((u64)value); if (retval) { - dprintk("Failed to set freq to 0x%x, with error 0x%lx\n", + pr_debug("Failed to set freq to 0x%x, with error 0x%lx\n", value, retval); return -ENODEV; } @@ -67,14 +65,14 @@ processor_get_pstate ( u64 pstate_index = 0; s64 retval; - dprintk("processor_get_pstate\n"); + pr_debug("processor_get_pstate\n"); retval = ia64_pal_get_pstate(&pstate_index, PAL_GET_PSTATE_TYPE_INSTANT); *value = (u32) pstate_index; if (retval) - dprintk("Failed to get current freq with " + pr_debug("Failed to get current freq with " "error 0x%lx, idx 0x%x\n", retval, *value); return (int)retval; @@ -90,7 +88,7 @@ extract_clock ( { unsigned long i; - dprintk("extract_clock\n"); + pr_debug("extract_clock\n"); for (i = 0; i < data->acpi_data.state_count; i++) { if (value == data->acpi_data.states[i].status) @@ -110,7 +108,7 @@ processor_get_freq ( cpumask_t saved_mask; unsigned long clock_freq; - dprintk("processor_get_freq\n"); + pr_debug("processor_get_freq\n"); saved_mask = current->cpus_allowed; set_cpus_allowed_ptr(current, cpumask_of(cpu)); @@ -148,7 +146,7 @@ processor_set_freq ( cpumask_t saved_mask; int retval; - dprintk("processor_set_freq\n"); + pr_debug("processor_set_freq\n"); saved_mask = current->cpus_allowed; set_cpus_allowed_ptr(current, cpumask_of(cpu)); @@ -159,16 +157,16 @@ processor_set_freq ( if (state == data->acpi_data.state) { if (unlikely(data->resume)) { - dprintk("Called after resume, resetting to P%d\n", state); + pr_debug("Called after resume, resetting to P%d\n", state); data->resume = 0; } else { - dprintk("Already at target state (P%d)\n", state); + pr_debug("Already at target state (P%d)\n", state); retval = 0; goto migrate_end; } } - dprintk("Transitioning from P%d to P%d\n", + pr_debug("Transitioning from P%d to P%d\n", data->acpi_data.state, state); /* cpufreq frequency struct */ @@ -186,7 +184,7 @@ processor_set_freq ( value = (u32) data->acpi_data.states[state].control; - dprintk("Transitioning to state: 0x%08x\n", value); + pr_debug("Transitioning to state: 0x%08x\n", value); ret = processor_set_pstate(value); if (ret) { @@ -219,7 +217,7 @@ acpi_cpufreq_get ( { struct cpufreq_acpi_io *data = acpi_io_data[cpu]; - dprintk("acpi_cpufreq_get\n"); + pr_debug("acpi_cpufreq_get\n"); return processor_get_freq(data, cpu); } @@ -235,7 +233,7 @@ acpi_cpufreq_target ( unsigned int next_state = 0; unsigned int result = 0; - dprintk("acpi_cpufreq_setpolicy\n"); + pr_debug("acpi_cpufreq_setpolicy\n"); result = cpufreq_frequency_table_target(policy, data->freq_table, target_freq, relation, &next_state); @@ -255,7 +253,7 @@ acpi_cpufreq_verify ( unsigned int result = 0; struct cpufreq_acpi_io *data = acpi_io_data[policy->cpu]; - dprintk("acpi_cpufreq_verify\n"); + pr_debug("acpi_cpufreq_verify\n"); result = cpufreq_frequency_table_verify(policy, data->freq_table); @@ -273,7 +271,7 @@ acpi_cpufreq_cpu_init ( struct cpufreq_acpi_io *data; unsigned int result = 0; - dprintk("acpi_cpufreq_cpu_init\n"); + pr_debug("acpi_cpufreq_cpu_init\n"); data = kzalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL); if (!data) @@ -288,7 +286,7 @@ acpi_cpufreq_cpu_init ( /* capability check */ if (data->acpi_data.state_count <= 1) { - dprintk("No P-States\n"); + pr_debug("No P-States\n"); result = -ENODEV; goto err_unreg; } @@ -297,7 +295,7 @@ acpi_cpufreq_cpu_init ( ACPI_ADR_SPACE_FIXED_HARDWARE) || (data->acpi_data.status_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) { - dprintk("Unsupported address space [%d, %d]\n", + pr_debug("Unsupported address space [%d, %d]\n", (u32) (data->acpi_data.control_register.space_id), (u32) (data->acpi_data.status_register.space_id)); result = -ENODEV; @@ -348,7 +346,7 @@ acpi_cpufreq_cpu_init ( "activated.\n", cpu); for (i = 0; i < data->acpi_data.state_count; i++) - dprintk(" %cP%d: %d MHz, %d mW, %d uS, %d uS, 0x%x 0x%x\n", + pr_debug(" %cP%d: %d MHz, %d mW, %d uS, %d uS, 0x%x 0x%x\n", (i == data->acpi_data.state?'*':' '), i, (u32) data->acpi_data.states[i].core_frequency, (u32) data->acpi_data.states[i].power, @@ -383,7 +381,7 @@ acpi_cpufreq_cpu_exit ( { struct cpufreq_acpi_io *data = acpi_io_data[policy->cpu]; - dprintk("acpi_cpufreq_cpu_exit\n"); + pr_debug("acpi_cpufreq_cpu_exit\n"); if (data) { cpufreq_frequency_table_put_attr(policy->cpu); @@ -418,7 +416,7 @@ static struct cpufreq_driver acpi_cpufreq_driver = { static int __init acpi_cpufreq_init (void) { - dprintk("acpi_cpufreq_init\n"); + pr_debug("acpi_cpufreq_init\n"); return cpufreq_register_driver(&acpi_cpufreq_driver); } @@ -427,7 +425,7 @@ acpi_cpufreq_init (void) static void __exit acpi_cpufreq_exit (void) { - dprintk("acpi_cpufreq_exit\n"); + pr_debug("acpi_cpufreq_exit\n"); cpufreq_unregister_driver(&acpi_cpufreq_driver); return; diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c index a2baafb2fe6d..4e04e1274388 100644 --- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -47,9 +47,6 @@ #include #include "mperf.h" -#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \ - "acpi-cpufreq", msg) - MODULE_AUTHOR("Paul Diefenbaugh, Dominik Brodowski"); MODULE_DESCRIPTION("ACPI Processor P-States Driver"); MODULE_LICENSE("GPL"); @@ -233,7 +230,7 @@ static u32 get_cur_val(const struct cpumask *mask) cmd.mask = mask; drv_read(&cmd); - dprintk("get_cur_val = %u\n", cmd.val); + pr_debug("get_cur_val = %u\n", cmd.val); return cmd.val; } @@ -244,7 +241,7 @@ static unsigned int get_cur_freq_on_cpu(unsigned int cpu) unsigned int freq; unsigned int cached_freq; - dprintk("get_cur_freq_on_cpu (%d)\n", cpu); + pr_debug("get_cur_freq_on_cpu (%d)\n", cpu); if (unlikely(data == NULL || data->acpi_data == NULL || data->freq_table == NULL)) { @@ -261,7 +258,7 @@ static unsigned int get_cur_freq_on_cpu(unsigned int cpu) data->resume = 1; } - dprintk("cur freq = %u\n", freq); + pr_debug("cur freq = %u\n", freq); return freq; } @@ -293,7 +290,7 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy, unsigned int i; int result = 0; - dprintk("acpi_cpufreq_target %d (%d)\n", target_freq, policy->cpu); + pr_debug("acpi_cpufreq_target %d (%d)\n", target_freq, policy->cpu); if (unlikely(data == NULL || data->acpi_data == NULL || data->freq_table == NULL)) { @@ -313,11 +310,11 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy, next_perf_state = data->freq_table[next_state].index; if (perf->state == next_perf_state) { if (unlikely(data->resume)) { - dprintk("Called after resume, resetting to P%d\n", + pr_debug("Called after resume, resetting to P%d\n", next_perf_state); data->resume = 0; } else { - dprintk("Already at target state (P%d)\n", + pr_debug("Already at target state (P%d)\n", next_perf_state); goto out; } @@ -357,7 +354,7 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy, if (acpi_pstate_strict) { if (!check_freqs(cmd.mask, freqs.new, data)) { - dprintk("acpi_cpufreq_target failed (%d)\n", + pr_debug("acpi_cpufreq_target failed (%d)\n", policy->cpu); result = -EAGAIN; goto out; @@ -378,7 +375,7 @@ static int acpi_cpufreq_verify(struct cpufreq_policy *policy) { struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu); - dprintk("acpi_cpufreq_verify\n"); + pr_debug("acpi_cpufreq_verify\n"); return cpufreq_frequency_table_verify(policy, data->freq_table); } @@ -433,11 +430,11 @@ static void free_acpi_perf_data(void) static int __init acpi_cpufreq_early_init(void) { unsigned int i; - dprintk("acpi_cpufreq_early_init\n"); + pr_debug("acpi_cpufreq_early_init\n"); acpi_perf_data = alloc_percpu(struct acpi_processor_performance); if (!acpi_perf_data) { - dprintk("Memory allocation error for acpi_perf_data.\n"); + pr_debug("Memory allocation error for acpi_perf_data.\n"); return -ENOMEM; } for_each_possible_cpu(i) { @@ -519,7 +516,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) static int blacklisted; #endif - dprintk("acpi_cpufreq_cpu_init\n"); + pr_debug("acpi_cpufreq_cpu_init\n"); #ifdef CONFIG_SMP if (blacklisted) @@ -566,7 +563,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) /* capability check */ if (perf->state_count <= 1) { - dprintk("No P-States\n"); + pr_debug("No P-States\n"); result = -ENODEV; goto err_unreg; } @@ -578,11 +575,11 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) switch (perf->control_register.space_id) { case ACPI_ADR_SPACE_SYSTEM_IO: - dprintk("SYSTEM IO addr space\n"); + pr_debug("SYSTEM IO addr space\n"); data->cpu_feature = SYSTEM_IO_CAPABLE; break; case ACPI_ADR_SPACE_FIXED_HARDWARE: - dprintk("HARDWARE addr space\n"); + pr_debug("HARDWARE addr space\n"); if (!check_est_cpu(cpu)) { result = -ENODEV; goto err_unreg; @@ -590,7 +587,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) data->cpu_feature = SYSTEM_INTEL_MSR_CAPABLE; break; default: - dprintk("Unknown addr space %d\n", + pr_debug("Unknown addr space %d\n", (u32) (perf->control_register.space_id)); result = -ENODEV; goto err_unreg; @@ -661,9 +658,9 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) if (cpu_has(c, X86_FEATURE_APERFMPERF)) acpi_cpufreq_driver.getavg = cpufreq_get_measured_perf; - dprintk("CPU%u - ACPI performance management activated.\n", cpu); + pr_debug("CPU%u - ACPI performance management activated.\n", cpu); for (i = 0; i < perf->state_count; i++) - dprintk(" %cP%d: %d MHz, %d mW, %d uS\n", + pr_debug(" %cP%d: %d MHz, %d mW, %d uS\n", (i == perf->state ? '*' : ' '), i, (u32) perf->states[i].core_frequency, (u32) perf->states[i].power, @@ -694,7 +691,7 @@ static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy) { struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu); - dprintk("acpi_cpufreq_cpu_exit\n"); + pr_debug("acpi_cpufreq_cpu_exit\n"); if (data) { cpufreq_frequency_table_put_attr(policy->cpu); @@ -712,7 +709,7 @@ static int acpi_cpufreq_resume(struct cpufreq_policy *policy) { struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu); - dprintk("acpi_cpufreq_resume\n"); + pr_debug("acpi_cpufreq_resume\n"); data->resume = 1; @@ -743,7 +740,7 @@ static int __init acpi_cpufreq_init(void) if (acpi_disabled) return 0; - dprintk("acpi_cpufreq_init\n"); + pr_debug("acpi_cpufreq_init\n"); ret = acpi_cpufreq_early_init(); if (ret) @@ -758,7 +755,7 @@ static int __init acpi_cpufreq_init(void) static void __exit acpi_cpufreq_exit(void) { - dprintk("acpi_cpufreq_exit\n"); + pr_debug("acpi_cpufreq_exit\n"); cpufreq_unregister_driver(&acpi_cpufreq_driver); diff --git a/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c b/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c index 141abebc4516..7bac808804f3 100644 --- a/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c +++ b/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c @@ -57,8 +57,6 @@ MODULE_PARM_DESC(min_fsb, "Minimum FSB to use, if not defined: current FSB - 50"); #define PFX "cpufreq-nforce2: " -#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \ - "cpufreq-nforce2", msg) /** * nforce2_calc_fsb - calculate FSB @@ -270,7 +268,7 @@ static int nforce2_target(struct cpufreq_policy *policy, if (freqs.old == freqs.new) return 0; - dprintk("Old CPU frequency %d kHz, new %d kHz\n", + pr_debug("Old CPU frequency %d kHz, new %d kHz\n", freqs.old, freqs.new); cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); @@ -282,7 +280,7 @@ static int nforce2_target(struct cpufreq_policy *policy, printk(KERN_ERR PFX "Changing FSB to %d failed\n", target_fsb); else - dprintk("Changed FSB successfully to %d\n", + pr_debug("Changed FSB successfully to %d\n", target_fsb); /* Enable IRQs */ diff --git a/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c b/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c index 32974cf84232..ffe1f2c92ed3 100644 --- a/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c +++ b/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c @@ -142,9 +142,6 @@ module_param(max_duration, int, 0444); #define POLICY_MIN_DIV 20 -#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \ - "gx-suspmod", msg) - /** * we can detect a core multipiler from dir0_lsb * from GX1 datasheet p.56, @@ -191,7 +188,7 @@ static __init struct pci_dev *gx_detect_chipset(void) /* check if CPU is a MediaGX or a Geode. */ if ((boot_cpu_data.x86_vendor != X86_VENDOR_NSC) && (boot_cpu_data.x86_vendor != X86_VENDOR_CYRIX)) { - dprintk("error: no MediaGX/Geode processor found!\n"); + pr_debug("error: no MediaGX/Geode processor found!\n"); return NULL; } @@ -201,7 +198,7 @@ static __init struct pci_dev *gx_detect_chipset(void) return gx_pci; } - dprintk("error: no supported chipset found!\n"); + pr_debug("error: no supported chipset found!\n"); return NULL; } @@ -305,14 +302,14 @@ static void gx_set_cpuspeed(unsigned int khz) break; default: local_irq_restore(flags); - dprintk("fatal: try to set unknown chipset.\n"); + pr_debug("fatal: try to set unknown chipset.\n"); return; } } else { suscfg = gx_params->pci_suscfg & ~(SUSMOD); gx_params->off_duration = 0; gx_params->on_duration = 0; - dprintk("suspend modulation disabled: cpu runs 100%% speed.\n"); + pr_debug("suspend modulation disabled: cpu runs 100%% speed.\n"); } gx_write_byte(PCI_MODOFF, gx_params->off_duration); @@ -327,9 +324,9 @@ static void gx_set_cpuspeed(unsigned int khz) cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - dprintk("suspend modulation w/ duration of ON:%d us, OFF:%d us\n", + pr_debug("suspend modulation w/ duration of ON:%d us, OFF:%d us\n", gx_params->on_duration * 32, gx_params->off_duration * 32); - dprintk("suspend modulation w/ clock speed: %d kHz.\n", freqs.new); + pr_debug("suspend modulation w/ clock speed: %d kHz.\n", freqs.new); } /**************************************************************** @@ -428,8 +425,8 @@ static int cpufreq_gx_cpu_init(struct cpufreq_policy *policy) stock_freq = maxfreq; curfreq = gx_get_cpuspeed(0); - dprintk("cpu max frequency is %d.\n", maxfreq); - dprintk("cpu current frequency is %dkHz.\n", curfreq); + pr_debug("cpu max frequency is %d.\n", maxfreq); + pr_debug("cpu current frequency is %dkHz.\n", curfreq); /* setup basic struct for cpufreq API */ policy->cpu = 0; @@ -475,7 +472,7 @@ static int __init cpufreq_gx_init(void) if (max_duration > 0xff) max_duration = 0xff; - dprintk("geode suspend modulation available.\n"); + pr_debug("geode suspend modulation available.\n"); params = kzalloc(sizeof(struct gxfreq_params), GFP_KERNEL); if (params == NULL) diff --git a/arch/x86/kernel/cpu/cpufreq/longhaul.c b/arch/x86/kernel/cpu/cpufreq/longhaul.c index cf48cdd6907d..f47d26e2a135 100644 --- a/arch/x86/kernel/cpu/cpufreq/longhaul.c +++ b/arch/x86/kernel/cpu/cpufreq/longhaul.c @@ -77,9 +77,6 @@ static int scale_voltage; static int disable_acpi_c3; static int revid_errata; -#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \ - "longhaul", msg) - /* Clock ratios multiplied by 10 */ static int mults[32]; @@ -87,7 +84,6 @@ static int eblcr[32]; static int longhaul_version; static struct cpufreq_frequency_table *longhaul_table; -#ifdef CONFIG_CPU_FREQ_DEBUG static char speedbuffer[8]; static char *print_speed(int speed) @@ -106,7 +102,6 @@ static char *print_speed(int speed) return speedbuffer; } -#endif static unsigned int calc_speed(int mult) @@ -275,7 +270,7 @@ static void longhaul_setstate(unsigned int table_index) cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - dprintk("Setting to FSB:%dMHz Mult:%d.%dx (%s)\n", + pr_debug("Setting to FSB:%dMHz Mult:%d.%dx (%s)\n", fsb, mult/10, mult%10, print_speed(speed/1000)); retry_loop: preempt_disable(); @@ -460,12 +455,12 @@ static int __cpuinit longhaul_get_ranges(void) break; } - dprintk("MinMult:%d.%dx MaxMult:%d.%dx\n", + pr_debug("MinMult:%d.%dx MaxMult:%d.%dx\n", minmult/10, minmult%10, maxmult/10, maxmult%10); highest_speed = calc_speed(maxmult); lowest_speed = calc_speed(minmult); - dprintk("FSB:%dMHz Lowest speed: %s Highest speed:%s\n", fsb, + pr_debug("FSB:%dMHz Lowest speed: %s Highest speed:%s\n", fsb, print_speed(lowest_speed/1000), print_speed(highest_speed/1000)); diff --git a/arch/x86/kernel/cpu/cpufreq/longrun.c b/arch/x86/kernel/cpu/cpufreq/longrun.c index d9f51367666b..34ea359b370e 100644 --- a/arch/x86/kernel/cpu/cpufreq/longrun.c +++ b/arch/x86/kernel/cpu/cpufreq/longrun.c @@ -15,9 +15,6 @@ #include #include -#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \ - "longrun", msg) - static struct cpufreq_driver longrun_driver; /** @@ -40,14 +37,14 @@ static void __cpuinit longrun_get_policy(struct cpufreq_policy *policy) u32 msr_lo, msr_hi; rdmsr(MSR_TMTA_LONGRUN_FLAGS, msr_lo, msr_hi); - dprintk("longrun flags are %x - %x\n", msr_lo, msr_hi); + pr_debug("longrun flags are %x - %x\n", msr_lo, msr_hi); if (msr_lo & 0x01) policy->policy = CPUFREQ_POLICY_PERFORMANCE; else policy->policy = CPUFREQ_POLICY_POWERSAVE; rdmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi); - dprintk("longrun ctrl is %x - %x\n", msr_lo, msr_hi); + pr_debug("longrun ctrl is %x - %x\n", msr_lo, msr_hi); msr_lo &= 0x0000007F; msr_hi &= 0x0000007F; @@ -150,7 +147,7 @@ static unsigned int longrun_get(unsigned int cpu) return 0; cpuid(0x80860007, &eax, &ebx, &ecx, &edx); - dprintk("cpuid eax is %u\n", eax); + pr_debug("cpuid eax is %u\n", eax); return eax * 1000; } @@ -196,7 +193,7 @@ static int __cpuinit longrun_determine_freqs(unsigned int *low_freq, rdmsr(MSR_TMTA_LRTI_VOLT_MHZ, msr_lo, msr_hi); *high_freq = msr_lo * 1000; /* to kHz */ - dprintk("longrun table interface told %u - %u kHz\n", + pr_debug("longrun table interface told %u - %u kHz\n", *low_freq, *high_freq); if (*low_freq > *high_freq) @@ -207,7 +204,7 @@ static int __cpuinit longrun_determine_freqs(unsigned int *low_freq, /* set the upper border to the value determined during TSC init */ *high_freq = (cpu_khz / 1000); *high_freq = *high_freq * 1000; - dprintk("high frequency is %u kHz\n", *high_freq); + pr_debug("high frequency is %u kHz\n", *high_freq); /* get current borders */ rdmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi); @@ -233,7 +230,7 @@ static int __cpuinit longrun_determine_freqs(unsigned int *low_freq, /* restore values */ wrmsr(MSR_TMTA_LONGRUN_CTRL, save_lo, save_hi); } - dprintk("percentage is %u %%, freq is %u MHz\n", ecx, eax); + pr_debug("percentage is %u %%, freq is %u MHz\n", ecx, eax); /* performance_pctg = (current_freq - low_freq)/(high_freq - low_freq) * eqals @@ -249,7 +246,7 @@ static int __cpuinit longrun_determine_freqs(unsigned int *low_freq, edx = ((eax - ebx) * 100) / (100 - ecx); *low_freq = edx * 1000; /* back to kHz */ - dprintk("low frequency is %u kHz\n", *low_freq); + pr_debug("low frequency is %u kHz\n", *low_freq); if (*low_freq > *high_freq) *low_freq = *high_freq; diff --git a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c index 52c93648e492..6be3e0760c26 100644 --- a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c +++ b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c @@ -35,8 +35,6 @@ #include "speedstep-lib.h" #define PFX "p4-clockmod: " -#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \ - "p4-clockmod", msg) /* * Duty Cycle (3bits), note DC_DISABLE is not specified in @@ -66,7 +64,7 @@ static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate) rdmsr_on_cpu(cpu, MSR_IA32_THERM_STATUS, &l, &h); if (l & 0x01) - dprintk("CPU#%d currently thermal throttled\n", cpu); + pr_debug("CPU#%d currently thermal throttled\n", cpu); if (has_N44_O17_errata[cpu] && (newstate == DC_25PT || newstate == DC_DFLT)) @@ -74,10 +72,10 @@ static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate) rdmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, &l, &h); if (newstate == DC_DISABLE) { - dprintk("CPU#%d disabling modulation\n", cpu); + pr_debug("CPU#%d disabling modulation\n", cpu); wrmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, l & ~(1<<4), h); } else { - dprintk("CPU#%d setting duty cycle to %d%%\n", + pr_debug("CPU#%d setting duty cycle to %d%%\n", cpu, ((125 * newstate) / 10)); /* bits 63 - 5 : reserved * bit 4 : enable/disable @@ -217,7 +215,7 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy) case 0x0f11: case 0x0f12: has_N44_O17_errata[policy->cpu] = 1; - dprintk("has errata -- disabling low frequencies\n"); + pr_debug("has errata -- disabling low frequencies\n"); } if (speedstep_detect_processor() == SPEEDSTEP_CPU_P4D && diff --git a/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c index 907c8e637ef5..7b0603eb0129 100644 --- a/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c @@ -48,9 +48,6 @@ #define BUF_SZ 4 -#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \ - "pcc-cpufreq", msg) - struct pcc_register_resource { u8 descriptor; u16 length; @@ -152,7 +149,7 @@ static unsigned int pcc_get_freq(unsigned int cpu) spin_lock(&pcc_lock); - dprintk("get: get_freq for CPU %d\n", cpu); + pr_debug("get: get_freq for CPU %d\n", cpu); pcc_cpu_data = per_cpu_ptr(pcc_cpu_info, cpu); input_buffer = 0x1; @@ -170,7 +167,7 @@ static unsigned int pcc_get_freq(unsigned int cpu) status = ioread16(&pcch_hdr->status); if (status != CMD_COMPLETE) { - dprintk("get: FAILED: for CPU %d, status is %d\n", + pr_debug("get: FAILED: for CPU %d, status is %d\n", cpu, status); goto cmd_incomplete; } @@ -178,14 +175,14 @@ static unsigned int pcc_get_freq(unsigned int cpu) curr_freq = (((ioread32(&pcch_hdr->nominal) * (output_buffer & 0xff)) / 100) * 1000); - dprintk("get: SUCCESS: (virtual) output_offset for cpu %d is " - "0x%x, contains a value of: 0x%x. Speed is: %d MHz\n", + pr_debug("get: SUCCESS: (virtual) output_offset for cpu %d is " + "0x%p, contains a value of: 0x%x. Speed is: %d MHz\n", cpu, (pcch_virt_addr + pcc_cpu_data->output_offset), output_buffer, curr_freq); freq_limit = (output_buffer >> 8) & 0xff; if (freq_limit != 0xff) { - dprintk("get: frequency for cpu %d is being temporarily" + pr_debug("get: frequency for cpu %d is being temporarily" " capped at %d\n", cpu, curr_freq); } @@ -212,8 +209,8 @@ static int pcc_cpufreq_target(struct cpufreq_policy *policy, cpu = policy->cpu; pcc_cpu_data = per_cpu_ptr(pcc_cpu_info, cpu); - dprintk("target: CPU %d should go to target freq: %d " - "(virtual) input_offset is 0x%x\n", + pr_debug("target: CPU %d should go to target freq: %d " + "(virtual) input_offset is 0x%p\n", cpu, target_freq, (pcch_virt_addr + pcc_cpu_data->input_offset)); @@ -234,14 +231,14 @@ static int pcc_cpufreq_target(struct cpufreq_policy *policy, status = ioread16(&pcch_hdr->status); if (status != CMD_COMPLETE) { - dprintk("target: FAILED for cpu %d, with status: 0x%x\n", + pr_debug("target: FAILED for cpu %d, with status: 0x%x\n", cpu, status); goto cmd_incomplete; } iowrite16(0, &pcch_hdr->status); cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - dprintk("target: was SUCCESSFUL for cpu %d\n", cpu); + pr_debug("target: was SUCCESSFUL for cpu %d\n", cpu); spin_unlock(&pcc_lock); return 0; @@ -293,7 +290,7 @@ static int pcc_get_offset(int cpu) memset_io((pcch_virt_addr + pcc_cpu_data->input_offset), 0, BUF_SZ); memset_io((pcch_virt_addr + pcc_cpu_data->output_offset), 0, BUF_SZ); - dprintk("pcc_get_offset: for CPU %d: pcc_cpu_data " + pr_debug("pcc_get_offset: for CPU %d: pcc_cpu_data " "input_offset: 0x%x, pcc_cpu_data output_offset: 0x%x\n", cpu, pcc_cpu_data->input_offset, pcc_cpu_data->output_offset); out_free: @@ -410,7 +407,7 @@ static int __init pcc_cpufreq_probe(void) if (ACPI_SUCCESS(status)) { ret = pcc_cpufreq_do_osc(&osc_handle); if (ret) - dprintk("probe: _OSC evaluation did not succeed\n"); + pr_debug("probe: _OSC evaluation did not succeed\n"); /* Firmware's use of _OSC is optional */ ret = 0; } @@ -433,7 +430,7 @@ static int __init pcc_cpufreq_probe(void) mem_resource = (struct pcc_memory_resource *)member->buffer.pointer; - dprintk("probe: mem_resource descriptor: 0x%x," + pr_debug("probe: mem_resource descriptor: 0x%x," " length: %d, space_id: %d, resource_usage: %d," " type_specific: %d, granularity: 0x%llx," " minimum: 0x%llx, maximum: 0x%llx," @@ -453,13 +450,13 @@ static int __init pcc_cpufreq_probe(void) pcch_virt_addr = ioremap_nocache(mem_resource->minimum, mem_resource->address_length); if (pcch_virt_addr == NULL) { - dprintk("probe: could not map shared mem region\n"); + pr_debug("probe: could not map shared mem region\n"); goto out_free; } pcch_hdr = pcch_virt_addr; - dprintk("probe: PCCH header (virtual) addr: 0x%p\n", pcch_hdr); - dprintk("probe: PCCH header is at physical address: 0x%llx," + pr_debug("probe: PCCH header (virtual) addr: 0x%p\n", pcch_hdr); + pr_debug("probe: PCCH header is at physical address: 0x%llx," " signature: 0x%x, length: %d bytes, major: %d, minor: %d," " supported features: 0x%x, command field: 0x%x," " status field: 0x%x, nominal latency: %d us\n", @@ -469,7 +466,7 @@ static int __init pcc_cpufreq_probe(void) ioread16(&pcch_hdr->command), ioread16(&pcch_hdr->status), ioread32(&pcch_hdr->latency)); - dprintk("probe: min time between commands: %d us," + pr_debug("probe: min time between commands: %d us," " max time between commands: %d us," " nominal CPU frequency: %d MHz," " minimum CPU frequency: %d MHz," @@ -494,7 +491,7 @@ static int __init pcc_cpufreq_probe(void) doorbell.access_width = 64; doorbell.address = reg_resource->address; - dprintk("probe: doorbell: space_id is %d, bit_width is %d, " + pr_debug("probe: doorbell: space_id is %d, bit_width is %d, " "bit_offset is %d, access_width is %d, address is 0x%llx\n", doorbell.space_id, doorbell.bit_width, doorbell.bit_offset, doorbell.access_width, reg_resource->address); @@ -515,7 +512,7 @@ static int __init pcc_cpufreq_probe(void) doorbell_write = member->integer.value; - dprintk("probe: doorbell_preserve: 0x%llx," + pr_debug("probe: doorbell_preserve: 0x%llx," " doorbell_write: 0x%llx\n", doorbell_preserve, doorbell_write); @@ -550,7 +547,7 @@ static int pcc_cpufreq_cpu_init(struct cpufreq_policy *policy) result = pcc_get_offset(cpu); if (result) { - dprintk("init: PCCP evaluation failed\n"); + pr_debug("init: PCCP evaluation failed\n"); goto out; } @@ -561,12 +558,12 @@ static int pcc_cpufreq_cpu_init(struct cpufreq_policy *policy) policy->cur = pcc_get_freq(cpu); if (!policy->cur) { - dprintk("init: Unable to get current CPU frequency\n"); + pr_debug("init: Unable to get current CPU frequency\n"); result = -EINVAL; goto out; } - dprintk("init: policy->max is %d, policy->min is %d\n", + pr_debug("init: policy->max is %d, policy->min is %d\n", policy->max, policy->min); out: return result; @@ -597,7 +594,7 @@ static int __init pcc_cpufreq_init(void) ret = pcc_cpufreq_probe(); if (ret) { - dprintk("pcc_cpufreq_init: PCCH evaluation failed\n"); + pr_debug("pcc_cpufreq_init: PCCH evaluation failed\n"); return ret; } diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k7.c b/arch/x86/kernel/cpu/cpufreq/powernow-k7.c index 4a45fd6e41ba..d71d9f372359 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k7.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k7.c @@ -68,7 +68,6 @@ union powernow_acpi_control_t { }; #endif -#ifdef CONFIG_CPU_FREQ_DEBUG /* divide by 1000 to get VCore voltage in V. */ static const int mobile_vid_table[32] = { 2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650, @@ -76,7 +75,6 @@ static const int mobile_vid_table[32] = { 1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100, 1075, 1050, 1025, 1000, 975, 950, 925, 0, }; -#endif /* divide by 10 to get FID. */ static const int fid_codes[32] = { @@ -103,9 +101,6 @@ static unsigned int fsb; static unsigned int latency; static char have_a0; -#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \ - "powernow-k7", msg) - static int check_fsb(unsigned int fsbspeed) { int delta; @@ -209,7 +204,7 @@ static int get_ranges(unsigned char *pst) vid = *pst++; powernow_table[j].index |= (vid << 8); /* upper 8 bits */ - dprintk(" FID: 0x%x (%d.%dx [%dMHz]) " + pr_debug(" FID: 0x%x (%d.%dx [%dMHz]) " "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10, fid_codes[fid] % 10, speed/1000, vid, mobile_vid_table[vid]/1000, @@ -367,7 +362,7 @@ static int powernow_acpi_init(void) unsigned int speed, speed_mhz; pc.val = (unsigned long) state->control; - dprintk("acpi: P%d: %d MHz %d mW %d uS control %08x SGTC %d\n", + pr_debug("acpi: P%d: %d MHz %d mW %d uS control %08x SGTC %d\n", i, (u32) state->core_frequency, (u32) state->power, @@ -401,7 +396,7 @@ static int powernow_acpi_init(void) invalidate_entry(i); } - dprintk(" FID: 0x%x (%d.%dx [%dMHz]) " + pr_debug(" FID: 0x%x (%d.%dx [%dMHz]) " "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10, fid_codes[fid] % 10, speed_mhz, vid, mobile_vid_table[vid]/1000, @@ -409,7 +404,7 @@ static int powernow_acpi_init(void) if (state->core_frequency != speed_mhz) { state->core_frequency = speed_mhz; - dprintk(" Corrected ACPI frequency to %d\n", + pr_debug(" Corrected ACPI frequency to %d\n", speed_mhz); } @@ -453,8 +448,8 @@ static int powernow_acpi_init(void) static void print_pst_entry(struct pst_s *pst, unsigned int j) { - dprintk("PST:%d (@%p)\n", j, pst); - dprintk(" cpuid: 0x%x fsb: %d maxFID: 0x%x startvid: 0x%x\n", + pr_debug("PST:%d (@%p)\n", j, pst); + pr_debug(" cpuid: 0x%x fsb: %d maxFID: 0x%x startvid: 0x%x\n", pst->cpuid, pst->fsbspeed, pst->maxfid, pst->startvid); } @@ -474,20 +469,20 @@ static int powernow_decode_bios(int maxfid, int startvid) p = phys_to_virt(i); if (memcmp(p, "AMDK7PNOW!", 10) == 0) { - dprintk("Found PSB header at %p\n", p); + pr_debug("Found PSB header at %p\n", p); psb = (struct psb_s *) p; - dprintk("Table version: 0x%x\n", psb->tableversion); + pr_debug("Table version: 0x%x\n", psb->tableversion); if (psb->tableversion != 0x12) { printk(KERN_INFO PFX "Sorry, only v1.2 tables" " supported right now\n"); return -ENODEV; } - dprintk("Flags: 0x%x\n", psb->flags); + pr_debug("Flags: 0x%x\n", psb->flags); if ((psb->flags & 1) == 0) - dprintk("Mobile voltage regulator\n"); + pr_debug("Mobile voltage regulator\n"); else - dprintk("Desktop voltage regulator\n"); + pr_debug("Desktop voltage regulator\n"); latency = psb->settlingtime; if (latency < 100) { @@ -497,9 +492,9 @@ static int powernow_decode_bios(int maxfid, int startvid) "Correcting.\n", latency); latency = 100; } - dprintk("Settling Time: %d microseconds.\n", + pr_debug("Settling Time: %d microseconds.\n", psb->settlingtime); - dprintk("Has %d PST tables. (Only dumping ones " + pr_debug("Has %d PST tables. (Only dumping ones " "relevant to this CPU).\n", psb->numpst); @@ -650,7 +645,7 @@ static int __cpuinit powernow_cpu_init(struct cpufreq_policy *policy) printk(KERN_WARNING PFX "can not determine bus frequency\n"); return -EINVAL; } - dprintk("FSB: %3dMHz\n", fsb/1000); + pr_debug("FSB: %3dMHz\n", fsb/1000); if (dmi_check_system(powernow_dmi_table) || acpi_force) { printk(KERN_INFO PFX "PSB/PST known to be broken. " diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c index 2368e38327b3..83479b6fb9a1 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c @@ -139,7 +139,7 @@ static int query_current_values_with_pending_wait(struct powernow_k8_data *data) } do { if (i++ > 10000) { - dprintk("detected change pending stuck\n"); + pr_debug("detected change pending stuck\n"); return 1; } rdmsr(MSR_FIDVID_STATUS, lo, hi); @@ -176,7 +176,7 @@ static void fidvid_msr_init(void) fid = lo & MSR_S_LO_CURRENT_FID; lo = fid | (vid << MSR_C_LO_VID_SHIFT); hi = MSR_C_HI_STP_GNT_BENIGN; - dprintk("cpu%d, init lo 0x%x, hi 0x%x\n", smp_processor_id(), lo, hi); + pr_debug("cpu%d, init lo 0x%x, hi 0x%x\n", smp_processor_id(), lo, hi); wrmsr(MSR_FIDVID_CTL, lo, hi); } @@ -196,7 +196,7 @@ static int write_new_fid(struct powernow_k8_data *data, u32 fid) lo |= (data->currvid << MSR_C_LO_VID_SHIFT); lo |= MSR_C_LO_INIT_FID_VID; - dprintk("writing fid 0x%x, lo 0x%x, hi 0x%x\n", + pr_debug("writing fid 0x%x, lo 0x%x, hi 0x%x\n", fid, lo, data->plllock * PLL_LOCK_CONVERSION); do { @@ -244,7 +244,7 @@ static int write_new_vid(struct powernow_k8_data *data, u32 vid) lo |= (vid << MSR_C_LO_VID_SHIFT); lo |= MSR_C_LO_INIT_FID_VID; - dprintk("writing vid 0x%x, lo 0x%x, hi 0x%x\n", + pr_debug("writing vid 0x%x, lo 0x%x, hi 0x%x\n", vid, lo, STOP_GRANT_5NS); do { @@ -325,7 +325,7 @@ static int transition_fid_vid(struct powernow_k8_data *data, return 1; } - dprintk("transitioned (cpu%d): new fid 0x%x, vid 0x%x\n", + pr_debug("transitioned (cpu%d): new fid 0x%x, vid 0x%x\n", smp_processor_id(), data->currfid, data->currvid); return 0; @@ -339,7 +339,7 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 savefid = data->currfid; u32 maxvid, lo, rvomult = 1; - dprintk("ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, " + pr_debug("ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, " "reqvid 0x%x, rvo 0x%x\n", smp_processor_id(), data->currfid, data->currvid, reqvid, data->rvo); @@ -349,12 +349,12 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, rvosteps *= rvomult; rdmsr(MSR_FIDVID_STATUS, lo, maxvid); maxvid = 0x1f & (maxvid >> 16); - dprintk("ph1 maxvid=0x%x\n", maxvid); + pr_debug("ph1 maxvid=0x%x\n", maxvid); if (reqvid < maxvid) /* lower numbers are higher voltages */ reqvid = maxvid; while (data->currvid > reqvid) { - dprintk("ph1: curr 0x%x, req vid 0x%x\n", + pr_debug("ph1: curr 0x%x, req vid 0x%x\n", data->currvid, reqvid); if (decrease_vid_code_by_step(data, reqvid, data->vidmvs)) return 1; @@ -365,7 +365,7 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, if (data->currvid == maxvid) { rvosteps = 0; } else { - dprintk("ph1: changing vid for rvo, req 0x%x\n", + pr_debug("ph1: changing vid for rvo, req 0x%x\n", data->currvid - 1); if (decrease_vid_code_by_step(data, data->currvid-1, 1)) return 1; @@ -382,7 +382,7 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, return 1; } - dprintk("ph1 complete, currfid 0x%x, currvid 0x%x\n", + pr_debug("ph1 complete, currfid 0x%x, currvid 0x%x\n", data->currfid, data->currvid); return 0; @@ -400,7 +400,7 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid) return 0; } - dprintk("ph2 (cpu%d): starting, currfid 0x%x, currvid 0x%x, " + pr_debug("ph2 (cpu%d): starting, currfid 0x%x, currvid 0x%x, " "reqfid 0x%x\n", smp_processor_id(), data->currfid, data->currvid, reqfid); @@ -457,7 +457,7 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid) return 1; } - dprintk("ph2 complete, currfid 0x%x, currvid 0x%x\n", + pr_debug("ph2 complete, currfid 0x%x, currvid 0x%x\n", data->currfid, data->currvid); return 0; @@ -470,7 +470,7 @@ static int core_voltage_post_transition(struct powernow_k8_data *data, u32 savefid = data->currfid; u32 savereqvid = reqvid; - dprintk("ph3 (cpu%d): starting, currfid 0x%x, currvid 0x%x\n", + pr_debug("ph3 (cpu%d): starting, currfid 0x%x, currvid 0x%x\n", smp_processor_id(), data->currfid, data->currvid); @@ -498,17 +498,17 @@ static int core_voltage_post_transition(struct powernow_k8_data *data, return 1; if (savereqvid != data->currvid) { - dprintk("ph3 failed, currvid 0x%x\n", data->currvid); + pr_debug("ph3 failed, currvid 0x%x\n", data->currvid); return 1; } if (savefid != data->currfid) { - dprintk("ph3 failed, currfid changed 0x%x\n", + pr_debug("ph3 failed, currfid changed 0x%x\n", data->currfid); return 1; } - dprintk("ph3 complete, currfid 0x%x, currvid 0x%x\n", + pr_debug("ph3 complete, currfid 0x%x, currvid 0x%x\n", data->currfid, data->currvid); return 0; @@ -707,7 +707,7 @@ static int fill_powernow_table(struct powernow_k8_data *data, return -EIO; } - dprintk("cfid 0x%x, cvid 0x%x\n", data->currfid, data->currvid); + pr_debug("cfid 0x%x, cvid 0x%x\n", data->currfid, data->currvid); data->powernow_table = powernow_table; if (cpumask_first(cpu_core_mask(data->cpu)) == data->cpu) print_basics(data); @@ -717,7 +717,7 @@ static int fill_powernow_table(struct powernow_k8_data *data, (pst[j].vid == data->currvid)) return 0; - dprintk("currfid/vid do not match PST, ignoring\n"); + pr_debug("currfid/vid do not match PST, ignoring\n"); return 0; } @@ -739,36 +739,36 @@ static int find_psb_table(struct powernow_k8_data *data) if (memcmp(psb, PSB_ID_STRING, PSB_ID_STRING_LEN) != 0) continue; - dprintk("found PSB header at 0x%p\n", psb); + pr_debug("found PSB header at 0x%p\n", psb); - dprintk("table vers: 0x%x\n", psb->tableversion); + pr_debug("table vers: 0x%x\n", psb->tableversion); if (psb->tableversion != PSB_VERSION_1_4) { printk(KERN_ERR FW_BUG PFX "PSB table is not v1.4\n"); return -ENODEV; } - dprintk("flags: 0x%x\n", psb->flags1); + pr_debug("flags: 0x%x\n", psb->flags1); if (psb->flags1) { printk(KERN_ERR FW_BUG PFX "unknown flags\n"); return -ENODEV; } data->vstable = psb->vstable; - dprintk("voltage stabilization time: %d(*20us)\n", + pr_debug("voltage stabilization time: %d(*20us)\n", data->vstable); - dprintk("flags2: 0x%x\n", psb->flags2); + pr_debug("flags2: 0x%x\n", psb->flags2); data->rvo = psb->flags2 & 3; data->irt = ((psb->flags2) >> 2) & 3; mvs = ((psb->flags2) >> 4) & 3; data->vidmvs = 1 << mvs; data->batps = ((psb->flags2) >> 6) & 3; - dprintk("ramp voltage offset: %d\n", data->rvo); - dprintk("isochronous relief time: %d\n", data->irt); - dprintk("maximum voltage step: %d - 0x%x\n", mvs, data->vidmvs); + pr_debug("ramp voltage offset: %d\n", data->rvo); + pr_debug("isochronous relief time: %d\n", data->irt); + pr_debug("maximum voltage step: %d - 0x%x\n", mvs, data->vidmvs); - dprintk("numpst: 0x%x\n", psb->num_tables); + pr_debug("numpst: 0x%x\n", psb->num_tables); cpst = psb->num_tables; if ((psb->cpuid == 0x00000fc0) || (psb->cpuid == 0x00000fe0)) { @@ -783,13 +783,13 @@ static int find_psb_table(struct powernow_k8_data *data) } data->plllock = psb->plllocktime; - dprintk("plllocktime: 0x%x (units 1us)\n", psb->plllocktime); - dprintk("maxfid: 0x%x\n", psb->maxfid); - dprintk("maxvid: 0x%x\n", psb->maxvid); + pr_debug("plllocktime: 0x%x (units 1us)\n", psb->plllocktime); + pr_debug("maxfid: 0x%x\n", psb->maxfid); + pr_debug("maxvid: 0x%x\n", psb->maxvid); maxvid = psb->maxvid; data->numps = psb->numps; - dprintk("numpstates: 0x%x\n", data->numps); + pr_debug("numpstates: 0x%x\n", data->numps); return fill_powernow_table(data, (struct pst_s *)(psb+1), maxvid); } @@ -834,13 +834,13 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) u64 control, status; if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) { - dprintk("register performance failed: bad ACPI data\n"); + pr_debug("register performance failed: bad ACPI data\n"); return -EIO; } /* verify the data contained in the ACPI structures */ if (data->acpi_data.state_count <= 1) { - dprintk("No ACPI P-States\n"); + pr_debug("No ACPI P-States\n"); goto err_out; } @@ -849,7 +849,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) if ((control != ACPI_ADR_SPACE_FIXED_HARDWARE) || (status != ACPI_ADR_SPACE_FIXED_HARDWARE)) { - dprintk("Invalid control/status registers (%x - %x)\n", + pr_debug("Invalid control/status registers (%llx - %llx)\n", control, status); goto err_out; } @@ -858,7 +858,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) powernow_table = kmalloc((sizeof(struct cpufreq_frequency_table) * (data->acpi_data.state_count + 1)), GFP_KERNEL); if (!powernow_table) { - dprintk("powernow_table memory alloc failure\n"); + pr_debug("powernow_table memory alloc failure\n"); goto err_out; } @@ -928,7 +928,7 @@ static int fill_powernow_table_pstate(struct powernow_k8_data *data, } rdmsr(MSR_PSTATE_DEF_BASE + index, lo, hi); if (!(hi & HW_PSTATE_VALID_MASK)) { - dprintk("invalid pstate %d, ignoring\n", index); + pr_debug("invalid pstate %d, ignoring\n", index); invalidate_entry(powernow_table, i); continue; } @@ -968,7 +968,7 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data, vid = (control >> VID_SHIFT) & VID_MASK; } - dprintk(" %d : fid 0x%x, vid 0x%x\n", i, fid, vid); + pr_debug(" %d : fid 0x%x, vid 0x%x\n", i, fid, vid); index = fid | (vid<<8); powernow_table[i].index = index; @@ -978,7 +978,7 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data, /* verify frequency is OK */ if ((freq > (MAX_FREQ * 1000)) || (freq < (MIN_FREQ * 1000))) { - dprintk("invalid freq %u kHz, ignoring\n", freq); + pr_debug("invalid freq %u kHz, ignoring\n", freq); invalidate_entry(powernow_table, i); continue; } @@ -986,7 +986,7 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data, /* verify voltage is OK - * BIOSs are using "off" to indicate invalid */ if (vid == VID_OFF) { - dprintk("invalid vid %u, ignoring\n", vid); + pr_debug("invalid vid %u, ignoring\n", vid); invalidate_entry(powernow_table, i); continue; } @@ -1047,7 +1047,7 @@ static int transition_frequency_fidvid(struct powernow_k8_data *data, int res, i; struct cpufreq_freqs freqs; - dprintk("cpu %d transition to index %u\n", smp_processor_id(), index); + pr_debug("cpu %d transition to index %u\n", smp_processor_id(), index); /* fid/vid correctness check for k8 */ /* fid are the lower 8 bits of the index we stored into @@ -1057,18 +1057,18 @@ static int transition_frequency_fidvid(struct powernow_k8_data *data, fid = data->powernow_table[index].index & 0xFF; vid = (data->powernow_table[index].index & 0xFF00) >> 8; - dprintk("table matched fid 0x%x, giving vid 0x%x\n", fid, vid); + pr_debug("table matched fid 0x%x, giving vid 0x%x\n", fid, vid); if (query_current_values_with_pending_wait(data)) return 1; if ((data->currvid == vid) && (data->currfid == fid)) { - dprintk("target matches current values (fid 0x%x, vid 0x%x)\n", + pr_debug("target matches current values (fid 0x%x, vid 0x%x)\n", fid, vid); return 0; } - dprintk("cpu %d, changing to fid 0x%x, vid 0x%x\n", + pr_debug("cpu %d, changing to fid 0x%x, vid 0x%x\n", smp_processor_id(), fid, vid); freqs.old = find_khz_freq_from_fid(data->currfid); freqs.new = find_khz_freq_from_fid(fid); @@ -1096,7 +1096,7 @@ static int transition_frequency_pstate(struct powernow_k8_data *data, int res, i; struct cpufreq_freqs freqs; - dprintk("cpu %d transition to index %u\n", smp_processor_id(), index); + pr_debug("cpu %d transition to index %u\n", smp_processor_id(), index); /* get MSR index for hardware pstate transition */ pstate = index & HW_PSTATE_MASK; @@ -1156,14 +1156,14 @@ static int powernowk8_target(struct cpufreq_policy *pol, goto err_out; } - dprintk("targ: cpu %d, %d kHz, min %d, max %d, relation %d\n", + pr_debug("targ: cpu %d, %d kHz, min %d, max %d, relation %d\n", pol->cpu, targfreq, pol->min, pol->max, relation); if (query_current_values_with_pending_wait(data)) goto err_out; if (cpu_family != CPU_HW_PSTATE) { - dprintk("targ: curr fid 0x%x, vid 0x%x\n", + pr_debug("targ: curr fid 0x%x, vid 0x%x\n", data->currfid, data->currvid); if ((checkvid != data->currvid) || @@ -1319,7 +1319,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) data->currpstate); else pol->cur = find_khz_freq_from_fid(data->currfid); - dprintk("policy current frequency %d kHz\n", pol->cur); + pr_debug("policy current frequency %d kHz\n", pol->cur); /* min/max the cpu is capable of */ if (cpufreq_frequency_table_cpuinfo(pol, data->powernow_table)) { @@ -1337,10 +1337,10 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) cpufreq_frequency_table_get_attr(data->powernow_table, pol->cpu); if (cpu_family == CPU_HW_PSTATE) - dprintk("cpu_init done, current pstate 0x%x\n", + pr_debug("cpu_init done, current pstate 0x%x\n", data->currpstate); else - dprintk("cpu_init done, current fid 0x%x, vid 0x%x\n", + pr_debug("cpu_init done, current fid 0x%x, vid 0x%x\n", data->currfid, data->currvid); per_cpu(powernow_data, pol->cpu) = data; @@ -1586,7 +1586,7 @@ static int __cpuinit powernowk8_init(void) /* driver entry point for term */ static void __exit powernowk8_exit(void) { - dprintk("exit\n"); + pr_debug("exit\n"); if (boot_cpu_has(X86_FEATURE_CPB)) { msrs_free(msrs); diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.h b/arch/x86/kernel/cpu/cpufreq/powernow-k8.h index df3529b1c02d..3744d26cdc2b 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.h +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.h @@ -211,8 +211,6 @@ struct pst_s { u8 vid; }; -#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "powernow-k8", msg) - static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid, u32 regfid); static int core_voltage_post_transition(struct powernow_k8_data *data, u32 reqvid); diff --git a/arch/x86/kernel/cpu/cpufreq/sc520_freq.c b/arch/x86/kernel/cpu/cpufreq/sc520_freq.c index 435a996a613a..1e205e6b1727 100644 --- a/arch/x86/kernel/cpu/cpufreq/sc520_freq.c +++ b/arch/x86/kernel/cpu/cpufreq/sc520_freq.c @@ -29,8 +29,6 @@ static __u8 __iomem *cpuctl; -#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \ - "sc520_freq", msg) #define PFX "sc520_freq: " static struct cpufreq_frequency_table sc520_freq_table[] = { @@ -66,7 +64,7 @@ static void sc520_freq_set_cpu_state(unsigned int state) cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - dprintk("attempting to set frequency to %i kHz\n", + pr_debug("attempting to set frequency to %i kHz\n", sc520_freq_table[state].frequency); local_irq_disable(); @@ -161,7 +159,7 @@ static int __init sc520_freq_init(void) /* Test if we have the right hardware */ if (c->x86_vendor != X86_VENDOR_AMD || c->x86 != 4 || c->x86_model != 9) { - dprintk("no Elan SC520 processor found!\n"); + pr_debug("no Elan SC520 processor found!\n"); return -ENODEV; } cpuctl = ioremap((unsigned long)(MMCR_BASE + OFFS_CPUCTL), 1); diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c index 9b1ff37de46a..6ea3455def21 100644 --- a/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c +++ b/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c @@ -29,9 +29,6 @@ #define PFX "speedstep-centrino: " #define MAINTAINER "cpufreq@vger.kernel.org" -#define dprintk(msg...) \ - cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "speedstep-centrino", msg) - #define INTEL_MSR_RANGE (0xffff) struct cpu_id @@ -244,7 +241,7 @@ static int centrino_cpu_init_table(struct cpufreq_policy *policy) if (model->cpu_id == NULL) { /* No match at all */ - dprintk("no support for CPU model \"%s\": " + pr_debug("no support for CPU model \"%s\": " "send /proc/cpuinfo to " MAINTAINER "\n", cpu->x86_model_id); return -ENOENT; @@ -252,15 +249,15 @@ static int centrino_cpu_init_table(struct cpufreq_policy *policy) if (model->op_points == NULL) { /* Matched a non-match */ - dprintk("no table support for CPU model \"%s\"\n", + pr_debug("no table support for CPU model \"%s\"\n", cpu->x86_model_id); - dprintk("try using the acpi-cpufreq driver\n"); + pr_debug("try using the acpi-cpufreq driver\n"); return -ENOENT; } per_cpu(centrino_model, policy->cpu) = model; - dprintk("found \"%s\": max frequency: %dkHz\n", + pr_debug("found \"%s\": max frequency: %dkHz\n", model->model_name, model->max_freq); return 0; @@ -369,7 +366,7 @@ static int centrino_cpu_init(struct cpufreq_policy *policy) per_cpu(centrino_cpu, policy->cpu) = &cpu_ids[i]; if (!per_cpu(centrino_cpu, policy->cpu)) { - dprintk("found unsupported CPU with " + pr_debug("found unsupported CPU with " "Enhanced SpeedStep: send /proc/cpuinfo to " MAINTAINER "\n"); return -ENODEV; @@ -385,7 +382,7 @@ static int centrino_cpu_init(struct cpufreq_policy *policy) if (!(l & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP)) { l |= MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP; - dprintk("trying to enable Enhanced SpeedStep (%x)\n", l); + pr_debug("trying to enable Enhanced SpeedStep (%x)\n", l); wrmsr(MSR_IA32_MISC_ENABLE, l, h); /* check to see if it stuck */ @@ -402,7 +399,7 @@ static int centrino_cpu_init(struct cpufreq_policy *policy) /* 10uS transition latency */ policy->cur = freq; - dprintk("centrino_cpu_init: cur=%dkHz\n", policy->cur); + pr_debug("centrino_cpu_init: cur=%dkHz\n", policy->cur); ret = cpufreq_frequency_table_cpuinfo(policy, per_cpu(centrino_model, policy->cpu)->op_points); @@ -498,7 +495,7 @@ static int centrino_target (struct cpufreq_policy *policy, good_cpu = j; if (good_cpu >= nr_cpu_ids) { - dprintk("couldn't limit to CPUs in this domain\n"); + pr_debug("couldn't limit to CPUs in this domain\n"); retval = -EAGAIN; if (first_cpu) { /* We haven't started the transition yet. */ @@ -512,7 +509,7 @@ static int centrino_target (struct cpufreq_policy *policy, if (first_cpu) { rdmsr_on_cpu(good_cpu, MSR_IA32_PERF_CTL, &oldmsr, &h); if (msr == (oldmsr & 0xffff)) { - dprintk("no change needed - msr was and needs " + pr_debug("no change needed - msr was and needs " "to be %x\n", oldmsr); retval = 0; goto out; @@ -521,7 +518,7 @@ static int centrino_target (struct cpufreq_policy *policy, freqs.old = extract_clock(oldmsr, cpu, 0); freqs.new = extract_clock(msr, cpu, 0); - dprintk("target=%dkHz old=%d new=%d msr=%04x\n", + pr_debug("target=%dkHz old=%d new=%d msr=%04x\n", target_freq, freqs.old, freqs.new, msr); for_each_cpu(k, policy->cpus) { diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c index 561758e95180..a748ce782fee 100644 --- a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c +++ b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c @@ -53,10 +53,6 @@ static struct cpufreq_frequency_table speedstep_freqs[] = { }; -#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \ - "speedstep-ich", msg) - - /** * speedstep_find_register - read the PMBASE address * @@ -80,7 +76,7 @@ static int speedstep_find_register(void) return -ENODEV; } - dprintk("pmbase is 0x%x\n", pmbase); + pr_debug("pmbase is 0x%x\n", pmbase); return 0; } @@ -106,13 +102,13 @@ static void speedstep_set_state(unsigned int state) /* read state */ value = inb(pmbase + 0x50); - dprintk("read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value); + pr_debug("read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value); /* write new state */ value &= 0xFE; value |= state; - dprintk("writing 0x%x to pmbase 0x%x + 0x50\n", value, pmbase); + pr_debug("writing 0x%x to pmbase 0x%x + 0x50\n", value, pmbase); /* Disable bus master arbitration */ pm2_blk = inb(pmbase + 0x20); @@ -132,10 +128,10 @@ static void speedstep_set_state(unsigned int state) /* Enable IRQs */ local_irq_restore(flags); - dprintk("read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value); + pr_debug("read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value); if (state == (value & 0x1)) - dprintk("change to %u MHz succeeded\n", + pr_debug("change to %u MHz succeeded\n", speedstep_get_frequency(speedstep_processor) / 1000); else printk(KERN_ERR "cpufreq: change failed - I/O error\n"); @@ -165,7 +161,7 @@ static int speedstep_activate(void) pci_read_config_word(speedstep_chipset_dev, 0x00A0, &value); if (!(value & 0x08)) { value |= 0x08; - dprintk("activating SpeedStep (TM) registers\n"); + pr_debug("activating SpeedStep (TM) registers\n"); pci_write_config_word(speedstep_chipset_dev, 0x00A0, value); } @@ -218,7 +214,7 @@ static unsigned int speedstep_detect_chipset(void) return 2; /* 2-M */ if (hostbridge->revision < 5) { - dprintk("hostbridge does not support speedstep\n"); + pr_debug("hostbridge does not support speedstep\n"); speedstep_chipset_dev = NULL; pci_dev_put(hostbridge); return 0; @@ -246,7 +242,7 @@ static unsigned int speedstep_get(unsigned int cpu) if (smp_call_function_single(cpu, get_freq_data, &speed, 1) != 0) BUG(); - dprintk("detected %u kHz as current frequency\n", speed); + pr_debug("detected %u kHz as current frequency\n", speed); return speed; } @@ -276,7 +272,7 @@ static int speedstep_target(struct cpufreq_policy *policy, freqs.new = speedstep_freqs[newstate].frequency; freqs.cpu = policy->cpu; - dprintk("transiting from %u to %u kHz\n", freqs.old, freqs.new); + pr_debug("transiting from %u to %u kHz\n", freqs.old, freqs.new); /* no transition necessary */ if (freqs.old == freqs.new) @@ -351,7 +347,7 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy) if (!speed) return -EIO; - dprintk("currently at %s speed setting - %i MHz\n", + pr_debug("currently at %s speed setting - %i MHz\n", (speed == speedstep_freqs[SPEEDSTEP_LOW].frequency) ? "low" : "high", (speed / 1000)); @@ -405,14 +401,14 @@ static int __init speedstep_init(void) /* detect processor */ speedstep_processor = speedstep_detect_processor(); if (!speedstep_processor) { - dprintk("Intel(R) SpeedStep(TM) capable processor " + pr_debug("Intel(R) SpeedStep(TM) capable processor " "not found\n"); return -ENODEV; } /* detect chipset */ if (!speedstep_detect_chipset()) { - dprintk("Intel(R) SpeedStep(TM) for this chipset not " + pr_debug("Intel(R) SpeedStep(TM) for this chipset not " "(yet) available.\n"); return -ENODEV; } diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c b/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c index a94ec6be69fa..8af2d2fd9d51 100644 --- a/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c +++ b/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c @@ -18,9 +18,6 @@ #include #include "speedstep-lib.h" -#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \ - "speedstep-lib", msg) - #define PFX "speedstep-lib: " #ifdef CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK @@ -75,7 +72,7 @@ static unsigned int pentium3_get_frequency(enum speedstep_processor processor) /* read MSR 0x2a - we only need the low 32 bits */ rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp); - dprintk("P3 - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp); + pr_debug("P3 - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp); msr_tmp = msr_lo; /* decode the FSB */ @@ -89,7 +86,7 @@ static unsigned int pentium3_get_frequency(enum speedstep_processor processor) /* decode the multiplier */ if (processor == SPEEDSTEP_CPU_PIII_C_EARLY) { - dprintk("workaround for early PIIIs\n"); + pr_debug("workaround for early PIIIs\n"); msr_lo &= 0x03c00000; } else msr_lo &= 0x0bc00000; @@ -100,7 +97,7 @@ static unsigned int pentium3_get_frequency(enum speedstep_processor processor) j++; } - dprintk("speed is %u\n", + pr_debug("speed is %u\n", (msr_decode_mult[j].ratio * msr_decode_fsb[i].value * 100)); return msr_decode_mult[j].ratio * msr_decode_fsb[i].value * 100; @@ -112,7 +109,7 @@ static unsigned int pentiumM_get_frequency(void) u32 msr_lo, msr_tmp; rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp); - dprintk("PM - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp); + pr_debug("PM - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp); /* see table B-2 of 24547212.pdf */ if (msr_lo & 0x00040000) { @@ -122,7 +119,7 @@ static unsigned int pentiumM_get_frequency(void) } msr_tmp = (msr_lo >> 22) & 0x1f; - dprintk("bits 22-26 are 0x%x, speed is %u\n", + pr_debug("bits 22-26 are 0x%x, speed is %u\n", msr_tmp, (msr_tmp * 100 * 1000)); return msr_tmp * 100 * 1000; @@ -160,11 +157,11 @@ static unsigned int pentium_core_get_frequency(void) } rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp); - dprintk("PCORE - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", + pr_debug("PCORE - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp); msr_tmp = (msr_lo >> 22) & 0x1f; - dprintk("bits 22-26 are 0x%x, speed is %u\n", + pr_debug("bits 22-26 are 0x%x, speed is %u\n", msr_tmp, (msr_tmp * fsb)); ret = (msr_tmp * fsb); @@ -190,7 +187,7 @@ static unsigned int pentium4_get_frequency(void) rdmsr(0x2c, msr_lo, msr_hi); - dprintk("P4 - MSR_EBC_FREQUENCY_ID: 0x%x 0x%x\n", msr_lo, msr_hi); + pr_debug("P4 - MSR_EBC_FREQUENCY_ID: 0x%x 0x%x\n", msr_lo, msr_hi); /* decode the FSB: see IA-32 Intel (C) Architecture Software * Developer's Manual, Volume 3: System Prgramming Guide, @@ -217,7 +214,7 @@ static unsigned int pentium4_get_frequency(void) /* Multiplier. */ mult = msr_lo >> 24; - dprintk("P4 - FSB %u kHz; Multiplier %u; Speed %u kHz\n", + pr_debug("P4 - FSB %u kHz; Multiplier %u; Speed %u kHz\n", fsb, mult, (fsb * mult)); ret = (fsb * mult); @@ -257,7 +254,7 @@ unsigned int speedstep_detect_processor(void) struct cpuinfo_x86 *c = &cpu_data(0); u32 ebx, msr_lo, msr_hi; - dprintk("x86: %x, model: %x\n", c->x86, c->x86_model); + pr_debug("x86: %x, model: %x\n", c->x86, c->x86_model); if ((c->x86_vendor != X86_VENDOR_INTEL) || ((c->x86 != 6) && (c->x86 != 0xF))) @@ -272,7 +269,7 @@ unsigned int speedstep_detect_processor(void) ebx = cpuid_ebx(0x00000001); ebx &= 0x000000FF; - dprintk("ebx value is %x, x86_mask is %x\n", ebx, c->x86_mask); + pr_debug("ebx value is %x, x86_mask is %x\n", ebx, c->x86_mask); switch (c->x86_mask) { case 4: @@ -327,7 +324,7 @@ unsigned int speedstep_detect_processor(void) /* cpuid_ebx(1) is 0x04 for desktop PIII, * 0x06 for mobile PIII-M */ ebx = cpuid_ebx(0x00000001); - dprintk("ebx is %x\n", ebx); + pr_debug("ebx is %x\n", ebx); ebx &= 0x000000FF; @@ -344,7 +341,7 @@ unsigned int speedstep_detect_processor(void) /* all mobile PIII Coppermines have FSB 100 MHz * ==> sort out a few desktop PIIIs. */ rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_hi); - dprintk("Coppermine: MSR_IA32_EBL_CR_POWERON is 0x%x, 0x%x\n", + pr_debug("Coppermine: MSR_IA32_EBL_CR_POWERON is 0x%x, 0x%x\n", msr_lo, msr_hi); msr_lo &= 0x00c0000; if (msr_lo != 0x0080000) @@ -357,12 +354,12 @@ unsigned int speedstep_detect_processor(void) * bit 56 or 57 is set */ rdmsr(MSR_IA32_PLATFORM_ID, msr_lo, msr_hi); - dprintk("Coppermine: MSR_IA32_PLATFORM ID is 0x%x, 0x%x\n", + pr_debug("Coppermine: MSR_IA32_PLATFORM ID is 0x%x, 0x%x\n", msr_lo, msr_hi); if ((msr_hi & (1<<18)) && (relaxed_check ? 1 : (msr_hi & (3<<24)))) { if (c->x86_mask == 0x01) { - dprintk("early PIII version\n"); + pr_debug("early PIII version\n"); return SPEEDSTEP_CPU_PIII_C_EARLY; } else return SPEEDSTEP_CPU_PIII_C; @@ -393,14 +390,14 @@ unsigned int speedstep_get_freqs(enum speedstep_processor processor, if ((!processor) || (!low_speed) || (!high_speed) || (!set_state)) return -EINVAL; - dprintk("trying to determine both speeds\n"); + pr_debug("trying to determine both speeds\n"); /* get current speed */ prev_speed = speedstep_get_frequency(processor); if (!prev_speed) return -EIO; - dprintk("previous speed is %u\n", prev_speed); + pr_debug("previous speed is %u\n", prev_speed); local_irq_save(flags); @@ -412,7 +409,7 @@ unsigned int speedstep_get_freqs(enum speedstep_processor processor, goto out; } - dprintk("low speed is %u\n", *low_speed); + pr_debug("low speed is %u\n", *low_speed); /* start latency measurement */ if (transition_latency) @@ -431,7 +428,7 @@ unsigned int speedstep_get_freqs(enum speedstep_processor processor, goto out; } - dprintk("high speed is %u\n", *high_speed); + pr_debug("high speed is %u\n", *high_speed); if (*low_speed == *high_speed) { ret = -ENODEV; @@ -445,7 +442,7 @@ unsigned int speedstep_get_freqs(enum speedstep_processor processor, if (transition_latency) { *transition_latency = (tv2.tv_sec - tv1.tv_sec) * USEC_PER_SEC + tv2.tv_usec - tv1.tv_usec; - dprintk("transition latency is %u uSec\n", *transition_latency); + pr_debug("transition latency is %u uSec\n", *transition_latency); /* convert uSec to nSec and add 20% for safety reasons */ *transition_latency *= 1200; diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c b/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c index 91bc25b67bc1..c76ead3490bf 100644 --- a/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c +++ b/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c @@ -55,9 +55,6 @@ static struct cpufreq_frequency_table speedstep_freqs[] = { * of DMA activity going on? */ #define SMI_TRIES 5 -#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \ - "speedstep-smi", msg) - /** * speedstep_smi_ownership */ @@ -70,7 +67,7 @@ static int speedstep_smi_ownership(void) command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff); magic = virt_to_phys(magic_data); - dprintk("trying to obtain ownership with command %x at port %x\n", + pr_debug("trying to obtain ownership with command %x at port %x\n", command, smi_port); __asm__ __volatile__( @@ -85,7 +82,7 @@ static int speedstep_smi_ownership(void) : "memory" ); - dprintk("result is %x\n", result); + pr_debug("result is %x\n", result); return result; } @@ -106,13 +103,13 @@ static int speedstep_smi_get_freqs(unsigned int *low, unsigned int *high) u32 function = GET_SPEEDSTEP_FREQS; if (!(ist_info.event & 0xFFFF)) { - dprintk("bug #1422 -- can't read freqs from BIOS\n"); + pr_debug("bug #1422 -- can't read freqs from BIOS\n"); return -ENODEV; } command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff); - dprintk("trying to determine frequencies with command %x at port %x\n", + pr_debug("trying to determine frequencies with command %x at port %x\n", command, smi_port); __asm__ __volatile__( @@ -129,7 +126,7 @@ static int speedstep_smi_get_freqs(unsigned int *low, unsigned int *high) "d" (smi_port), "S" (0), "D" (0) ); - dprintk("result %x, low_freq %u, high_freq %u\n", + pr_debug("result %x, low_freq %u, high_freq %u\n", result, low_mhz, high_mhz); /* abort if results are obviously incorrect... */ @@ -154,7 +151,7 @@ static int speedstep_get_state(void) command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff); - dprintk("trying to determine current setting with command %x " + pr_debug("trying to determine current setting with command %x " "at port %x\n", command, smi_port); __asm__ __volatile__( @@ -168,7 +165,7 @@ static int speedstep_get_state(void) "d" (smi_port), "S" (0), "D" (0) ); - dprintk("state is %x, result is %x\n", state, result); + pr_debug("state is %x, result is %x\n", state, result); return state & 1; } @@ -194,13 +191,13 @@ static void speedstep_set_state(unsigned int state) command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff); - dprintk("trying to set frequency to state %u " + pr_debug("trying to set frequency to state %u " "with command %x at port %x\n", state, command, smi_port); do { if (retry) { - dprintk("retry %u, previous result %u, waiting...\n", + pr_debug("retry %u, previous result %u, waiting...\n", retry, result); mdelay(retry * 50); } @@ -221,7 +218,7 @@ static void speedstep_set_state(unsigned int state) local_irq_restore(flags); if (new_state == state) - dprintk("change to %u MHz succeeded after %u tries " + pr_debug("change to %u MHz succeeded after %u tries " "with result %u\n", (speedstep_freqs[new_state].frequency / 1000), retry, result); @@ -292,7 +289,7 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy) result = speedstep_smi_ownership(); if (result) { - dprintk("fails in acquiring ownership of a SMI interface.\n"); + pr_debug("fails in acquiring ownership of a SMI interface.\n"); return -EINVAL; } @@ -304,7 +301,7 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy) if (result) { /* fall back to speedstep_lib.c dection mechanism: * try both states out */ - dprintk("could not detect low and high frequencies " + pr_debug("could not detect low and high frequencies " "by SMI call.\n"); result = speedstep_get_freqs(speedstep_processor, low, high, @@ -312,18 +309,18 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy) &speedstep_set_state); if (result) { - dprintk("could not detect two different speeds" + pr_debug("could not detect two different speeds" " -- aborting.\n"); return result; } else - dprintk("workaround worked.\n"); + pr_debug("workaround worked.\n"); } /* get current speed setting */ state = speedstep_get_state(); speed = speedstep_freqs[state].frequency; - dprintk("currently at %s speed setting - %i MHz\n", + pr_debug("currently at %s speed setting - %i MHz\n", (speed == speedstep_freqs[SPEEDSTEP_LOW].frequency) ? "low" : "high", (speed / 1000)); @@ -360,7 +357,7 @@ static int speedstep_resume(struct cpufreq_policy *policy) int result = speedstep_smi_ownership(); if (result) - dprintk("fails in re-acquiring ownership of a SMI interface.\n"); + pr_debug("fails in re-acquiring ownership of a SMI interface.\n"); return result; } @@ -403,12 +400,12 @@ static int __init speedstep_init(void) } if (!speedstep_processor) { - dprintk("No supported Intel CPU detected.\n"); + pr_debug("No supported Intel CPU detected.\n"); return -ENODEV; } - dprintk("signature:0x%.8lx, command:0x%.8lx, " - "event:0x%.8lx, perf_level:0x%.8lx.\n", + pr_debug("signature:0x%.8ulx, command:0x%.8ulx, " + "event:0x%.8ulx, perf_level:0x%.8ulx.\n", ist_info.signature, ist_info.command, ist_info.event, ist_info.perf_level); diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 3a73a93596e8..85b32376dad7 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -49,10 +49,6 @@ ACPI_MODULE_NAME("processor_perflib"); static DEFINE_MUTEX(performance_mutex); -/* Use cpufreq debug layer for _PPC changes. */ -#define cpufreq_printk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_CORE, \ - "cpufreq-core", msg) - /* * _PPC support is implemented as a CPUfreq policy notifier: * This means each time a CPUfreq driver registered also with @@ -145,7 +141,7 @@ static int acpi_processor_get_platform_limit(struct acpi_processor *pr) return -ENODEV; } - cpufreq_printk("CPU %d: _PPC is %d - frequency %s limited\n", pr->id, + pr_debug("CPU %d: _PPC is %d - frequency %s limited\n", pr->id, (int)ppc, ppc ? "" : "not"); pr->performance_platform_limit = (int)ppc; diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index ca8ee8093d6c..b78baa547ef5 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig @@ -18,19 +18,6 @@ if CPU_FREQ config CPU_FREQ_TABLE tristate -config CPU_FREQ_DEBUG - bool "Enable CPUfreq debugging" - help - Say Y here to enable CPUfreq subsystem (including drivers) - debugging. You will need to activate it via the kernel - command line by passing - cpufreq.debug= - - To get , add - 1 to activate CPUfreq core debugging, - 2 to activate CPUfreq drivers debugging, and - 4 to activate CPUfreq governor debugging - config CPU_FREQ_STAT tristate "CPU frequency translation statistics" select CPU_FREQ_TABLE diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 7c10f96c5ae9..1e08af43ae72 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -32,9 +32,6 @@ #include -#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_CORE, \ - "cpufreq-core", msg) - /** * The "cpufreq driver" - the arch- or hardware-dependent low * level driver of CPUFreq support, and its spinlock. This lock @@ -180,93 +177,6 @@ void cpufreq_cpu_put(struct cpufreq_policy *data) EXPORT_SYMBOL_GPL(cpufreq_cpu_put); -/********************************************************************* - * UNIFIED DEBUG HELPERS * - *********************************************************************/ -#ifdef CONFIG_CPU_FREQ_DEBUG - -/* what part(s) of the CPUfreq subsystem are debugged? */ -static unsigned int debug; - -/* is the debug output ratelimit'ed using printk_ratelimit? User can - * set or modify this value. - */ -static unsigned int debug_ratelimit = 1; - -/* is the printk_ratelimit'ing enabled? It's enabled after a successful - * loading of a cpufreq driver, temporarily disabled when a new policy - * is set, and disabled upon cpufreq driver removal - */ -static unsigned int disable_ratelimit = 1; -static DEFINE_SPINLOCK(disable_ratelimit_lock); - -static void cpufreq_debug_enable_ratelimit(void) -{ - unsigned long flags; - - spin_lock_irqsave(&disable_ratelimit_lock, flags); - if (disable_ratelimit) - disable_ratelimit--; - spin_unlock_irqrestore(&disable_ratelimit_lock, flags); -} - -static void cpufreq_debug_disable_ratelimit(void) -{ - unsigned long flags; - - spin_lock_irqsave(&disable_ratelimit_lock, flags); - disable_ratelimit++; - spin_unlock_irqrestore(&disable_ratelimit_lock, flags); -} - -void cpufreq_debug_printk(unsigned int type, const char *prefix, - const char *fmt, ...) -{ - char s[256]; - va_list args; - unsigned int len; - unsigned long flags; - - WARN_ON(!prefix); - if (type & debug) { - spin_lock_irqsave(&disable_ratelimit_lock, flags); - if (!disable_ratelimit && debug_ratelimit - && !printk_ratelimit()) { - spin_unlock_irqrestore(&disable_ratelimit_lock, flags); - return; - } - spin_unlock_irqrestore(&disable_ratelimit_lock, flags); - - len = snprintf(s, 256, KERN_DEBUG "%s: ", prefix); - - va_start(args, fmt); - len += vsnprintf(&s[len], (256 - len), fmt, args); - va_end(args); - - printk(s); - - WARN_ON(len < 5); - } -} -EXPORT_SYMBOL(cpufreq_debug_printk); - - -module_param(debug, uint, 0644); -MODULE_PARM_DESC(debug, "CPUfreq debugging: add 1 to debug core," - " 2 to debug drivers, and 4 to debug governors."); - -module_param(debug_ratelimit, uint, 0644); -MODULE_PARM_DESC(debug_ratelimit, "CPUfreq debugging:" - " set to 0 to disable ratelimiting."); - -#else /* !CONFIG_CPU_FREQ_DEBUG */ - -static inline void cpufreq_debug_enable_ratelimit(void) { return; } -static inline void cpufreq_debug_disable_ratelimit(void) { return; } - -#endif /* CONFIG_CPU_FREQ_DEBUG */ - - /********************************************************************* * EXTERNALLY AFFECTING FREQUENCY CHANGES * *********************************************************************/ @@ -291,7 +201,7 @@ static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci) if (!l_p_j_ref_freq) { l_p_j_ref = loops_per_jiffy; l_p_j_ref_freq = ci->old; - dprintk("saving %lu as reference value for loops_per_jiffy; " + pr_debug("saving %lu as reference value for loops_per_jiffy; " "freq is %u kHz\n", l_p_j_ref, l_p_j_ref_freq); } if ((val == CPUFREQ_PRECHANGE && ci->old < ci->new) || @@ -299,7 +209,7 @@ static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci) (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) { loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq, ci->new); - dprintk("scaling loops_per_jiffy to %lu " + pr_debug("scaling loops_per_jiffy to %lu " "for frequency %u kHz\n", loops_per_jiffy, ci->new); } } @@ -326,7 +236,7 @@ void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state) BUG_ON(irqs_disabled()); freqs->flags = cpufreq_driver->flags; - dprintk("notification %u of frequency transition to %u kHz\n", + pr_debug("notification %u of frequency transition to %u kHz\n", state, freqs->new); policy = per_cpu(cpufreq_cpu_data, freqs->cpu); @@ -340,7 +250,7 @@ void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state) if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) { if ((policy) && (policy->cpu == freqs->cpu) && (policy->cur) && (policy->cur != freqs->old)) { - dprintk("Warning: CPU frequency is" + pr_debug("Warning: CPU frequency is" " %u, cpufreq assumed %u kHz.\n", freqs->old, policy->cur); freqs->old = policy->cur; @@ -353,7 +263,7 @@ void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state) case CPUFREQ_POSTCHANGE: adjust_jiffies(CPUFREQ_POSTCHANGE, freqs); - dprintk("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new, + pr_debug("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new, (unsigned long)freqs->cpu); trace_power_frequency(POWER_PSTATE, freqs->new, freqs->cpu); trace_cpu_frequency(freqs->new, freqs->cpu); @@ -753,7 +663,7 @@ no_policy: static void cpufreq_sysfs_release(struct kobject *kobj) { struct cpufreq_policy *policy = to_policy(kobj); - dprintk("last reference is dropped\n"); + pr_debug("last reference is dropped\n"); complete(&policy->kobj_unregister); } @@ -788,7 +698,7 @@ static int cpufreq_add_dev_policy(unsigned int cpu, gov = __find_governor(per_cpu(cpufreq_cpu_governor, cpu)); if (gov) { policy->governor = gov; - dprintk("Restoring governor %s for cpu %d\n", + pr_debug("Restoring governor %s for cpu %d\n", policy->governor->name, cpu); } #endif @@ -824,7 +734,7 @@ static int cpufreq_add_dev_policy(unsigned int cpu, per_cpu(cpufreq_cpu_data, cpu) = managed_policy; spin_unlock_irqrestore(&cpufreq_driver_lock, flags); - dprintk("CPU already managed, adding link\n"); + pr_debug("CPU already managed, adding link\n"); ret = sysfs_create_link(&sys_dev->kobj, &managed_policy->kobj, "cpufreq"); @@ -865,7 +775,7 @@ static int cpufreq_add_dev_symlink(unsigned int cpu, if (!cpu_online(j)) continue; - dprintk("CPU %u already managed, adding link\n", j); + pr_debug("CPU %u already managed, adding link\n", j); managed_policy = cpufreq_cpu_get(cpu); cpu_sys_dev = get_cpu_sysdev(j); ret = sysfs_create_link(&cpu_sys_dev->kobj, &policy->kobj, @@ -941,7 +851,7 @@ static int cpufreq_add_dev_interface(unsigned int cpu, policy->user_policy.governor = policy->governor; if (ret) { - dprintk("setting policy failed\n"); + pr_debug("setting policy failed\n"); if (cpufreq_driver->exit) cpufreq_driver->exit(policy); } @@ -977,8 +887,7 @@ static int cpufreq_add_dev(struct sys_device *sys_dev) if (cpu_is_offline(cpu)) return 0; - cpufreq_debug_disable_ratelimit(); - dprintk("adding CPU %u\n", cpu); + pr_debug("adding CPU %u\n", cpu); #ifdef CONFIG_SMP /* check whether a different CPU already registered this @@ -986,7 +895,6 @@ static int cpufreq_add_dev(struct sys_device *sys_dev) policy = cpufreq_cpu_get(cpu); if (unlikely(policy)) { cpufreq_cpu_put(policy); - cpufreq_debug_enable_ratelimit(); return 0; } #endif @@ -1037,7 +945,7 @@ static int cpufreq_add_dev(struct sys_device *sys_dev) */ ret = cpufreq_driver->init(policy); if (ret) { - dprintk("initialization failed\n"); + pr_debug("initialization failed\n"); goto err_unlock_policy; } policy->user_policy.min = policy->min; @@ -1063,8 +971,7 @@ static int cpufreq_add_dev(struct sys_device *sys_dev) kobject_uevent(&policy->kobj, KOBJ_ADD); module_put(cpufreq_driver->owner); - dprintk("initialization complete\n"); - cpufreq_debug_enable_ratelimit(); + pr_debug("initialization complete\n"); return 0; @@ -1088,7 +995,6 @@ err_free_policy: nomem_out: module_put(cpufreq_driver->owner); module_out: - cpufreq_debug_enable_ratelimit(); return ret; } @@ -1112,15 +1018,13 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev) unsigned int j; #endif - cpufreq_debug_disable_ratelimit(); - dprintk("unregistering CPU %u\n", cpu); + pr_debug("unregistering CPU %u\n", cpu); spin_lock_irqsave(&cpufreq_driver_lock, flags); data = per_cpu(cpufreq_cpu_data, cpu); if (!data) { spin_unlock_irqrestore(&cpufreq_driver_lock, flags); - cpufreq_debug_enable_ratelimit(); unlock_policy_rwsem_write(cpu); return -EINVAL; } @@ -1132,12 +1036,11 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev) * only need to unlink, put and exit */ if (unlikely(cpu != data->cpu)) { - dprintk("removing link\n"); + pr_debug("removing link\n"); cpumask_clear_cpu(cpu, data->cpus); spin_unlock_irqrestore(&cpufreq_driver_lock, flags); kobj = &sys_dev->kobj; cpufreq_cpu_put(data); - cpufreq_debug_enable_ratelimit(); unlock_policy_rwsem_write(cpu); sysfs_remove_link(kobj, "cpufreq"); return 0; @@ -1170,7 +1073,7 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev) for_each_cpu(j, data->cpus) { if (j == cpu) continue; - dprintk("removing link for cpu %u\n", j); + pr_debug("removing link for cpu %u\n", j); #ifdef CONFIG_HOTPLUG_CPU strncpy(per_cpu(cpufreq_cpu_governor, j), data->governor->name, CPUFREQ_NAME_LEN); @@ -1199,17 +1102,15 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev) * not referenced anymore by anybody before we proceed with * unloading. */ - dprintk("waiting for dropping of refcount\n"); + pr_debug("waiting for dropping of refcount\n"); wait_for_completion(cmp); - dprintk("wait complete\n"); + pr_debug("wait complete\n"); lock_policy_rwsem_write(cpu); if (cpufreq_driver->exit) cpufreq_driver->exit(data); unlock_policy_rwsem_write(cpu); - cpufreq_debug_enable_ratelimit(); - #ifdef CONFIG_HOTPLUG_CPU /* when the CPU which is the parent of the kobj is hotplugged * offline, check for siblings, and create cpufreq sysfs interface @@ -1255,7 +1156,7 @@ static void handle_update(struct work_struct *work) struct cpufreq_policy *policy = container_of(work, struct cpufreq_policy, update); unsigned int cpu = policy->cpu; - dprintk("handle_update for cpu %u called\n", cpu); + pr_debug("handle_update for cpu %u called\n", cpu); cpufreq_update_policy(cpu); } @@ -1273,7 +1174,7 @@ static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq, { struct cpufreq_freqs freqs; - dprintk("Warning: CPU frequency out of sync: cpufreq and timing " + pr_debug("Warning: CPU frequency out of sync: cpufreq and timing " "core thinks of %u, is %u kHz.\n", old_freq, new_freq); freqs.cpu = cpu; @@ -1376,7 +1277,7 @@ static int cpufreq_bp_suspend(void) int cpu = smp_processor_id(); struct cpufreq_policy *cpu_policy; - dprintk("suspending cpu %u\n", cpu); + pr_debug("suspending cpu %u\n", cpu); /* If there's no policy for the boot CPU, we have nothing to do. */ cpu_policy = cpufreq_cpu_get(cpu); @@ -1414,7 +1315,7 @@ static void cpufreq_bp_resume(void) int cpu = smp_processor_id(); struct cpufreq_policy *cpu_policy; - dprintk("resuming cpu %u\n", cpu); + pr_debug("resuming cpu %u\n", cpu); /* If there's no policy for the boot CPU, we have nothing to do. */ cpu_policy = cpufreq_cpu_get(cpu); @@ -1526,7 +1427,7 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy, { int retval = -EINVAL; - dprintk("target for CPU %u: %u kHz, relation %u\n", policy->cpu, + pr_debug("target for CPU %u: %u kHz, relation %u\n", policy->cpu, target_freq, relation); if (cpu_online(policy->cpu) && cpufreq_driver->target) retval = cpufreq_driver->target(policy, target_freq, relation); @@ -1612,7 +1513,7 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, if (!try_module_get(policy->governor->owner)) return -EINVAL; - dprintk("__cpufreq_governor for CPU %u, event %u\n", + pr_debug("__cpufreq_governor for CPU %u, event %u\n", policy->cpu, event); ret = policy->governor->governor(policy, event); @@ -1713,8 +1614,7 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, { int ret = 0; - cpufreq_debug_disable_ratelimit(); - dprintk("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu, + pr_debug("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu, policy->min, policy->max); memcpy(&policy->cpuinfo, &data->cpuinfo, @@ -1751,19 +1651,19 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, data->min = policy->min; data->max = policy->max; - dprintk("new min and max freqs are %u - %u kHz\n", + pr_debug("new min and max freqs are %u - %u kHz\n", data->min, data->max); if (cpufreq_driver->setpolicy) { data->policy = policy->policy; - dprintk("setting range\n"); + pr_debug("setting range\n"); ret = cpufreq_driver->setpolicy(policy); } else { if (policy->governor != data->governor) { /* save old, working values */ struct cpufreq_governor *old_gov = data->governor; - dprintk("governor switch\n"); + pr_debug("governor switch\n"); /* end old governor */ if (data->governor) @@ -1773,7 +1673,7 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, data->governor = policy->governor; if (__cpufreq_governor(data, CPUFREQ_GOV_START)) { /* new governor failed, so re-start old one */ - dprintk("starting governor %s failed\n", + pr_debug("starting governor %s failed\n", data->governor->name); if (old_gov) { data->governor = old_gov; @@ -1785,12 +1685,11 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, } /* might be a policy change, too, so fall through */ } - dprintk("governor: change or update limits\n"); + pr_debug("governor: change or update limits\n"); __cpufreq_governor(data, CPUFREQ_GOV_LIMITS); } error_out: - cpufreq_debug_enable_ratelimit(); return ret; } @@ -1817,7 +1716,7 @@ int cpufreq_update_policy(unsigned int cpu) goto fail; } - dprintk("updating policy for CPU %u\n", cpu); + pr_debug("updating policy for CPU %u\n", cpu); memcpy(&policy, data, sizeof(struct cpufreq_policy)); policy.min = data->user_policy.min; policy.max = data->user_policy.max; @@ -1829,7 +1728,7 @@ int cpufreq_update_policy(unsigned int cpu) if (cpufreq_driver->get) { policy.cur = cpufreq_driver->get(cpu); if (!data->cur) { - dprintk("Driver did not initialize current freq"); + pr_debug("Driver did not initialize current freq"); data->cur = policy.cur; } else { if (data->cur != policy.cur) @@ -1905,7 +1804,7 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data) ((!driver_data->setpolicy) && (!driver_data->target))) return -EINVAL; - dprintk("trying to register driver %s\n", driver_data->name); + pr_debug("trying to register driver %s\n", driver_data->name); if (driver_data->setpolicy) driver_data->flags |= CPUFREQ_CONST_LOOPS; @@ -1936,15 +1835,14 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data) /* if all ->init() calls failed, unregister */ if (ret) { - dprintk("no CPU initialized for driver %s\n", + pr_debug("no CPU initialized for driver %s\n", driver_data->name); goto err_sysdev_unreg; } } register_hotcpu_notifier(&cpufreq_cpu_notifier); - dprintk("driver %s up and running\n", driver_data->name); - cpufreq_debug_enable_ratelimit(); + pr_debug("driver %s up and running\n", driver_data->name); return 0; err_sysdev_unreg: @@ -1971,14 +1869,10 @@ int cpufreq_unregister_driver(struct cpufreq_driver *driver) { unsigned long flags; - cpufreq_debug_disable_ratelimit(); - - if (!cpufreq_driver || (driver != cpufreq_driver)) { - cpufreq_debug_enable_ratelimit(); + if (!cpufreq_driver || (driver != cpufreq_driver)) return -EINVAL; - } - dprintk("unregistering driver %s\n", driver->name); + pr_debug("unregistering driver %s\n", driver->name); sysdev_driver_unregister(&cpu_sysdev_class, &cpufreq_sysdev_driver); unregister_hotcpu_notifier(&cpufreq_cpu_notifier); diff --git a/drivers/cpufreq/cpufreq_performance.c b/drivers/cpufreq/cpufreq_performance.c index 7e2e515087f8..f13a8a9af6a1 100644 --- a/drivers/cpufreq/cpufreq_performance.c +++ b/drivers/cpufreq/cpufreq_performance.c @@ -15,9 +15,6 @@ #include #include -#define dprintk(msg...) \ - cpufreq_debug_printk(CPUFREQ_DEBUG_GOVERNOR, "performance", msg) - static int cpufreq_governor_performance(struct cpufreq_policy *policy, unsigned int event) @@ -25,7 +22,7 @@ static int cpufreq_governor_performance(struct cpufreq_policy *policy, switch (event) { case CPUFREQ_GOV_START: case CPUFREQ_GOV_LIMITS: - dprintk("setting to %u kHz because of event %u\n", + pr_debug("setting to %u kHz because of event %u\n", policy->max, event); __cpufreq_driver_target(policy, policy->max, CPUFREQ_RELATION_H); diff --git a/drivers/cpufreq/cpufreq_powersave.c b/drivers/cpufreq/cpufreq_powersave.c index e6db5faf3eb1..4c2eb512f2bc 100644 --- a/drivers/cpufreq/cpufreq_powersave.c +++ b/drivers/cpufreq/cpufreq_powersave.c @@ -15,16 +15,13 @@ #include #include -#define dprintk(msg...) \ - cpufreq_debug_printk(CPUFREQ_DEBUG_GOVERNOR, "powersave", msg) - static int cpufreq_governor_powersave(struct cpufreq_policy *policy, unsigned int event) { switch (event) { case CPUFREQ_GOV_START: case CPUFREQ_GOV_LIMITS: - dprintk("setting to %u kHz because of event %u\n", + pr_debug("setting to %u kHz because of event %u\n", policy->min, event); __cpufreq_driver_target(policy, policy->min, CPUFREQ_RELATION_L); diff --git a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c index 66d2d1d6c80f..f231015904c0 100644 --- a/drivers/cpufreq/cpufreq_userspace.c +++ b/drivers/cpufreq/cpufreq_userspace.c @@ -37,9 +37,6 @@ static DEFINE_PER_CPU(unsigned int, cpu_is_managed); static DEFINE_MUTEX(userspace_mutex); static int cpus_using_userspace_governor; -#define dprintk(msg...) \ - cpufreq_debug_printk(CPUFREQ_DEBUG_GOVERNOR, "userspace", msg) - /* keep track of frequency transitions */ static int userspace_cpufreq_notifier(struct notifier_block *nb, unsigned long val, @@ -50,7 +47,7 @@ userspace_cpufreq_notifier(struct notifier_block *nb, unsigned long val, if (!per_cpu(cpu_is_managed, freq->cpu)) return 0; - dprintk("saving cpu_cur_freq of cpu %u to be %u kHz\n", + pr_debug("saving cpu_cur_freq of cpu %u to be %u kHz\n", freq->cpu, freq->new); per_cpu(cpu_cur_freq, freq->cpu) = freq->new; @@ -73,7 +70,7 @@ static int cpufreq_set(struct cpufreq_policy *policy, unsigned int freq) { int ret = -EINVAL; - dprintk("cpufreq_set for cpu %u, freq %u kHz\n", policy->cpu, freq); + pr_debug("cpufreq_set for cpu %u, freq %u kHz\n", policy->cpu, freq); mutex_lock(&userspace_mutex); if (!per_cpu(cpu_is_managed, policy->cpu)) @@ -134,7 +131,7 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy, per_cpu(cpu_max_freq, cpu) = policy->max; per_cpu(cpu_cur_freq, cpu) = policy->cur; per_cpu(cpu_set_freq, cpu) = policy->cur; - dprintk("managing cpu %u started " + pr_debug("managing cpu %u started " "(%u - %u kHz, currently %u kHz)\n", cpu, per_cpu(cpu_min_freq, cpu), @@ -156,12 +153,12 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy, per_cpu(cpu_min_freq, cpu) = 0; per_cpu(cpu_max_freq, cpu) = 0; per_cpu(cpu_set_freq, cpu) = 0; - dprintk("managing cpu %u stopped\n", cpu); + pr_debug("managing cpu %u stopped\n", cpu); mutex_unlock(&userspace_mutex); break; case CPUFREQ_GOV_LIMITS: mutex_lock(&userspace_mutex); - dprintk("limit event for cpu %u: %u - %u kHz, " + pr_debug("limit event for cpu %u: %u - %u kHz, " "currently %u kHz, last set to %u kHz\n", cpu, policy->min, policy->max, per_cpu(cpu_cur_freq, cpu), diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c index 05432216e224..90431cb92804 100644 --- a/drivers/cpufreq/freq_table.c +++ b/drivers/cpufreq/freq_table.c @@ -14,9 +14,6 @@ #include #include -#define dprintk(msg...) \ - cpufreq_debug_printk(CPUFREQ_DEBUG_CORE, "freq-table", msg) - /********************************************************************* * FREQUENCY TABLE HELPERS * *********************************************************************/ @@ -31,11 +28,11 @@ int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy, for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) { unsigned int freq = table[i].frequency; if (freq == CPUFREQ_ENTRY_INVALID) { - dprintk("table entry %u is invalid, skipping\n", i); + pr_debug("table entry %u is invalid, skipping\n", i); continue; } - dprintk("table entry %u: %u kHz, %u index\n", + pr_debug("table entry %u: %u kHz, %u index\n", i, freq, table[i].index); if (freq < min_freq) min_freq = freq; @@ -61,7 +58,7 @@ int cpufreq_frequency_table_verify(struct cpufreq_policy *policy, unsigned int i; unsigned int count = 0; - dprintk("request for verification of policy (%u - %u kHz) for cpu %u\n", + pr_debug("request for verification of policy (%u - %u kHz) for cpu %u\n", policy->min, policy->max, policy->cpu); if (!cpu_online(policy->cpu)) @@ -86,7 +83,7 @@ int cpufreq_frequency_table_verify(struct cpufreq_policy *policy, cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, policy->cpuinfo.max_freq); - dprintk("verification lead to (%u - %u kHz) for cpu %u\n", + pr_debug("verification lead to (%u - %u kHz) for cpu %u\n", policy->min, policy->max, policy->cpu); return 0; @@ -110,7 +107,7 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy, }; unsigned int i; - dprintk("request for target %u kHz (relation: %u) for cpu %u\n", + pr_debug("request for target %u kHz (relation: %u) for cpu %u\n", target_freq, relation, policy->cpu); switch (relation) { @@ -167,7 +164,7 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy, } else *index = optimal.index; - dprintk("target is %u (%u kHz, %u)\n", *index, table[*index].frequency, + pr_debug("target is %u (%u kHz, %u)\n", *index, table[*index].frequency, table[*index].index); return 0; @@ -216,14 +213,14 @@ EXPORT_SYMBOL_GPL(cpufreq_freq_attr_scaling_available_freqs); void cpufreq_frequency_table_get_attr(struct cpufreq_frequency_table *table, unsigned int cpu) { - dprintk("setting show_table for cpu %u to %p\n", cpu, table); + pr_debug("setting show_table for cpu %u to %p\n", cpu, table); per_cpu(cpufreq_show_table, cpu) = table; } EXPORT_SYMBOL_GPL(cpufreq_frequency_table_get_attr); void cpufreq_frequency_table_put_attr(unsigned int cpu) { - dprintk("clearing show_table for cpu %u\n", cpu); + pr_debug("clearing show_table for cpu %u\n", cpu); per_cpu(cpufreq_show_table, cpu) = NULL; } EXPORT_SYMBOL_GPL(cpufreq_frequency_table_put_attr); diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 9343dd3de858..2845f6e67221 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -397,23 +397,4 @@ void cpufreq_frequency_table_get_attr(struct cpufreq_frequency_table *table, void cpufreq_frequency_table_put_attr(unsigned int cpu); -/********************************************************************* - * UNIFIED DEBUG HELPERS * - *********************************************************************/ - -#define CPUFREQ_DEBUG_CORE 1 -#define CPUFREQ_DEBUG_DRIVER 2 -#define CPUFREQ_DEBUG_GOVERNOR 4 - -#ifdef CONFIG_CPU_FREQ_DEBUG - -extern void cpufreq_debug_printk(unsigned int type, const char *prefix, - const char *fmt, ...); - -#else - -#define cpufreq_debug_printk(msg...) do { } while(0) - -#endif /* CONFIG_CPU_FREQ_DEBUG */ - #endif /* _LINUX_CPUFREQ_H */ -- cgit From 335dc3335ff692173bc766b248f7a97f3a23b30a Mon Sep 17 00:00:00 2001 From: Thiago Farina Date: Thu, 28 Apr 2011 20:42:53 -0300 Subject: [CPUFREQ] cpufreq.h: Fix some checkpatch.pl coding style issues. Before: $ scripts/checkpatch.pl --file --terse include/linux/cpufreq.h total: 14 errors, 11 warnings, 419 lines checked After: $ scripts/checkpatch.pl --file --terse include/linux/cpufreq.h total: 2 errors, 4 warnings, 422 lines checked Signed-off-by: Thiago Farina Signed-off-by: Dave Jones --- include/linux/cpufreq.h | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) (limited to 'include/linux') diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 2845f6e67221..11be48e0d168 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -3,7 +3,7 @@ * * Copyright (C) 2001 Russell King * (C) 2002 - 2003 Dominik Brodowski - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. @@ -56,9 +56,9 @@ static inline int cpufreq_unregister_notifier(struct notifier_block *nb, #define CPUFREQ_POLICY_POWERSAVE (1) #define CPUFREQ_POLICY_PERFORMANCE (2) -/* Frequency values here are CPU kHz so that hardware which doesn't run - * with some frequencies can complain without having to guess what per - * cent / per mille means. +/* Frequency values here are CPU kHz so that hardware which doesn't run + * with some frequencies can complain without having to guess what per + * cent / per mille means. * Maximum transition latency is in nanoseconds - if it's unknown, * CPUFREQ_ETERNAL shall be used. */ @@ -72,13 +72,15 @@ extern struct kobject *cpufreq_global_kobject; struct cpufreq_cpuinfo { unsigned int max_freq; unsigned int min_freq; - unsigned int transition_latency; /* in 10^(-9) s = nanoseconds */ + + /* in 10^(-9) s = nanoseconds */ + unsigned int transition_latency; }; struct cpufreq_real_policy { unsigned int min; /* in kHz */ unsigned int max; /* in kHz */ - unsigned int policy; /* see above */ + unsigned int policy; /* see above */ struct cpufreq_governor *governor; /* see below */ }; @@ -94,7 +96,7 @@ struct cpufreq_policy { unsigned int max; /* in kHz */ unsigned int cur; /* in kHz, only needed if cpufreq * governors are used */ - unsigned int policy; /* see above */ + unsigned int policy; /* see above */ struct cpufreq_governor *governor; /* see below */ struct work_struct update; /* if update_policy() needs to be @@ -167,11 +169,11 @@ static inline unsigned long cpufreq_scale(unsigned long old, u_int div, u_int mu struct cpufreq_governor { char name[CPUFREQ_NAME_LEN]; - int (*governor) (struct cpufreq_policy *policy, + int (*governor) (struct cpufreq_policy *policy, unsigned int event); ssize_t (*show_setspeed) (struct cpufreq_policy *policy, char *buf); - int (*store_setspeed) (struct cpufreq_policy *policy, + int (*store_setspeed) (struct cpufreq_policy *policy, unsigned int freq); unsigned int max_transition_latency; /* HW must be able to switch to next freq faster than this value in nano secs or we @@ -180,7 +182,8 @@ struct cpufreq_governor { struct module *owner; }; -/* pass a target to the cpufreq driver +/* + * Pass a target to the cpufreq driver. */ extern int cpufreq_driver_target(struct cpufreq_policy *policy, unsigned int target_freq, @@ -237,9 +240,9 @@ struct cpufreq_driver { /* flags */ -#define CPUFREQ_STICKY 0x01 /* the driver isn't removed even if +#define CPUFREQ_STICKY 0x01 /* the driver isn't removed even if * all ->init() calls failed */ -#define CPUFREQ_CONST_LOOPS 0x02 /* loops_per_jiffy or other kernel +#define CPUFREQ_CONST_LOOPS 0x02 /* loops_per_jiffy or other kernel * "constants" aren't affected by * frequency transitions */ #define CPUFREQ_PM_NO_WARN 0x04 /* don't warn on suspend/resume speed @@ -252,7 +255,7 @@ int cpufreq_unregister_driver(struct cpufreq_driver *driver_data); void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state); -static inline void cpufreq_verify_within_limits(struct cpufreq_policy *policy, unsigned int min, unsigned int max) +static inline void cpufreq_verify_within_limits(struct cpufreq_policy *policy, unsigned int min, unsigned int max) { if (policy->min < min) policy->min = min; @@ -386,12 +389,12 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy, /* the following 3 funtions are for cpufreq core use only */ struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu); struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu); -void cpufreq_cpu_put (struct cpufreq_policy *data); +void cpufreq_cpu_put(struct cpufreq_policy *data); /* the following are really really optional */ extern struct freq_attr cpufreq_freq_attr_scaling_available_freqs; -void cpufreq_frequency_table_get_attr(struct cpufreq_frequency_table *table, +void cpufreq_frequency_table_get_attr(struct cpufreq_frequency_table *table, unsigned int cpu); void cpufreq_frequency_table_put_attr(unsigned int cpu); -- cgit From 9a1b9496cd2b013f74885218947fa7120d53e74c Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 4 May 2011 12:18:54 -0700 Subject: ipv4: Pass explicit saddr/daddr args to ipmr_get_route(). This eliminates the need to use rt->rt_{src,dst}. Signed-off-by: David S. Miller --- include/linux/mroute.h | 1 + net/ipv4/ipmr.c | 16 ++++++++-------- net/ipv4/route.c | 4 +++- 3 files changed, 12 insertions(+), 9 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mroute.h b/include/linux/mroute.h index b21d567692b2..46caaf44339d 100644 --- a/include/linux/mroute.h +++ b/include/linux/mroute.h @@ -244,6 +244,7 @@ struct mfc_cache { #ifdef __KERNEL__ struct rtmsg; extern int ipmr_get_route(struct net *net, struct sk_buff *skb, + __be32 saddr, __be32 daddr, struct rtmsg *rtm, int nowait); #endif diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 86033b7a05ba..30a7763c400e 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -2041,20 +2041,20 @@ rtattr_failure: return -EMSGSIZE; } -int ipmr_get_route(struct net *net, - struct sk_buff *skb, struct rtmsg *rtm, int nowait) +int ipmr_get_route(struct net *net, struct sk_buff *skb, + __be32 saddr, __be32 daddr, + struct rtmsg *rtm, int nowait) { - int err; - struct mr_table *mrt; struct mfc_cache *cache; - struct rtable *rt = skb_rtable(skb); + struct mr_table *mrt; + int err; mrt = ipmr_get_table(net, RT_TABLE_DEFAULT); if (mrt == NULL) return -ENOENT; rcu_read_lock(); - cache = ipmr_cache_find(mrt, rt->rt_src, rt->rt_dst); + cache = ipmr_cache_find(mrt, saddr, daddr); if (cache == NULL) { struct sk_buff *skb2; @@ -2087,8 +2087,8 @@ int ipmr_get_route(struct net *net, skb_reset_network_header(skb2); iph = ip_hdr(skb2); iph->ihl = sizeof(struct iphdr) >> 2; - iph->saddr = rt->rt_src; - iph->daddr = rt->rt_dst; + iph->saddr = saddr; + iph->daddr = daddr; iph->version = 0; err = ipmr_cache_unresolved(mrt, vif, skb2); read_unlock(&mrt_lock); diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 3bc685454b5b..6a83840b16af 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2857,7 +2857,9 @@ static int rt_fill_info(struct net *net, if (ipv4_is_multicast(dst) && !ipv4_is_local_multicast(dst) && IPV4_DEVCONF_ALL(net, MC_FORWARDING)) { - int err = ipmr_get_route(net, skb, r, nowait); + int err = ipmr_get_route(net, skb, + rt->rt_src, rt->rt_dst, + r, nowait); if (err <= 0) { if (!nowait) { if (err == 0) -- cgit From 1650629d1800bf05ad775f974e931ca2fa03b0ff Mon Sep 17 00:00:00 2001 From: Kurt Van Dijck Date: Tue, 3 May 2011 18:40:57 +0000 Subject: can: make struct can_proto const commit 53914b67993c724cec585863755c9ebc8446e83b had the same message. That commit did put everything in place but did not make can_proto const itself. Signed-off-by: Kurt Van Dijck Acked-by: Oliver Hartkopp Signed-off-by: David S. Miller --- include/linux/can/core.h | 4 ++-- net/can/af_can.c | 12 ++++++------ net/can/bcm.c | 2 +- net/can/raw.c | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) (limited to 'include/linux') diff --git a/include/linux/can/core.h b/include/linux/can/core.h index 6f70a6d3a16e..5ce6b5d62ecc 100644 --- a/include/linux/can/core.h +++ b/include/linux/can/core.h @@ -44,8 +44,8 @@ struct can_proto { /* function prototypes for the CAN networklayer core (af_can.c) */ -extern int can_proto_register(struct can_proto *cp); -extern void can_proto_unregister(struct can_proto *cp); +extern int can_proto_register(const struct can_proto *cp); +extern void can_proto_unregister(const struct can_proto *cp); extern int can_rx_register(struct net_device *dev, canid_t can_id, canid_t mask, diff --git a/net/can/af_can.c b/net/can/af_can.c index a8dcaa49675a..5b52762b9f20 100644 --- a/net/can/af_can.c +++ b/net/can/af_can.c @@ -84,7 +84,7 @@ static DEFINE_SPINLOCK(can_rcvlists_lock); static struct kmem_cache *rcv_cache __read_mostly; /* table of registered CAN protocols */ -static struct can_proto *proto_tab[CAN_NPROTO] __read_mostly; +static const struct can_proto *proto_tab[CAN_NPROTO] __read_mostly; static DEFINE_MUTEX(proto_tab_lock); struct timer_list can_stattimer; /* timer for statistics update */ @@ -115,9 +115,9 @@ static void can_sock_destruct(struct sock *sk) skb_queue_purge(&sk->sk_receive_queue); } -static struct can_proto *can_try_module_get(int protocol) +static const struct can_proto *can_try_module_get(int protocol) { - struct can_proto *cp; + const struct can_proto *cp; rcu_read_lock(); cp = rcu_dereference(proto_tab[protocol]); @@ -132,7 +132,7 @@ static int can_create(struct net *net, struct socket *sock, int protocol, int kern) { struct sock *sk; - struct can_proto *cp; + const struct can_proto *cp; int err = 0; sock->state = SS_UNCONNECTED; @@ -691,7 +691,7 @@ drop: * -EBUSY protocol already in use * -ENOBUF if proto_register() fails */ -int can_proto_register(struct can_proto *cp) +int can_proto_register(const struct can_proto *cp) { int proto = cp->protocol; int err = 0; @@ -728,7 +728,7 @@ EXPORT_SYMBOL(can_proto_register); * can_proto_unregister - unregister CAN transport protocol * @cp: pointer to CAN protocol structure */ -void can_proto_unregister(struct can_proto *cp) +void can_proto_unregister(const struct can_proto *cp) { int proto = cp->protocol; diff --git a/net/can/bcm.c b/net/can/bcm.c index 8a6a05e7c3c8..cced806098a9 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c @@ -1601,7 +1601,7 @@ static struct proto bcm_proto __read_mostly = { .init = bcm_init, }; -static struct can_proto bcm_can_proto __read_mostly = { +static const struct can_proto bcm_can_proto = { .type = SOCK_DGRAM, .protocol = CAN_BCM, .ops = &bcm_ops, diff --git a/net/can/raw.c b/net/can/raw.c index 0eb39a7fdf64..dea99a6e596c 100644 --- a/net/can/raw.c +++ b/net/can/raw.c @@ -774,7 +774,7 @@ static struct proto raw_proto __read_mostly = { .init = raw_init, }; -static struct can_proto raw_can_proto __read_mostly = { +static const struct can_proto raw_can_proto = { .type = SOCK_RAW, .protocol = CAN_RAW, .ops = &raw_ops, -- cgit From 30106b8ce2cc2243514116d6f29086e6deecc754 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 4 May 2011 15:38:19 +0200 Subject: slub: Fix the lockless code on 32-bit platforms with no 64-bit cmpxchg The SLUB allocator use of the cmpxchg_double logic was wrong: it actually needs the irq-safe one. That happens automatically when we use the native unlocked 'cmpxchg8b' instruction, but when compiling the kernel for older x86 CPUs that do not support that instruction, we fall back to the generic emulation code. And if you don't specify that you want the irq-safe version, the generic code ends up just open-coding the cmpxchg8b equivalent without any protection against interrupts or preemption. Which definitely doesn't work for SLUB. This was reported by Werner Landgraf , who saw instability with his distro-kernel that was compiled to support pretty much everything under the sun. Most big Linux distributions tend to compile for PPro and later, and would never have noticed this problem. This also fixes the prototypes for the irqsafe cmpxchg_double functions to use 'bool' like they should. [ Btw, that whole "generic code defaults to no protection" design just sounds stupid - if the code needs no protection, there is no reason to use "cmpxchg_double" to begin with. So we should probably just remove the unprotected version entirely as pointless. - Linus ] Signed-off-by: Thomas Gleixner Reported-and-tested-by: werner Acked-and-tested-by: Ingo Molnar Acked-by: Christoph Lameter Cc: Pekka Enberg Cc: Jens Axboe Cc: Tejun Heo Link: http://lkml.kernel.org/r/alpine.LFD.2.02.1105041539050.3005@ionos Signed-off-by: Ingo Molnar Signed-off-by: Linus Torvalds --- include/linux/percpu.h | 2 +- mm/slub.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/percpu.h b/include/linux/percpu.h index 3a5c4449fd36..8b97308e65df 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h @@ -948,7 +948,7 @@ do { \ irqsafe_generic_cpu_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) # endif # define irqsafe_cpu_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) \ - __pcpu_double_call_return_int(irqsafe_cpu_cmpxchg_double_, (pcp1), (pcp2), (oval1), (oval2), (nval1), (nval2)) + __pcpu_double_call_return_bool(irqsafe_cpu_cmpxchg_double_, (pcp1), (pcp2), (oval1), (oval2), (nval1), (nval2)) #endif #endif /* __LINUX_PERCPU_H */ diff --git a/mm/slub.c b/mm/slub.c index 94d2a33a866e..9d2e5e46bf09 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -1940,7 +1940,7 @@ redo: * Since this is without lock semantics the protection is only against * code executing on this cpu *not* from access by other cpus. */ - if (unlikely(!this_cpu_cmpxchg_double( + if (unlikely(!irqsafe_cpu_cmpxchg_double( s->cpu_slab->freelist, s->cpu_slab->tid, object, tid, get_freepointer(s, object), next_tid(tid)))) { @@ -2145,7 +2145,7 @@ redo: set_freepointer(s, object, c->freelist); #ifdef CONFIG_CMPXCHG_LOCAL - if (unlikely(!this_cpu_cmpxchg_double( + if (unlikely(!irqsafe_cpu_cmpxchg_double( s->cpu_slab->freelist, s->cpu_slab->tid, c->freelist, tid, object, next_tid(tid)))) { -- cgit From 228e548e602061b08ee8e8966f567c12aa079682 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Mon, 2 May 2011 20:21:35 +0000 Subject: net: Add sendmmsg socket system call This patch adds a multiple message send syscall and is the send version of the existing recvmmsg syscall. This is heavily based on the patch by Arnaldo that added recvmmsg. I wrote a microbenchmark to test the performance gains of using this new syscall: http://ozlabs.org/~anton/junkcode/sendmmsg_test.c The test was run on a ppc64 box with a 10 Gbit network card. The benchmark can send both UDP and RAW ethernet packets. 64B UDP batch pkts/sec 1 804570 2 872800 (+ 8 %) 4 916556 (+14 %) 8 939712 (+17 %) 16 952688 (+18 %) 32 956448 (+19 %) 64 964800 (+20 %) 64B raw socket batch pkts/sec 1 1201449 2 1350028 (+12 %) 4 1461416 (+22 %) 8 1513080 (+26 %) 16 1541216 (+28 %) 32 1553440 (+29 %) 64 1557888 (+30 %) We see a 20% improvement in throughput on UDP send and 30% on raw socket send. [ Add sparc syscall entries. -DaveM ] Signed-off-by: Anton Blanchard Signed-off-by: David S. Miller --- arch/powerpc/include/asm/systbl.h | 1 + arch/powerpc/include/asm/unistd.h | 3 +- arch/sparc/include/asm/unistd.h | 3 +- arch/sparc/kernel/systbls_32.S | 2 +- arch/sparc/kernel/systbls_64.S | 4 +- arch/x86/ia32/ia32entry.S | 1 + arch/x86/include/asm/unistd_32.h | 3 +- arch/x86/include/asm/unistd_64.h | 2 + arch/x86/kernel/syscall_table_32.S | 1 + include/linux/net.h | 1 + include/linux/socket.h | 2 + include/linux/syscalls.h | 2 + include/net/compat.h | 2 + kernel/sys_ni.c | 2 + net/compat.c | 16 ++- net/socket.c | 199 +++++++++++++++++++++++++++++-------- 16 files changed, 192 insertions(+), 52 deletions(-) (limited to 'include/linux') diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h index 60f64b132bd4..8489d372077f 100644 --- a/arch/powerpc/include/asm/systbl.h +++ b/arch/powerpc/include/asm/systbl.h @@ -352,3 +352,4 @@ SYSCALL_SPU(name_to_handle_at) COMPAT_SYS_SPU(open_by_handle_at) COMPAT_SYS_SPU(clock_adjtime) SYSCALL_SPU(syncfs) +COMPAT_SYS_SPU(sendmmsg) diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h index 3c215648ce6d..6d23c8193caa 100644 --- a/arch/powerpc/include/asm/unistd.h +++ b/arch/powerpc/include/asm/unistd.h @@ -371,10 +371,11 @@ #define __NR_open_by_handle_at 346 #define __NR_clock_adjtime 347 #define __NR_syncfs 348 +#define __NR_sendmmsg 349 #ifdef __KERNEL__ -#define __NR_syscalls 349 +#define __NR_syscalls 350 #define __NR__exit __NR_exit #define NR_syscalls __NR_syscalls diff --git a/arch/sparc/include/asm/unistd.h b/arch/sparc/include/asm/unistd.h index 9d897b6db983..c5387ed0add8 100644 --- a/arch/sparc/include/asm/unistd.h +++ b/arch/sparc/include/asm/unistd.h @@ -404,8 +404,9 @@ #define __NR_open_by_handle_at 333 #define __NR_clock_adjtime 334 #define __NR_syncfs 335 +#define __NR_sendmmsg 336 -#define NR_syscalls 336 +#define NR_syscalls 337 #ifdef __32bit_syscall_numbers__ /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants, diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S index 47ac73c32e88..332c83ff7701 100644 --- a/arch/sparc/kernel/systbls_32.S +++ b/arch/sparc/kernel/systbls_32.S @@ -84,4 +84,4 @@ sys_call_table: /*320*/ .long sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv /*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init /*330*/ .long sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime -/*335*/ .long sys_syncfs +/*335*/ .long sys_syncfs, sys_sendmmsg diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S index 4f3170c1ef47..43887ca0be0e 100644 --- a/arch/sparc/kernel/systbls_64.S +++ b/arch/sparc/kernel/systbls_64.S @@ -85,7 +85,7 @@ sys_call_table32: /*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, compat_sys_preadv .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init /*330*/ .word sys32_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime - .word sys_syncfs + .word sys_syncfs, compat_sys_sendmmsg #endif /* CONFIG_COMPAT */ @@ -162,4 +162,4 @@ sys_call_table: /*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init /*330*/ .word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime - .word sys_syncfs + .word sys_syncfs, sys_sendmmsg diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index 849a9d23c71d..95f5826be458 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S @@ -848,4 +848,5 @@ ia32_sys_call_table: .quad compat_sys_open_by_handle_at .quad compat_sys_clock_adjtime .quad sys_syncfs + .quad compat_sys_sendmmsg /* 345 */ ia32_syscall_end: diff --git a/arch/x86/include/asm/unistd_32.h b/arch/x86/include/asm/unistd_32.h index a755ef5e5977..fb6a625c99bf 100644 --- a/arch/x86/include/asm/unistd_32.h +++ b/arch/x86/include/asm/unistd_32.h @@ -350,10 +350,11 @@ #define __NR_open_by_handle_at 342 #define __NR_clock_adjtime 343 #define __NR_syncfs 344 +#define __NR_sendmmsg 345 #ifdef __KERNEL__ -#define NR_syscalls 345 +#define NR_syscalls 346 #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR diff --git a/arch/x86/include/asm/unistd_64.h b/arch/x86/include/asm/unistd_64.h index 160fa76bd578..79f90eb15aad 100644 --- a/arch/x86/include/asm/unistd_64.h +++ b/arch/x86/include/asm/unistd_64.h @@ -677,6 +677,8 @@ __SYSCALL(__NR_open_by_handle_at, sys_open_by_handle_at) __SYSCALL(__NR_clock_adjtime, sys_clock_adjtime) #define __NR_syncfs 306 __SYSCALL(__NR_syncfs, sys_syncfs) +#define __NR_sendmmsg 307 +__SYSCALL(__NR_sendmmsg, sys_sendmmsg) #ifndef __NO_STUBS #define __ARCH_WANT_OLD_READDIR diff --git a/arch/x86/kernel/syscall_table_32.S b/arch/x86/kernel/syscall_table_32.S index abce34d5c79d..32cbffb0c494 100644 --- a/arch/x86/kernel/syscall_table_32.S +++ b/arch/x86/kernel/syscall_table_32.S @@ -344,3 +344,4 @@ ENTRY(sys_call_table) .long sys_open_by_handle_at .long sys_clock_adjtime .long sys_syncfs + .long sys_sendmmsg /* 345 */ diff --git a/include/linux/net.h b/include/linux/net.h index 94de83c0f877..1da55e9b6f01 100644 --- a/include/linux/net.h +++ b/include/linux/net.h @@ -42,6 +42,7 @@ #define SYS_RECVMSG 17 /* sys_recvmsg(2) */ #define SYS_ACCEPT4 18 /* sys_accept4(2) */ #define SYS_RECVMMSG 19 /* sys_recvmmsg(2) */ +#define SYS_SENDMMSG 20 /* sys_sendmmsg(2) */ typedef enum { SS_FREE = 0, /* not allocated */ diff --git a/include/linux/socket.h b/include/linux/socket.h index d2b5e982f079..4ef98e422fde 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -333,5 +333,7 @@ struct timespec; extern int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, unsigned int flags, struct timespec *timeout); +extern int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, + unsigned int vlen, unsigned int flags); #endif /* not kernel and not glibc */ #endif /* _LINUX_SOCKET_H */ diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 83ecc1749ef6..ab71447d0c5a 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -610,6 +610,8 @@ asmlinkage long sys_send(int, void __user *, size_t, unsigned); asmlinkage long sys_sendto(int, void __user *, size_t, unsigned, struct sockaddr __user *, int); asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags); +asmlinkage long sys_sendmmsg(int fd, struct mmsghdr __user *msg, + unsigned int vlen, unsigned flags); asmlinkage long sys_recv(int, void __user *, size_t, unsigned); asmlinkage long sys_recvfrom(int, void __user *, size_t, unsigned, struct sockaddr __user *, int __user *); diff --git a/include/net/compat.h b/include/net/compat.h index 28d5428ec6a2..9ee75edcc295 100644 --- a/include/net/compat.h +++ b/include/net/compat.h @@ -43,6 +43,8 @@ extern int compat_sock_get_timestampns(struct sock *, struct timespec __user *); extern int get_compat_msghdr(struct msghdr *, struct compat_msghdr __user *); extern int verify_compat_iovec(struct msghdr *, struct iovec *, struct sockaddr *, int); extern asmlinkage long compat_sys_sendmsg(int,struct compat_msghdr __user *,unsigned); +extern asmlinkage long compat_sys_sendmmsg(int, struct compat_mmsghdr __user *, + unsigned, unsigned); extern asmlinkage long compat_sys_recvmsg(int,struct compat_msghdr __user *,unsigned); extern asmlinkage long compat_sys_recvmmsg(int, struct compat_mmsghdr __user *, unsigned, unsigned, diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c index 25cc41cd8f33..97e966f171c6 100644 --- a/kernel/sys_ni.c +++ b/kernel/sys_ni.c @@ -46,7 +46,9 @@ cond_syscall(sys_getsockopt); cond_syscall(compat_sys_getsockopt); cond_syscall(sys_shutdown); cond_syscall(sys_sendmsg); +cond_syscall(sys_sendmmsg); cond_syscall(compat_sys_sendmsg); +cond_syscall(compat_sys_sendmmsg); cond_syscall(sys_recvmsg); cond_syscall(sys_recvmmsg); cond_syscall(compat_sys_recvmsg); diff --git a/net/compat.c b/net/compat.c index 3649d5895361..c578d9382e19 100644 --- a/net/compat.c +++ b/net/compat.c @@ -722,11 +722,11 @@ EXPORT_SYMBOL(compat_mc_getsockopt); /* Argument list sizes for compat_sys_socketcall */ #define AL(x) ((x) * sizeof(u32)) -static unsigned char nas[20] = { +static unsigned char nas[21] = { AL(0), AL(3), AL(3), AL(3), AL(2), AL(3), AL(3), AL(3), AL(4), AL(4), AL(4), AL(6), AL(6), AL(2), AL(5), AL(5), AL(3), AL(3), - AL(4), AL(5) + AL(4), AL(5), AL(4) }; #undef AL @@ -735,6 +735,13 @@ asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg, uns return sys_sendmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); } +asmlinkage long compat_sys_sendmmsg(int fd, struct compat_mmsghdr __user *mmsg, + unsigned vlen, unsigned int flags) +{ + return __sys_sendmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, + flags | MSG_CMSG_COMPAT); +} + asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg, unsigned int flags) { return sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); @@ -780,7 +787,7 @@ asmlinkage long compat_sys_socketcall(int call, u32 __user *args) u32 a[6]; u32 a0, a1; - if (call < SYS_SOCKET || call > SYS_RECVMMSG) + if (call < SYS_SOCKET || call > SYS_SENDMMSG) return -EINVAL; if (copy_from_user(a, args, nas[call])) return -EFAULT; @@ -839,6 +846,9 @@ asmlinkage long compat_sys_socketcall(int call, u32 __user *args) case SYS_SENDMSG: ret = compat_sys_sendmsg(a0, compat_ptr(a1), a[2]); break; + case SYS_SENDMMSG: + ret = compat_sys_sendmmsg(a0, compat_ptr(a1), a[2], a[3]); + break; case SYS_RECVMSG: ret = compat_sys_recvmsg(a0, compat_ptr(a1), a[2]); break; diff --git a/net/socket.c b/net/socket.c index d25f5a9d6fa2..ed50255143d5 100644 --- a/net/socket.c +++ b/net/socket.c @@ -551,11 +551,10 @@ int sock_tx_timestamp(struct sock *sk, __u8 *tx_flags) } EXPORT_SYMBOL(sock_tx_timestamp); -static inline int __sock_sendmsg(struct kiocb *iocb, struct socket *sock, - struct msghdr *msg, size_t size) +static inline int __sock_sendmsg_nosec(struct kiocb *iocb, struct socket *sock, + struct msghdr *msg, size_t size) { struct sock_iocb *si = kiocb_to_siocb(iocb); - int err; sock_update_classid(sock->sk); @@ -564,13 +563,17 @@ static inline int __sock_sendmsg(struct kiocb *iocb, struct socket *sock, si->msg = msg; si->size = size; - err = security_socket_sendmsg(sock, msg, size); - if (err) - return err; - return sock->ops->sendmsg(iocb, sock, msg, size); } +static inline int __sock_sendmsg(struct kiocb *iocb, struct socket *sock, + struct msghdr *msg, size_t size) +{ + int err = security_socket_sendmsg(sock, msg, size); + + return err ?: __sock_sendmsg_nosec(iocb, sock, msg, size); +} + int sock_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) { struct kiocb iocb; @@ -586,6 +589,20 @@ int sock_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) } EXPORT_SYMBOL(sock_sendmsg); +int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg, size_t size) +{ + struct kiocb iocb; + struct sock_iocb siocb; + int ret; + + init_sync_kiocb(&iocb, NULL); + iocb.private = &siocb; + ret = __sock_sendmsg_nosec(&iocb, sock, msg, size); + if (-EIOCBQUEUED == ret) + ret = wait_on_sync_kiocb(&iocb); + return ret; +} + int kernel_sendmsg(struct socket *sock, struct msghdr *msg, struct kvec *vec, size_t num, size_t size) { @@ -1863,57 +1880,47 @@ SYSCALL_DEFINE2(shutdown, int, fd, int, how) #define COMPAT_NAMELEN(msg) COMPAT_MSG(msg, msg_namelen) #define COMPAT_FLAGS(msg) COMPAT_MSG(msg, msg_flags) -/* - * BSD sendmsg interface - */ - -SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned, flags) +static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg, + struct msghdr *msg_sys, unsigned flags, int nosec) { struct compat_msghdr __user *msg_compat = (struct compat_msghdr __user *)msg; - struct socket *sock; struct sockaddr_storage address; struct iovec iovstack[UIO_FASTIOV], *iov = iovstack; unsigned char ctl[sizeof(struct cmsghdr) + 20] __attribute__ ((aligned(sizeof(__kernel_size_t)))); /* 20 is size of ipv6_pktinfo */ unsigned char *ctl_buf = ctl; - struct msghdr msg_sys; int err, ctl_len, iov_size, total_len; - int fput_needed; err = -EFAULT; if (MSG_CMSG_COMPAT & flags) { - if (get_compat_msghdr(&msg_sys, msg_compat)) + if (get_compat_msghdr(msg_sys, msg_compat)) return -EFAULT; - } else if (copy_from_user(&msg_sys, msg, sizeof(struct msghdr))) + } else if (copy_from_user(msg_sys, msg, sizeof(struct msghdr))) return -EFAULT; - sock = sockfd_lookup_light(fd, &err, &fput_needed); - if (!sock) - goto out; - /* do not move before msg_sys is valid */ err = -EMSGSIZE; - if (msg_sys.msg_iovlen > UIO_MAXIOV) - goto out_put; + if (msg_sys->msg_iovlen > UIO_MAXIOV) + goto out; /* Check whether to allocate the iovec area */ err = -ENOMEM; - iov_size = msg_sys.msg_iovlen * sizeof(struct iovec); - if (msg_sys.msg_iovlen > UIO_FASTIOV) { + iov_size = msg_sys->msg_iovlen * sizeof(struct iovec); + if (msg_sys->msg_iovlen > UIO_FASTIOV) { iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL); if (!iov) - goto out_put; + goto out; } /* This will also move the address data into kernel space */ if (MSG_CMSG_COMPAT & flags) { - err = verify_compat_iovec(&msg_sys, iov, + err = verify_compat_iovec(msg_sys, iov, (struct sockaddr *)&address, VERIFY_READ); } else - err = verify_iovec(&msg_sys, iov, + err = verify_iovec(msg_sys, iov, (struct sockaddr *)&address, VERIFY_READ); if (err < 0) @@ -1922,17 +1929,17 @@ SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned, flags) err = -ENOBUFS; - if (msg_sys.msg_controllen > INT_MAX) + if (msg_sys->msg_controllen > INT_MAX) goto out_freeiov; - ctl_len = msg_sys.msg_controllen; + ctl_len = msg_sys->msg_controllen; if ((MSG_CMSG_COMPAT & flags) && ctl_len) { err = - cmsghdr_from_user_compat_to_kern(&msg_sys, sock->sk, ctl, + cmsghdr_from_user_compat_to_kern(msg_sys, sock->sk, ctl, sizeof(ctl)); if (err) goto out_freeiov; - ctl_buf = msg_sys.msg_control; - ctl_len = msg_sys.msg_controllen; + ctl_buf = msg_sys->msg_control; + ctl_len = msg_sys->msg_controllen; } else if (ctl_len) { if (ctl_len > sizeof(ctl)) { ctl_buf = sock_kmalloc(sock->sk, ctl_len, GFP_KERNEL); @@ -1941,21 +1948,22 @@ SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned, flags) } err = -EFAULT; /* - * Careful! Before this, msg_sys.msg_control contains a user pointer. + * Careful! Before this, msg_sys->msg_control contains a user pointer. * Afterwards, it will be a kernel pointer. Thus the compiler-assisted * checking falls down on this. */ if (copy_from_user(ctl_buf, - (void __user __force *)msg_sys.msg_control, + (void __user __force *)msg_sys->msg_control, ctl_len)) goto out_freectl; - msg_sys.msg_control = ctl_buf; + msg_sys->msg_control = ctl_buf; } - msg_sys.msg_flags = flags; + msg_sys->msg_flags = flags; if (sock->file->f_flags & O_NONBLOCK) - msg_sys.msg_flags |= MSG_DONTWAIT; - err = sock_sendmsg(sock, &msg_sys, total_len); + msg_sys->msg_flags |= MSG_DONTWAIT; + err = (nosec ? sock_sendmsg_nosec : sock_sendmsg)(sock, msg_sys, + total_len); out_freectl: if (ctl_buf != ctl) @@ -1963,12 +1971,114 @@ out_freectl: out_freeiov: if (iov != iovstack) sock_kfree_s(sock->sk, iov, iov_size); -out_put: +out: + return err; +} + +/* + * BSD sendmsg interface + */ + +SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned, flags) +{ + int fput_needed, err; + struct msghdr msg_sys; + struct socket *sock = sockfd_lookup_light(fd, &err, &fput_needed); + + if (!sock) + goto out; + + err = __sys_sendmsg(sock, msg, &msg_sys, flags, 0); + fput_light(sock->file, fput_needed); out: return err; } +/* + * Linux sendmmsg interface + */ + +int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, + unsigned int flags) +{ + int fput_needed, err, datagrams; + struct socket *sock; + struct mmsghdr __user *entry; + struct compat_mmsghdr __user *compat_entry; + struct msghdr msg_sys; + + datagrams = 0; + + sock = sockfd_lookup_light(fd, &err, &fput_needed); + if (!sock) + return err; + + err = sock_error(sock->sk); + if (err) + goto out_put; + + entry = mmsg; + compat_entry = (struct compat_mmsghdr __user *)mmsg; + + while (datagrams < vlen) { + /* + * No need to ask LSM for more than the first datagram. + */ + if (MSG_CMSG_COMPAT & flags) { + err = __sys_sendmsg(sock, (struct msghdr __user *)compat_entry, + &msg_sys, flags, datagrams); + if (err < 0) + break; + err = __put_user(err, &compat_entry->msg_len); + ++compat_entry; + } else { + err = __sys_sendmsg(sock, (struct msghdr __user *)entry, + &msg_sys, flags, datagrams); + if (err < 0) + break; + err = put_user(err, &entry->msg_len); + ++entry; + } + + if (err) + break; + ++datagrams; + } + +out_put: + fput_light(sock->file, fput_needed); + + if (err == 0) + return datagrams; + + if (datagrams != 0) { + /* + * We may send less entries than requested (vlen) if the + * sock is non blocking... + */ + if (err != -EAGAIN) { + /* + * ... or if sendmsg returns an error after we + * send some datagrams, where we record the + * error to return on the next call or if the + * app asks about it using getsockopt(SO_ERROR). + */ + sock->sk->sk_err = -err; + } + + return datagrams; + } + + return err; +} + +SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg, + unsigned int, vlen, unsigned int, flags) +{ + return __sys_sendmmsg(fd, mmsg, vlen, flags); +} + static int __sys_recvmsg(struct socket *sock, struct msghdr __user *msg, struct msghdr *msg_sys, unsigned flags, int nosec) { @@ -2214,11 +2324,11 @@ SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg, #ifdef __ARCH_WANT_SYS_SOCKETCALL /* Argument list sizes for sys_socketcall */ #define AL(x) ((x) * sizeof(unsigned long)) -static const unsigned char nargs[20] = { +static const unsigned char nargs[21] = { AL(0), AL(3), AL(3), AL(3), AL(2), AL(3), AL(3), AL(3), AL(4), AL(4), AL(4), AL(6), AL(6), AL(2), AL(5), AL(5), AL(3), AL(3), - AL(4), AL(5) + AL(4), AL(5), AL(4) }; #undef AL @@ -2238,7 +2348,7 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) int err; unsigned int len; - if (call < 1 || call > SYS_RECVMMSG) + if (call < 1 || call > SYS_SENDMMSG) return -EINVAL; len = nargs[call]; @@ -2313,6 +2423,9 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) case SYS_SENDMSG: err = sys_sendmsg(a0, (struct msghdr __user *)a1, a[2]); break; + case SYS_SENDMMSG: + err = sys_sendmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3]); + break; case SYS_RECVMSG: err = sys_recvmsg(a0, (struct msghdr __user *)a1, a[2]); break; -- cgit From ff1b6e69ad4f31fb3c9c6da2665655f2e798dd70 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 4 May 2011 15:37:28 +0200 Subject: nl80211/cfg80211: WoWLAN support This is based on (but now quite far from) the original work from Luis and Eliad. Add support for configuring WoWLAN triggers, and getting the configuration out again. Changes from the original patchset are too numerous to list, but one important change needs highlighting: the suspend() callback is passed NULL for the trigger configuration if userspace has not configured WoWLAN at all. Signed-off-by: Luis R. Rodriguez Signed-off-by: Eliad Peller Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/linux/nl80211.h | 99 ++++++++++++++++++++ include/net/cfg80211.h | 74 ++++++++++++++- net/mac80211/cfg.c | 3 +- net/wireless/core.c | 8 ++ net/wireless/core.h | 14 +++ net/wireless/nl80211.c | 243 ++++++++++++++++++++++++++++++++++++++++++++++++ net/wireless/sysfs.c | 2 +- 7 files changed, 439 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index be8df57b789d..a75dea9c416e 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -420,6 +420,14 @@ * new station with the AUTHENTICATED flag unset and maybe change it later * depending on the authentication result. * + * @NL80211_CMD_GET_WOWLAN: get Wake-on-Wireless-LAN (WoWLAN) settings. + * @NL80211_CMD_SET_WOWLAN: set Wake-on-Wireless-LAN (WoWLAN) settings. + * Since wireless is more complex than wired ethernet, it supports + * various triggers. These triggers can be configured through this + * command with the %NL80211_ATTR_WOWLAN_TRIGGERS attribute. For + * more background information, see + * http://wireless.kernel.org/en/users/Documentation/WoWLAN. + * * @NL80211_CMD_MAX: highest used command number * @__NL80211_CMD_AFTER_LAST: internal use */ @@ -534,6 +542,9 @@ enum nl80211_commands { NL80211_CMD_NEW_PEER_CANDIDATE, + NL80211_CMD_GET_WOWLAN, + NL80211_CMD_SET_WOWLAN, + /* add new commands above here */ /* used to define NL80211_CMD_MAX below */ @@ -903,6 +914,13 @@ enum nl80211_commands { * allows auth frames in a mesh to be passed to userspace for processing via * the @NL80211_MESH_SETUP_USERSPACE_AUTH flag. * + * @NL80211_ATTR_WOWLAN_SUPPORTED: indicates, as part of the wiphy capabilities, + * the supported WoWLAN triggers + * @NL80211_ATTR_WOWLAN_TRIGGERS: used by %NL80211_CMD_SET_WOWLAN to + * indicate which WoW triggers should be enabled. This is also + * used by %NL80211_CMD_GET_WOWLAN to get the currently enabled WoWLAN + * triggers. + * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use */ @@ -1092,6 +1110,9 @@ enum nl80211_attrs { NL80211_ATTR_SUPPORT_MESH_AUTH, + NL80211_ATTR_WOWLAN_TRIGGERS, + NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, @@ -2061,4 +2082,82 @@ enum nl80211_tx_power_setting { NL80211_TX_POWER_FIXED, }; +/** + * enum nl80211_wowlan_packet_pattern_attr - WoWLAN packet pattern attribute + * @__NL80211_WOWLAN_PKTPAT_INVALID: invalid number for nested attribute + * @NL80211_WOWLAN_PKTPAT_PATTERN: the pattern, values where the mask has + * a zero bit are ignored + * @NL80211_WOWLAN_PKTPAT_MASK: pattern mask, must be long enough to have + * a bit for each byte in the pattern. The lowest-order bit corresponds + * to the first byte of the pattern, but the bytes of the pattern are + * in a little-endian-like format, i.e. the 9th byte of the pattern + * corresponds to the lowest-order bit in the second byte of the mask. + * For example: The match 00:xx:00:00:xx:00:00:00:00:xx:xx:xx (where + * xx indicates "don't care") would be represented by a pattern of + * twelve zero bytes, and a mask of "0xed,0x07". + * Note that the pattern matching is done as though frames were not + * 802.11 frames but 802.3 frames, i.e. the frame is fully unpacked + * first (including SNAP header unpacking) and then matched. + * @NUM_NL80211_WOWLAN_PKTPAT: number of attributes + * @MAX_NL80211_WOWLAN_PKTPAT: max attribute number + */ +enum nl80211_wowlan_packet_pattern_attr { + __NL80211_WOWLAN_PKTPAT_INVALID, + NL80211_WOWLAN_PKTPAT_MASK, + NL80211_WOWLAN_PKTPAT_PATTERN, + + NUM_NL80211_WOWLAN_PKTPAT, + MAX_NL80211_WOWLAN_PKTPAT = NUM_NL80211_WOWLAN_PKTPAT - 1, +}; + +/** + * struct nl80211_wowlan_pattern_support - pattern support information + * @max_patterns: maximum number of patterns supported + * @min_pattern_len: minimum length of each pattern + * @max_pattern_len: maximum length of each pattern + * + * This struct is carried in %NL80211_WOWLAN_TRIG_PKT_PATTERN when + * that is part of %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED in the + * capability information given by the kernel to userspace. + */ +struct nl80211_wowlan_pattern_support { + __u32 max_patterns; + __u32 min_pattern_len; + __u32 max_pattern_len; +} __attribute__((packed)); + +/** + * enum nl80211_wowlan_triggers - WoWLAN trigger definitions + * @__NL80211_WOWLAN_TRIG_INVALID: invalid number for nested attributes + * @NL80211_WOWLAN_TRIG_ANY: wake up on any activity, do not really put + * the chip into a special state -- works best with chips that have + * support for low-power operation already (flag) + * @NL80211_WOWLAN_TRIG_DISCONNECT: wake up on disconnect, the way disconnect + * is detected is implementation-specific (flag) + * @NL80211_WOWLAN_TRIG_MAGIC_PKT: wake up on magic packet (6x 0xff, followed + * by 16 repetitions of MAC addr, anywhere in payload) (flag) + * @NL80211_WOWLAN_TRIG_PKT_PATTERN: wake up on the specified packet patterns + * which are passed in an array of nested attributes, each nested attribute + * defining a with attributes from &struct nl80211_wowlan_trig_pkt_pattern. + * Each pattern defines a wakeup packet. The matching is done on the MSDU, + * i.e. as though the packet was an 802.3 packet, so the pattern matching + * is done after the packet is converted to the MSDU. + * + * In %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED, it is a binary attribute + * carrying a &struct nl80211_wowlan_pattern_support. + * @NUM_NL80211_WOWLAN_TRIG: number of wake on wireless triggers + * @MAX_NL80211_WOWLAN_TRIG: highest wowlan trigger attribute number + */ +enum nl80211_wowlan_triggers { + __NL80211_WOWLAN_TRIG_INVALID, + NL80211_WOWLAN_TRIG_ANY, + NL80211_WOWLAN_TRIG_DISCONNECT, + NL80211_WOWLAN_TRIG_MAGIC_PKT, + NL80211_WOWLAN_TRIG_PKT_PATTERN, + + /* keep last */ + NUM_NL80211_WOWLAN_TRIG, + MAX_NL80211_WOWLAN_TRIG = NUM_NL80211_WOWLAN_TRIG - 1 +}; + #endif /* __LINUX_NL80211_H */ diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 4932dfcb72b4..0920daf36807 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1087,6 +1087,38 @@ struct cfg80211_pmksa { u8 *pmkid; }; +/** + * struct cfg80211_wowlan_trig_pkt_pattern - packet pattern + * @mask: bitmask where to match pattern and where to ignore bytes, + * one bit per byte, in same format as nl80211 + * @pattern: bytes to match where bitmask is 1 + * @pattern_len: length of pattern (in bytes) + * + * Internal note: @mask and @pattern are allocated in one chunk of + * memory, free @mask only! + */ +struct cfg80211_wowlan_trig_pkt_pattern { + u8 *mask, *pattern; + int pattern_len; +}; + +/** + * struct cfg80211_wowlan - Wake on Wireless-LAN support info + * + * This structure defines the enabled WoWLAN triggers for the device. + * @any: wake up on any activity -- special trigger if device continues + * operating as normal during suspend + * @disconnect: wake up if getting disconnected + * @magic_pkt: wake up on receiving magic packet + * @patterns: wake up on receiving packet matching a pattern + * @n_patterns: number of patterns + */ +struct cfg80211_wowlan { + bool any, disconnect, magic_pkt; + struct cfg80211_wowlan_trig_pkt_pattern *patterns; + int n_patterns; +}; + /** * struct cfg80211_ops - backend description for wireless configuration * @@ -1100,7 +1132,9 @@ struct cfg80211_pmksa { * wireless extensions but this is subject to reevaluation as soon as this * code is used more widely and we have a first user without wext. * - * @suspend: wiphy device needs to be suspended + * @suspend: wiphy device needs to be suspended. The variable @wow will + * be %NULL or contain the enabled Wake-on-Wireless triggers that are + * configured for the device. * @resume: wiphy device needs to be resumed * * @add_virtual_intf: create a new virtual interface with the given name, @@ -1244,7 +1278,7 @@ struct cfg80211_pmksa { * @get_ringparam: Get tx and rx ring current and maximum sizes. */ struct cfg80211_ops { - int (*suspend)(struct wiphy *wiphy); + int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); int (*resume)(struct wiphy *wiphy); struct net_device * (*add_virtual_intf)(struct wiphy *wiphy, @@ -1479,6 +1513,38 @@ struct ieee80211_txrx_stypes { u16 tx, rx; }; +/** + * enum wiphy_wowlan_support_flags - WoWLAN support flags + * @WIPHY_WOWLAN_ANY: supports wakeup for the special "any" + * trigger that keeps the device operating as-is and + * wakes up the host on any activity, for example a + * received packet that passed filtering; note that the + * packet should be preserved in that case + * @WIPHY_WOWLAN_MAGIC_PKT: supports wakeup on magic packet + * (see nl80211.h) + * @WIPHY_WOWLAN_DISCONNECT: supports wakeup on disconnect + */ +enum wiphy_wowlan_support_flags { + WIPHY_WOWLAN_ANY = BIT(0), + WIPHY_WOWLAN_MAGIC_PKT = BIT(1), + WIPHY_WOWLAN_DISCONNECT = BIT(2), +}; + +/** + * struct wiphy_wowlan_support - WoWLAN support data + * @flags: see &enum wiphy_wowlan_support_flags + * @n_patterns: number of supported wakeup patterns + * (see nl80211.h for the pattern definition) + * @pattern_max_len: maximum length of each pattern + * @pattern_min_len: minimum length of each pattern + */ +struct wiphy_wowlan_support { + u32 flags; + int n_patterns; + int pattern_max_len; + int pattern_min_len; +}; + /** * struct wiphy - wireless hardware description * @reg_notifier: the driver's regulatory notification callback, @@ -1546,6 +1612,8 @@ struct ieee80211_txrx_stypes { * * @max_remain_on_channel_duration: Maximum time a remain-on-channel operation * may request, if implemented. + * + * @wowlan: WoWLAN support information */ struct wiphy { /* assign these fields before you register the wiphy */ @@ -1583,6 +1651,8 @@ struct wiphy { char fw_version[ETHTOOL_BUSINFO_LEN]; u32 hw_version; + struct wiphy_wowlan_support wowlan; + u16 max_remain_on_channel_duration; u8 max_num_pmkids; diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 12d52cec9515..321d598eb8cb 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1297,7 +1297,8 @@ static int ieee80211_set_channel(struct wiphy *wiphy, } #ifdef CONFIG_PM -static int ieee80211_suspend(struct wiphy *wiphy) +static int ieee80211_suspend(struct wiphy *wiphy, + struct cfg80211_wowlan *wowlan) { return __ieee80211_suspend(wiphy_priv(wiphy)); } diff --git a/net/wireless/core.c b/net/wireless/core.c index bbf1fa11107a..bea0d80710c8 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -493,6 +493,13 @@ int wiphy_register(struct wiphy *wiphy) return -EINVAL; } + if (rdev->wiphy.wowlan.n_patterns) { + if (WARN_ON(!rdev->wiphy.wowlan.pattern_min_len || + rdev->wiphy.wowlan.pattern_min_len > + rdev->wiphy.wowlan.pattern_max_len)) + return -EINVAL; + } + /* check and set up bitrates */ ieee80211_set_bitrate_flags(wiphy); @@ -631,6 +638,7 @@ void cfg80211_dev_free(struct cfg80211_registered_device *rdev) mutex_destroy(&rdev->devlist_mtx); list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list) cfg80211_put_bss(&scan->pub); + cfg80211_rdev_free_wowlan(rdev); kfree(rdev); } diff --git a/net/wireless/core.h b/net/wireless/core.h index 26a0a084e16b..7a18c10a7fb6 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -70,6 +70,8 @@ struct cfg80211_registered_device { struct work_struct conn_work; struct work_struct event_work; + struct cfg80211_wowlan *wowlan; + /* must be last because of the way we do wiphy_priv(), * and it should at least be aligned to NETDEV_ALIGN */ struct wiphy wiphy __attribute__((__aligned__(NETDEV_ALIGN))); @@ -89,6 +91,18 @@ bool wiphy_idx_valid(int wiphy_idx) return wiphy_idx >= 0; } +static inline void +cfg80211_rdev_free_wowlan(struct cfg80211_registered_device *rdev) +{ + int i; + + if (!rdev->wowlan) + return; + for (i = 0; i < rdev->wowlan->n_patterns; i++) + kfree(rdev->wowlan->patterns[i].mask); + kfree(rdev->wowlan->patterns); + kfree(rdev->wowlan); +} extern struct workqueue_struct *cfg80211_wq; extern struct mutex cfg80211_mutex; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index ab77f943dc04..0a199a1ca9b6 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -173,6 +173,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { [NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 }, [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG }, [NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED }, + [NL80211_ATTR_WOWLAN_TRIGGERS] = { .type = NLA_NESTED }, }; /* policy for the key attributes */ @@ -194,6 +195,15 @@ nl80211_key_default_policy[NUM_NL80211_KEY_DEFAULT_TYPES] = { [NL80211_KEY_DEFAULT_TYPE_MULTICAST] = { .type = NLA_FLAG }, }; +/* policy for WoWLAN attributes */ +static const struct nla_policy +nl80211_wowlan_policy[NUM_NL80211_WOWLAN_TRIG] = { + [NL80211_WOWLAN_TRIG_ANY] = { .type = NLA_FLAG }, + [NL80211_WOWLAN_TRIG_DISCONNECT] = { .type = NLA_FLAG }, + [NL80211_WOWLAN_TRIG_MAGIC_PKT] = { .type = NLA_FLAG }, + [NL80211_WOWLAN_TRIG_PKT_PATTERN] = { .type = NLA_NESTED }, +}; + /* ifidx get helper */ static int nl80211_get_ifidx(struct netlink_callback *cb) { @@ -821,6 +831,35 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, nla_nest_end(msg, nl_ifs); } + if (dev->wiphy.wowlan.flags || dev->wiphy.wowlan.n_patterns) { + struct nlattr *nl_wowlan; + + nl_wowlan = nla_nest_start(msg, + NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED); + if (!nl_wowlan) + goto nla_put_failure; + + if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_ANY) + NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_ANY); + if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_DISCONNECT) + NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT); + if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_MAGIC_PKT) + NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT); + if (dev->wiphy.wowlan.n_patterns) { + struct nl80211_wowlan_pattern_support pat = { + .max_patterns = dev->wiphy.wowlan.n_patterns, + .min_pattern_len = + dev->wiphy.wowlan.pattern_min_len, + .max_pattern_len = + dev->wiphy.wowlan.pattern_max_len, + }; + NLA_PUT(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN, + sizeof(pat), &pat); + } + + nla_nest_end(msg, nl_wowlan); + } + return genlmsg_end(msg, hdr); nla_put_failure: @@ -4808,6 +4847,194 @@ static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info) return cfg80211_leave_mesh(rdev, dev); } +static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct sk_buff *msg; + void *hdr; + + if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns) + return -EOPNOTSUPP; + + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (!msg) + return -ENOMEM; + + hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, + NL80211_CMD_GET_WOWLAN); + if (!hdr) + goto nla_put_failure; + + if (rdev->wowlan) { + struct nlattr *nl_wowlan; + + nl_wowlan = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS); + if (!nl_wowlan) + goto nla_put_failure; + + if (rdev->wowlan->any) + NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_ANY); + if (rdev->wowlan->disconnect) + NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT); + if (rdev->wowlan->magic_pkt) + NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT); + if (rdev->wowlan->n_patterns) { + struct nlattr *nl_pats, *nl_pat; + int i, pat_len; + + nl_pats = nla_nest_start(msg, + NL80211_WOWLAN_TRIG_PKT_PATTERN); + if (!nl_pats) + goto nla_put_failure; + + for (i = 0; i < rdev->wowlan->n_patterns; i++) { + nl_pat = nla_nest_start(msg, i + 1); + if (!nl_pat) + goto nla_put_failure; + pat_len = rdev->wowlan->patterns[i].pattern_len; + NLA_PUT(msg, NL80211_WOWLAN_PKTPAT_MASK, + DIV_ROUND_UP(pat_len, 8), + rdev->wowlan->patterns[i].mask); + NLA_PUT(msg, NL80211_WOWLAN_PKTPAT_PATTERN, + pat_len, + rdev->wowlan->patterns[i].pattern); + nla_nest_end(msg, nl_pat); + } + nla_nest_end(msg, nl_pats); + } + + nla_nest_end(msg, nl_wowlan); + } + + genlmsg_end(msg, hdr); + return genlmsg_reply(msg, info); + +nla_put_failure: + nlmsg_free(msg); + return -ENOBUFS; +} + +static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct nlattr *tb[NUM_NL80211_WOWLAN_TRIG]; + struct cfg80211_wowlan no_triggers = {}; + struct cfg80211_wowlan new_triggers = {}; + struct wiphy_wowlan_support *wowlan = &rdev->wiphy.wowlan; + int err, i; + + if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns) + return -EOPNOTSUPP; + + if (!info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) + goto no_triggers; + + err = nla_parse(tb, MAX_NL80211_WOWLAN_TRIG, + nla_data(info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]), + nla_len(info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]), + nl80211_wowlan_policy); + if (err) + return err; + + if (tb[NL80211_WOWLAN_TRIG_ANY]) { + if (!(wowlan->flags & WIPHY_WOWLAN_ANY)) + return -EINVAL; + new_triggers.any = true; + } + + if (tb[NL80211_WOWLAN_TRIG_DISCONNECT]) { + if (!(wowlan->flags & WIPHY_WOWLAN_DISCONNECT)) + return -EINVAL; + new_triggers.disconnect = true; + } + + if (tb[NL80211_WOWLAN_TRIG_MAGIC_PKT]) { + if (!(wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT)) + return -EINVAL; + new_triggers.magic_pkt = true; + } + + if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) { + struct nlattr *pat; + int n_patterns = 0; + int rem, pat_len, mask_len; + struct nlattr *pat_tb[NUM_NL80211_WOWLAN_PKTPAT]; + + nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN], + rem) + n_patterns++; + if (n_patterns > wowlan->n_patterns) + return -EINVAL; + + new_triggers.patterns = kcalloc(n_patterns, + sizeof(new_triggers.patterns[0]), + GFP_KERNEL); + if (!new_triggers.patterns) + return -ENOMEM; + + new_triggers.n_patterns = n_patterns; + i = 0; + + nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN], + rem) { + nla_parse(pat_tb, MAX_NL80211_WOWLAN_PKTPAT, + nla_data(pat), nla_len(pat), NULL); + err = -EINVAL; + if (!pat_tb[NL80211_WOWLAN_PKTPAT_MASK] || + !pat_tb[NL80211_WOWLAN_PKTPAT_PATTERN]) + goto error; + pat_len = nla_len(pat_tb[NL80211_WOWLAN_PKTPAT_PATTERN]); + mask_len = DIV_ROUND_UP(pat_len, 8); + if (nla_len(pat_tb[NL80211_WOWLAN_PKTPAT_MASK]) != + mask_len) + goto error; + if (pat_len > wowlan->pattern_max_len || + pat_len < wowlan->pattern_min_len) + goto error; + + new_triggers.patterns[i].mask = + kmalloc(mask_len + pat_len, GFP_KERNEL); + if (!new_triggers.patterns[i].mask) { + err = -ENOMEM; + goto error; + } + new_triggers.patterns[i].pattern = + new_triggers.patterns[i].mask + mask_len; + memcpy(new_triggers.patterns[i].mask, + nla_data(pat_tb[NL80211_WOWLAN_PKTPAT_MASK]), + mask_len); + new_triggers.patterns[i].pattern_len = pat_len; + memcpy(new_triggers.patterns[i].pattern, + nla_data(pat_tb[NL80211_WOWLAN_PKTPAT_PATTERN]), + pat_len); + i++; + } + } + + if (memcmp(&new_triggers, &no_triggers, sizeof(new_triggers))) { + struct cfg80211_wowlan *ntrig; + ntrig = kmemdup(&new_triggers, sizeof(new_triggers), + GFP_KERNEL); + if (!ntrig) { + err = -ENOMEM; + goto error; + } + cfg80211_rdev_free_wowlan(rdev); + rdev->wowlan = ntrig; + } else { + no_triggers: + cfg80211_rdev_free_wowlan(rdev); + rdev->wowlan = NULL; + } + + return 0; + error: + for (i = 0; i < new_triggers.n_patterns; i++) + kfree(new_triggers.patterns[i].mask); + kfree(new_triggers.patterns); + return err; +} + #define NL80211_FLAG_NEED_WIPHY 0x01 #define NL80211_FLAG_NEED_NETDEV 0x02 #define NL80211_FLAG_NEED_RTNL 0x04 @@ -5306,6 +5533,22 @@ static struct genl_ops nl80211_ops[] = { .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | NL80211_FLAG_NEED_RTNL, }, + { + .cmd = NL80211_CMD_GET_WOWLAN, + .doit = nl80211_get_wowlan, + .policy = nl80211_policy, + /* can be retrieved by unprivileged users */ + .internal_flags = NL80211_FLAG_NEED_WIPHY | + NL80211_FLAG_NEED_RTNL, + }, + { + .cmd = NL80211_CMD_SET_WOWLAN, + .doit = nl80211_set_wowlan, + .policy = nl80211_policy, + .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_WIPHY | + NL80211_FLAG_NEED_RTNL, + }, }; static struct genl_multicast_group nl80211_mlme_mcgrp = { diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c index 4294fa22bb2d..c6e4ca6a7d2e 100644 --- a/net/wireless/sysfs.c +++ b/net/wireless/sysfs.c @@ -93,7 +93,7 @@ static int wiphy_suspend(struct device *dev, pm_message_t state) if (rdev->ops->suspend) { rtnl_lock(); - ret = rdev->ops->suspend(&rdev->wiphy); + ret = rdev->ops->suspend(&rdev->wiphy, rdev->wowlan); rtnl_unlock(); } -- cgit From a26ac2455ffcf3be5c6ef92bc6df7182700f2114 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Wed, 12 Jan 2011 14:10:23 -0800 Subject: rcu: move TREE_RCU from softirq to kthread If RCU priority boosting is to be meaningful, callback invocation must be boosted in addition to preempted RCU readers. Otherwise, in presence of CPU real-time threads, the grace period ends, but the callbacks don't get invoked. If the callbacks don't get invoked, the associated memory doesn't get freed, so the system is still subject to OOM. But it is not reasonable to priority-boost RCU_SOFTIRQ, so this commit moves the callback invocations to a kthread, which can be boosted easily. Also add comments and properly synchronized all accesses to rcu_cpu_kthread_task, as suggested by Lai Jiangshan. Signed-off-by: Paul E. McKenney Signed-off-by: Paul E. McKenney Reviewed-by: Josh Triplett --- Documentation/filesystems/proc.txt | 1 - include/linux/interrupt.h | 1 - include/trace/events/irq.h | 3 +- kernel/rcutree.c | 340 +++++++++++++++++++++++++++++++++++- kernel/rcutree.h | 8 + kernel/rcutree_plugin.h | 4 +- kernel/softirq.c | 2 +- tools/perf/util/trace-event-parse.c | 1 - 8 files changed, 348 insertions(+), 12 deletions(-) (limited to 'include/linux') diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index b0b814d75ca1..60740e8ecb37 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt @@ -836,7 +836,6 @@ Provides counts of softirq handlers serviced since boot time, for each cpu. TASKLET: 0 0 0 290 SCHED: 27035 26983 26971 26746 HRTIMER: 0 0 0 0 - RCU: 1678 1769 2178 2250 1.3 IDE devices in /proc/ide diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index bea0ac750712..6c12989839d9 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -414,7 +414,6 @@ enum TASKLET_SOFTIRQ, SCHED_SOFTIRQ, HRTIMER_SOFTIRQ, - RCU_SOFTIRQ, /* Preferable RCU should always be the last softirq */ NR_SOFTIRQS }; diff --git a/include/trace/events/irq.h b/include/trace/events/irq.h index 1c09820df585..ae045ca7d356 100644 --- a/include/trace/events/irq.h +++ b/include/trace/events/irq.h @@ -20,8 +20,7 @@ struct softirq_action; softirq_name(BLOCK_IOPOLL), \ softirq_name(TASKLET), \ softirq_name(SCHED), \ - softirq_name(HRTIMER), \ - softirq_name(RCU)) + softirq_name(HRTIMER)) /** * irq_handler_entry - called immediately before the irq action handler diff --git a/kernel/rcutree.c b/kernel/rcutree.c index 0ac1cc03f935..18e33313873e 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c @@ -47,6 +47,8 @@ #include #include #include +#include +#include #include "rcutree.h" @@ -82,6 +84,20 @@ DEFINE_PER_CPU(struct rcu_data, rcu_bh_data); int rcu_scheduler_active __read_mostly; EXPORT_SYMBOL_GPL(rcu_scheduler_active); +/* + * Control variables for per-CPU and per-rcu_node kthreads. These + * handle all flavors of RCU. + */ +static DEFINE_PER_CPU(struct task_struct *, rcu_cpu_kthread_task); +static DEFINE_PER_CPU(wait_queue_head_t, rcu_cpu_wq); +static DEFINE_PER_CPU(char, rcu_cpu_has_work); +static char rcu_kthreads_spawnable; + +static void rcu_node_kthread_setaffinity(struct rcu_node *rnp); +static void invoke_rcu_kthread(void); + +#define RCU_KTHREAD_PRIO 1 /* RT priority for per-CPU kthreads. */ + /* * Return true if an RCU grace period is in progress. The ACCESS_ONCE()s * permit this function to be invoked without holding the root rcu_node @@ -1009,6 +1025,8 @@ static void rcu_send_cbs_to_online(struct rcu_state *rsp) /* * Remove the outgoing CPU from the bitmasks in the rcu_node hierarchy * and move all callbacks from the outgoing CPU to the current one. + * There can only be one CPU hotplug operation at a time, so no other + * CPU can be attempting to update rcu_cpu_kthread_task. */ static void __rcu_offline_cpu(int cpu, struct rcu_state *rsp) { @@ -1017,6 +1035,14 @@ static void __rcu_offline_cpu(int cpu, struct rcu_state *rsp) int need_report = 0; struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu); struct rcu_node *rnp; + struct task_struct *t; + + /* Stop the CPU's kthread. */ + t = per_cpu(rcu_cpu_kthread_task, cpu); + if (t != NULL) { + per_cpu(rcu_cpu_kthread_task, cpu) = NULL; + kthread_stop(t); + } /* Exclude any attempts to start a new grace period. */ raw_spin_lock_irqsave(&rsp->onofflock, flags); @@ -1054,6 +1080,19 @@ static void __rcu_offline_cpu(int cpu, struct rcu_state *rsp) raw_spin_unlock_irqrestore(&rnp->lock, flags); if (need_report & RCU_OFL_TASKS_EXP_GP) rcu_report_exp_rnp(rsp, rnp); + + /* + * If there are no more online CPUs for this rcu_node structure, + * kill the rcu_node structure's kthread. Otherwise, adjust its + * affinity. + */ + t = rnp->node_kthread_task; + if (t != NULL && + rnp->qsmaskinit == 0) { + kthread_stop(t); + rnp->node_kthread_task = NULL; + } else + rcu_node_kthread_setaffinity(rnp); } /* @@ -1151,7 +1190,7 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp) /* Re-raise the RCU softirq if there are callbacks remaining. */ if (cpu_has_callbacks_ready_to_invoke(rdp)) - raise_softirq(RCU_SOFTIRQ); + invoke_rcu_kthread(); } /* @@ -1197,7 +1236,7 @@ void rcu_check_callbacks(int cpu, int user) } rcu_preempt_check_callbacks(cpu); if (rcu_pending(cpu)) - raise_softirq(RCU_SOFTIRQ); + invoke_rcu_kthread(); } #ifdef CONFIG_SMP @@ -1361,7 +1400,7 @@ __rcu_process_callbacks(struct rcu_state *rsp, struct rcu_data *rdp) /* * Do softirq processing for the current CPU. */ -static void rcu_process_callbacks(struct softirq_action *unused) +static void rcu_process_callbacks(void) { __rcu_process_callbacks(&rcu_sched_state, &__get_cpu_var(rcu_sched_data)); @@ -1372,6 +1411,281 @@ static void rcu_process_callbacks(struct softirq_action *unused) rcu_needs_cpu_flush(); } +/* + * Wake up the current CPU's kthread. This replaces raise_softirq() + * in earlier versions of RCU. Note that because we are running on + * the current CPU with interrupts disabled, the rcu_cpu_kthread_task + * cannot disappear out from under us. + */ +static void invoke_rcu_kthread(void) +{ + unsigned long flags; + wait_queue_head_t *q; + int cpu; + + local_irq_save(flags); + cpu = smp_processor_id(); + per_cpu(rcu_cpu_has_work, cpu) = 1; + if (per_cpu(rcu_cpu_kthread_task, cpu) == NULL) { + local_irq_restore(flags); + return; + } + q = &per_cpu(rcu_cpu_wq, cpu); + wake_up(q); + local_irq_restore(flags); +} + +/* + * Timer handler to initiate the waking up of per-CPU kthreads that + * have yielded the CPU due to excess numbers of RCU callbacks. + */ +static void rcu_cpu_kthread_timer(unsigned long arg) +{ + unsigned long flags; + struct rcu_data *rdp = (struct rcu_data *)arg; + struct rcu_node *rnp = rdp->mynode; + struct task_struct *t; + + raw_spin_lock_irqsave(&rnp->lock, flags); + rnp->wakemask |= rdp->grpmask; + t = rnp->node_kthread_task; + if (t == NULL) { + raw_spin_unlock_irqrestore(&rnp->lock, flags); + return; + } + wake_up_process(t); + raw_spin_unlock_irqrestore(&rnp->lock, flags); +} + +/* + * Drop to non-real-time priority and yield, but only after posting a + * timer that will cause us to regain our real-time priority if we + * remain preempted. Either way, we restore our real-time priority + * before returning. + */ +static void rcu_yield(int cpu) +{ + struct rcu_data *rdp = per_cpu_ptr(rcu_sched_state.rda, cpu); + struct sched_param sp; + struct timer_list yield_timer; + + setup_timer_on_stack(&yield_timer, rcu_cpu_kthread_timer, (unsigned long)rdp); + mod_timer(&yield_timer, jiffies + 2); + sp.sched_priority = 0; + sched_setscheduler_nocheck(current, SCHED_NORMAL, &sp); + schedule(); + sp.sched_priority = RCU_KTHREAD_PRIO; + sched_setscheduler_nocheck(current, SCHED_FIFO, &sp); + del_timer(&yield_timer); +} + +/* + * Handle cases where the rcu_cpu_kthread() ends up on the wrong CPU. + * This can happen while the corresponding CPU is either coming online + * or going offline. We cannot wait until the CPU is fully online + * before starting the kthread, because the various notifier functions + * can wait for RCU grace periods. So we park rcu_cpu_kthread() until + * the corresponding CPU is online. + * + * Return 1 if the kthread needs to stop, 0 otherwise. + * + * Caller must disable bh. This function can momentarily enable it. + */ +static int rcu_cpu_kthread_should_stop(int cpu) +{ + while (cpu_is_offline(cpu) || + !cpumask_equal(¤t->cpus_allowed, cpumask_of(cpu)) || + smp_processor_id() != cpu) { + if (kthread_should_stop()) + return 1; + local_bh_enable(); + schedule_timeout_uninterruptible(1); + if (!cpumask_equal(¤t->cpus_allowed, cpumask_of(cpu))) + set_cpus_allowed_ptr(current, cpumask_of(cpu)); + local_bh_disable(); + } + return 0; +} + +/* + * Per-CPU kernel thread that invokes RCU callbacks. This replaces the + * earlier RCU softirq. + */ +static int rcu_cpu_kthread(void *arg) +{ + int cpu = (int)(long)arg; + unsigned long flags; + int spincnt = 0; + wait_queue_head_t *wqp = &per_cpu(rcu_cpu_wq, cpu); + char work; + char *workp = &per_cpu(rcu_cpu_has_work, cpu); + + for (;;) { + wait_event_interruptible(*wqp, + *workp != 0 || kthread_should_stop()); + local_bh_disable(); + if (rcu_cpu_kthread_should_stop(cpu)) { + local_bh_enable(); + break; + } + local_irq_save(flags); + work = *workp; + *workp = 0; + local_irq_restore(flags); + if (work) + rcu_process_callbacks(); + local_bh_enable(); + if (*workp != 0) + spincnt++; + else + spincnt = 0; + if (spincnt > 10) { + rcu_yield(cpu); + spincnt = 0; + } + } + return 0; +} + +/* + * Spawn a per-CPU kthread, setting up affinity and priority. + * Because the CPU hotplug lock is held, no other CPU will be attempting + * to manipulate rcu_cpu_kthread_task. There might be another CPU + * attempting to access it during boot, but the locking in kthread_bind() + * will enforce sufficient ordering. + */ +static int __cpuinit rcu_spawn_one_cpu_kthread(int cpu) +{ + struct sched_param sp; + struct task_struct *t; + + if (!rcu_kthreads_spawnable || + per_cpu(rcu_cpu_kthread_task, cpu) != NULL) + return 0; + t = kthread_create(rcu_cpu_kthread, (void *)(long)cpu, "rcuc%d", cpu); + if (IS_ERR(t)) + return PTR_ERR(t); + kthread_bind(t, cpu); + WARN_ON_ONCE(per_cpu(rcu_cpu_kthread_task, cpu) != NULL); + per_cpu(rcu_cpu_kthread_task, cpu) = t; + wake_up_process(t); + sp.sched_priority = RCU_KTHREAD_PRIO; + sched_setscheduler_nocheck(t, SCHED_FIFO, &sp); + return 0; +} + +/* + * Per-rcu_node kthread, which is in charge of waking up the per-CPU + * kthreads when needed. We ignore requests to wake up kthreads + * for offline CPUs, which is OK because force_quiescent_state() + * takes care of this case. + */ +static int rcu_node_kthread(void *arg) +{ + int cpu; + unsigned long flags; + unsigned long mask; + struct rcu_node *rnp = (struct rcu_node *)arg; + struct sched_param sp; + struct task_struct *t; + + for (;;) { + wait_event_interruptible(rnp->node_wq, rnp->wakemask != 0 || + kthread_should_stop()); + if (kthread_should_stop()) + break; + raw_spin_lock_irqsave(&rnp->lock, flags); + mask = rnp->wakemask; + rnp->wakemask = 0; + raw_spin_unlock_irqrestore(&rnp->lock, flags); + for (cpu = rnp->grplo; cpu <= rnp->grphi; cpu++, mask >>= 1) { + if ((mask & 0x1) == 0) + continue; + preempt_disable(); + t = per_cpu(rcu_cpu_kthread_task, cpu); + if (!cpu_online(cpu) || t == NULL) { + preempt_enable(); + continue; + } + per_cpu(rcu_cpu_has_work, cpu) = 1; + sp.sched_priority = RCU_KTHREAD_PRIO; + sched_setscheduler_nocheck(t, SCHED_FIFO, &sp); + preempt_enable(); + } + } + return 0; +} + +/* + * Set the per-rcu_node kthread's affinity to cover all CPUs that are + * served by the rcu_node in question. + */ +static void rcu_node_kthread_setaffinity(struct rcu_node *rnp) +{ + cpumask_var_t cm; + int cpu; + unsigned long mask = rnp->qsmaskinit; + + if (rnp->node_kthread_task == NULL || + rnp->qsmaskinit == 0) + return; + if (!alloc_cpumask_var(&cm, GFP_KERNEL)) + return; + cpumask_clear(cm); + for (cpu = rnp->grplo; cpu <= rnp->grphi; cpu++, mask >>= 1) + if (mask & 0x1) + cpumask_set_cpu(cpu, cm); + set_cpus_allowed_ptr(rnp->node_kthread_task, cm); + free_cpumask_var(cm); +} + +/* + * Spawn a per-rcu_node kthread, setting priority and affinity. + */ +static int __cpuinit rcu_spawn_one_node_kthread(struct rcu_state *rsp, + struct rcu_node *rnp) +{ + int rnp_index = rnp - &rsp->node[0]; + struct sched_param sp; + struct task_struct *t; + + if (!rcu_kthreads_spawnable || + rnp->qsmaskinit == 0 || + rnp->node_kthread_task != NULL) + return 0; + t = kthread_create(rcu_node_kthread, (void *)rnp, "rcun%d", rnp_index); + if (IS_ERR(t)) + return PTR_ERR(t); + rnp->node_kthread_task = t; + wake_up_process(t); + sp.sched_priority = 99; + sched_setscheduler_nocheck(t, SCHED_FIFO, &sp); + return 0; +} + +/* + * Spawn all kthreads -- called as soon as the scheduler is running. + */ +static int __init rcu_spawn_kthreads(void) +{ + int cpu; + struct rcu_node *rnp; + + rcu_kthreads_spawnable = 1; + for_each_possible_cpu(cpu) { + init_waitqueue_head(&per_cpu(rcu_cpu_wq, cpu)); + per_cpu(rcu_cpu_has_work, cpu) = 0; + if (cpu_online(cpu)) + (void)rcu_spawn_one_cpu_kthread(cpu); + } + rcu_for_each_leaf_node(&rcu_sched_state, rnp) { + init_waitqueue_head(&rnp->node_wq); + (void)rcu_spawn_one_node_kthread(&rcu_sched_state, rnp); + } + return 0; +} +early_initcall(rcu_spawn_kthreads); + static void __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu), struct rcu_state *rsp) @@ -1771,6 +2085,19 @@ static void __cpuinit rcu_online_cpu(int cpu) rcu_preempt_init_percpu_data(cpu); } +static void __cpuinit rcu_online_kthreads(int cpu) +{ + struct rcu_data *rdp = per_cpu_ptr(rcu_sched_state.rda, cpu); + struct rcu_node *rnp = rdp->mynode; + + /* Fire up the incoming CPU's kthread and leaf rcu_node kthread. */ + if (rcu_kthreads_spawnable) { + (void)rcu_spawn_one_cpu_kthread(cpu); + if (rnp->node_kthread_task == NULL) + (void)rcu_spawn_one_node_kthread(&rcu_sched_state, rnp); + } +} + /* * Handle CPU online/offline notification events. */ @@ -1778,11 +2105,17 @@ static int __cpuinit rcu_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) { long cpu = (long)hcpu; + struct rcu_data *rdp = per_cpu_ptr(rcu_sched_state.rda, cpu); + struct rcu_node *rnp = rdp->mynode; switch (action) { case CPU_UP_PREPARE: case CPU_UP_PREPARE_FROZEN: rcu_online_cpu(cpu); + rcu_online_kthreads(cpu); + break; + case CPU_ONLINE: + rcu_node_kthread_setaffinity(rnp); break; case CPU_DYING: case CPU_DYING_FROZEN: @@ -1923,7 +2256,6 @@ void __init rcu_init(void) rcu_init_one(&rcu_sched_state, &rcu_sched_data); rcu_init_one(&rcu_bh_state, &rcu_bh_data); __rcu_init_preempt(); - open_softirq(RCU_SOFTIRQ, rcu_process_callbacks); /* * We don't need protection against CPU-hotplug here because diff --git a/kernel/rcutree.h b/kernel/rcutree.h index 5a439c180e69..c0213802d164 100644 --- a/kernel/rcutree.h +++ b/kernel/rcutree.h @@ -111,6 +111,7 @@ struct rcu_node { /* elements that need to drain to allow the */ /* current expedited grace period to */ /* complete (only for TREE_PREEMPT_RCU). */ + unsigned long wakemask; /* CPUs whose kthread needs to be awakened. */ unsigned long qsmaskinit; /* Per-GP initial value for qsmask & expmask. */ unsigned long grpmask; /* Mask to apply to parent qsmask. */ @@ -134,6 +135,13 @@ struct rcu_node { /* if there is no such task. If there */ /* is no current expedited grace period, */ /* then there can cannot be any such task. */ + struct task_struct *node_kthread_task; + /* kthread that takes care of this rcu_node */ + /* structure, for example, awakening the */ + /* per-CPU kthreads as needed. */ + wait_queue_head_t node_wq; + /* Wait queue on which to park the per-node */ + /* kthread. */ } ____cacheline_internodealigned_in_smp; /* diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h index 774f010a4619..b9bd69a5a4fe 100644 --- a/kernel/rcutree_plugin.h +++ b/kernel/rcutree_plugin.h @@ -1206,7 +1206,7 @@ static DEFINE_PER_CPU(unsigned long, rcu_dyntick_holdoff); * * Because it is not legal to invoke rcu_process_callbacks() with irqs * disabled, we do one pass of force_quiescent_state(), then do a - * raise_softirq() to cause rcu_process_callbacks() to be invoked later. + * invoke_rcu_kthread() to cause rcu_process_callbacks() to be invoked later. * The per-cpu rcu_dyntick_drain variable controls the sequencing. */ int rcu_needs_cpu(int cpu) @@ -1257,7 +1257,7 @@ int rcu_needs_cpu(int cpu) /* If RCU callbacks are still pending, RCU still needs this CPU. */ if (c) - raise_softirq(RCU_SOFTIRQ); + invoke_rcu_kthread(); return c; } diff --git a/kernel/softirq.c b/kernel/softirq.c index 174f976c2874..13960170cad4 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -58,7 +58,7 @@ DEFINE_PER_CPU(struct task_struct *, ksoftirqd); char *softirq_to_name[NR_SOFTIRQS] = { "HI", "TIMER", "NET_TX", "NET_RX", "BLOCK", "BLOCK_IOPOLL", - "TASKLET", "SCHED", "HRTIMER", "RCU" + "TASKLET", "SCHED", "HRTIMER" }; /* diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c index 0a7ed5b5e281..1e88485c16a0 100644 --- a/tools/perf/util/trace-event-parse.c +++ b/tools/perf/util/trace-event-parse.c @@ -2187,7 +2187,6 @@ static const struct flag flags[] = { { "TASKLET_SOFTIRQ", 6 }, { "SCHED_SOFTIRQ", 7 }, { "HRTIMER_SOFTIRQ", 8 }, - { "RCU_SOFTIRQ", 9 }, { "HRTIMER_NORESTART", 0 }, { "HRTIMER_RESTART", 1 }, -- cgit From 4a29865689dbb87a02e3b0fff4a4ae5041273173 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Sun, 3 Apr 2011 21:33:51 -0700 Subject: rcu: make rcutorture version numbers available through debugfs It is not possible to accurately correlate rcutorture output with that of debugfs. This patch therefore adds a debugfs file that prints out the rcutorture version number, permitting easy correlation. Signed-off-by: Paul E. McKenney Signed-off-by: Paul E. McKenney Reviewed-by: Josh Triplett --- include/linux/rcupdate.h | 13 ++++++++++++- include/linux/rcutree.h | 3 +++ kernel/rcutorture.c | 8 +++++--- kernel/rcutree.c | 37 +++++++++++++++++++++++++++++++++++++ kernel/rcutree_trace.c | 28 ++++++++++++++++++++++++++++ 5 files changed, 85 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index ff422d2b7f90..9e169c2ba91f 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -47,6 +47,18 @@ extern int rcutorture_runnable; /* for sysctl */ #endif /* #ifdef CONFIG_RCU_TORTURE_TEST */ +#if defined(CONFIG_TREE_RCU) || defined(CONFIG_TREE_PREEMPT_RCU) +extern void rcutorture_record_test_transition(void); +extern void rcutorture_record_progress(unsigned long vernum); +#else +static inline void rcutorture_record_test_transition(void) +{ +} +static inline void rcutorture_record_progress(unsigned long vernum) +{ +} +#endif + #define UINT_CMP_GE(a, b) (UINT_MAX / 2 >= (a) - (b)) #define UINT_CMP_LT(a, b) (UINT_MAX / 2 < (a) - (b)) #define ULONG_CMP_GE(a, b) (ULONG_MAX / 2 >= (a) - (b)) @@ -68,7 +80,6 @@ extern void call_rcu_sched(struct rcu_head *head, extern void synchronize_sched(void); extern void rcu_barrier_bh(void); extern void rcu_barrier_sched(void); -extern int sched_expedited_torture_stats(char *page); static inline void __rcu_read_lock_bh(void) { diff --git a/include/linux/rcutree.h b/include/linux/rcutree.h index 3a933482734a..284dad10c55b 100644 --- a/include/linux/rcutree.h +++ b/include/linux/rcutree.h @@ -58,9 +58,12 @@ static inline void synchronize_rcu_bh_expedited(void) extern void rcu_barrier(void); +extern unsigned long rcutorture_testseq; +extern unsigned long rcutorture_vernum; extern long rcu_batches_completed(void); extern long rcu_batches_completed_bh(void); extern long rcu_batches_completed_sched(void); + extern void rcu_force_quiescent_state(void); extern void rcu_bh_force_quiescent_state(void); extern void rcu_sched_force_quiescent_state(void); diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c index 22b0e74e7d99..c2f58ec24751 100644 --- a/kernel/rcutorture.c +++ b/kernel/rcutorture.c @@ -131,7 +131,7 @@ struct rcu_torture { static LIST_HEAD(rcu_torture_freelist); static struct rcu_torture __rcu *rcu_torture_current; -static long rcu_torture_current_version; +static unsigned long rcu_torture_current_version; static struct rcu_torture rcu_tortures[10 * RCU_TORTURE_PIPE_LEN]; static DEFINE_SPINLOCK(rcu_torture_lock); static DEFINE_PER_CPU(long [RCU_TORTURE_PIPE_LEN + 1], rcu_torture_count) = @@ -884,7 +884,7 @@ rcu_torture_writer(void *arg) old_rp->rtort_pipe_count++; cur_ops->deferred_free(old_rp); } - rcu_torture_current_version++; + rcutorture_record_progress(++rcu_torture_current_version); oldbatch = cur_ops->completed(); rcu_stutter_wait("rcu_torture_writer"); } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP); @@ -1064,7 +1064,7 @@ rcu_torture_printk(char *page) } cnt += sprintf(&page[cnt], "%s%s ", torture_type, TORTURE_FLAG); cnt += sprintf(&page[cnt], - "rtc: %p ver: %ld tfle: %d rta: %d rtaf: %d rtf: %d " + "rtc: %p ver: %lu tfle: %d rta: %d rtaf: %d rtf: %d " "rtmbe: %d rtbke: %ld rtbre: %ld " "rtbf: %ld rtb: %ld nt: %ld", rcu_torture_current, @@ -1325,6 +1325,7 @@ rcu_torture_cleanup(void) int i; mutex_lock(&fullstop_mutex); + rcutorture_record_test_transition(); if (fullstop == FULLSTOP_SHUTDOWN) { printk(KERN_WARNING /* but going down anyway, so... */ "Concurrent 'rmmod rcutorture' and shutdown illegal!\n"); @@ -1616,6 +1617,7 @@ rcu_torture_init(void) } } register_reboot_notifier(&rcutorture_shutdown_nb); + rcutorture_record_test_transition(); mutex_unlock(&fullstop_mutex); return 0; diff --git a/kernel/rcutree.c b/kernel/rcutree.c index d8917401cbbc..bb84deca3319 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c @@ -101,6 +101,18 @@ static void invoke_rcu_cpu_kthread(void); #define RCU_KTHREAD_PRIO 1 /* RT priority for per-CPU kthreads. */ +/* + * Track the rcutorture test sequence number and the update version + * number within a given test. The rcutorture_testseq is incremented + * on every rcutorture module load and unload, so has an odd value + * when a test is running. The rcutorture_vernum is set to zero + * when rcutorture starts and is incremented on each rcutorture update. + * These variables enable correlating rcutorture output with the + * RCU tracing information. + */ +unsigned long rcutorture_testseq; +unsigned long rcutorture_vernum; + /* * Return true if an RCU grace period is in progress. The ACCESS_ONCE()s * permit this function to be invoked without holding the root rcu_node @@ -192,6 +204,31 @@ void rcu_bh_force_quiescent_state(void) } EXPORT_SYMBOL_GPL(rcu_bh_force_quiescent_state); +/* + * Record the number of times rcutorture tests have been initiated and + * terminated. This information allows the debugfs tracing stats to be + * correlated to the rcutorture messages, even when the rcutorture module + * is being repeatedly loaded and unloaded. In other words, we cannot + * store this state in rcutorture itself. + */ +void rcutorture_record_test_transition(void) +{ + rcutorture_testseq++; + rcutorture_vernum = 0; +} +EXPORT_SYMBOL_GPL(rcutorture_record_test_transition); + +/* + * Record the number of writer passes through the current rcutorture test. + * This is also used to correlate debugfs tracing stats with the rcutorture + * messages. + */ +void rcutorture_record_progress(unsigned long vernum) +{ + rcutorture_vernum++; +} +EXPORT_SYMBOL_GPL(rcutorture_record_progress); + /* * Force a quiescent state for RCU-sched. */ diff --git a/kernel/rcutree_trace.c b/kernel/rcutree_trace.c index fc40e89a028c..3baa235786b5 100644 --- a/kernel/rcutree_trace.c +++ b/kernel/rcutree_trace.c @@ -394,6 +394,29 @@ static const struct file_operations rcu_pending_fops = { .release = single_release, }; +static int show_rcutorture(struct seq_file *m, void *unused) +{ + seq_printf(m, "rcutorture test sequence: %lu %s\n", + rcutorture_testseq >> 1, + (rcutorture_testseq & 0x1) ? "(test in progress)" : ""); + seq_printf(m, "rcutorture update version number: %lu\n", + rcutorture_vernum); + return 0; +} + +static int rcutorture_open(struct inode *inode, struct file *file) +{ + return single_open(file, show_rcutorture, NULL); +} + +static const struct file_operations rcutorture_fops = { + .owner = THIS_MODULE, + .open = rcutorture_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + static struct dentry *rcudir; static int __init rcutree_trace_init(void) @@ -430,6 +453,11 @@ static int __init rcutree_trace_init(void) NULL, &rcu_pending_fops); if (!retval) goto free_out; + + retval = debugfs_create_file("rcutorture", 0444, rcudir, + NULL, &rcutorture_fops); + if (!retval) + goto free_out; return 0; free_out: debugfs_remove_recursive(rcudir); -- cgit From b0c9d7ff2793502650ad987c3f237d5fe5587a1e Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Tue, 29 Mar 2011 12:56:56 -0700 Subject: rcu: add DEBUG_OBJECTS_RCU_HEAD check for alignment Verify that rcu_head structures are aligned to a four-byte boundary. This check is enabled by CONFIG_DEBUG_OBJECTS_RCU_HEAD. Signed-off-by: Paul E. McKenney Reviewed-by: Josh Triplett --- include/linux/rcupdate.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 9e169c2ba91f..c7aeacf7fc98 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -785,6 +785,7 @@ extern struct debug_obj_descr rcuhead_debug_descr; static inline void debug_rcu_head_queue(struct rcu_head *head) { + WARN_ON_ONCE((unsigned long)head & 0x3); debug_object_activate(head, &rcuhead_debug_descr); debug_object_active_state(head, &rcuhead_debug_descr, STATE_RCU_HEAD_READY, -- cgit From 9ab1544eb4196ca8d05c433b2eb56f74496b1ee3 Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Fri, 18 Mar 2011 11:15:47 +0800 Subject: rcu: introduce kfree_rcu() Many rcu callbacks functions just call kfree() on the base structure. These functions are trivial, but their size adds up, and furthermore when they are used in a kernel module, that module must invoke the high-latency rcu_barrier() function at module-unload time. The kfree_rcu() function introduced by this commit addresses this issue. Rather than encoding a function address in the embedded rcu_head structure, kfree_rcu() instead encodes the offset of the rcu_head structure within the base structure. Because the functions are not allowed in the low-order 4096 bytes of kernel virtual memory, offsets up to 4095 bytes can be accommodated. If the offset is larger than 4095 bytes, a compile-time error will be generated in __kfree_rcu(). If this error is triggered, you can either fall back to use of call_rcu() or rearrange the structure to position the rcu_head structure into the first 4096 bytes. Note that the allowable offset might decrease in the future, for example, to allow something like kmem_cache_free_rcu(). The new kfree_rcu() function can replace code as follows: call_rcu(&p->rcu, simple_kfree_callback); where "simple_kfree_callback()" might be defined as follows: void simple_kfree_callback(struct rcu_head *p) { struct foo *q = container_of(p, struct foo, rcu); kfree(q); } with the following: kfree_rcu(&p->rcu, rcu); Note that the "rcu" is the name of a field in the structure being freed. The reason for using this rather than passing in a pointer to the base structure is that the above approach allows better type checking. This commit is based on earlier work by Lai Jiangshan and Manfred Spraul: Lai's V1 patch: http://lkml.org/lkml/2008/9/18/1 Manfred's patch: http://lkml.org/lkml/2009/1/2/115 Signed-off-by: Lai Jiangshan Signed-off-by: Manfred Spraul Signed-off-by: Paul E. McKenney Reviewed-by: David Howells Reviewed-by: Josh Triplett --- include/linux/rcupdate.h | 56 ++++++++++++++++++++++++++++++++++++++++++++++++ kernel/rcutiny.c | 2 +- kernel/rcutree.c | 2 +- 3 files changed, 58 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index c7aeacf7fc98..99f9aa7c2804 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -809,4 +809,60 @@ static inline void debug_rcu_head_unqueue(struct rcu_head *head) } #endif /* #else !CONFIG_DEBUG_OBJECTS_RCU_HEAD */ +static __always_inline bool __is_kfree_rcu_offset(unsigned long offset) +{ + return offset < 4096; +} + +static __always_inline +void __kfree_rcu(struct rcu_head *head, unsigned long offset) +{ + typedef void (*rcu_callback)(struct rcu_head *); + + BUILD_BUG_ON(!__builtin_constant_p(offset)); + + /* See the kfree_rcu() header comment. */ + BUILD_BUG_ON(!__is_kfree_rcu_offset(offset)); + + call_rcu(head, (rcu_callback)offset); +} + +extern void kfree(const void *); + +static inline void __rcu_reclaim(struct rcu_head *head) +{ + unsigned long offset = (unsigned long)head->func; + + if (__is_kfree_rcu_offset(offset)) + kfree((void *)head - offset); + else + head->func(head); +} + +/** + * kfree_rcu() - kfree an object after a grace period. + * @ptr: pointer to kfree + * @rcu_head: the name of the struct rcu_head within the type of @ptr. + * + * Many rcu callbacks functions just call kfree() on the base structure. + * These functions are trivial, but their size adds up, and furthermore + * when they are used in a kernel module, that module must invoke the + * high-latency rcu_barrier() function at module-unload time. + * + * The kfree_rcu() function handles this issue. Rather than encoding a + * function address in the embedded rcu_head structure, kfree_rcu() instead + * encodes the offset of the rcu_head structure within the base structure. + * Because the functions are not allowed in the low-order 4096 bytes of + * kernel virtual memory, offsets up to 4095 bytes can be accommodated. + * If the offset is larger than 4095 bytes, a compile-time error will + * be generated in __kfree_rcu(). If this error is triggered, you can + * either fall back to use of call_rcu() or rearrange the structure to + * position the rcu_head structure into the first 4096 bytes. + * + * Note that the allowable offset might decrease in the future, for example, + * to allow something like kmem_cache_free_rcu(). + */ +#define kfree_rcu(ptr, rcu_head) \ + __kfree_rcu(&((ptr)->rcu_head), offsetof(typeof(*(ptr)), rcu_head)) + #endif /* __LINUX_RCUPDATE_H */ diff --git a/kernel/rcutiny.c b/kernel/rcutiny.c index 0c343b9a46d5..4d60fbc9c64c 100644 --- a/kernel/rcutiny.c +++ b/kernel/rcutiny.c @@ -167,7 +167,7 @@ static void rcu_process_callbacks(struct rcu_ctrlblk *rcp) prefetch(next); debug_rcu_head_unqueue(list); local_bh_disable(); - list->func(list); + __rcu_reclaim(list); local_bh_enable(); list = next; RCU_TRACE(cb_count++); diff --git a/kernel/rcutree.c b/kernel/rcutree.c index b579e4f97210..2c07adb97088 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c @@ -1206,7 +1206,7 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp) next = list->next; prefetch(next); debug_rcu_head_unqueue(list); - list->func(list); + __rcu_reclaim(list); list = next; if (++count >= rdp->blimit) break; -- cgit From 29ce831000081dd757d3116bf774aafffc4b6b20 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Wed, 4 May 2011 16:31:03 +0300 Subject: rcu: provide rcu_virt_note_context_switch() function. Provide rcu_virt_note_context_switch() for vitalization use to note quiescent state during guest entry. Signed-off-by: Gleb Natapov Signed-off-by: Paul E. McKenney --- include/linux/rcutiny.h | 8 ++++++++ include/linux/rcutree.h | 10 ++++++++++ kernel/rcutree.c | 1 + 3 files changed, 19 insertions(+) (limited to 'include/linux') diff --git a/include/linux/rcutiny.h b/include/linux/rcutiny.h index 30ebd7c8d874..52b3e0281fd0 100644 --- a/include/linux/rcutiny.h +++ b/include/linux/rcutiny.h @@ -99,6 +99,14 @@ static inline void rcu_note_context_switch(int cpu) rcu_preempt_note_context_switch(); } +/* + * Take advantage of the fact that there is only one CPU, which + * allows us to ignore virtualization-based context switches. + */ +static inline void rcu_virt_note_context_switch(int cpu) +{ +} + /* * Return the number of grace periods. */ diff --git a/include/linux/rcutree.h b/include/linux/rcutree.h index 284dad10c55b..e65d06634dd8 100644 --- a/include/linux/rcutree.h +++ b/include/linux/rcutree.h @@ -35,6 +35,16 @@ extern void rcu_note_context_switch(int cpu); extern int rcu_needs_cpu(int cpu); extern void rcu_cpu_stall_reset(void); +/* + * Note a virtualization-based context switch. This is simply a + * wrapper around rcu_note_context_switch(), which allows TINY_RCU + * to save a few bytes. + */ +static inline void rcu_virt_note_context_switch(int cpu) +{ + rcu_note_context_switch(cpu); +} + #ifdef CONFIG_TREE_PREEMPT_RCU extern void exit_rcu(void); diff --git a/kernel/rcutree.c b/kernel/rcutree.c index b2fe2a273df2..54ff7eb92819 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c @@ -157,6 +157,7 @@ void rcu_note_context_switch(int cpu) rcu_sched_qs(cpu); rcu_preempt_note_context_switch(cpu); } +EXPORT_SYMBOL_GPL(rcu_note_context_switch); #ifdef CONFIG_NO_HZ DEFINE_PER_CPU(struct rcu_dynticks, rcu_dynticks) = { -- cgit From f3876930952390a31c3a7fd68dd621464a36eb80 Mon Sep 17 00:00:00 2001 From: "shaohua.li@intel.com" Date: Fri, 6 May 2011 11:34:32 -0600 Subject: block: add a non-queueable flush flag flush request isn't queueable in some drives. Add a flag to let driver notify block layer about this. We can optimize flush performance with the knowledge. Stable: 2.6.39 only Cc: stable@kernel.org Signed-off-by: Shaohua Li Acked-by: Tejun Heo Signed-off-by: Jens Axboe --- block/blk-settings.c | 6 ++++++ include/linux/blkdev.h | 7 +++++++ 2 files changed, 13 insertions(+) (limited to 'include/linux') diff --git a/block/blk-settings.c b/block/blk-settings.c index 1fa769293597..cd3c428e194f 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c @@ -790,6 +790,12 @@ void blk_queue_flush(struct request_queue *q, unsigned int flush) } EXPORT_SYMBOL_GPL(blk_queue_flush); +void blk_queue_flush_queueable(struct request_queue *q, bool queueable) +{ + q->flush_not_queueable = !queueable; +} +EXPORT_SYMBOL_GPL(blk_queue_flush_queueable); + static int __init blk_settings_init(void) { blk_max_low_pfn = max_low_pfn - 1; diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index cbbfd98ad4a3..8bd2a271b2d8 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -364,6 +364,7 @@ struct request_queue * for flush operations */ unsigned int flush_flags; + unsigned int flush_not_queueable:1; unsigned int flush_pending_idx:1; unsigned int flush_running_idx:1; unsigned long flush_pending_since; @@ -843,6 +844,7 @@ extern void blk_queue_softirq_done(struct request_queue *, softirq_done_fn *); extern void blk_queue_rq_timed_out(struct request_queue *, rq_timed_out_fn *); extern void blk_queue_rq_timeout(struct request_queue *, unsigned int); extern void blk_queue_flush(struct request_queue *q, unsigned int flush); +extern void blk_queue_flush_queueable(struct request_queue *q, bool queueable); extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev); extern int blk_rq_map_sg(struct request_queue *, struct request *, struct scatterlist *); @@ -1111,6 +1113,11 @@ static inline unsigned int block_size(struct block_device *bdev) return bdev->bd_block_size; } +static inline bool queue_flush_queueable(struct request_queue *q) +{ + return !q->flush_not_queueable; +} + typedef struct {struct page *v;} Sector; unsigned char *read_dev_sector(struct block_device *, sector_t, Sector *); -- cgit From 3ac0cc4508709d42ec9aa351086c7d38bfc0660c Mon Sep 17 00:00:00 2001 From: "shaohua.li@intel.com" Date: Fri, 6 May 2011 11:34:41 -0600 Subject: block: hold queue if flush is running for non-queueable flush drive In some drives, flush requests are non-queueable. When flush request is running, normal read/write requests can't run. If block layer dispatches such request, driver can't handle it and requeue it. Tejun suggested we can hold the queue when flush is running. This can avoid unnecessary requeue. Also this can improve performance. For example, we have request flush1, write1, flush 2. flush1 is dispatched, then queue is hold, write1 isn't inserted to queue. After flush1 is finished, flush2 will be dispatched. Since disk cache is already clean, flush2 will be finished very soon, so looks like flush2 is folded to flush1. In my test, the queue holding completely solves a regression introduced by commit 53d63e6b0dfb95882ec0219ba6bbd50cde423794: block: make the flush insertion use the tail of the dispatch list It's not a preempt type request, in fact we have to insert it behind requests that do specify INSERT_FRONT. which causes about 20% regression running a sysbench fileio workload. Stable: 2.6.39 only Cc: stable@kernel.org Signed-off-by: Shaohua Li Acked-by: Tejun Heo Signed-off-by: Jens Axboe --- block/blk-flush.c | 16 +++++++++++----- block/blk.h | 21 ++++++++++++++++++++- include/linux/blkdev.h | 1 + 3 files changed, 32 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/block/blk-flush.c b/block/blk-flush.c index 6c9b5e189e62..bb21e4c36f70 100644 --- a/block/blk-flush.c +++ b/block/blk-flush.c @@ -212,13 +212,19 @@ static void flush_end_io(struct request *flush_rq, int error) } /* - * Moving a request silently to empty queue_head may stall the - * queue. Kick the queue in those cases. This function is called - * from request completion path and calling directly into - * request_fn may confuse the driver. Always use kblockd. + * Kick the queue to avoid stall for two cases: + * 1. Moving a request silently to empty queue_head may stall the + * queue. + * 2. When flush request is running in non-queueable queue, the + * queue is hold. Restart the queue after flush request is finished + * to avoid stall. + * This function is called from request completion path and calling + * directly into request_fn may confuse the driver. Always use + * kblockd. */ - if (queued) + if (queued || q->flush_queue_delayed) blk_run_queue_async(q); + q->flush_queue_delayed = 0; } /** diff --git a/block/blk.h b/block/blk.h index c9df8fc3c999..83e4bff36201 100644 --- a/block/blk.h +++ b/block/blk.h @@ -62,7 +62,26 @@ static inline struct request *__elv_next_request(struct request_queue *q) rq = list_entry_rq(q->queue_head.next); return rq; } - + /* + * Flush request is running and flush request isn't queueable + * in the drive, we can hold the queue till flush request is + * finished. Even we don't do this, driver can't dispatch next + * requests and will requeue them. And this can improve + * throughput too. For example, we have request flush1, write1, + * flush 2. flush1 is dispatched, then queue is hold, write1 + * isn't inserted to queue. After flush1 is finished, flush2 + * will be dispatched. Since disk cache is already clean, + * flush2 will be finished very soon, so looks like flush2 is + * folded to flush1. + * Since the queue is hold, a flag is set to indicate the queue + * should be restarted later. Please see flush_end_io() for + * details. + */ + if (q->flush_pending_idx != q->flush_running_idx && + !queue_flush_queueable(q)) { + q->flush_queue_delayed = 1; + return NULL; + } if (!q->elevator->ops->elevator_dispatch_fn(q, 0)) return NULL; } diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 8bd2a271b2d8..9f921bf4bf8c 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -365,6 +365,7 @@ struct request_queue */ unsigned int flush_flags; unsigned int flush_not_queueable:1; + unsigned int flush_queue_delayed:1; unsigned int flush_pending_idx:1; unsigned int flush_running_idx:1; unsigned long flush_pending_since; -- cgit From a3a4a5acd3bd2f6f1e102e1f1b9d2e2bb320a7fd Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Thu, 5 May 2011 23:55:18 -0400 Subject: Regression: partial revert "tracing: Remove lock_depth from event entry" This partially reverts commit e6e1e2593592a8f6f6380496655d8c6f67431266. That commit changed the structure layout of the trace structure, which in turn broke PowerTOP (1.9x generation) quite badly. I appreciate not wanting to expose the variable in question, and PowerTOP was not using it, so I've replaced the variable with just a padding field - that way if in the future a new field is needed it can just use this padding field. Signed-off-by: Arjan van de Ven Signed-off-by: Linus Torvalds --- include/linux/ftrace_event.h | 1 + kernel/trace/trace.c | 1 + kernel/trace/trace_events.c | 1 + 3 files changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index 22b32af1b5ec..b5a550a39a70 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h @@ -37,6 +37,7 @@ struct trace_entry { unsigned char flags; unsigned char preempt_count; int pid; + int padding; }; #define FTRACE_MAX_EVENT \ diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index d38c16a06a6f..1cb49be7c7fb 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1110,6 +1110,7 @@ tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags, entry->preempt_count = pc & 0xff; entry->pid = (tsk) ? tsk->pid : 0; + entry->padding = 0; entry->flags = #ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT (irqs_disabled_flags(flags) ? TRACE_FLAG_IRQS_OFF : 0) | diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index e88f74fe1d4c..2fe110341359 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -116,6 +116,7 @@ static int trace_define_common_fields(void) __common_field(unsigned char, flags); __common_field(unsigned char, preempt_count); __common_field(int, pid); + __common_field(int, padding); return ret; } -- cgit From 880ffb5c6c5c8c8c6efd9efe9355317322b4603b Mon Sep 17 00:00:00 2001 From: Wanlong Gao Date: Thu, 5 May 2011 07:55:36 +0800 Subject: driver core: Add the device driver-model structures to kerneldoc Add the comments to the structure bus_type, device_driver, device, class to device.h for generating the driver-model kerneldoc. With another patch these all removed from the files in Documentation/driver-model/ since they are out of date. That will keep things up to date and provide a better way to document this stuff. Signed-off-by: Wanlong Gao Acked-by: Harry Wei Signed-off-by: Greg Kroah-Hartman --- Documentation/DocBook/device-drivers.tmpl | 6 +- include/linux/device.h | 154 +++++++++++++++++++++++++++++- 2 files changed, 154 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/Documentation/DocBook/device-drivers.tmpl b/Documentation/DocBook/device-drivers.tmpl index 36f63d4a0a06..b638e50cf8f6 100644 --- a/Documentation/DocBook/device-drivers.tmpl +++ b/Documentation/DocBook/device-drivers.tmpl @@ -96,10 +96,10 @@ X!Iinclude/linux/kobject.h Device drivers infrastructure + The Basic Device Driver-Model Structures +!Iinclude/linux/device.h + Device Drivers Base - !Edrivers/base/driver.c !Edrivers/base/core.c !Edrivers/base/class.c diff --git a/include/linux/device.h b/include/linux/device.h index 2215d013ca96..42365067a836 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -47,6 +47,38 @@ extern int __must_check bus_create_file(struct bus_type *, struct bus_attribute *); extern void bus_remove_file(struct bus_type *, struct bus_attribute *); +/** + * struct bus_type - The bus type of the device + * + * @name: The name of the bus. + * @bus_attrs: Default attributes of the bus. + * @dev_attrs: Default attributes of the devices on the bus. + * @drv_attrs: Default attributes of the device drivers on the bus. + * @match: Called, perhaps multiple times, whenever a new device or driver + * is added for this bus. It should return a nonzero value if the + * given device can be handled by the given driver. + * @uevent: Called when a device is added, removed, or a few other things + * that generate uevents to add the environment variables. + * @probe: Called when a new device or driver add to this bus, and callback + * the specific driver's probe to initial the matched device. + * @remove: Called when a device removed from this bus. + * @shutdown: Called at shut-down time to quiesce the device. + * @suspend: Called when a device on this bus wants to go to sleep mode. + * @resume: Called to bring a device on this bus out of sleep mode. + * @pm: Power management operations of this bus, callback the specific + * device driver's pm-ops. + * @p: The private data of the driver core, only the driver core can + * touch this. + * + * A bus is a channel between the processor and one or more devices. For the + * purposes of the device model, all devices are connected via a bus, even if + * it is an internal, virtual, "platform" bus. Buses can plug into each other. + * A USB controller is usually a PCI device, for example. The device model + * represents the actual connections between buses and the devices they control. + * A bus is represented by the bus_type structure. It contains the name, the + * default attributes, the bus' methods, PM operations, and the driver core's + * private data. + */ struct bus_type { const char *name; struct bus_attribute *bus_attrs; @@ -119,6 +151,37 @@ extern int bus_unregister_notifier(struct bus_type *bus, extern struct kset *bus_get_kset(struct bus_type *bus); extern struct klist *bus_get_device_klist(struct bus_type *bus); +/** + * struct device_driver - The basic device driver structure + * @name: Name of the device driver. + * @bus: The bus which the device of this driver belongs to. + * @owner: The module owner. + * @mod_name: Used for built-in modules. + * @suppress_bind_attrs: Disables bind/unbind via sysfs. + * @of_match_table: The open firmware table. + * @probe: Called to query the existence of a specific device, + * whether this driver can work with it, and bind the driver + * to a specific device. + * @remove: Called when the device is removed from the system to + * unbind a device from this driver. + * @shutdown: Called at shut-down time to quiesce the device. + * @suspend: Called to put the device to sleep mode. Usually to a + * low power state. + * @resume: Called to bring a device from sleep mode. + * @groups: Default attributes that get created by the driver core + * automatically. + * @pm: Power management operations of the device which matched + * this driver. + * @p: Driver core's private data, no one other than the driver + * core can touch this. + * + * The device driver-model tracks all of the drivers known to the system. + * The main reason for this tracking is to enable the driver core to match + * up drivers with new devices. Once drivers are known objects within the + * system, however, a number of other things become possible. Device drivers + * can export information and configuration variables that are independent + * of any specific device. + */ struct device_driver { const char *name; struct bus_type *bus; @@ -185,8 +248,34 @@ struct device *driver_find_device(struct device_driver *drv, struct device *start, void *data, int (*match)(struct device *dev, void *data)); -/* - * device classes +/** + * struct class - device classes + * @name: Name of the class. + * @owner: The module owner. + * @class_attrs: Default attributes of this class. + * @dev_attrs: Default attributes of the devices belong to the class. + * @dev_bin_attrs: Default binary attributes of the devices belong to the class. + * @dev_kobj: The kobject that represents this class and links it into the hierarchy. + * @dev_uevent: Called when a device is added, removed from this class, or a + * few other things that generate uevents to add the environment + * variables. + * @devnode: Callback to provide the devtmpfs. + * @class_release: Called to release this class. + * @dev_release: Called to release the device. + * @suspend: Used to put the device to sleep mode, usually to a low power + * state. + * @resume: Used to bring the device from the sleep mode. + * @ns_type: Callbacks so sysfs can detemine namespaces. + * @namespace: Namespace of the device belongs to this class. + * @pm: The default device power management operations of this class. + * @p: The private data of the driver core, no one other than the + * driver core can touch this. + * + * A class is a higher-level view of a device that abstracts out low-level + * implementation details. Drivers may see a SCSI disk or an ATA disk, but, + * at the class level, they are all simply disks. Classes allow user space + * to work with devices based on what they do, rather than how they are + * connected or how they work. */ struct class { const char *name; @@ -401,6 +490,65 @@ struct device_dma_parameters { unsigned long segment_boundary_mask; }; +/** + * struct device - The basic device structure + * @parent: The device's "parent" device, the device to which it is attached. + * In most cases, a parent device is some sort of bus or host + * controller. If parent is NULL, the device, is a top-level device, + * which is not usually what you want. + * @p: Holds the private data of the driver core portions of the device. + * See the comment of the struct device_private for detail. + * @kobj: A top-level, abstract class from which other classes are derived. + * @init_name: Initial name of the device. + * @type: The type of device. + * This identifies the device type and carries type-specific + * information. + * @mutex: Mutex to synchronize calls to its driver. + * @bus: Type of bus device is on. + * @driver: Which driver has allocated this + * @platform_data: Platform data specific to the device. + * Example: For devices on custom boards, as typical of embedded + * and SOC based hardware, Linux often uses platform_data to point + * to board-specific structures describing devices and how they + * are wired. That can include what ports are available, chip + * variants, which GPIO pins act in what additional roles, and so + * on. This shrinks the "Board Support Packages" (BSPs) and + * minimizes board-specific #ifdefs in drivers. + * @power: For device power management. + * See Documentation/power/devices.txt for details. + * @pwr_domain: Provide callbacks that are executed during system suspend, + * hibernation, system resume and during runtime PM transitions + * along with subsystem-level and driver-level callbacks. + * @numa_node: NUMA node this device is close to. + * @dma_mask: Dma mask (if dma'ble device). + * @coherent_dma_mask: Like dma_mask, but for alloc_coherent mapping as not all + * hardware supports 64-bit addresses for consistent allocations + * such descriptors. + * @dma_parms: A low level driver may set these to teach IOMMU code about + * segment limitations. + * @dma_pools: Dma pools (if dma'ble device). + * @dma_mem: Internal for coherent mem override. + * @archdata: For arch-specific additions. + * @of_node: Associated device tree node. + * @of_match: Matching of_device_id from driver. + * @devt: For creating the sysfs "dev". + * @devres_lock: Spinlock to protect the resource of the device. + * @devres_head: The resources list of the device. + * @knode_class: The node used to add the device to the class list. + * @class: The class of the device. + * @groups: Optional attribute groups. + * @release: Callback to free the device after all references have + * gone away. This should be set by the allocator of the + * device (i.e. the bus driver that discovered the device). + * + * At the lowest level, every device in a Linux system is represented by an + * instance of struct device. The device structure contains the information + * that the device model core needs to model the system. Most subsystems, + * however, track additional information about the devices they host. As a + * result, it is rare for devices to be represented by bare device structures; + * instead, that structure, like kobject structures, is usually embedded within + * a higher-level representation of the device. + */ struct device { struct device *parent; @@ -611,7 +759,7 @@ extern int (*platform_notify)(struct device *dev); extern int (*platform_notify_remove)(struct device *dev); -/** +/* * get_device - atomically increment the reference count for the device. * */ -- cgit From 3df004532582d0cc721da0df28311bcedd639724 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Thu, 5 May 2011 12:11:21 +0200 Subject: usb: fix building musb drivers Commit 3dacdf11 "usb: factor out state_string() on otg drivers" broke building musb drivers since there is already another otg_state_string() function in musb drivers, but with different prototype. Fix musb drivers to use common otg_state_string(), too. Also provide a nop for otg_state_string() if CONFIG_USB_OTG_UTILS is not defined. Signed-off-by: Anatolij Gustschin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/am35x.c | 11 ++++--- drivers/usb/musb/blackfin.c | 7 +++-- drivers/usb/musb/da8xx.c | 11 ++++--- drivers/usb/musb/davinci.c | 5 ++-- drivers/usb/musb/musb_core.c | 65 ++++++++++++++++------------------------- drivers/usb/musb/musb_debug.h | 2 -- drivers/usb/musb/musb_gadget.c | 9 +++--- drivers/usb/musb/musb_host.c | 2 +- drivers/usb/musb/musb_virthub.c | 5 ++-- drivers/usb/musb/omap2430.c | 7 +++-- drivers/usb/musb/tusb6010.c | 16 +++++----- include/linux/usb/otg.h | 7 ++++- 12 files changed, 74 insertions(+), 73 deletions(-) (limited to 'include/linux') diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c index d5a3da37c90c..9e6209f87d3b 100644 --- a/drivers/usb/musb/am35x.c +++ b/drivers/usb/musb/am35x.c @@ -151,7 +151,8 @@ static void otg_timer(unsigned long _musb) * status change events (from the transceiver) otherwise. */ devctl = musb_readb(mregs, MUSB_DEVCTL); - DBG(7, "Poll devctl %02x (%s)\n", devctl, otg_state_string(musb)); + DBG(7, "Poll devctl %02x (%s)\n", devctl, + otg_state_string(musb->xceiv->state)); spin_lock_irqsave(&musb->lock, flags); switch (musb->xceiv->state) { @@ -202,7 +203,8 @@ static void am35x_musb_try_idle(struct musb *musb, unsigned long timeout) /* Never idle if active, or when VBUS timeout is not set as host */ if (musb->is_active || (musb->a_wait_bcon == 0 && musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) { - DBG(4, "%s active, deleting timer\n", otg_state_string(musb)); + DBG(4, "%s active, deleting timer\n", + otg_state_string(musb->xceiv->state)); del_timer(&otg_workaround); last_timer = jiffies; return; @@ -215,7 +217,8 @@ static void am35x_musb_try_idle(struct musb *musb, unsigned long timeout) last_timer = timeout; DBG(4, "%s inactive, starting idle timer for %u ms\n", - otg_state_string(musb), jiffies_to_msecs(timeout - jiffies)); + otg_state_string(musb->xceiv->state), + jiffies_to_msecs(timeout - jiffies)); mod_timer(&otg_workaround, timeout); } @@ -304,7 +307,7 @@ static irqreturn_t am35x_musb_interrupt(int irq, void *hci) /* NOTE: this must complete power-on within 100 ms. */ DBG(2, "VBUS %s (%s)%s, devctl %02x\n", drvvbus ? "on" : "off", - otg_state_string(musb), + otg_state_string(musb->xceiv->state), err ? " ERROR" : "", devctl); ret = IRQ_HANDLED; diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index 8e2a1ff8a35a..e141d89656e1 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c @@ -279,12 +279,13 @@ static void musb_conn_timer_handler(unsigned long _musb) } break; default: - DBG(1, "%s state not handled\n", otg_state_string(musb)); + DBG(1, "%s state not handled\n", + otg_state_string(musb->xceiv->state)); break; } spin_unlock_irqrestore(&musb->lock, flags); - DBG(4, "state is %s\n", otg_state_string(musb)); + DBG(4, "state is %s\n", otg_state_string(musb->xceiv->state)); } static void bfin_musb_enable(struct musb *musb) @@ -308,7 +309,7 @@ static void bfin_musb_set_vbus(struct musb *musb, int is_on) DBG(1, "VBUS %s, devctl %02x " /* otg %3x conf %08x prcm %08x */ "\n", - otg_state_string(musb), + otg_state_string(musb->xceiv->state), musb_readb(musb->mregs, MUSB_DEVCTL)); } diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index 69a0da3c8f09..0d8984993a38 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c @@ -199,7 +199,8 @@ static void otg_timer(unsigned long _musb) * status change events (from the transceiver) otherwise. */ devctl = musb_readb(mregs, MUSB_DEVCTL); - DBG(7, "Poll devctl %02x (%s)\n", devctl, otg_state_string(musb)); + DBG(7, "Poll devctl %02x (%s)\n", devctl, + otg_state_string(musb->xceiv->state)); spin_lock_irqsave(&musb->lock, flags); switch (musb->xceiv->state) { @@ -273,7 +274,8 @@ static void da8xx_musb_try_idle(struct musb *musb, unsigned long timeout) /* Never idle if active, or when VBUS timeout is not set as host */ if (musb->is_active || (musb->a_wait_bcon == 0 && musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) { - DBG(4, "%s active, deleting timer\n", otg_state_string(musb)); + DBG(4, "%s active, deleting timer\n", + otg_state_string(musb->xceiv->state)); del_timer(&otg_workaround); last_timer = jiffies; return; @@ -286,7 +288,8 @@ static void da8xx_musb_try_idle(struct musb *musb, unsigned long timeout) last_timer = timeout; DBG(4, "%s inactive, starting idle timer for %u ms\n", - otg_state_string(musb), jiffies_to_msecs(timeout - jiffies)); + otg_state_string(musb->xceiv->state), + jiffies_to_msecs(timeout - jiffies)); mod_timer(&otg_workaround, timeout); } @@ -365,7 +368,7 @@ static irqreturn_t da8xx_musb_interrupt(int irq, void *hci) DBG(2, "VBUS %s (%s)%s, devctl %02x\n", drvvbus ? "on" : "off", - otg_state_string(musb), + otg_state_string(musb->xceiv->state), err ? " ERROR" : "", devctl); ret = IRQ_HANDLED; diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index e6de097fb7e8..3661b81a9571 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c @@ -220,7 +220,8 @@ static void otg_timer(unsigned long _musb) * status change events (from the transceiver) otherwise. */ devctl = musb_readb(mregs, MUSB_DEVCTL); - DBG(7, "poll devctl %02x (%s)\n", devctl, otg_state_string(musb)); + DBG(7, "poll devctl %02x (%s)\n", devctl, + otg_state_string(musb->xceiv->state)); spin_lock_irqsave(&musb->lock, flags); switch (musb->xceiv->state) { @@ -356,7 +357,7 @@ static irqreturn_t davinci_musb_interrupt(int irq, void *__hci) davinci_musb_source_power(musb, drvvbus, 0); DBG(2, "VBUS %s (%s)%s, devctl %02x\n", drvvbus ? "on" : "off", - otg_state_string(musb), + otg_state_string(musb->xceiv->state), err ? " ERROR" : "", devctl); retval = IRQ_HANDLED; diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index f10ff00ca09e..9a280872c2b4 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -333,26 +333,6 @@ void musb_load_testpacket(struct musb *musb) /*-------------------------------------------------------------------------*/ -const char *otg_state_string(struct musb *musb) -{ - switch (musb->xceiv->state) { - case OTG_STATE_A_IDLE: return "a_idle"; - case OTG_STATE_A_WAIT_VRISE: return "a_wait_vrise"; - case OTG_STATE_A_WAIT_BCON: return "a_wait_bcon"; - case OTG_STATE_A_HOST: return "a_host"; - case OTG_STATE_A_SUSPEND: return "a_suspend"; - case OTG_STATE_A_PERIPHERAL: return "a_peripheral"; - case OTG_STATE_A_WAIT_VFALL: return "a_wait_vfall"; - case OTG_STATE_A_VBUS_ERR: return "a_vbus_err"; - case OTG_STATE_B_IDLE: return "b_idle"; - case OTG_STATE_B_SRP_INIT: return "b_srp_init"; - case OTG_STATE_B_PERIPHERAL: return "b_peripheral"; - case OTG_STATE_B_WAIT_ACON: return "b_wait_acon"; - case OTG_STATE_B_HOST: return "b_host"; - default: return "UNDEFINED"; - } -} - #ifdef CONFIG_USB_MUSB_OTG /* @@ -373,12 +353,14 @@ void musb_otg_timer_func(unsigned long data) break; case OTG_STATE_A_SUSPEND: case OTG_STATE_A_WAIT_BCON: - DBG(1, "HNP: %s timeout\n", otg_state_string(musb)); + DBG(1, "HNP: %s timeout\n", + otg_state_string(musb->xceiv->state)); musb_platform_set_vbus(musb, 0); musb->xceiv->state = OTG_STATE_A_WAIT_VFALL; break; default: - DBG(1, "HNP: Unhandled mode %s\n", otg_state_string(musb)); + DBG(1, "HNP: Unhandled mode %s\n", + otg_state_string(musb->xceiv->state)); } musb->ignore_disconnect = 0; spin_unlock_irqrestore(&musb->lock, flags); @@ -393,12 +375,13 @@ void musb_hnp_stop(struct musb *musb) void __iomem *mbase = musb->mregs; u8 reg; - DBG(1, "HNP: stop from %s\n", otg_state_string(musb)); + DBG(1, "HNP: stop from %s\n", otg_state_string(musb->xceiv->state)); switch (musb->xceiv->state) { case OTG_STATE_A_PERIPHERAL: musb_g_disconnect(musb); - DBG(1, "HNP: back to %s\n", otg_state_string(musb)); + DBG(1, "HNP: back to %s\n", + otg_state_string(musb->xceiv->state)); break; case OTG_STATE_B_HOST: DBG(1, "HNP: Disabling HR\n"); @@ -412,7 +395,7 @@ void musb_hnp_stop(struct musb *musb) break; default: DBG(1, "HNP: Stopping in unknown state %s\n", - otg_state_string(musb)); + otg_state_string(musb->xceiv->state)); } /* @@ -451,7 +434,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, */ if (int_usb & MUSB_INTR_RESUME) { handled = IRQ_HANDLED; - DBG(3, "RESUME (%s)\n", otg_state_string(musb)); + DBG(3, "RESUME (%s)\n", otg_state_string(musb->xceiv->state)); if (devctl & MUSB_DEVCTL_HM) { #ifdef CONFIG_USB_MUSB_HDRC_HCD @@ -492,7 +475,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, default: WARNING("bogus %s RESUME (%s)\n", "host", - otg_state_string(musb)); + otg_state_string(musb->xceiv->state)); } #endif } else { @@ -526,7 +509,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, default: WARNING("bogus %s RESUME (%s)\n", "peripheral", - otg_state_string(musb)); + otg_state_string(musb->xceiv->state)); } } } @@ -542,7 +525,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, return IRQ_HANDLED; } - DBG(1, "SESSION_REQUEST (%s)\n", otg_state_string(musb)); + DBG(1, "SESSION_REQUEST (%s)\n", + otg_state_string(musb->xceiv->state)); /* IRQ arrives from ID pin sense or (later, if VBUS power * is removed) SRP. responses are time critical: @@ -607,7 +591,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, } DBG(1, "VBUS_ERROR in %s (%02x, %s), retry #%d, port1 %08x\n", - otg_state_string(musb), + otg_state_string(musb->xceiv->state), devctl, ({ char *s; switch (devctl & MUSB_DEVCTL_VBUS) { @@ -633,7 +617,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, #endif if (int_usb & MUSB_INTR_SUSPEND) { DBG(1, "SUSPEND (%s) devctl %02x power %02x\n", - otg_state_string(musb), devctl, power); + otg_state_string(musb->xceiv->state), devctl, power); handled = IRQ_HANDLED; switch (musb->xceiv->state) { @@ -758,13 +742,13 @@ b_host: usb_hcd_resume_root_hub(hcd); DBG(1, "CONNECT (%s) devctl %02x\n", - otg_state_string(musb), devctl); + otg_state_string(musb->xceiv->state), devctl); } #endif /* CONFIG_USB_MUSB_HDRC_HCD */ if ((int_usb & MUSB_INTR_DISCONNECT) && !musb->ignore_disconnect) { DBG(1, "DISCONNECT (%s) as %s, devctl %02x\n", - otg_state_string(musb), + otg_state_string(musb->xceiv->state), MUSB_MODE(musb), devctl); handled = IRQ_HANDLED; @@ -807,7 +791,7 @@ b_host: #endif /* GADGET */ default: WARNING("unhandled DISCONNECT transition (%s)\n", - otg_state_string(musb)); + otg_state_string(musb->xceiv->state)); break; } } @@ -832,7 +816,8 @@ b_host: musb_writeb(musb->mregs, MUSB_DEVCTL, 0); } } else if (is_peripheral_capable()) { - DBG(1, "BUS RESET as %s\n", otg_state_string(musb)); + DBG(1, "BUS RESET as %s\n", + otg_state_string(musb->xceiv->state)); switch (musb->xceiv->state) { #ifdef CONFIG_USB_OTG case OTG_STATE_A_SUSPEND: @@ -846,8 +831,8 @@ b_host: case OTG_STATE_A_WAIT_BCON: /* OPT TD.4.7-900ms */ /* never use invalid T(a_wait_bcon) */ DBG(1, "HNP: in %s, %d msec timeout\n", - otg_state_string(musb), - TA_WAIT_BCON(musb)); + otg_state_string(musb->xceiv->state), + TA_WAIT_BCON(musb)); mod_timer(&musb->otg_timer, jiffies + msecs_to_jiffies(TA_WAIT_BCON(musb))); break; @@ -858,7 +843,7 @@ b_host: break; case OTG_STATE_B_WAIT_ACON: DBG(1, "HNP: RESET (%s), to b_peripheral\n", - otg_state_string(musb)); + otg_state_string(musb->xceiv->state)); musb->xceiv->state = OTG_STATE_B_PERIPHERAL; musb_g_reset(musb); break; @@ -871,7 +856,7 @@ b_host: break; default: DBG(1, "Unhandled BUS RESET as %s\n", - otg_state_string(musb)); + otg_state_string(musb->xceiv->state)); } } } @@ -1713,7 +1698,7 @@ musb_mode_show(struct device *dev, struct device_attribute *attr, char *buf) int ret = -EINVAL; spin_lock_irqsave(&musb->lock, flags); - ret = sprintf(buf, "%s\n", otg_state_string(musb)); + ret = sprintf(buf, "%s\n", otg_state_string(musb->xceiv->state)); spin_unlock_irqrestore(&musb->lock, flags); return ret; diff --git a/drivers/usb/musb/musb_debug.h b/drivers/usb/musb/musb_debug.h index 94f6973cf8f7..f958a49a0124 100644 --- a/drivers/usb/musb/musb_debug.h +++ b/drivers/usb/musb/musb_debug.h @@ -54,8 +54,6 @@ static inline int _dbg_level(unsigned l) return musb_debug >= l; } -extern const char *otg_state_string(struct musb *); - #ifdef CONFIG_DEBUG_FS extern int musb_init_debugfs(struct musb *musb); extern void musb_exit_debugfs(struct musb *musb); diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 6dfbf9ffd7a6..3d799195c8b4 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1556,7 +1556,8 @@ static int musb_gadget_wakeup(struct usb_gadget *gadget) status = 0; goto done; default: - DBG(2, "Unhandled wake: %s\n", otg_state_string(musb)); + DBG(2, "Unhandled wake: %s\n", + otg_state_string(musb->xceiv->state)); goto done; } @@ -2039,7 +2040,7 @@ void musb_g_resume(struct musb *musb) break; default: WARNING("unhandled RESUME transition (%s)\n", - otg_state_string(musb)); + otg_state_string(musb->xceiv->state)); } } @@ -2069,7 +2070,7 @@ void musb_g_suspend(struct musb *musb) * A_PERIPHERAL may need care too */ WARNING("unhandled SUSPEND transition (%s)\n", - otg_state_string(musb)); + otg_state_string(musb->xceiv->state)); } } @@ -2104,7 +2105,7 @@ void musb_g_disconnect(struct musb *musb) default: #ifdef CONFIG_USB_MUSB_OTG DBG(2, "Unhandled disconnect %s, setting a_idle\n", - otg_state_string(musb)); + otg_state_string(musb->xceiv->state)); musb->xceiv->state = OTG_STATE_A_IDLE; MUSB_HST_MODE(musb); break; diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 5eef4a8847db..07b106c7de82 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -2304,7 +2304,7 @@ static int musb_bus_suspend(struct usb_hcd *hcd) if (musb->is_active) { WARNING("trying to suspend as %s while active\n", - otg_state_string(musb)); + otg_state_string(musb->xceiv->state)); return -EBUSY; } else return 0; diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c index 489104a5ae14..bb1247d5fd04 100644 --- a/drivers/usb/musb/musb_virthub.c +++ b/drivers/usb/musb/musb_virthub.c @@ -98,7 +98,7 @@ static void musb_port_suspend(struct musb *musb, bool do_suspend) #endif default: DBG(1, "bogus rh suspend? %s\n", - otg_state_string(musb)); + otg_state_string(musb->xceiv->state)); } } else if (power & MUSB_POWER_SUSPENDM) { power &= ~MUSB_POWER_SUSPENDM; @@ -208,7 +208,8 @@ void musb_root_disconnect(struct musb *musb) musb->xceiv->state = OTG_STATE_B_IDLE; break; default: - DBG(1, "host disconnect (%s)\n", otg_state_string(musb)); + DBG(1, "host disconnect (%s)\n", + otg_state_string(musb->xceiv->state)); } } diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 57a27fa954b4..d51b15adc0b0 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -114,7 +114,8 @@ static void omap2430_musb_try_idle(struct musb *musb, unsigned long timeout) /* Never idle if active, or when VBUS timeout is not set as host */ if (musb->is_active || ((musb->a_wait_bcon == 0) && (musb->xceiv->state == OTG_STATE_A_WAIT_BCON))) { - DBG(4, "%s active, deleting timer\n", otg_state_string(musb)); + DBG(4, "%s active, deleting timer\n", + otg_state_string(musb->xceiv->state)); del_timer(&musb_idle_timer); last_timer = jiffies; return; @@ -131,7 +132,7 @@ static void omap2430_musb_try_idle(struct musb *musb, unsigned long timeout) last_timer = timeout; DBG(4, "%s inactive, for idle timer for %lu ms\n", - otg_state_string(musb), + otg_state_string(musb->xceiv->state), (unsigned long)jiffies_to_msecs(timeout - jiffies)); mod_timer(&musb_idle_timer, timeout); } @@ -195,7 +196,7 @@ static void omap2430_musb_set_vbus(struct musb *musb, int is_on) DBG(1, "VBUS %s, devctl %02x " /* otg %3x conf %08x prcm %08x */ "\n", - otg_state_string(musb), + otg_state_string(musb->xceiv->state), musb_readb(musb->mregs, MUSB_DEVCTL)); } diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index c47aac4a1f98..221feaaded72 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -422,7 +422,7 @@ static void musb_do_idle(unsigned long _musb) && (musb->idle_timeout == 0 || time_after(jiffies, musb->idle_timeout))) { DBG(4, "Nothing connected %s, turning off VBUS\n", - otg_state_string(musb)); + otg_state_string(musb->xceiv->state)); } /* FALLTHROUGH */ case OTG_STATE_A_IDLE: @@ -481,7 +481,8 @@ static void tusb_musb_try_idle(struct musb *musb, unsigned long timeout) /* Never idle if active, or when VBUS timeout is not set as host */ if (musb->is_active || ((musb->a_wait_bcon == 0) && (musb->xceiv->state == OTG_STATE_A_WAIT_BCON))) { - DBG(4, "%s active, deleting timer\n", otg_state_string(musb)); + DBG(4, "%s active, deleting timer\n", + otg_state_string(musb->xceiv->state)); del_timer(&musb_idle_timer); last_timer = jiffies; return; @@ -498,7 +499,7 @@ static void tusb_musb_try_idle(struct musb *musb, unsigned long timeout) last_timer = timeout; DBG(4, "%s inactive, for idle timer for %lu ms\n", - otg_state_string(musb), + otg_state_string(musb->xceiv->state), (unsigned long)jiffies_to_msecs(timeout - jiffies)); mod_timer(&musb_idle_timer, timeout); } @@ -573,7 +574,7 @@ static void tusb_musb_set_vbus(struct musb *musb, int is_on) musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); DBG(1, "VBUS %s, devctl %02x otg %3x conf %08x prcm %08x\n", - otg_state_string(musb), + otg_state_string(musb->xceiv->state), musb_readb(musb->mregs, MUSB_DEVCTL), musb_readl(tbase, TUSB_DEV_OTG_STAT), conf, prcm); @@ -702,13 +703,13 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) musb->is_active = 0; } DBG(2, "vbus change, %s, otg %03x\n", - otg_state_string(musb), otg_stat); + otg_state_string(musb->xceiv->state), otg_stat); idle_timeout = jiffies + (1 * HZ); schedule_work(&musb->irq_work); } else /* A-dev state machine */ { DBG(2, "vbus change, %s, otg %03x\n", - otg_state_string(musb), otg_stat); + otg_state_string(musb->xceiv->state), otg_stat); switch (musb->xceiv->state) { case OTG_STATE_A_IDLE: @@ -756,7 +757,8 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) if (int_src & TUSB_INT_SRC_OTG_TIMEOUT) { u8 devctl; - DBG(4, "%s timer, %03x\n", otg_state_string(musb), otg_stat); + DBG(4, "%s timer, %03x\n", + otg_state_string(musb->xceiv->state), otg_stat); switch (musb->xceiv->state) { case OTG_STATE_A_WAIT_VRISE: diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h index bc84858b3a4d..d87f44f5b04e 100644 --- a/include/linux/usb/otg.h +++ b/include/linux/usb/otg.h @@ -168,6 +168,7 @@ otg_shutdown(struct otg_transceiver *otg) #ifdef CONFIG_USB_OTG_UTILS extern struct otg_transceiver *otg_get_transceiver(void); extern void otg_put_transceiver(struct otg_transceiver *); +extern const char *otg_state_string(enum usb_otg_state state); #else static inline struct otg_transceiver *otg_get_transceiver(void) { @@ -177,6 +178,11 @@ static inline struct otg_transceiver *otg_get_transceiver(void) static inline void otg_put_transceiver(struct otg_transceiver *x) { } + +static inline const char *otg_state_string(enum usb_otg_state state) +{ + return NULL; +} #endif /* Context: can sleep */ @@ -246,6 +252,5 @@ otg_unregister_notifier(struct otg_transceiver *otg, struct notifier_block *nb) /* for OTG controller drivers (and maybe other stuff) */ extern int usb_bus_start_enum(struct usb_bus *bus, unsigned port_num); -extern const char *otg_state_string(enum usb_otg_state state); #endif /* __LINUX_USB_OTG_H */ -- cgit From 0f73cac8e41723d600c91a0f5b481dc3202f4f82 Mon Sep 17 00:00:00 2001 From: Anji jonnala Date: Wed, 4 May 2011 10:19:46 +0530 Subject: USB: OTG: msm: vote for dayatona fabric clock HSUSB core clock is derived from daytona fabric clock and for HSUSB operational require minimum core clock at 55MHz. Since, HSUSB cannot tolerate daytona fabric clock change in the middle of HSUSB operational, vote for maximum Daytona fabric clock while usb is operational Signed-off-by: Anji jonnala Signed-off-by: Pavankumar Kondeti Signed-off-by: Greg Kroah-Hartman --- drivers/usb/otg/msm_otg.c | 36 +++++++++++++++++++++++++++++++++++- include/linux/usb/msm_hsusb.h | 7 +++++-- 2 files changed, 40 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c index f58b7dab75aa..7792fef0be5e 100644 --- a/drivers/usb/otg/msm_otg.c +++ b/drivers/usb/otg/msm_otg.c @@ -324,6 +324,9 @@ static int msm_otg_suspend(struct msm_otg *motg) if (motg->core_clk) clk_disable(motg->core_clk); + if (!IS_ERR(motg->pclk_src)) + clk_disable(motg->pclk_src); + if (device_may_wakeup(otg->dev)) enable_irq_wake(motg->irq); if (bus) @@ -347,6 +350,9 @@ static int msm_otg_resume(struct msm_otg *motg) if (!atomic_read(&motg->in_lpm)) return 0; + if (!IS_ERR(motg->pclk_src)) + clk_enable(motg->pclk_src); + clk_enable(motg->pclk); clk_enable(motg->clk); if (motg->core_clk) @@ -862,12 +868,31 @@ static int __init msm_otg_probe(struct platform_device *pdev) ret = PTR_ERR(motg->clk); goto put_phy_reset_clk; } + clk_set_rate(motg->clk, 60000000); + + /* + * If USB Core is running its protocol engine based on CORE CLK, + * CORE CLK must be running at >55Mhz for correct HSUSB + * operation and USB core cannot tolerate frequency changes on + * CORE CLK. For such USB cores, vote for maximum clk frequency + * on pclk source + */ + if (motg->pdata->pclk_src_name) { + motg->pclk_src = clk_get(&pdev->dev, + motg->pdata->pclk_src_name); + if (IS_ERR(motg->pclk_src)) + goto put_clk; + clk_set_rate(motg->pclk_src, INT_MAX); + clk_enable(motg->pclk_src); + } else + motg->pclk_src = ERR_PTR(-ENOENT); + motg->pclk = clk_get(&pdev->dev, "usb_hs_pclk"); if (IS_ERR(motg->pclk)) { dev_err(&pdev->dev, "failed to get usb_hs_pclk\n"); ret = PTR_ERR(motg->pclk); - goto put_clk; + goto put_pclk_src; } /* @@ -955,6 +980,11 @@ put_core_clk: if (motg->core_clk) clk_put(motg->core_clk); clk_put(motg->pclk); +put_pclk_src: + if (!IS_ERR(motg->pclk_src)) { + clk_disable(motg->pclk_src); + clk_put(motg->pclk_src); + } put_clk: clk_put(motg->clk); put_phy_reset_clk: @@ -1004,6 +1034,10 @@ static int __devexit msm_otg_remove(struct platform_device *pdev) clk_disable(motg->clk); if (motg->core_clk) clk_disable(motg->core_clk); + if (!IS_ERR(motg->pclk_src)) { + clk_disable(motg->pclk_src); + clk_put(motg->pclk_src); + } iounmap(motg->regs); pm_runtime_set_suspended(&pdev->dev); diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h index 3657403eac18..31ef1853f93c 100644 --- a/include/linux/usb/msm_hsusb.h +++ b/include/linux/usb/msm_hsusb.h @@ -64,7 +64,8 @@ enum otg_control_type { * @otg_control: OTG switch controlled by user/Id pin * @default_mode: Default operational mode. Applicable only if * OTG switch is controller by user. - * + * @pclk_src_name: pclk is derived from ebi1_usb_clk in case of 7x27 and 8k + * dfab_usb_hs_clk in case of 8660 and 8960. */ struct msm_otg_platform_data { int *phy_init_seq; @@ -74,6 +75,7 @@ struct msm_otg_platform_data { enum otg_control_type otg_control; enum usb_mode_type default_mode; void (*setup_gpio)(enum usb_otg_state state); + char *pclk_src_name; }; /** @@ -83,6 +85,7 @@ struct msm_otg_platform_data { * @irq: IRQ number assigned for HSUSB controller. * @clk: clock struct of usb_hs_clk. * @pclk: clock struct of usb_hs_pclk. + * @pclk_src: pclk source for voting. * @phy_reset_clk: clock struct of usb_phy_clk. * @core_clk: clock struct of usb_hs_core_clk. * @regs: ioremapped register base address. @@ -90,7 +93,6 @@ struct msm_otg_platform_data { * @sm_work: OTG state machine work. * @in_lpm: indicates low power mode (LPM) state. * @async_int: Async interrupt arrived. - * */ struct msm_otg { struct otg_transceiver otg; @@ -98,6 +100,7 @@ struct msm_otg { int irq; struct clk *clk; struct clk *pclk; + struct clk *pclk_src; struct clk *phy_reset_clk; struct clk *core_clk; void __iomem *regs; -- cgit From d860852e087eed7eadbea64f1a8db9a231c5e9b3 Mon Sep 17 00:00:00 2001 From: Pavankumar Kondeti Date: Wed, 4 May 2011 10:19:47 +0530 Subject: USB: OTG: msm: Implement charger detection Implement good battery algorithm defined in the battery charging V1.2 spec for detecting different charging ports. USB hardware is put into low power mode when connected to a dedicated charging port. vbus_draw and set_power methods are implemented for determining the allowed current from Host in different states (un-configured/suspend/configured). The charger block is implemented using vendor specific registers and the PHY used in MSM8960(28nm PHY) different from older targets like MSM8x60 and MSM7x30(45nm PHY). The PHY vendor and product id registers are not implemented in the above chipsets. Hence PHY type is passed via platform data. Signed-off-by: Pavankumar Kondeti Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/ci13xxx_udc.c | 10 ++ drivers/usb/otg/msm_otg.c | 380 ++++++++++++++++++++++++++++++++++++++- include/linux/usb/msm_hsusb.h | 72 +++++++- 3 files changed, 457 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c index 68123ee01392..baaf87ed7685 100644 --- a/drivers/usb/gadget/ci13xxx_udc.c +++ b/drivers/usb/gadget/ci13xxx_udc.c @@ -2506,6 +2506,15 @@ out: return ret; } +static int ci13xxx_vbus_draw(struct usb_gadget *_gadget, unsigned mA) +{ + struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget); + + if (udc->transceiver) + return otg_set_power(udc->transceiver, mA); + return -ENOTSUPP; +} + /** * Device operations part of the API to the USB controller hardware, * which don't involve endpoints (or i/o) @@ -2514,6 +2523,7 @@ out: static const struct usb_gadget_ops usb_gadget_ops = { .vbus_session = ci13xxx_vbus_session, .wakeup = ci13xxx_wakeup, + .vbus_draw = ci13xxx_vbus_draw, }; /** diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c index 7792fef0be5e..854b7e3413dd 100644 --- a/drivers/usb/otg/msm_otg.c +++ b/drivers/usb/otg/msm_otg.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved. +/* Copyright (c) 2009-2011, Code Aurora Forum. 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 @@ -409,6 +409,33 @@ skip_phy_resume: } #endif +static void msm_otg_notify_charger(struct msm_otg *motg, unsigned mA) +{ + if (motg->cur_power == mA) + return; + + /* TODO: Notify PMIC about available current */ + dev_info(motg->otg.dev, "Avail curr from USB = %u\n", mA); + motg->cur_power = mA; +} + +static int msm_otg_set_power(struct otg_transceiver *otg, unsigned mA) +{ + struct msm_otg *motg = container_of(otg, struct msm_otg, otg); + + /* + * Gadget driver uses set_power method to notify about the + * available current based on suspend/configured states. + * + * IDEV_CHG can be drawn irrespective of suspend/un-configured + * states when CDP/ACA is connected. + */ + if (motg->chg_type == USB_SDP_CHARGER) + msm_otg_notify_charger(motg, mA); + + return 0; +} + static void msm_otg_start_host(struct otg_transceiver *otg, int on) { struct msm_otg *motg = container_of(otg, struct msm_otg, otg); @@ -563,6 +590,306 @@ static int msm_otg_set_peripheral(struct otg_transceiver *otg, return 0; } +static bool msm_chg_check_secondary_det(struct msm_otg *motg) +{ + struct otg_transceiver *otg = &motg->otg; + u32 chg_det; + bool ret = false; + + switch (motg->pdata->phy_type) { + case CI_45NM_INTEGRATED_PHY: + chg_det = ulpi_read(otg, 0x34); + ret = chg_det & (1 << 4); + break; + case SNPS_28NM_INTEGRATED_PHY: + chg_det = ulpi_read(otg, 0x87); + ret = chg_det & 1; + break; + default: + break; + } + return ret; +} + +static void msm_chg_enable_secondary_det(struct msm_otg *motg) +{ + struct otg_transceiver *otg = &motg->otg; + u32 chg_det; + + switch (motg->pdata->phy_type) { + case CI_45NM_INTEGRATED_PHY: + chg_det = ulpi_read(otg, 0x34); + /* Turn off charger block */ + chg_det |= ~(1 << 1); + ulpi_write(otg, chg_det, 0x34); + udelay(20); + /* control chg block via ULPI */ + chg_det &= ~(1 << 3); + ulpi_write(otg, chg_det, 0x34); + /* put it in host mode for enabling D- source */ + chg_det &= ~(1 << 2); + ulpi_write(otg, chg_det, 0x34); + /* Turn on chg detect block */ + chg_det &= ~(1 << 1); + ulpi_write(otg, chg_det, 0x34); + udelay(20); + /* enable chg detection */ + chg_det &= ~(1 << 0); + ulpi_write(otg, chg_det, 0x34); + break; + case SNPS_28NM_INTEGRATED_PHY: + /* + * Configure DM as current source, DP as current sink + * and enable battery charging comparators. + */ + ulpi_write(otg, 0x8, 0x85); + ulpi_write(otg, 0x2, 0x85); + ulpi_write(otg, 0x1, 0x85); + break; + default: + break; + } +} + +static bool msm_chg_check_primary_det(struct msm_otg *motg) +{ + struct otg_transceiver *otg = &motg->otg; + u32 chg_det; + bool ret = false; + + switch (motg->pdata->phy_type) { + case CI_45NM_INTEGRATED_PHY: + chg_det = ulpi_read(otg, 0x34); + ret = chg_det & (1 << 4); + break; + case SNPS_28NM_INTEGRATED_PHY: + chg_det = ulpi_read(otg, 0x87); + ret = chg_det & 1; + break; + default: + break; + } + return ret; +} + +static void msm_chg_enable_primary_det(struct msm_otg *motg) +{ + struct otg_transceiver *otg = &motg->otg; + u32 chg_det; + + switch (motg->pdata->phy_type) { + case CI_45NM_INTEGRATED_PHY: + chg_det = ulpi_read(otg, 0x34); + /* enable chg detection */ + chg_det &= ~(1 << 0); + ulpi_write(otg, chg_det, 0x34); + break; + case SNPS_28NM_INTEGRATED_PHY: + /* + * Configure DP as current source, DM as current sink + * and enable battery charging comparators. + */ + ulpi_write(otg, 0x2, 0x85); + ulpi_write(otg, 0x1, 0x85); + break; + default: + break; + } +} + +static bool msm_chg_check_dcd(struct msm_otg *motg) +{ + struct otg_transceiver *otg = &motg->otg; + u32 line_state; + bool ret = false; + + switch (motg->pdata->phy_type) { + case CI_45NM_INTEGRATED_PHY: + line_state = ulpi_read(otg, 0x15); + ret = !(line_state & 1); + break; + case SNPS_28NM_INTEGRATED_PHY: + line_state = ulpi_read(otg, 0x87); + ret = line_state & 2; + break; + default: + break; + } + return ret; +} + +static void msm_chg_disable_dcd(struct msm_otg *motg) +{ + struct otg_transceiver *otg = &motg->otg; + u32 chg_det; + + switch (motg->pdata->phy_type) { + case CI_45NM_INTEGRATED_PHY: + chg_det = ulpi_read(otg, 0x34); + chg_det &= ~(1 << 5); + ulpi_write(otg, chg_det, 0x34); + break; + case SNPS_28NM_INTEGRATED_PHY: + ulpi_write(otg, 0x10, 0x86); + break; + default: + break; + } +} + +static void msm_chg_enable_dcd(struct msm_otg *motg) +{ + struct otg_transceiver *otg = &motg->otg; + u32 chg_det; + + switch (motg->pdata->phy_type) { + case CI_45NM_INTEGRATED_PHY: + chg_det = ulpi_read(otg, 0x34); + /* Turn on D+ current source */ + chg_det |= (1 << 5); + ulpi_write(otg, chg_det, 0x34); + break; + case SNPS_28NM_INTEGRATED_PHY: + /* Data contact detection enable */ + ulpi_write(otg, 0x10, 0x85); + break; + default: + break; + } +} + +static void msm_chg_block_on(struct msm_otg *motg) +{ + struct otg_transceiver *otg = &motg->otg; + u32 func_ctrl, chg_det; + + /* put the controller in non-driving mode */ + func_ctrl = ulpi_read(otg, ULPI_FUNC_CTRL); + func_ctrl &= ~ULPI_FUNC_CTRL_OPMODE_MASK; + func_ctrl |= ULPI_FUNC_CTRL_OPMODE_NONDRIVING; + ulpi_write(otg, func_ctrl, ULPI_FUNC_CTRL); + + switch (motg->pdata->phy_type) { + case CI_45NM_INTEGRATED_PHY: + chg_det = ulpi_read(otg, 0x34); + /* control chg block via ULPI */ + chg_det &= ~(1 << 3); + ulpi_write(otg, chg_det, 0x34); + /* Turn on chg detect block */ + chg_det &= ~(1 << 1); + ulpi_write(otg, chg_det, 0x34); + udelay(20); + break; + case SNPS_28NM_INTEGRATED_PHY: + /* Clear charger detecting control bits */ + ulpi_write(otg, 0x3F, 0x86); + /* Clear alt interrupt latch and enable bits */ + ulpi_write(otg, 0x1F, 0x92); + ulpi_write(otg, 0x1F, 0x95); + udelay(100); + break; + default: + break; + } +} + +static void msm_chg_block_off(struct msm_otg *motg) +{ + struct otg_transceiver *otg = &motg->otg; + u32 func_ctrl, chg_det; + + switch (motg->pdata->phy_type) { + case CI_45NM_INTEGRATED_PHY: + chg_det = ulpi_read(otg, 0x34); + /* Turn off charger block */ + chg_det |= ~(1 << 1); + ulpi_write(otg, chg_det, 0x34); + break; + case SNPS_28NM_INTEGRATED_PHY: + /* Clear charger detecting control bits */ + ulpi_write(otg, 0x3F, 0x86); + /* Clear alt interrupt latch and enable bits */ + ulpi_write(otg, 0x1F, 0x92); + ulpi_write(otg, 0x1F, 0x95); + break; + default: + break; + } + + /* put the controller in normal mode */ + func_ctrl = ulpi_read(otg, ULPI_FUNC_CTRL); + func_ctrl &= ~ULPI_FUNC_CTRL_OPMODE_MASK; + func_ctrl |= ULPI_FUNC_CTRL_OPMODE_NORMAL; + ulpi_write(otg, func_ctrl, ULPI_FUNC_CTRL); +} + +#define MSM_CHG_DCD_POLL_TIME (100 * HZ/1000) /* 100 msec */ +#define MSM_CHG_DCD_MAX_RETRIES 6 /* Tdcd_tmout = 6 * 100 msec */ +#define MSM_CHG_PRIMARY_DET_TIME (40 * HZ/1000) /* TVDPSRC_ON */ +#define MSM_CHG_SECONDARY_DET_TIME (40 * HZ/1000) /* TVDMSRC_ON */ +static void msm_chg_detect_work(struct work_struct *w) +{ + struct msm_otg *motg = container_of(w, struct msm_otg, chg_work.work); + struct otg_transceiver *otg = &motg->otg; + bool is_dcd, tmout, vout; + unsigned long delay; + + dev_dbg(otg->dev, "chg detection work\n"); + switch (motg->chg_state) { + case USB_CHG_STATE_UNDEFINED: + pm_runtime_get_sync(otg->dev); + msm_chg_block_on(motg); + msm_chg_enable_dcd(motg); + motg->chg_state = USB_CHG_STATE_WAIT_FOR_DCD; + motg->dcd_retries = 0; + delay = MSM_CHG_DCD_POLL_TIME; + break; + case USB_CHG_STATE_WAIT_FOR_DCD: + is_dcd = msm_chg_check_dcd(motg); + tmout = ++motg->dcd_retries == MSM_CHG_DCD_MAX_RETRIES; + if (is_dcd || tmout) { + msm_chg_disable_dcd(motg); + msm_chg_enable_primary_det(motg); + delay = MSM_CHG_PRIMARY_DET_TIME; + motg->chg_state = USB_CHG_STATE_DCD_DONE; + } else { + delay = MSM_CHG_DCD_POLL_TIME; + } + break; + case USB_CHG_STATE_DCD_DONE: + vout = msm_chg_check_primary_det(motg); + if (vout) { + msm_chg_enable_secondary_det(motg); + delay = MSM_CHG_SECONDARY_DET_TIME; + motg->chg_state = USB_CHG_STATE_PRIMARY_DONE; + } else { + motg->chg_type = USB_SDP_CHARGER; + motg->chg_state = USB_CHG_STATE_DETECTED; + delay = 0; + } + break; + case USB_CHG_STATE_PRIMARY_DONE: + vout = msm_chg_check_secondary_det(motg); + if (vout) + motg->chg_type = USB_DCP_CHARGER; + else + motg->chg_type = USB_CDP_CHARGER; + motg->chg_state = USB_CHG_STATE_SECONDARY_DONE; + /* fall through */ + case USB_CHG_STATE_SECONDARY_DONE: + motg->chg_state = USB_CHG_STATE_DETECTED; + case USB_CHG_STATE_DETECTED: + msm_chg_block_off(motg); + dev_dbg(otg->dev, "charger = %d\n", motg->chg_type); + schedule_work(&motg->sm_work); + return; + default: + return; + } + + schedule_delayed_work(&motg->chg_work, delay); +} + /* * We support OTG, Peripheral only and Host only configurations. In case * of OTG, mode switch (host-->peripheral/peripheral-->host) can happen @@ -633,9 +960,48 @@ static void msm_otg_sm_work(struct work_struct *w) writel(readl(USB_OTGSC) & ~OTGSC_BSVIE, USB_OTGSC); msm_otg_start_host(otg, 1); otg->state = OTG_STATE_A_HOST; - } else if (test_bit(B_SESS_VLD, &motg->inputs) && otg->gadget) { - msm_otg_start_peripheral(otg, 1); - otg->state = OTG_STATE_B_PERIPHERAL; + } else if (test_bit(B_SESS_VLD, &motg->inputs)) { + switch (motg->chg_state) { + case USB_CHG_STATE_UNDEFINED: + msm_chg_detect_work(&motg->chg_work.work); + break; + case USB_CHG_STATE_DETECTED: + switch (motg->chg_type) { + case USB_DCP_CHARGER: + msm_otg_notify_charger(motg, + IDEV_CHG_MAX); + break; + case USB_CDP_CHARGER: + msm_otg_notify_charger(motg, + IDEV_CHG_MAX); + msm_otg_start_peripheral(otg, 1); + otg->state = OTG_STATE_B_PERIPHERAL; + break; + case USB_SDP_CHARGER: + msm_otg_notify_charger(motg, IUNIT); + msm_otg_start_peripheral(otg, 1); + otg->state = OTG_STATE_B_PERIPHERAL; + break; + default: + break; + } + break; + default: + break; + } + } else { + /* + * If charger detection work is pending, decrement + * the pm usage counter to balance with the one that + * is incremented in charger detection work. + */ + if (cancel_delayed_work_sync(&motg->chg_work)) { + pm_runtime_put_sync(otg->dev); + msm_otg_reset(otg); + } + msm_otg_notify_charger(motg, 0); + motg->chg_state = USB_CHG_STATE_UNDEFINED; + motg->chg_type = USB_INVALID_CHARGER; } pm_runtime_put_sync(otg->dev); break; @@ -643,7 +1009,10 @@ static void msm_otg_sm_work(struct work_struct *w) dev_dbg(otg->dev, "OTG_STATE_B_PERIPHERAL state\n"); if (!test_bit(B_SESS_VLD, &motg->inputs) || !test_bit(ID, &motg->inputs)) { + msm_otg_notify_charger(motg, 0); msm_otg_start_peripheral(otg, 0); + motg->chg_state = USB_CHG_STATE_UNDEFINED; + motg->chg_type = USB_INVALID_CHARGER; otg->state = OTG_STATE_B_IDLE; msm_otg_reset(otg); schedule_work(w); @@ -935,6 +1304,7 @@ static int __init msm_otg_probe(struct platform_device *pdev) writel(0, USB_OTGSC); INIT_WORK(&motg->sm_work, msm_otg_sm_work); + INIT_DELAYED_WORK(&motg->chg_work, msm_chg_detect_work); ret = request_irq(motg->irq, msm_otg_irq, IRQF_SHARED, "msm_otg", motg); if (ret) { @@ -945,6 +1315,7 @@ static int __init msm_otg_probe(struct platform_device *pdev) otg->init = msm_otg_reset; otg->set_host = msm_otg_set_host; otg->set_peripheral = msm_otg_set_peripheral; + otg->set_power = msm_otg_set_power; otg->io_ops = &msm_otg_io_ops; @@ -1004,6 +1375,7 @@ static int __devexit msm_otg_remove(struct platform_device *pdev) return -EBUSY; msm_otg_debugfs_cleanup(); + cancel_delayed_work_sync(&motg->chg_work); cancel_work_sync(&motg->sm_work); pm_runtime_resume(&pdev->dev); diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h index 31ef1853f93c..00311fe9d0df 100644 --- a/include/linux/usb/msm_hsusb.h +++ b/include/linux/usb/msm_hsusb.h @@ -2,7 +2,7 @@ * * Copyright (C) 2008 Google, Inc. * Author: Brian Swetland - * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved. + * Copyright (c) 2009-2011, Code Aurora Forum. 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 @@ -53,6 +53,64 @@ enum otg_control_type { OTG_USER_CONTROL, }; +/** + * PHY used in + * + * INVALID_PHY Unsupported PHY + * CI_45NM_INTEGRATED_PHY Chipidea 45nm integrated PHY + * SNPS_28NM_INTEGRATED_PHY Synopsis 28nm integrated PHY + * + */ +enum msm_usb_phy_type { + INVALID_PHY = 0, + CI_45NM_INTEGRATED_PHY, + SNPS_28NM_INTEGRATED_PHY, +}; + +#define IDEV_CHG_MAX 1500 +#define IUNIT 100 + +/** + * Different states involved in USB charger detection. + * + * USB_CHG_STATE_UNDEFINED USB charger is not connected or detection + * process is not yet started. + * USB_CHG_STATE_WAIT_FOR_DCD Waiting for Data pins contact. + * USB_CHG_STATE_DCD_DONE Data pin contact is detected. + * USB_CHG_STATE_PRIMARY_DONE Primary detection is completed (Detects + * between SDP and DCP/CDP). + * USB_CHG_STATE_SECONDARY_DONE Secondary detection is completed (Detects + * between DCP and CDP). + * USB_CHG_STATE_DETECTED USB charger type is determined. + * + */ +enum usb_chg_state { + USB_CHG_STATE_UNDEFINED = 0, + USB_CHG_STATE_WAIT_FOR_DCD, + USB_CHG_STATE_DCD_DONE, + USB_CHG_STATE_PRIMARY_DONE, + USB_CHG_STATE_SECONDARY_DONE, + USB_CHG_STATE_DETECTED, +}; + +/** + * USB charger types + * + * USB_INVALID_CHARGER Invalid USB charger. + * USB_SDP_CHARGER Standard downstream port. Refers to a downstream port + * on USB2.0 compliant host/hub. + * USB_DCP_CHARGER Dedicated charger port (AC charger/ Wall charger). + * USB_CDP_CHARGER Charging downstream port. Enumeration can happen and + * IDEV_CHG_MAX can be drawn irrespective of USB state. + * + */ +enum usb_chg_type { + USB_INVALID_CHARGER = 0, + USB_SDP_CHARGER, + USB_DCP_CHARGER, + USB_CDP_CHARGER, +}; + /** * struct msm_otg_platform_data - platform device data * for msm_otg driver. @@ -74,6 +132,7 @@ struct msm_otg_platform_data { enum usb_mode_type mode; enum otg_control_type otg_control; enum usb_mode_type default_mode; + enum msm_usb_phy_type phy_type; void (*setup_gpio)(enum usb_otg_state state); char *pclk_src_name; }; @@ -93,6 +152,12 @@ struct msm_otg_platform_data { * @sm_work: OTG state machine work. * @in_lpm: indicates low power mode (LPM) state. * @async_int: Async interrupt arrived. + * @cur_power: The amount of mA available from downstream port. + * @chg_work: Charger detection work. + * @chg_state: The state of charger detection process. + * @chg_type: The type of charger attached. + * @dcd_retires: The retry count used to track Data contact + * detection process. */ struct msm_otg { struct otg_transceiver otg; @@ -110,6 +175,11 @@ struct msm_otg { struct work_struct sm_work; atomic_t in_lpm; int async_int; + unsigned cur_power; + struct delayed_work chg_work; + enum usb_chg_state chg_state; + enum usb_chg_type chg_type; + u8 dcd_retries; }; #endif -- cgit From 04aebcbb1b6dccadc8862b2765265f65a946db57 Mon Sep 17 00:00:00 2001 From: Pavankumar Kondeti Date: Wed, 4 May 2011 10:19:49 +0530 Subject: USB: OTG: msm: Add PHY suspend support for MSM8960 Signed-off-by: Pavankumar Kondeti Signed-off-by: Greg Kroah-Hartman --- drivers/usb/otg/msm_otg.c | 64 +++++++++++++++++++++++++++++++++------- include/linux/usb/msm_hsusb_hw.h | 2 ++ 2 files changed, 56 insertions(+), 10 deletions(-) (limited to 'include/linux') diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c index 628ba7d943da..1cdda6c05238 100644 --- a/drivers/usb/otg/msm_otg.c +++ b/drivers/usb/otg/msm_otg.c @@ -163,6 +163,32 @@ put_3p3: return rc; } +#ifdef CONFIG_PM_SLEEP +#define USB_PHY_SUSP_DIG_VOL 500000 +static int msm_hsusb_config_vddcx(int high) +{ + int max_vol = USB_PHY_VDD_DIG_VOL_MAX; + int min_vol; + int ret; + + if (high) + min_vol = USB_PHY_VDD_DIG_VOL_MIN; + else + min_vol = USB_PHY_SUSP_DIG_VOL; + + ret = regulator_set_voltage(hsusb_vddcx, min_vol, max_vol); + if (ret) { + pr_err("%s: unable to set the voltage for regulator " + "HSUSB_VDDCX\n", __func__); + return ret; + } + + pr_debug("%s: min_vol:%d max_vol:%d\n", __func__, min_vol, max_vol); + + return ret; +} +#endif + static int msm_hsusb_ldo_set_mode(int on) { int ret = 0; @@ -434,27 +460,28 @@ static int msm_otg_suspend(struct msm_otg *motg) disable_irq(motg->irq); /* + * Chipidea 45-nm PHY suspend sequence: + * * Interrupt Latch Register auto-clear feature is not present * in all PHY versions. Latch register is clear on read type. * Clear latch register to avoid spurious wakeup from * low power mode (LPM). - */ - ulpi_read(otg, 0x14); - - /* + * * PHY comparators are disabled when PHY enters into low power * mode (LPM). Keep PHY comparators ON in LPM only when we expect * VBUS/Id notifications from USB PHY. Otherwise turn off USB * PHY comparators. This save significant amount of power. - */ - if (pdata->otg_control == OTG_PHY_CONTROL) - ulpi_write(otg, 0x01, 0x30); - - /* + * * PLL is not turned off when PHY enters into low power mode (LPM). * Disable PLL for maximum power savings. */ - ulpi_write(otg, 0x08, 0x09); + + if (motg->pdata->phy_type == CI_45NM_INTEGRATED_PHY) { + ulpi_read(otg, 0x14); + if (pdata->otg_control == OTG_PHY_CONTROL) + ulpi_write(otg, 0x01, 0x30); + ulpi_write(otg, 0x08, 0x09); + } /* * PHY may take some time or even fail to enter into low power @@ -485,6 +512,10 @@ static int msm_otg_suspend(struct msm_otg *motg) */ writel(readl(USB_USBCMD) | ASYNC_INTR_CTRL | ULPI_STP_CTRL, USB_USBCMD); + if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY && + motg->pdata->otg_control == OTG_PMIC_CONTROL) + writel(readl(USB_PHY_CTRL) | PHY_RETEN, USB_PHY_CTRL); + clk_disable(motg->pclk); clk_disable(motg->clk); if (motg->core_clk) @@ -493,6 +524,12 @@ static int msm_otg_suspend(struct msm_otg *motg) if (!IS_ERR(motg->pclk_src)) clk_disable(motg->pclk_src); + if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY && + motg->pdata->otg_control == OTG_PMIC_CONTROL) { + msm_hsusb_ldo_set_mode(0); + msm_hsusb_config_vddcx(0); + } + if (device_may_wakeup(otg->dev)) enable_irq_wake(motg->irq); if (bus) @@ -524,6 +561,13 @@ static int msm_otg_resume(struct msm_otg *motg) if (motg->core_clk) clk_enable(motg->core_clk); + if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY && + motg->pdata->otg_control == OTG_PMIC_CONTROL) { + msm_hsusb_ldo_set_mode(1); + msm_hsusb_config_vddcx(1); + writel(readl(USB_PHY_CTRL) & ~PHY_RETEN, USB_PHY_CTRL); + } + temp = readl(USB_USBCMD); temp &= ~ASYNC_INTR_CTRL; temp &= ~ULPI_STP_CTRL; diff --git a/include/linux/usb/msm_hsusb_hw.h b/include/linux/usb/msm_hsusb_hw.h index 7d1babbff071..6e97a2d3d39f 100644 --- a/include/linux/usb/msm_hsusb_hw.h +++ b/include/linux/usb/msm_hsusb_hw.h @@ -24,6 +24,7 @@ #define USB_PORTSC (MSM_USB_BASE + 0x0184) #define USB_OTGSC (MSM_USB_BASE + 0x01A4) #define USB_USBMODE (MSM_USB_BASE + 0x01A8) +#define USB_PHY_CTRL (MSM_USB_BASE + 0x0240) #define USBCMD_RESET 2 #define USB_USBINTR (MSM_USB_BASE + 0x0148) @@ -42,6 +43,7 @@ #define ASYNC_INTR_CTRL (1 << 29) /* Enable async interrupt */ #define ULPI_STP_CTRL (1 << 30) /* Block communication with PHY */ +#define PHY_RETEN (1 << 1) /* PHY retention enable/disable */ /* OTG definitions */ #define OTGSC_INTSTS_MASK (0x7f << 16) -- cgit From 23ceb5b7719e9276d4fa72a3ecf94dd396755276 Mon Sep 17 00:00:00 2001 From: Tao Ma Date: Fri, 6 May 2011 19:30:02 -0600 Subject: block: Remove extra discard_alignment from hd_struct. Currently, hd_struct.discard_alignment is only used when we show /sys/block/sdx/sdx/discard_alignment. So remove it and calculate when it is asked to show. Signed-off-by: Tao Ma Signed-off-by: Jens Axboe --- fs/partitions/check.c | 9 ++++++--- include/linux/genhd.h | 1 - 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/fs/partitions/check.c b/fs/partitions/check.c index d545e97d99c3..b7e16bccd5e5 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c @@ -255,7 +255,12 @@ ssize_t part_discard_alignment_show(struct device *dev, struct device_attribute *attr, char *buf) { struct hd_struct *p = dev_to_part(dev); - return sprintf(buf, "%u\n", p->discard_alignment); + struct gendisk *disk = dev_to_disk(dev); + + return sprintf(buf, "%u\n", + (unsigned long long)queue_limit_discard_alignment( + &disk->queue->limits, + p->start_sect)); } ssize_t part_stat_show(struct device *dev, @@ -449,8 +454,6 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno, p->start_sect = start; p->alignment_offset = queue_limit_alignment_offset(&disk->queue->limits, start); - p->discard_alignment = - queue_limit_discard_alignment(&disk->queue->limits, start); p->nr_sects = len; p->partno = partno; p->policy = get_disk_ro(disk); diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 300d7582006e..b78956b3c2e7 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -100,7 +100,6 @@ struct hd_struct { sector_t start_sect; sector_t nr_sects; sector_t alignment_offset; - unsigned int discard_alignment; struct device __dev; struct kobject *holder_dir; int policy, partno; -- cgit From 1759415e630e5db0dd2390df9f94892cbfb9a8a2 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Thu, 5 May 2011 15:23:54 -0500 Subject: slub: Remove CONFIG_CMPXCHG_LOCAL ifdeffery Remove the #ifdefs. This means that the irqsafe_cpu_cmpxchg_double() is used everywhere. There may be performance implications since: A. We now have to manage a transaction ID for all arches B. The interrupt holdoff for arches not supporting CONFIG_CMPXCHG_LOCAL is reduced to a very short irqoff section. There are no multiple irqoff/irqon sequences as a result of this change. Even in the fallback case we only have to do one disable and enable like before. Signed-off-by: Christoph Lameter Signed-off-by: Pekka Enberg --- include/linux/slub_def.h | 2 -- mm/slub.c | 56 ------------------------------------------------ 2 files changed, 58 deletions(-) (limited to 'include/linux') diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h index 45ca123e8002..ca0c076b2374 100644 --- a/include/linux/slub_def.h +++ b/include/linux/slub_def.h @@ -37,9 +37,7 @@ enum stat_item { struct kmem_cache_cpu { void **freelist; /* Pointer to next available object */ -#ifdef CONFIG_CMPXCHG_LOCAL unsigned long tid; /* Globally unique transaction id */ -#endif struct page *page; /* The slab from which we are allocating */ int node; /* The node of the page (or -1 for debug) */ #ifdef CONFIG_SLUB_STATS diff --git a/mm/slub.c b/mm/slub.c index c952fac112e8..461199f019d6 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -1551,7 +1551,6 @@ static void unfreeze_slab(struct kmem_cache *s, struct page *page, int tail) } } -#ifdef CONFIG_CMPXCHG_LOCAL #ifdef CONFIG_PREEMPT /* * Calculate the next globally unique transaction for disambiguiation @@ -1611,17 +1610,12 @@ static inline void note_cmpxchg_failure(const char *n, stat(s, CMPXCHG_DOUBLE_CPU_FAIL); } -#endif - void init_kmem_cache_cpus(struct kmem_cache *s) { -#ifdef CONFIG_CMPXCHG_LOCAL int cpu; for_each_possible_cpu(cpu) per_cpu_ptr(s->cpu_slab, cpu)->tid = init_tid(cpu); -#endif - } /* * Remove the cpu slab @@ -1654,9 +1648,7 @@ static void deactivate_slab(struct kmem_cache *s, struct kmem_cache_cpu *c) page->inuse--; } c->page = NULL; -#ifdef CONFIG_CMPXCHG_LOCAL c->tid = next_tid(c->tid); -#endif unfreeze_slab(s, page, tail); } @@ -1791,7 +1783,6 @@ static void *__slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node, { void **object; struct page *page; -#ifdef CONFIG_CMPXCHG_LOCAL unsigned long flags; local_irq_save(flags); @@ -1802,7 +1793,6 @@ static void *__slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node, * pointer. */ c = this_cpu_ptr(s->cpu_slab); -#endif #endif /* We handle __GFP_ZERO in the caller */ @@ -1831,10 +1821,8 @@ load_freelist: unlock_out: slab_unlock(page); -#ifdef CONFIG_CMPXCHG_LOCAL c->tid = next_tid(c->tid); local_irq_restore(flags); -#endif stat(s, ALLOC_SLOWPATH); return object; @@ -1873,9 +1861,7 @@ load_from_page: } if (!(gfpflags & __GFP_NOWARN) && printk_ratelimit()) slab_out_of_memory(s, gfpflags, node); -#ifdef CONFIG_CMPXCHG_LOCAL local_irq_restore(flags); -#endif return NULL; debug: if (!alloc_debug_processing(s, page, object, addr)) @@ -1902,20 +1888,12 @@ static __always_inline void *slab_alloc(struct kmem_cache *s, { void **object; struct kmem_cache_cpu *c; -#ifdef CONFIG_CMPXCHG_LOCAL unsigned long tid; -#else - unsigned long flags; -#endif if (slab_pre_alloc_hook(s, gfpflags)) return NULL; -#ifndef CONFIG_CMPXCHG_LOCAL - local_irq_save(flags); -#else redo: -#endif /* * Must read kmem_cache cpu data via this cpu ptr. Preemption is @@ -1925,7 +1903,6 @@ redo: */ c = __this_cpu_ptr(s->cpu_slab); -#ifdef CONFIG_CMPXCHG_LOCAL /* * The transaction ids are globally unique per cpu and per operation on * a per cpu queue. Thus they can be guarantee that the cmpxchg_double @@ -1934,7 +1911,6 @@ redo: */ tid = c->tid; barrier(); -#endif object = c->freelist; if (unlikely(!object || !node_match(c, node))) @@ -1942,7 +1918,6 @@ redo: object = __slab_alloc(s, gfpflags, node, addr, c); else { -#ifdef CONFIG_CMPXCHG_LOCAL /* * The cmpxchg will only match if there was no additonal * operation and if we are on the right processor. @@ -1963,16 +1938,9 @@ redo: note_cmpxchg_failure("slab_alloc", s, tid); goto redo; } -#else - c->freelist = get_freepointer(s, object); -#endif stat(s, ALLOC_FASTPATH); } -#ifndef CONFIG_CMPXCHG_LOCAL - local_irq_restore(flags); -#endif - if (unlikely(gfpflags & __GFP_ZERO) && object) memset(object, 0, s->objsize); @@ -2049,11 +2017,9 @@ static void __slab_free(struct kmem_cache *s, struct page *page, { void *prior; void **object = (void *)x; -#ifdef CONFIG_CMPXCHG_LOCAL unsigned long flags; local_irq_save(flags); -#endif slab_lock(page); stat(s, FREE_SLOWPATH); @@ -2084,9 +2050,7 @@ static void __slab_free(struct kmem_cache *s, struct page *page, out_unlock: slab_unlock(page); -#ifdef CONFIG_CMPXCHG_LOCAL local_irq_restore(flags); -#endif return; slab_empty: @@ -2098,9 +2062,7 @@ slab_empty: stat(s, FREE_REMOVE_PARTIAL); } slab_unlock(page); -#ifdef CONFIG_CMPXCHG_LOCAL local_irq_restore(flags); -#endif stat(s, FREE_SLAB); discard_slab(s, page); } @@ -2121,20 +2083,11 @@ static __always_inline void slab_free(struct kmem_cache *s, { void **object = (void *)x; struct kmem_cache_cpu *c; -#ifdef CONFIG_CMPXCHG_LOCAL unsigned long tid; -#else - unsigned long flags; -#endif slab_free_hook(s, x); -#ifndef CONFIG_CMPXCHG_LOCAL - local_irq_save(flags); - -#else redo: -#endif /* * Determine the currently cpus per cpu slab. @@ -2144,15 +2097,12 @@ redo: */ c = __this_cpu_ptr(s->cpu_slab); -#ifdef CONFIG_CMPXCHG_LOCAL tid = c->tid; barrier(); -#endif if (likely(page == c->page && c->node != NUMA_NO_NODE)) { set_freepointer(s, object, c->freelist); -#ifdef CONFIG_CMPXCHG_LOCAL if (unlikely(!this_cpu_cmpxchg_double( s->cpu_slab->freelist, s->cpu_slab->tid, c->freelist, tid, @@ -2161,16 +2111,10 @@ redo: note_cmpxchg_failure("slab_free", s, tid); goto redo; } -#else - c->freelist = object; -#endif stat(s, FREE_FASTPATH); } else __slab_free(s, page, x, addr); -#ifndef CONFIG_CMPXCHG_LOCAL - local_irq_restore(flags); -#endif } void kmem_cache_free(struct kmem_cache *s, void *x) -- cgit From 1ab7b6ac2709d0eb05a7144cd0e14faa3a7ea162 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Thu, 14 Apr 2011 23:46:06 -0700 Subject: ethtool: remove phys_id from ethtool_ops After that all the upstream kernel drivers now use phys_id, and the old ethtool_ops interface (phys_id) can be removed. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- include/linux/ethtool.h | 7 ------- net/core/ethtool.c | 6 +----- 2 files changed, 1 insertion(+), 12 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 4194a2067a14..d659fdc77eb3 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -814,12 +814,6 @@ bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported); * the indicator accordingly. Finally, it is called with the argument * %ETHTOOL_ID_INACTIVE and must deactivate the indicator. Returns a * negative error code or zero. - * @phys_id: Deprecated in favour of @set_phys_id. - * Identify the physical device, e.g. by flashing an LED - * attached to it until interrupted by a signal or the given time - * (in seconds) elapses. If the given time is zero, use a default - * time limit. Returns a negative error code or zero. Being - * interrupted by a signal is not an error. * @get_ethtool_stats: Return extended statistics about the device. * This is only useful if the device maintains statistics not * included in &struct rtnl_link_stats64. @@ -908,7 +902,6 @@ struct ethtool_ops { void (*self_test)(struct net_device *, struct ethtool_test *, u64 *); void (*get_strings)(struct net_device *, u32 stringset, u8 *); int (*set_phys_id)(struct net_device *, enum ethtool_phys_id_state); - int (*phys_id)(struct net_device *, u32); void (*get_ethtool_stats)(struct net_device *, struct ethtool_stats *, u64 *); int (*begin)(struct net_device *); diff --git a/net/core/ethtool.c b/net/core/ethtool.c index d8b1a8d85a96..927819d92248 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -1655,7 +1655,7 @@ static int ethtool_phys_id(struct net_device *dev, void __user *useraddr) static bool busy; int rc; - if (!dev->ethtool_ops->set_phys_id && !dev->ethtool_ops->phys_id) + if (!dev->ethtool_ops->set_phys_id) return -EOPNOTSUPP; if (busy) @@ -1664,10 +1664,6 @@ static int ethtool_phys_id(struct net_device *dev, void __user *useraddr) if (copy_from_user(&id, useraddr, sizeof(id))) return -EFAULT; - if (!dev->ethtool_ops->set_phys_id) - /* Do it the old way */ - return dev->ethtool_ops->phys_id(dev, id.data); - rc = dev->ethtool_ops->set_phys_id(dev, ETHTOOL_ID_ACTIVE); if (rc < 0) return rc; -- cgit From 57cc71bc3c0cf18bfd1b7bc8cd0eb6c303da24c5 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Mon, 2 May 2011 21:30:08 +0000 Subject: ethtool: Add 20G bit definitions Add 20G supported and advertising bit definitions. 20G will be supported with the 57840 chips. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein ------ include/linux/ethtool.h | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) Signed-off-by: David S. Miller --- include/linux/ethtool.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index d659fdc77eb3..bd0b50b85f06 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -1025,6 +1025,8 @@ struct ethtool_ops { #define SUPPORTED_10000baseKX4_Full (1 << 18) #define SUPPORTED_10000baseKR_Full (1 << 19) #define SUPPORTED_10000baseR_FEC (1 << 20) +#define SUPPORTED_20000baseMLD2_Full (1 << 21) +#define SUPPORTED_20000baseKR2_Full (1 << 22) /* Indicates what features are advertised by the interface. */ #define ADVERTISED_10baseT_Half (1 << 0) @@ -1048,6 +1050,8 @@ struct ethtool_ops { #define ADVERTISED_10000baseKX4_Full (1 << 18) #define ADVERTISED_10000baseKR_Full (1 << 19) #define ADVERTISED_10000baseR_FEC (1 << 20) +#define ADVERTISED_20000baseMLD2_Full (1 << 21) +#define ADVERTISED_20000baseKR2_Full (1 << 22) /* The following are all involved in forcing a particular link * mode for the device for setting things. When getting the -- cgit From eed2a12f1ed9aabf0676f4d0db34aad51976c5c6 Mon Sep 17 00:00:00 2001 From: Mahesh Bandewar Date: Wed, 4 May 2011 15:30:11 +0000 Subject: net: Allow ethtool to set interface in loopback mode. This patch enables ethtool to set the loopback mode on a given interface. By configuring the interface in loopback mode in conjunction with a policy route / rule, a userland application can stress the egress / ingress path exposing the flows of the change in progress and potentially help developer(s) understand the impact of those changes without even sending a packet out on the network. Following set of commands illustrates one such example - a) ip -4 addr add 192.168.1.1/24 dev eth1 b) ip -4 rule add from all iif eth1 lookup 250 c) ip -4 route add local 0/0 dev lo proto kernel scope host table 250 d) arp -Ds 192.168.1.100 eth1 e) arp -Ds 192.168.1.200 eth1 f) sysctl -w net.ipv4.ip_nonlocal_bind=1 g) sysctl -w net.ipv4.conf.all.accept_local=1 # Assuming that the machine has 8 cores h) taskset 000f netserver -L 192.168.1.200 i) taskset 00f0 netperf -t TCP_CRR -L 192.168.1.100 -H 192.168.1.200 -l 30 Signed-off-by: Mahesh Bandewar Acked-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/loopback.c | 3 ++- include/linux/netdevice.h | 3 ++- net/core/ethtool.c | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index d70fb76edb77..4ce9e5f2c069 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -174,7 +174,8 @@ static void loopback_setup(struct net_device *dev) | NETIF_F_HIGHDMA | NETIF_F_LLTX | NETIF_F_NETNS_LOCAL - | NETIF_F_VLAN_CHALLENGED; + | NETIF_F_VLAN_CHALLENGED + | NETIF_F_LOOPBACK; dev->ethtool_ops = &loopback_ethtool_ops; dev->header_ops = ð_header_ops; dev->netdev_ops = &loopback_ops; diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index d5de66af46f9..e7244ed1f9a8 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1067,6 +1067,7 @@ struct net_device { #define NETIF_F_RXHASH (1 << 28) /* Receive hashing offload */ #define NETIF_F_RXCSUM (1 << 29) /* Receive checksumming offload */ #define NETIF_F_NOCACHE_COPY (1 << 30) /* Use no-cache copyfromuser */ +#define NETIF_F_LOOPBACK (1 << 31) /* Enable loopback */ /* Segmentation offload features */ #define NETIF_F_GSO_SHIFT 16 @@ -1082,7 +1083,7 @@ struct net_device { /* = all defined minus driver/device-class-related */ #define NETIF_F_NEVER_CHANGE (NETIF_F_VLAN_CHALLENGED | \ NETIF_F_LLTX | NETIF_F_NETNS_LOCAL) -#define NETIF_F_ETHTOOL_BITS (0x7f3fffff & ~NETIF_F_NEVER_CHANGE) +#define NETIF_F_ETHTOOL_BITS (0xff3fffff & ~NETIF_F_NEVER_CHANGE) /* List of features with software fallbacks. */ #define NETIF_F_GSO_SOFTWARE (NETIF_F_TSO | NETIF_F_TSO_ECN | \ diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 927819d92248..b6f405888538 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -362,7 +362,7 @@ static const char netdev_features_strings[ETHTOOL_DEV_FEATURE_WORDS * 32][ETH_GS /* NETIF_F_RXHASH */ "rx-hashing", /* NETIF_F_RXCSUM */ "rx-checksum", /* NETIF_F_NOCACHE_COPY */ "tx-nocache-copy" - "", + /* NETIF_F_LOOPBACK */ "loopback", }; static int __ethtool_get_sset_count(struct net_device *dev, int sset) -- cgit From 245e37182b7dead255bdc9e333e0bcc128360675 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Sun, 8 May 2011 16:41:45 -0700 Subject: ide: Use linux/mutex.h The IDE code is still including asm/mutex.h instead of linux/mutex.h Signed-off-by: Anton Blanchard Signed-off-by: David S. Miller --- include/linux/ide.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 072fe8c93e6f..42557851b12e 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -18,13 +18,13 @@ #include #include #include +#include #ifdef CONFIG_BLK_DEV_IDEACPI #include #endif #include #include #include -#include /* for request_sense */ #include -- cgit From 000703f44c77b152cd966eaf06f4ab043274ff46 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 9 May 2011 11:40:25 +1000 Subject: mxm/wmi: add MXMX interface entry point. The MXMX method appears to be a mutex of some sort. Signed-off-by: Dave Airlie --- drivers/gpu/drm/nouveau/nouveau_acpi.c | 1 + drivers/platform/x86/mxm-wmi.c | 28 +++++++++++++++++++++++++++- include/linux/mxm-wmi.h | 1 + 3 files changed, 29 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index e0a885b72e0e..f0d459bb46e4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c @@ -150,6 +150,7 @@ static int nouveau_dsm(acpi_handle handle, int func, int arg, uint32_t *result) static int nouveau_dsm_switch_mux(acpi_handle handle, int mux_id) { + mxm_wmi_call_mxmx(mux_id == NOUVEAU_DSM_LED_STAMINA ? MXM_MXDS_ADAPTER_IGD : MXM_MXDS_ADAPTER_0); mxm_wmi_call_mxds(mux_id == NOUVEAU_DSM_LED_STAMINA ? MXM_MXDS_ADAPTER_IGD : MXM_MXDS_ADAPTER_0); return nouveau_dsm(handle, NOUVEAU_DSM_LED, mux_id, NULL); } diff --git a/drivers/platform/x86/mxm-wmi.c b/drivers/platform/x86/mxm-wmi.c index 12b6f341e72b..0aea63b3729a 100644 --- a/drivers/platform/x86/mxm-wmi.c +++ b/drivers/platform/x86/mxm-wmi.c @@ -32,6 +32,7 @@ MODULE_LICENSE("GPL"); MODULE_ALIAS("wmi:"MXM_WMMX_GUID); #define MXM_WMMX_FUNC_MXDS 0x5344584D /* "MXDS" */ +#define MXM_WMMX_FUNC_MXMX 0x53445344 /* "MXMX" */ struct mxds_args { u32 func; @@ -51,7 +52,7 @@ int mxm_wmi_call_mxds(int adapter) acpi_status status; printk("calling mux switch %d\n", adapter); - + status = wmi_evaluate_method(MXM_WMMX_GUID, 0x1, adapter, &input, &output); @@ -64,6 +65,31 @@ int mxm_wmi_call_mxds(int adapter) } EXPORT_SYMBOL_GPL(mxm_wmi_call_mxds); +int mxm_wmi_call_mxmx(int adapter) +{ + struct mxds_args args = { + .func = MXM_WMMX_FUNC_MXMX, + .args = 0, + .xarg = 1, + }; + struct acpi_buffer input = { (acpi_size)sizeof(args), &args }; + struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; + acpi_status status; + + printk("calling mux switch %d\n", adapter); + + status = wmi_evaluate_method(MXM_WMMX_GUID, 0x1, adapter, &input, + &output); + + if (ACPI_FAILURE(status)) + return status; + + printk("mux mutex set switched %d\n", status); + return 0; + +} +EXPORT_SYMBOL_GPL(mxm_wmi_call_mxmx); + bool mxm_wmi_supported(void) { bool guid_valid; diff --git a/include/linux/mxm-wmi.h b/include/linux/mxm-wmi.h index 51359c0718bf..617a2950523c 100644 --- a/include/linux/mxm-wmi.h +++ b/include/linux/mxm-wmi.h @@ -27,6 +27,7 @@ /* integrated adapter */ #define MXM_MXDS_ADAPTER_IGD 0x10 int mxm_wmi_call_mxds(int adapter); +int mxm_wmi_call_mxmx(int adapter); bool mxm_wmi_supported(void); #endif -- cgit From 48752e1b1802231ef2a076f34d861918b7d571c3 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 9 May 2011 04:40:44 +0000 Subject: vlan: remove one synchronize_net() call MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At VLAN dismantle phase, unregister_vlan_dev() makes one synchronize_net() call after vlan_group_set_device(grp, vlan_id, NULL). This call can be safely removed because we are calling unregister_netdevice_queue() to queue device for deletion, and this process needs at least one rcu grace period to complete. Signed-off-by: Eric Dumazet Cc: Ben Greear Cc: Patrick McHardy Cc: Paul E. McKenney Cc: Jesse Gross Cc: MichaÅ‚ MirosÅ‚aw Acked-by: Jesse Gross Signed-off-by: David S. Miller --- include/linux/if_vlan.h | 1 - net/8021q/vlan.c | 10 ++++------ 2 files changed, 4 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index 546d9d35fbd4..290bd8ac94cf 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -86,7 +86,6 @@ struct vlan_group { * the vlan is attached to. */ unsigned int nr_vlans; - int killall; struct hlist_node hlist; /* linked list */ struct net_device **vlan_devices_arrays[VLAN_GROUP_ARRAY_SPLIT_PARTS]; struct rcu_head rcu; diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 969e7004cf86..718d635d3379 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -120,9 +120,10 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head) grp->nr_vlans--; vlan_group_set_device(grp, vlan_id, NULL); - if (!grp->killall) - synchronize_net(); - + /* Because unregister_netdevice_queue() makes sure at least one rcu + * grace period is respected before device freeing, + * we dont need to call synchronize_net() here. + */ unregister_netdevice_queue(dev, head); /* If the group is now empty, kill off the group. */ @@ -478,9 +479,6 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, if (dev->reg_state != NETREG_UNREGISTERING) break; - /* Delete all VLANs for this dev. */ - grp->killall = 1; - for (i = 0; i < VLAN_N_VID; i++) { vlandev = vlan_group_get_device(grp, i); if (!vlandev) -- cgit From 4940fc889e1e63667a15243028ddcd84d471cd8e Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Sat, 7 May 2011 23:00:07 +0000 Subject: net: add mac_pton() for parsing MAC address mac_pton() parses MAC address in form XX:XX:XX:XX:XX:XX and only in that form. mac_pton() doesn't dirty result until it's sure string representation is valid. mac_pton() doesn't care about characters _after_ last octet, it's up to caller to deal with it. mac_pton() diverges from 0/-E return value convention. Target usage: if (!mac_pton(str, whatever->mac)) return -EINVAL; /* ->mac being u8 [ETH_ALEN] is filled at this point. */ /* optionally check str[3 * ETH_ALEN - 1] for termination */ Use mac_pton() in pktgen and netconsole for start. Signed-off-by: Alexey Dobriyan Signed-off-by: David S. Miller --- drivers/net/netconsole.c | 20 ++++-------------- include/linux/if_ether.h | 1 + net/core/netpoll.c | 26 +----------------------- net/core/pktgen.c | 53 ++++++++---------------------------------------- net/core/utils.c | 24 ++++++++++++++++++++++ 5 files changed, 38 insertions(+), 86 deletions(-) (limited to 'include/linux') diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 62fdbaa1fb60..a83e101440fd 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -429,8 +429,6 @@ static ssize_t store_remote_mac(struct netconsole_target *nt, size_t count) { u8 remote_mac[ETH_ALEN]; - char *p = (char *) buf; - int i; if (nt->enabled) { printk(KERN_ERR "netconsole: target (%s) is enabled, " @@ -439,23 +437,13 @@ static ssize_t store_remote_mac(struct netconsole_target *nt, return -EINVAL; } - for (i = 0; i < ETH_ALEN - 1; i++) { - remote_mac[i] = simple_strtoul(p, &p, 16); - if (*p != ':') - goto invalid; - p++; - } - remote_mac[ETH_ALEN - 1] = simple_strtoul(p, &p, 16); - if (*p && (*p != '\n')) - goto invalid; - + if (!mac_pton(buf, remote_mac)) + return -EINVAL; + if (buf[3 * ETH_ALEN - 1] && buf[3 * ETH_ALEN - 1] != '\n') + return -EINVAL; memcpy(nt->np.remote_mac, remote_mac, ETH_ALEN); return strnlen(buf, count); - -invalid: - printk(KERN_ERR "netconsole: invalid input\n"); - return -EINVAL; } /* diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h index be69043d2896..0f1325d98295 100644 --- a/include/linux/if_ether.h +++ b/include/linux/if_ether.h @@ -136,6 +136,7 @@ int eth_header_parse(const struct sk_buff *skb, unsigned char *haddr); extern struct ctl_table ether_table[]; #endif +int mac_pton(const char *s, u8 *mac); extern ssize_t sysfs_format_mac(char *buf, const unsigned char *addr, int len); #endif diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 46d9c3a4de2f..2d7d6d473781 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -698,32 +698,8 @@ int netpoll_parse_options(struct netpoll *np, char *opt) if (*cur != 0) { /* MAC address */ - if ((delim = strchr(cur, ':')) == NULL) + if (!mac_pton(cur, np->remote_mac)) goto parse_failed; - *delim = 0; - np->remote_mac[0] = simple_strtol(cur, NULL, 16); - cur = delim + 1; - if ((delim = strchr(cur, ':')) == NULL) - goto parse_failed; - *delim = 0; - np->remote_mac[1] = simple_strtol(cur, NULL, 16); - cur = delim + 1; - if ((delim = strchr(cur, ':')) == NULL) - goto parse_failed; - *delim = 0; - np->remote_mac[2] = simple_strtol(cur, NULL, 16); - cur = delim + 1; - if ((delim = strchr(cur, ':')) == NULL) - goto parse_failed; - *delim = 0; - np->remote_mac[3] = simple_strtol(cur, NULL, 16); - cur = delim + 1; - if ((delim = strchr(cur, ':')) == NULL) - goto parse_failed; - *delim = 0; - np->remote_mac[4] = simple_strtol(cur, NULL, 16); - cur = delim + 1; - np->remote_mac[5] = simple_strtol(cur, NULL, 16); } netpoll_print_options(np); diff --git a/net/core/pktgen.c b/net/core/pktgen.c index d41d88b53e18..379270f14771 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -1420,11 +1420,6 @@ static ssize_t pktgen_if_write(struct file *file, return count; } if (!strcmp(name, "dst_mac")) { - char *v = valstr; - unsigned char old_dmac[ETH_ALEN]; - unsigned char *m = pkt_dev->dst_mac; - memcpy(old_dmac, pkt_dev->dst_mac, ETH_ALEN); - len = strn_len(&user_buffer[i], sizeof(valstr) - 1); if (len < 0) return len; @@ -1432,35 +1427,16 @@ static ssize_t pktgen_if_write(struct file *file, memset(valstr, 0, sizeof(valstr)); if (copy_from_user(valstr, &user_buffer[i], len)) return -EFAULT; - i += len; - - for (*m = 0; *v && m < pkt_dev->dst_mac + 6; v++) { - int value; - - value = hex_to_bin(*v); - if (value >= 0) - *m = *m * 16 + value; - - if (*v == ':') { - m++; - *m = 0; - } - } + if (!mac_pton(valstr, pkt_dev->dst_mac)) + return -EINVAL; /* Set up Dest MAC */ - if (compare_ether_addr(old_dmac, pkt_dev->dst_mac)) - memcpy(&(pkt_dev->hh[0]), pkt_dev->dst_mac, ETH_ALEN); + memcpy(&pkt_dev->hh[0], pkt_dev->dst_mac, ETH_ALEN); - sprintf(pg_result, "OK: dstmac"); + sprintf(pg_result, "OK: dstmac %pM", pkt_dev->dst_mac); return count; } if (!strcmp(name, "src_mac")) { - char *v = valstr; - unsigned char old_smac[ETH_ALEN]; - unsigned char *m = pkt_dev->src_mac; - - memcpy(old_smac, pkt_dev->src_mac, ETH_ALEN); - len = strn_len(&user_buffer[i], sizeof(valstr) - 1); if (len < 0) return len; @@ -1468,26 +1444,13 @@ static ssize_t pktgen_if_write(struct file *file, memset(valstr, 0, sizeof(valstr)); if (copy_from_user(valstr, &user_buffer[i], len)) return -EFAULT; - i += len; - - for (*m = 0; *v && m < pkt_dev->src_mac + 6; v++) { - int value; - - value = hex_to_bin(*v); - if (value >= 0) - *m = *m * 16 + value; - - if (*v == ':') { - m++; - *m = 0; - } - } + if (!mac_pton(valstr, pkt_dev->src_mac)) + return -EINVAL; /* Set up Src MAC */ - if (compare_ether_addr(old_smac, pkt_dev->src_mac)) - memcpy(&(pkt_dev->hh[6]), pkt_dev->src_mac, ETH_ALEN); + memcpy(&pkt_dev->hh[6], pkt_dev->src_mac, ETH_ALEN); - sprintf(pg_result, "OK: srcmac"); + sprintf(pg_result, "OK: srcmac %pM", pkt_dev->src_mac); return count; } diff --git a/net/core/utils.c b/net/core/utils.c index 5fea0ab21902..2012bc797f9c 100644 --- a/net/core/utils.c +++ b/net/core/utils.c @@ -296,3 +296,27 @@ void inet_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb, csum_unfold(*sum))); } EXPORT_SYMBOL(inet_proto_csum_replace4); + +int mac_pton(const char *s, u8 *mac) +{ + int i; + + /* XX:XX:XX:XX:XX:XX */ + if (strlen(s) < 3 * ETH_ALEN - 1) + return 0; + + /* Don't dirty result unless string is valid MAC. */ + for (i = 0; i < ETH_ALEN; i++) { + if (!strchr("0123456789abcdefABCDEF", s[i * 3])) + return 0; + if (!strchr("0123456789abcdefABCDEF", s[i * 3 + 1])) + return 0; + if (i != ETH_ALEN - 1 && s[i * 3 + 2] != ':') + return 0; + } + for (i = 0; i < ETH_ALEN; i++) { + mac[i] = (hex_to_bin(s[i * 3]) << 4) | hex_to_bin(s[i * 3 + 1]); + } + return 1; +} +EXPORT_SYMBOL(mac_pton); -- cgit From a09a79f66874c905af35d5bb5e5f2fdc7b6b894d Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Mon, 9 May 2011 13:01:09 +0200 Subject: Don't lock guardpage if the stack is growing up Linux kernel excludes guard page when performing mlock on a VMA with down-growing stack. However, some architectures have up-growing stack and locking the guard page should be excluded in this case too. This patch fixes lvm2 on PA-RISC (and possibly other architectures with up-growing stack). lvm2 calculates number of used pages when locking and when unlocking and reports an internal error if the numbers mismatch. [ Patch changed fairly extensively to also fix /proc//maps for the grows-up case, and to move things around a bit to clean it all up and share the infrstructure with the /proc bits. Tested on ia64 that has both grow-up and grow-down segments - Linus ] Signed-off-by: Mikulas Patocka Tested-by: Tony Luck Cc: stable@kernel.org Signed-off-by: Linus Torvalds --- fs/proc/task_mmu.c | 12 +++++++----- include/linux/mm.h | 24 +++++++++++++++++++++++- mm/memory.c | 16 +++++++--------- 3 files changed, 37 insertions(+), 15 deletions(-) (limited to 'include/linux') diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 2e7addfd9803..318d8654989b 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -214,7 +214,7 @@ static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma) int flags = vma->vm_flags; unsigned long ino = 0; unsigned long long pgoff = 0; - unsigned long start; + unsigned long start, end; dev_t dev = 0; int len; @@ -227,13 +227,15 @@ static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma) /* We don't show the stack guard page in /proc/maps */ start = vma->vm_start; - if (vma->vm_flags & VM_GROWSDOWN) - if (!vma_stack_continue(vma->vm_prev, vma->vm_start)) - start += PAGE_SIZE; + if (stack_guard_page_start(vma, start)) + start += PAGE_SIZE; + end = vma->vm_end; + if (stack_guard_page_end(vma, end)) + end -= PAGE_SIZE; seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu %n", start, - vma->vm_end, + end, flags & VM_READ ? 'r' : '-', flags & VM_WRITE ? 'w' : '-', flags & VM_EXEC ? 'x' : '-', diff --git a/include/linux/mm.h b/include/linux/mm.h index 2348db26bc3d..6507dde38b16 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1011,11 +1011,33 @@ int set_page_dirty_lock(struct page *page); int clear_page_dirty_for_io(struct page *page); /* Is the vma a continuation of the stack vma above it? */ -static inline int vma_stack_continue(struct vm_area_struct *vma, unsigned long addr) +static inline int vma_growsdown(struct vm_area_struct *vma, unsigned long addr) { return vma && (vma->vm_end == addr) && (vma->vm_flags & VM_GROWSDOWN); } +static inline int stack_guard_page_start(struct vm_area_struct *vma, + unsigned long addr) +{ + return (vma->vm_flags & VM_GROWSDOWN) && + (vma->vm_start == addr) && + !vma_growsdown(vma->vm_prev, addr); +} + +/* Is the vma a continuation of the stack vma below it? */ +static inline int vma_growsup(struct vm_area_struct *vma, unsigned long addr) +{ + return vma && (vma->vm_start == addr) && (vma->vm_flags & VM_GROWSUP); +} + +static inline int stack_guard_page_end(struct vm_area_struct *vma, + unsigned long addr) +{ + return (vma->vm_flags & VM_GROWSUP) && + (vma->vm_end == addr) && + !vma_growsup(vma->vm_next, addr); +} + extern unsigned long move_page_tables(struct vm_area_struct *vma, unsigned long old_addr, struct vm_area_struct *new_vma, unsigned long new_addr, unsigned long len); diff --git a/mm/memory.c b/mm/memory.c index 27f425378112..61e66f026563 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1412,9 +1412,8 @@ no_page_table: static inline int stack_guard_page(struct vm_area_struct *vma, unsigned long addr) { - return (vma->vm_flags & VM_GROWSDOWN) && - (vma->vm_start == addr) && - !vma_stack_continue(vma->vm_prev, addr); + return stack_guard_page_start(vma, addr) || + stack_guard_page_end(vma, addr+PAGE_SIZE); } /** @@ -1551,12 +1550,6 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, continue; } - /* - * For mlock, just skip the stack guard page. - */ - if ((gup_flags & FOLL_MLOCK) && stack_guard_page(vma, start)) - goto next_page; - do { struct page *page; unsigned int foll_flags = gup_flags; @@ -1573,6 +1566,11 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, int ret; unsigned int fault_flags = 0; + /* For mlock, just skip the stack guard page. */ + if (foll_flags & FOLL_MLOCK) { + if (stack_guard_page(vma, start)) + goto next_page; + } if (foll_flags & FOLL_WRITE) fault_flags |= FAULT_FLAG_WRITE; if (nonblocking) -- cgit From 70f23fd66bc821a0e99647f70a809e277cc93c4c Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Tue, 10 May 2011 10:16:21 +0200 Subject: treewide: fix a few typos in comments - kenrel -> kernel - whetehr -> whether - ttt -> tt - sss -> ss Signed-off-by: Justin P. Mattock Signed-off-by: Jiri Kosina --- Documentation/devicetree/bindings/powerpc/nintendo/wii.txt | 2 +- Documentation/feature-removal-schedule.txt | 2 +- arch/arm/mach-msm/include/mach/msm_iomap.h | 2 +- arch/arm/mach-omap2/control.h | 2 +- arch/ia64/hp/common/sba_iommu.c | 2 +- arch/powerpc/include/asm/pte-hash64-64k.h | 2 +- arch/powerpc/kernel/kgdb.c | 2 +- arch/x86/xen/pci-swiotlb-xen.c | 2 +- drivers/acpi/acpica/utresrc.c | 2 +- drivers/acpi/video.c | 2 +- drivers/firmware/efivars.c | 2 +- drivers/macintosh/therm_pm72.c | 4 ++-- drivers/media/dvb/dvb-usb/dw2102.c | 2 +- drivers/media/video/msp3400-driver.c | 2 +- drivers/media/video/saa7164/saa7164-encoder.c | 2 +- drivers/media/video/saa7164/saa7164-vbi.c | 2 +- drivers/message/i2o/README.ioctl | 2 +- drivers/net/can/pch_can.c | 2 +- drivers/net/irda/ali-ircc.c | 2 +- drivers/net/s2io.c | 2 +- drivers/net/ucc_geth_ethtool.c | 2 +- drivers/net/usb/usbnet.c | 2 +- drivers/net/wan/pc300_drv.c | 2 +- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 8 ++++---- drivers/net/wireless/ipw2x00/ipw2200.c | 2 +- drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c | 2 +- drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h | 2 +- drivers/scsi/constants.c | 2 +- drivers/scsi/esp_scsi.c | 2 +- drivers/scsi/lpfc/lpfc_attr.c | 2 +- drivers/scsi/lpfc/lpfc_hw.h | 2 +- drivers/scsi/lpfc/lpfc_sli.c | 2 +- drivers/scsi/nsp32_debug.c | 2 +- drivers/scsi/pcmcia/nsp_debug.c | 2 +- drivers/scsi/qla4xxx/ql4_mbx.c | 2 +- drivers/tty/n_gsm.c | 2 +- drivers/usb/host/imx21-dbg.c | 2 +- drivers/usb/misc/usbtest.c | 2 +- fs/btrfs/relocation.c | 2 +- fs/freevxfs/vxfs_inode.c | 2 +- fs/nfsd/stats.c | 2 +- fs/squashfs/Kconfig | 4 ++-- fs/squashfs/cache.c | 2 +- fs/xfs/xfs_inode.c | 2 +- include/linux/posix-clock.h | 2 +- include/net/genetlink.h | 2 +- include/net/netlink.h | 2 +- net/sunrpc/xprtrdma/svc_rdma_transport.c | 2 +- 48 files changed, 53 insertions(+), 53 deletions(-) (limited to 'include/linux') diff --git a/Documentation/devicetree/bindings/powerpc/nintendo/wii.txt b/Documentation/devicetree/bindings/powerpc/nintendo/wii.txt index a7e155a023b8..36afa322b04b 100644 --- a/Documentation/devicetree/bindings/powerpc/nintendo/wii.txt +++ b/Documentation/devicetree/bindings/powerpc/nintendo/wii.txt @@ -127,7 +127,7 @@ Nintendo Wii device tree - reg : should contain the SDHCI registers location and length - interrupts : should contain the SDHCI interrupt -1.j) The Inter-Processsor Communication (IPC) node +1.j) The Inter-Processor Communication (IPC) node Represent the Inter-Processor Communication interface. This interface enables communications between the Broadway and the Starlet processors. diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 492e81df2968..9536652eadbf 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -226,7 +226,7 @@ Who: Zhang Rui What: CONFIG_ACPI_PROCFS_POWER When: 2.6.39 Why: sysfs I/F for ACPI power devices, including AC and Battery, - has been working in upstream kenrel since 2.6.24, Sep 2007. + has been working in upstream kernel since 2.6.24, Sep 2007. In 2.6.37, we make the sysfs I/F always built in and this option disabled by default. Remove this option and the ACPI power procfs interface in 2.6.39. diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h index c98c7591f3b8..2f494b6a9d0a 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap.h @@ -55,7 +55,7 @@ #include "msm_iomap-8960.h" -/* Virtual addressses shared across all MSM targets. */ +/* Virtual addresses shared across all MSM targets. */ #define MSM_CSR_BASE IOMEM(0xE0001000) #define MSM_QGIC_DIST_BASE IOMEM(0xF0000000) #define MSM_QGIC_CPU_BASE IOMEM(0xF0001000) diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h index c2804c1c4efd..a016c8b59e00 100644 --- a/arch/arm/mach-omap2/control.h +++ b/arch/arm/mach-omap2/control.h @@ -236,7 +236,7 @@ #define OMAP343X_CONTROL_WKUP_DEBOBS3 (OMAP343X_CONTROL_GENERAL_WKUP + 0x014) #define OMAP343X_CONTROL_WKUP_DEBOBS4 (OMAP343X_CONTROL_GENERAL_WKUP + 0x018) -/* 36xx-only RTA - Retention till Accesss control registers and bits */ +/* 36xx-only RTA - Retention till Access control registers and bits */ #define OMAP36XX_CONTROL_MEM_RTA_CTRL 0x40C #define OMAP36XX_RTA_DISABLE 0x0 diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c index 4ce8d1358fee..ab3ccab132ce 100644 --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c @@ -1063,7 +1063,7 @@ static void sba_unmap_page(struct device *dev, dma_addr_t iova, size_t size, /* ** Address does not fall w/in IOVA, must be bypassing */ - DBG_BYPASS("sba_unmap_single_atttrs() bypass addr: 0x%lx\n", + DBG_BYPASS("sba_unmap_single_attrs() bypass addr: 0x%lx\n", iova); #ifdef ENABLE_MARK_CLEAN diff --git a/arch/powerpc/include/asm/pte-hash64-64k.h b/arch/powerpc/include/asm/pte-hash64-64k.h index c4490f9c67c4..59247e816ac5 100644 --- a/arch/powerpc/include/asm/pte-hash64-64k.h +++ b/arch/powerpc/include/asm/pte-hash64-64k.h @@ -22,7 +22,7 @@ #define _PAGE_HASHPTE _PAGE_HPTE_SUB /* Note the full page bits must be in the same location as for normal - * 4k pages as the same asssembly will be used to insert 64K pages + * 4k pages as the same assembly will be used to insert 64K pages * wether the kernel has CONFIG_PPC_64K_PAGES or not */ #define _PAGE_F_SECOND 0x00008000 /* full page: hidx bits */ diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c index 42850ee00ada..9411747bbcaf 100644 --- a/arch/powerpc/kernel/kgdb.c +++ b/arch/powerpc/kernel/kgdb.c @@ -142,7 +142,7 @@ static int kgdb_singlestep(struct pt_regs *regs) return 0; /* - * On Book E and perhaps other processsors, singlestep is handled on + * On Book E and perhaps other processors, singlestep is handled on * the critical exception stack. This causes current_thread_info() * to fail, since it it locates the thread_info by masking off * the low bits of the current stack pointer. We work around diff --git a/arch/x86/xen/pci-swiotlb-xen.c b/arch/x86/xen/pci-swiotlb-xen.c index bfd0632fe65e..b480d4207a4c 100644 --- a/arch/x86/xen/pci-swiotlb-xen.c +++ b/arch/x86/xen/pci-swiotlb-xen.c @@ -36,7 +36,7 @@ int __init pci_xen_swiotlb_detect(void) /* If running as PV guest, either iommu=soft, or swiotlb=force will * activate this IOMMU. If running as PV privileged, activate it - * irregardlesss. + * irregardless. */ if ((xen_initial_domain() || swiotlb || swiotlb_force) && (xen_pv_domain())) diff --git a/drivers/acpi/acpica/utresrc.c b/drivers/acpi/acpica/utresrc.c index 84e051844247..6ffd3a8bdaa5 100644 --- a/drivers/acpi/acpica/utresrc.c +++ b/drivers/acpi/acpica/utresrc.c @@ -50,7 +50,7 @@ ACPI_MODULE_NAME("utresrc") #if defined(ACPI_DISASSEMBLER) || defined (ACPI_DEBUGGER) /* * Strings used to decode resource descriptors. - * Used by both the disasssembler and the debugger resource dump routines + * Used by both the disassembler and the debugger resource dump routines */ const char *acpi_gbl_bm_decode[] = { "NotBusMaster", diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index ec574fc8fbc6..db39e9e607d8 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -1521,7 +1521,7 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) acpi_bus_generate_proc_event(device, event, 0); keycode = KEY_BRIGHTNESSDOWN; break; - case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightnesss */ + case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightness */ if (brightness_switch_enabled) acpi_video_switch_brightness(video_device, event); acpi_bus_generate_proc_event(device, event, 0); diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index ff0c373e3bbf..5629a0c56f61 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c @@ -321,7 +321,7 @@ efivar_show_raw(struct efivar_entry *entry, char *buf) /* * Generic read/write functions that call the specific functions of - * the atttributes... + * the attributes... */ static ssize_t efivar_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index bb8b722a9783..0ff92c208005 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c @@ -44,11 +44,11 @@ * TODO: - Check MPU structure version/signature * - Add things like /sbin/overtemp for non-critical * overtemp conditions so userland can take some policy - * decisions, like slewing down CPUs + * decisions, like slowing down CPUs * - Deal with fan and i2c failures in a better way * - Maybe do a generic PID based on params used for * U3 and Drives ? Definitely need to factor code a bit - * bettter... also make sensor detection more robust using + * better... also make sensor detection more robust using * the device-tree to probe for them * - Figure out how to get the slots consumption and set the * slots fan accordingly diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index f5b9da18f611..d312323504a4 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c @@ -1377,7 +1377,7 @@ static struct rc_map_table rc_map_su3000_table[] = { { 0x0f, KEY_BLUE }, /* bottom yellow button */ { 0x14, KEY_AUDIO }, /* Snapshot */ { 0x38, KEY_TV }, /* TV/Radio */ - { 0x0c, KEY_ESC } /* upper Red buttton */ + { 0x0c, KEY_ESC } /* upper Red button */ }; static struct rc_map_dvb_usb_table_table keys_tables[] = { diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c index 8126622fb4f5..de5d481b0328 100644 --- a/drivers/media/video/msp3400-driver.c +++ b/drivers/media/video/msp3400-driver.c @@ -96,7 +96,7 @@ MODULE_PARM_DESC(debug, "Enable debug messages [0-3]"); MODULE_PARM_DESC(stereo_threshold, "Sets signal threshold to activate stereo"); MODULE_PARM_DESC(standard, "Specify audio standard: 32 = NTSC, 64 = radio, Default: Autodetect"); MODULE_PARM_DESC(amsound, "Hardwire AM sound at 6.5Hz (France), FM can autoscan"); -MODULE_PARM_DESC(dolby, "Activates Dolby processsing"); +MODULE_PARM_DESC(dolby, "Activates Dolby processing"); /* ---------------------------------------------------------------------- */ diff --git a/drivers/media/video/saa7164/saa7164-encoder.c b/drivers/media/video/saa7164/saa7164-encoder.c index f9d594698832..400364569c8d 100644 --- a/drivers/media/video/saa7164/saa7164-encoder.c +++ b/drivers/media/video/saa7164/saa7164-encoder.c @@ -177,7 +177,7 @@ static int saa7164_encoder_buffers_alloc(struct saa7164_port *port) } } - /* Allocate some kenrel kernel buffers for copying + /* Allocate some kernel buffers for copying * to userpsace. */ len = params->numberoflines * params->pitch; diff --git a/drivers/media/video/saa7164/saa7164-vbi.c b/drivers/media/video/saa7164/saa7164-vbi.c index 9e5b01c29cf5..bc1fcedba874 100644 --- a/drivers/media/video/saa7164/saa7164-vbi.c +++ b/drivers/media/video/saa7164/saa7164-vbi.c @@ -148,7 +148,7 @@ static int saa7164_vbi_buffers_alloc(struct saa7164_port *port) } } - /* Allocate some kenrel kernel buffers for copying + /* Allocate some kernel buffers for copying * to userpsace. */ len = params->numberoflines * params->pitch; diff --git a/drivers/message/i2o/README.ioctl b/drivers/message/i2o/README.ioctl index 65c0c47aeb79..5fb195af43e2 100644 --- a/drivers/message/i2o/README.ioctl +++ b/drivers/message/i2o/README.ioctl @@ -110,7 +110,7 @@ V. Getting Logical Configuration Table ENOBUFS Buffer not large enough. If this occurs, the required buffer length is written into *(lct->reslen) -VI. Settting Parameters +VI. Setting Parameters SYNOPSIS diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index e54712b22c27..d11fbb2b95ff 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -653,7 +653,7 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 obj_num, int quota) u16 data_reg; do { - /* Reading the messsage object from the Message RAM */ + /* Reading the message object from the Message RAM */ iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask); pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, obj_num); diff --git a/drivers/net/irda/ali-ircc.c b/drivers/net/irda/ali-ircc.c index 872183f29ec4..d532dde5120f 100644 --- a/drivers/net/irda/ali-ircc.c +++ b/drivers/net/irda/ali-ircc.c @@ -1800,7 +1800,7 @@ static int ali_ircc_dma_receive_complete(struct ali_ircc_cb *self) MessageCount = inb(iobase+ FIR_LSR)&0x07; if (MessageCount > 0) - IRDA_DEBUG(0, "%s(), Messsage count = %d,\n", __func__ , MessageCount); + IRDA_DEBUG(0, "%s(), Message count = %d,\n", __func__ , MessageCount); for (i=0; i<=MessageCount; i++) { diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 337bdcd5abc9..665c3d832034 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -7231,7 +7231,7 @@ static void do_s2io_card_down(struct s2io_nic *sp, int do_io) /* As per the HW requirement we need to replenish the * receive buffer to avoid the ring bump. Since there is * no intention of processing the Rx frame at this pointwe are - * just settting the ownership bit of rxd in Each Rx + * just setting the ownership bit of rxd in Each Rx * ring to HW and set the appropriate buffer size * based on the ring mode */ diff --git a/drivers/net/ucc_geth_ethtool.c b/drivers/net/ucc_geth_ethtool.c index 6f92e48f02d3..cfd8881452ac 100644 --- a/drivers/net/ucc_geth_ethtool.c +++ b/drivers/net/ucc_geth_ethtool.c @@ -6,7 +6,7 @@ * Author: Li Yang * * Limitation: - * Can only get/set setttings of the first queue. + * Can only get/set settings of the first queue. * Need to re-open the interface manually after changing some parameters. * * This program is free software; you can redistribute it and/or modify it diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 069c1cf0fdf7..fef9ecc7b7aa 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -109,7 +109,7 @@ int usbnet_get_endpoints(struct usbnet *dev, struct usb_interface *intf) /* take the first altsetting with in-bulk + out-bulk; * remember any status endpoint, just in case; - * ignore other endpoints and altsetttings. + * ignore other endpoints and altsettings. */ for (ep = 0; ep < alt->desc.bNumEndpoints; ep++) { struct usb_host_endpoint *e; diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c index f875cfae3093..737b59f1a8dc 100644 --- a/drivers/net/wan/pc300_drv.c +++ b/drivers/net/wan/pc300_drv.c @@ -1445,7 +1445,7 @@ static void falc_update_stats(pc300_t * card, int ch) * Description: In the remote loopback mode the clock and data recovered * from the line inputs RL1/2 or RDIP/RDIN are routed back * to the line outputs XL1/2 or XDOP/XDON via the analog - * transmitter. As in normal mode they are processsed by + * transmitter. As in normal mode they are processed by * the synchronizer and then sent to the system interface. *---------------------------------------------------------------------------- */ diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 6eadf975ae48..aa1ba5dbfebb 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -3329,26 +3329,26 @@ static int ar9300_eeprom_restore_internal(struct ath_hw *ah, else cptr = AR9300_BASE_ADDR; ath_dbg(common, ATH_DBG_EEPROM, - "Trying EEPROM accesss at Address 0x%04x\n", cptr); + "Trying EEPROM access at Address 0x%04x\n", cptr); if (ar9300_check_eeprom_header(ah, read, cptr)) goto found; cptr = AR9300_BASE_ADDR_512; ath_dbg(common, ATH_DBG_EEPROM, - "Trying EEPROM accesss at Address 0x%04x\n", cptr); + "Trying EEPROM access at Address 0x%04x\n", cptr); if (ar9300_check_eeprom_header(ah, read, cptr)) goto found; read = ar9300_read_otp; cptr = AR9300_BASE_ADDR; ath_dbg(common, ATH_DBG_EEPROM, - "Trying OTP accesss at Address 0x%04x\n", cptr); + "Trying OTP access at Address 0x%04x\n", cptr); if (ar9300_check_eeprom_header(ah, read, cptr)) goto found; cptr = AR9300_BASE_ADDR_512; ath_dbg(common, ATH_DBG_EEPROM, - "Trying OTP accesss at Address 0x%04x\n", cptr); + "Trying OTP access at Address 0x%04x\n", cptr); if (ar9300_check_eeprom_header(ah, read, cptr)) goto found; diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index 42c3fe37af64..87813c33bdc2 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c @@ -7430,7 +7430,7 @@ static int ipw_associate_network(struct ipw_priv *priv, priv->assoc_request.capability &= ~cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME); - IPW_DEBUG_ASSOC("%sssocation attempt: '%s', channel %d, " + IPW_DEBUG_ASSOC("%ssociation attempt: '%s', channel %d, " "802.11%c [%d], %s[:%s], enc=%s%s%s%c%c\n", roaming ? "Rea" : "A", print_ssid(ssid, priv->essid, priv->essid_len), diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c b/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c index 078ed600f47a..232aff1fe784 100644 --- a/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c +++ b/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c @@ -1,5 +1,5 @@ /* - * Aic7xxx SCSI host adapter firmware asssembler symbol table implementation + * Aic7xxx SCSI host adapter firmware assembler symbol table implementation * * Copyright (c) 1997 Justin T. Gibbs. * Copyright (c) 2002 Adaptec Inc. diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h b/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h index 2ba73ae7c777..34bbcad7f83f 100644 --- a/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h +++ b/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h @@ -1,5 +1,5 @@ /* - * Aic7xxx SCSI host adapter firmware asssembler symbol table definitions + * Aic7xxx SCSI host adapter firmware assembler symbol table definitions * * Copyright (c) 1997 Justin T. Gibbs. * Copyright (c) 2002 Adaptec Inc. diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c index d0c82340f0e2..d0cdde57d7d2 100644 --- a/drivers/scsi/constants.c +++ b/drivers/scsi/constants.c @@ -34,7 +34,7 @@ static const char * cdb_byte0_names[] = { /* 00-03 */ "Test Unit Ready", "Rezero Unit/Rewind", NULL, "Request Sense", /* 04-07 */ "Format Unit/Medium", "Read Block Limits", NULL, - "Reasssign Blocks", + "Reassign Blocks", /* 08-0d */ "Read(6)", NULL, "Write(6)", "Seek(6)", NULL, NULL, /* 0e-12 */ NULL, "Read Reverse", "Write Filemarks", "Space", "Inquiry", /* 13-16 */ "Verify(6)", "Recover Buffered Data", "Mode Select(6)", diff --git a/drivers/scsi/esp_scsi.c b/drivers/scsi/esp_scsi.c index 57558523c1b8..182831e1e0b2 100644 --- a/drivers/scsi/esp_scsi.c +++ b/drivers/scsi/esp_scsi.c @@ -1059,7 +1059,7 @@ static struct esp_cmd_entry *esp_reconnect_with_tag(struct esp *esp, esp->ops->send_dma_cmd(esp, esp->command_block_dma, 2, 2, 1, ESP_CMD_DMA | ESP_CMD_TI); - /* ACK the msssage. */ + /* ACK the message. */ scsi_esp_cmd(esp, ESP_CMD_MOK); for (i = 0; i < ESP_RESELECT_TAG_LIMIT; i++) { diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 17d789325f40..8dcbf8fff673 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -4532,7 +4532,7 @@ lpfc_set_vport_symbolic_name(struct fc_vport *fc_vport) * * This function is called by the lpfc_get_cfgparam() routine to set the * module lpfc_log_verbose into the @phba cfg_log_verbose for use with - * log messsage according to the module's lpfc_log_verbose parameter setting + * log message according to the module's lpfc_log_verbose parameter setting * before hba port or vport created. **/ static void diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h index 95f11ed79463..86b6f7e6686a 100644 --- a/drivers/scsi/lpfc/lpfc_hw.h +++ b/drivers/scsi/lpfc/lpfc_hw.h @@ -1002,7 +1002,7 @@ typedef struct _ELS_PKT { /* Structure is in Big Endian format */ #define SLI_MGMT_GRPL 0x102 /* Get registered Port list */ #define SLI_MGMT_GPAT 0x110 /* Get Port attributes */ #define SLI_MGMT_RHBA 0x200 /* Register HBA */ -#define SLI_MGMT_RHAT 0x201 /* Register HBA atttributes */ +#define SLI_MGMT_RHAT 0x201 /* Register HBA attributes */ #define SLI_MGMT_RPRT 0x210 /* Register Port */ #define SLI_MGMT_RPA 0x211 /* Register Port attributes */ #define SLI_MGMT_DHBA 0x300 /* De-register HBA */ diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index dacabbe0a586..63c5d627a5a3 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -3040,7 +3040,7 @@ lpfc_sli_sp_handle_rspiocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, list_add_tail(&rspiocbp->list, &(pring->iocb_continueq)); pring->iocb_continueq_cnt++; - /* Now, determine whetehr the list is completed for processing */ + /* Now, determine whether the list is completed for processing */ irsp = &rspiocbp->iocb; if (irsp->ulpLe) { /* diff --git a/drivers/scsi/nsp32_debug.c b/drivers/scsi/nsp32_debug.c index 2fb3fb58858d..58806f432a16 100644 --- a/drivers/scsi/nsp32_debug.c +++ b/drivers/scsi/nsp32_debug.c @@ -13,7 +13,7 @@ static const char unknown[] = "UNKNOWN"; static const char * group_0_commands[] = { /* 00-03 */ "Test Unit Ready", "Rezero Unit", unknown, "Request Sense", -/* 04-07 */ "Format Unit", "Read Block Limits", unknown, "Reasssign Blocks", +/* 04-07 */ "Format Unit", "Read Block Limits", unknown, "Reassign Blocks", /* 08-0d */ "Read (6)", unknown, "Write (6)", "Seek (6)", unknown, unknown, /* 0e-12 */ unknown, "Read Reverse", "Write Filemarks", "Space", "Inquiry", /* 13-16 */ unknown, "Recover Buffered Data", "Mode Select", "Reserve", diff --git a/drivers/scsi/pcmcia/nsp_debug.c b/drivers/scsi/pcmcia/nsp_debug.c index 3c6ef64fcbff..6aa7d269d3b3 100644 --- a/drivers/scsi/pcmcia/nsp_debug.c +++ b/drivers/scsi/pcmcia/nsp_debug.c @@ -15,7 +15,7 @@ static const char unknown[] = "UNKNOWN"; static const char * group_0_commands[] = { /* 00-03 */ "Test Unit Ready", "Rezero Unit", unknown, "Request Sense", -/* 04-07 */ "Format Unit", "Read Block Limits", unknown, "Reasssign Blocks", +/* 04-07 */ "Format Unit", "Read Block Limits", unknown, "Reassign Blocks", /* 08-0d */ "Read (6)", unknown, "Write (6)", "Seek (6)", unknown, unknown, /* 0e-12 */ unknown, "Read Reverse", "Write Filemarks", "Space", "Inquiry", /* 13-16 */ unknown, "Recover Buffered Data", "Mode Select", "Reserve", diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c index f9d81c8372c3..d78b58dc5011 100644 --- a/drivers/scsi/qla4xxx/ql4_mbx.c +++ b/drivers/scsi/qla4xxx/ql4_mbx.c @@ -19,7 +19,7 @@ * @mbx_cmd: data pointer for mailbox in registers. * @mbx_sts: data pointer for mailbox out registers. * - * This routine isssue mailbox commands and waits for completion. + * This routine issue mailbox commands and waits for completion. * If outCount is 0, this routine completes successfully WITHOUT waiting * for the mailbox command to complete. **/ diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 74273e638c0d..77623b936538 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -2128,7 +2128,7 @@ static int gsmld_attach_gsm(struct tty_struct *tty, struct gsm_mux *gsm) /** * gsmld_detach_gsm - stop doing 0710 mux - * @tty: tty atttached to the mux + * @tty: tty attached to the mux * @gsm: mux * * Shutdown and then clean up the resources used by the line discipline diff --git a/drivers/usb/host/imx21-dbg.c b/drivers/usb/host/imx21-dbg.c index 512f647448ca..6d7533427163 100644 --- a/drivers/usb/host/imx21-dbg.c +++ b/drivers/usb/host/imx21-dbg.c @@ -384,7 +384,7 @@ static void debug_isoc_show_one(struct seq_file *s, seq_printf(s, "%s %d:\n" "cc=0X%02X\n" "scheduled frame %d (%d)\n" - "submittted frame %d (%d)\n" + "submitted frame %d (%d)\n" "completed frame %d (%d)\n" "requested length=%d\n" "completed length=%d\n\n", diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 388cc128072a..ff9a01f8d405 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -104,7 +104,7 @@ get_endpoints(struct usbtest_dev *dev, struct usb_interface *intf) alt = intf->altsetting + tmp; /* take the first altsetting with in-bulk + out-bulk; - * ignore other endpoints and altsetttings. + * ignore other endpoints and altsettings. */ for (ep = 0; ep < alt->desc.bNumEndpoints; ep++) { struct usb_host_endpoint *e; diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 199a80134312..f340f7c99d09 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -709,7 +709,7 @@ again: WARN_ON(cur->checked); if (!list_empty(&cur->upper)) { /* - * the backref was added previously when processsing + * the backref was added previously when processing * backref of type BTRFS_TREE_BLOCK_REF_KEY */ BUG_ON(!list_is_singular(&cur->upper)); diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c index 2ba6719ac612..1a4311437a8b 100644 --- a/fs/freevxfs/vxfs_inode.c +++ b/fs/freevxfs/vxfs_inode.c @@ -272,7 +272,7 @@ vxfs_get_fake_inode(struct super_block *sbp, struct vxfs_inode_info *vip) * *ip: VFS inode * * Description: - * vxfs_put_fake_inode frees all data asssociated with @ip. + * vxfs_put_fake_inode frees all data associated with @ip. */ void vxfs_put_fake_inode(struct inode *ip) diff --git a/fs/nfsd/stats.c b/fs/nfsd/stats.c index 5232d3e8fb2f..a2e2402b2afb 100644 --- a/fs/nfsd/stats.c +++ b/fs/nfsd/stats.c @@ -8,7 +8,7 @@ * Statistsics for the reply cache * fh * statistics for filehandle lookup - * io + * io * statistics for IO throughput * th <10%-20%> <20%-30%> ... <90%-100%> <100%> * time (seconds) when nfsd thread usage above thresholds diff --git a/fs/squashfs/Kconfig b/fs/squashfs/Kconfig index efc309fa3035..7797218d0b30 100644 --- a/fs/squashfs/Kconfig +++ b/fs/squashfs/Kconfig @@ -42,7 +42,7 @@ config SQUASHFS_LZO select LZO_DECOMPRESS help Saying Y here includes support for reading Squashfs file systems - compressed with LZO compresssion. LZO compression is mainly + compressed with LZO compression. LZO compression is mainly aimed at embedded systems with slower CPUs where the overheads of zlib are too high. @@ -57,7 +57,7 @@ config SQUASHFS_XZ select XZ_DEC help Saying Y here includes support for reading Squashfs file systems - compressed with XZ compresssion. XZ gives better compression than + compressed with XZ compression. XZ gives better compression than the default zlib compression, at the expense of greater CPU and memory overhead. diff --git a/fs/squashfs/cache.c b/fs/squashfs/cache.c index c37b520132ff..4b5a3fbb1f1f 100644 --- a/fs/squashfs/cache.c +++ b/fs/squashfs/cache.c @@ -29,7 +29,7 @@ * plus functions layered ontop of the generic cache implementation to * access the metadata and fragment caches. * - * To avoid out of memory and fragmentation isssues with vmalloc the cache + * To avoid out of memory and fragmentation issues with vmalloc the cache * uses sequences of kmalloced PAGE_CACHE_SIZE buffers. * * It should be noted that the cache is not used for file datablocks, these diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index a37480a6e023..d11ce613d692 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1470,7 +1470,7 @@ xfs_itruncate_finish( * file but the log buffers containing the free and reallocation * don't, then we'd end up with garbage in the blocks being freed. * As long as we make the new_size permanent before actually - * freeing any blocks it doesn't matter if they get writtten to. + * freeing any blocks it doesn't matter if they get written to. * * The callers must signal into us whether or not the size * setting here must be synchronous. There are a few cases diff --git a/include/linux/posix-clock.h b/include/linux/posix-clock.h index 7f1183dcd119..34c4498b800f 100644 --- a/include/linux/posix-clock.h +++ b/include/linux/posix-clock.h @@ -45,7 +45,7 @@ struct posix_clock; * @timer_create: Create a new timer * @timer_delete: Remove a previously created timer * @timer_gettime: Get remaining time and interval of a timer - * @timer_setttime: Set a timer's initial expiration and interval + * @timer_settime: Set a timer's initial expiration and interval * @fasync: Optional character device fasync method * @mmap: Optional character device mmap method * @open: Optional character device open method diff --git a/include/net/genetlink.h b/include/net/genetlink.h index b4c7c1cbcf40..d420f28b6d60 100644 --- a/include/net/genetlink.h +++ b/include/net/genetlink.h @@ -260,7 +260,7 @@ static inline int genlmsg_reply(struct sk_buff *skb, struct genl_info *info) /** * gennlmsg_data - head of message payload - * @gnlh: genetlink messsage header + * @gnlh: genetlink message header */ static inline void *genlmsg_data(const struct genlmsghdr *gnlh) { diff --git a/include/net/netlink.h b/include/net/netlink.h index 8a3906a08f5f..02740a94f108 100644 --- a/include/net/netlink.h +++ b/include/net/netlink.h @@ -290,7 +290,7 @@ static inline int nlmsg_padlen(int payload) /** * nlmsg_data - head of message payload - * @nlh: netlink messsage header + * @nlh: netlink message header */ static inline void *nlmsg_data(const struct nlmsghdr *nlh) { diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c index 1a10dcd999ea..6c014dd3a20b 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_transport.c +++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c @@ -333,7 +333,7 @@ static void rq_cq_reap(struct svcxprt_rdma *xprt) } /* - * Processs a completion context + * Process a completion context */ static void process_context(struct svcxprt_rdma *xprt, struct svc_rdma_op_ctxt *ctxt) -- cgit From 6c6de1aa65189c37cc3c9af78da756c06a99899b Mon Sep 17 00:00:00 2001 From: Ryusuke Konishi Date: Sat, 30 Apr 2011 18:56:12 +0900 Subject: nilfs2: super root size should change depending on inode size The size of super root structure depends on inode size, so NILFS_SR_BYTES macro should be a function of the inode size. This fixes the issue. Even though a different size value will be written for a possible future filesystem with extended inode, but fortunately this does not break disk format compatibility. Signed-off-by: Ryusuke Konishi --- fs/nilfs2/segbuf.c | 5 ++++- fs/nilfs2/segment.c | 2 +- include/linux/nilfs2_fs.h | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/fs/nilfs2/segbuf.c b/fs/nilfs2/segbuf.c index 410ec2b1af4f..850a7c0228fb 100644 --- a/fs/nilfs2/segbuf.c +++ b/fs/nilfs2/segbuf.c @@ -239,12 +239,15 @@ nilfs_segbuf_fill_in_super_root_crc(struct nilfs_segment_buffer *segbuf, u32 seed) { struct nilfs_super_root *raw_sr; + struct the_nilfs *nilfs = segbuf->sb_super->s_fs_info; + unsigned srsize; u32 crc; raw_sr = (struct nilfs_super_root *)segbuf->sb_super_root->b_data; + srsize = NILFS_SR_BYTES(nilfs->ns_inode_size); crc = crc32_le(seed, (unsigned char *)raw_sr + sizeof(raw_sr->sr_sum), - NILFS_SR_BYTES - sizeof(raw_sr->sr_sum)); + srsize - sizeof(raw_sr->sr_sum)); raw_sr->sr_sum = cpu_to_le32(crc); } diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index abbfab974700..8006d0cd4440 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c @@ -894,7 +894,7 @@ static void nilfs_segctor_fill_in_super_root(struct nilfs_sc_info *sci, bh_sr = NILFS_LAST_SEGBUF(&sci->sc_segbufs)->sb_super_root; raw_sr = (struct nilfs_super_root *)bh_sr->b_data; - raw_sr->sr_bytes = cpu_to_le16(NILFS_SR_BYTES); + raw_sr->sr_bytes = cpu_to_le16(NILFS_SR_BYTES(isz)); raw_sr->sr_nongc_ctime = cpu_to_le64(nilfs_doing_gc() ? nilfs->ns_nongc_ctime : sci->sc_seg_ctime); diff --git a/include/linux/nilfs2_fs.h b/include/linux/nilfs2_fs.h index 8768c469e93e..bd8678f8a421 100644 --- a/include/linux/nilfs2_fs.h +++ b/include/linux/nilfs2_fs.h @@ -107,7 +107,7 @@ struct nilfs_super_root { #define NILFS_SR_DAT_OFFSET(inode_size) NILFS_SR_MDT_OFFSET(inode_size, 0) #define NILFS_SR_CPFILE_OFFSET(inode_size) NILFS_SR_MDT_OFFSET(inode_size, 1) #define NILFS_SR_SUFILE_OFFSET(inode_size) NILFS_SR_MDT_OFFSET(inode_size, 2) -#define NILFS_SR_BYTES (sizeof(struct nilfs_super_root)) +#define NILFS_SR_BYTES(inode_size) NILFS_SR_MDT_OFFSET(inode_size, 3) /* * Maximal mount counts -- cgit From 619205da5b567504310daf829dede1187fa29bbc Mon Sep 17 00:00:00 2001 From: Ryusuke Konishi Date: Thu, 5 May 2011 01:23:57 +0900 Subject: nilfs2: add ioctl which limits range of segment to be allocated This adds a new ioctl command which limits range of segment to be allocated. This is intended to gather data whithin a range of the partition before shrinking the filesystem, or to control new log location for some purpose. If a range is specified by the ioctl, segment allocator of nilfs tries to allocate new segments from the range unless no free segments are available there. Signed-off-by: Ryusuke Konishi --- fs/nilfs2/ioctl.c | 34 ++++++++++++++++++++++ fs/nilfs2/sufile.c | 73 ++++++++++++++++++++++++++++++++++++++++------- fs/nilfs2/sufile.h | 1 + include/linux/nilfs2_fs.h | 2 ++ 4 files changed, 100 insertions(+), 10 deletions(-) (limited to 'include/linux') diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c index f2469ba6246b..6f617773a7f7 100644 --- a/fs/nilfs2/ioctl.c +++ b/fs/nilfs2/ioctl.c @@ -698,6 +698,38 @@ static int nilfs_ioctl_sync(struct inode *inode, struct file *filp, return 0; } +static int nilfs_ioctl_set_alloc_range(struct inode *inode, void __user *argp) +{ + struct the_nilfs *nilfs = inode->i_sb->s_fs_info; + __u64 range[2]; + __u64 minseg, maxseg; + unsigned long segbytes; + int ret = -EPERM; + + if (!capable(CAP_SYS_ADMIN)) + goto out; + + ret = -EFAULT; + if (copy_from_user(range, argp, sizeof(__u64[2]))) + goto out; + + ret = -ERANGE; + if (range[1] > i_size_read(inode->i_sb->s_bdev->bd_inode)) + goto out; + + segbytes = nilfs->ns_blocks_per_segment * nilfs->ns_blocksize; + + minseg = range[0] + segbytes - 1; + do_div(minseg, segbytes); + maxseg = NILFS_SB2_OFFSET_BYTES(range[1]); + do_div(maxseg, segbytes); + maxseg--; + + ret = nilfs_sufile_set_alloc_range(nilfs->ns_sufile, minseg, maxseg); +out: + return ret; +} + static int nilfs_ioctl_get_info(struct inode *inode, struct file *filp, unsigned int cmd, void __user *argp, size_t membsz, @@ -763,6 +795,8 @@ long nilfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) return nilfs_ioctl_clean_segments(inode, filp, cmd, argp); case NILFS_IOCTL_SYNC: return nilfs_ioctl_sync(inode, filp, cmd, argp); + case NILFS_IOCTL_SET_ALLOC_RANGE: + return nilfs_ioctl_set_alloc_range(inode, argp); default: return -ENOTTY; } diff --git a/fs/nilfs2/sufile.c b/fs/nilfs2/sufile.c index 1d6f488ccae8..f4374df00ad5 100644 --- a/fs/nilfs2/sufile.c +++ b/fs/nilfs2/sufile.c @@ -33,7 +33,9 @@ struct nilfs_sufile_info { struct nilfs_mdt_info mi; - unsigned long ncleansegs; + unsigned long ncleansegs;/* number of clean segments */ + __u64 allocmin; /* lower limit of allocatable segment range */ + __u64 allocmax; /* upper limit of allocatable segment range */ }; static inline struct nilfs_sufile_info *NILFS_SUI(struct inode *sufile) @@ -247,6 +249,35 @@ int nilfs_sufile_update(struct inode *sufile, __u64 segnum, int create, return ret; } +/** + * nilfs_sufile_set_alloc_range - limit range of segment to be allocated + * @sufile: inode of segment usage file + * @start: minimum segment number of allocatable region (inclusive) + * @end: maximum segment number of allocatable region (inclusive) + * + * Return Value: On success, 0 is returned. On error, one of the + * following negative error codes is returned. + * + * %-ERANGE - invalid segment region + */ +int nilfs_sufile_set_alloc_range(struct inode *sufile, __u64 start, __u64 end) +{ + struct nilfs_sufile_info *sui = NILFS_SUI(sufile); + __u64 nsegs; + int ret = -ERANGE; + + down_write(&NILFS_MDT(sufile)->mi_sem); + nsegs = nilfs_sufile_get_nsegments(sufile); + + if (start <= end && end < nsegs) { + sui->allocmin = start; + sui->allocmax = end; + ret = 0; + } + up_write(&NILFS_MDT(sufile)->mi_sem); + return ret; +} + /** * nilfs_sufile_alloc - allocate a segment * @sufile: inode of segment usage file @@ -269,11 +300,12 @@ int nilfs_sufile_alloc(struct inode *sufile, __u64 *segnump) struct buffer_head *header_bh, *su_bh; struct nilfs_sufile_header *header; struct nilfs_segment_usage *su; + struct nilfs_sufile_info *sui = NILFS_SUI(sufile); size_t susz = NILFS_MDT(sufile)->mi_entry_size; __u64 segnum, maxsegnum, last_alloc; void *kaddr; - unsigned long nsegments, ncleansegs, nsus; - int ret, i, j; + unsigned long nsegments, ncleansegs, nsus, cnt; + int ret, j; down_write(&NILFS_MDT(sufile)->mi_sem); @@ -287,13 +319,31 @@ int nilfs_sufile_alloc(struct inode *sufile, __u64 *segnump) kunmap_atomic(kaddr, KM_USER0); nsegments = nilfs_sufile_get_nsegments(sufile); + maxsegnum = sui->allocmax; segnum = last_alloc + 1; - maxsegnum = nsegments - 1; - for (i = 0; i < nsegments; i += nsus) { - if (segnum >= nsegments) { - /* wrap around */ - segnum = 0; - maxsegnum = last_alloc; + if (segnum < sui->allocmin || segnum > sui->allocmax) + segnum = sui->allocmin; + + for (cnt = 0; cnt < nsegments; cnt += nsus) { + if (segnum > maxsegnum) { + if (cnt < sui->allocmax - sui->allocmin + 1) { + /* + * wrap around in the limited region. + * if allocation started from + * sui->allocmin, this never happens. + */ + segnum = sui->allocmin; + maxsegnum = last_alloc; + } else if (segnum > sui->allocmin && + sui->allocmax + 1 < nsegments) { + segnum = sui->allocmax + 1; + maxsegnum = nsegments - 1; + } else if (sui->allocmin > 0) { + segnum = 0; + maxsegnum = sui->allocmin - 1; + } else { + break; /* never happens */ + } } ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, 1, &su_bh); @@ -319,7 +369,7 @@ int nilfs_sufile_alloc(struct inode *sufile, __u64 *segnump) header->sh_last_alloc = cpu_to_le64(segnum); kunmap_atomic(kaddr, KM_USER0); - NILFS_SUI(sufile)->ncleansegs--; + sui->ncleansegs--; nilfs_mdt_mark_buffer_dirty(header_bh); nilfs_mdt_mark_buffer_dirty(su_bh); nilfs_mdt_mark_dirty(sufile); @@ -679,6 +729,9 @@ int nilfs_sufile_read(struct super_block *sb, size_t susize, kunmap_atomic(kaddr, KM_USER0); brelse(header_bh); + sui->allocmax = nilfs_sufile_get_nsegments(sufile) - 1; + sui->allocmin = 0; + unlock_new_inode(sufile); out: *inodep = sufile; diff --git a/fs/nilfs2/sufile.h b/fs/nilfs2/sufile.h index a943fbacb45b..57bfee9cd02d 100644 --- a/fs/nilfs2/sufile.h +++ b/fs/nilfs2/sufile.h @@ -36,6 +36,7 @@ static inline unsigned long nilfs_sufile_get_nsegments(struct inode *sufile) unsigned long nilfs_sufile_get_ncleansegs(struct inode *sufile); +int nilfs_sufile_set_alloc_range(struct inode *sufile, __u64 start, __u64 end); int nilfs_sufile_alloc(struct inode *, __u64 *); int nilfs_sufile_mark_dirty(struct inode *sufile, __u64 segnum); int nilfs_sufile_set_segment_usage(struct inode *sufile, __u64 segnum, diff --git a/include/linux/nilfs2_fs.h b/include/linux/nilfs2_fs.h index bd8678f8a421..7454ad7451b4 100644 --- a/include/linux/nilfs2_fs.h +++ b/include/linux/nilfs2_fs.h @@ -845,5 +845,7 @@ struct nilfs_bdesc { _IOR(NILFS_IOCTL_IDENT, 0x8A, __u64) #define NILFS_IOCTL_RESIZE \ _IOW(NILFS_IOCTL_IDENT, 0x8B, __u64) +#define NILFS_IOCTL_SET_ALLOC_RANGE \ + _IOW(NILFS_IOCTL_IDENT, 0x8C, __u64[2]) #endif /* _LINUX_NILFS_FS_H */ -- cgit From 8369ae33b705222aa05ab53c7d6b4458f4ed161b Mon Sep 17 00:00:00 2001 From: RafaÅ‚ MiÅ‚ecki Date: Mon, 9 May 2011 18:56:46 +0200 Subject: bcma: add Broadcom specific AMBA bus driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Broadcom has released cards based on a new AMBA-based bus type. From a programming point of view, this new bus type differs from AMBA and does not use AMBA common registers. It also differs enough from SSB. We decided that a new bus driver is needed to keep the code clean. In its current form, the driver detects devices present on the bus and registers them in the system. It allows registering BCMA drivers for specified bus devices and provides them basic operations. The bus driver itself includes two important bus managing drivers: ChipCommon core driver and PCI(c) core driver. They are early used to allow correct initialization. Currently code is limited to supporting buses on PCI(e) devices, however the driver is designed to be used also on other hosts. The host abstraction layer is implemented and already used for PCI(e). Support for PCI(e) hosts is working and seems to be stable (access to 80211 core was tested successfully on a few devices). We can still optimize it by using some fixed windows, but this can be done later without affecting any external code. Windows are just ranges in MMIO used for accessing cores on the bus. Cc: Greg KH Cc: Michael Büsch Cc: Larry Finger Cc: George Kashperko Cc: Arend van Spriel Cc: linux-arm-kernel@lists.infradead.org Cc: Russell King Cc: Arnd Bergmann Cc: Andy Botting Cc: linuxdriverproject Cc: linux-kernel@vger.kernel.org Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- Documentation/ABI/testing/sysfs-bus-bcma | 31 +++ MAINTAINERS | 7 + drivers/Kconfig | 2 + drivers/Makefile | 1 + drivers/bcma/Kconfig | 33 +++ drivers/bcma/Makefile | 7 + drivers/bcma/README | 19 ++ drivers/bcma/TODO | 3 + drivers/bcma/bcma_private.h | 28 +++ drivers/bcma/core.c | 51 ++++ drivers/bcma/driver_chipcommon.c | 87 +++++++ drivers/bcma/driver_chipcommon_pmu.c | 134 +++++++++++ drivers/bcma/driver_pci.c | 163 +++++++++++++ drivers/bcma/host_pci.c | 196 +++++++++++++++ drivers/bcma/main.c | 247 +++++++++++++++++++ drivers/bcma/scan.c | 360 ++++++++++++++++++++++++++++ drivers/bcma/scan.h | 56 +++++ include/linux/bcma/bcma.h | 224 +++++++++++++++++ include/linux/bcma/bcma_driver_chipcommon.h | 297 +++++++++++++++++++++++ include/linux/bcma/bcma_driver_pci.h | 89 +++++++ include/linux/bcma/bcma_regs.h | 34 +++ include/linux/mod_devicetable.h | 17 ++ scripts/mod/file2alias.c | 22 ++ 23 files changed, 2108 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-bcma create mode 100644 drivers/bcma/Kconfig create mode 100644 drivers/bcma/Makefile create mode 100644 drivers/bcma/README create mode 100644 drivers/bcma/TODO create mode 100644 drivers/bcma/bcma_private.h create mode 100644 drivers/bcma/core.c create mode 100644 drivers/bcma/driver_chipcommon.c create mode 100644 drivers/bcma/driver_chipcommon_pmu.c create mode 100644 drivers/bcma/driver_pci.c create mode 100644 drivers/bcma/host_pci.c create mode 100644 drivers/bcma/main.c create mode 100644 drivers/bcma/scan.c create mode 100644 drivers/bcma/scan.h create mode 100644 include/linux/bcma/bcma.h create mode 100644 include/linux/bcma/bcma_driver_chipcommon.h create mode 100644 include/linux/bcma/bcma_driver_pci.h create mode 100644 include/linux/bcma/bcma_regs.h (limited to 'include/linux') diff --git a/Documentation/ABI/testing/sysfs-bus-bcma b/Documentation/ABI/testing/sysfs-bus-bcma new file mode 100644 index 000000000000..06b62badddd1 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-bcma @@ -0,0 +1,31 @@ +What: /sys/bus/bcma/devices/.../manuf +Date: May 2011 +KernelVersion: 2.6.40 +Contact: RafaÅ‚ MiÅ‚ecki +Description: + Each BCMA core has it's manufacturer id. See + include/linux/bcma/bcma.h for possible values. + +What: /sys/bus/bcma/devices/.../id +Date: May 2011 +KernelVersion: 2.6.40 +Contact: RafaÅ‚ MiÅ‚ecki +Description: + There are a few types of BCMA cores, they can be identified by + id field. + +What: /sys/bus/bcma/devices/.../rev +Date: May 2011 +KernelVersion: 2.6.40 +Contact: RafaÅ‚ MiÅ‚ecki +Description: + BCMA cores of the same type can still slightly differ depending + on their revision. Use it for detailed programming. + +What: /sys/bus/bcma/devices/.../class +Date: May 2011 +KernelVersion: 2.6.40 +Contact: RafaÅ‚ MiÅ‚ecki +Description: + Each BCMA core is identified by few fields, including class it + belongs to. See include/linux/bcma/bcma.h for possible values. diff --git a/MAINTAINERS b/MAINTAINERS index 9f9104987a73..df5585819a62 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5810,6 +5810,13 @@ S: Maintained F: drivers/ssb/ F: include/linux/ssb/ +BROADCOM SPECIFIC AMBA DRIVER (BCMA) +M: RafaÅ‚ MiÅ‚ecki +L: linux-wireless@vger.kernel.org +S: Maintained +F: drivers/bcma/ +F: include/linux/bcma/ + SONY VAIO CONTROL DEVICE DRIVER M: Mattia Dongili L: platform-driver-x86@vger.kernel.org diff --git a/drivers/Kconfig b/drivers/Kconfig index 177c7d156933..aca706751469 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -68,6 +68,8 @@ source "drivers/watchdog/Kconfig" source "drivers/ssb/Kconfig" +source "drivers/bcma/Kconfig" + source "drivers/mfd/Kconfig" source "drivers/regulator/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index 3f135b6fb014..a29527f4ded6 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -110,6 +110,7 @@ obj-$(CONFIG_HID) += hid/ obj-$(CONFIG_PPC_PS3) += ps3/ obj-$(CONFIG_OF) += of/ obj-$(CONFIG_SSB) += ssb/ +obj-$(CONFIG_BCMA) += bcma/ obj-$(CONFIG_VHOST_NET) += vhost/ obj-$(CONFIG_VLYNQ) += vlynq/ obj-$(CONFIG_STAGING) += staging/ diff --git a/drivers/bcma/Kconfig b/drivers/bcma/Kconfig new file mode 100644 index 000000000000..353781b5b78b --- /dev/null +++ b/drivers/bcma/Kconfig @@ -0,0 +1,33 @@ +config BCMA_POSSIBLE + bool + depends on HAS_IOMEM && HAS_DMA + default y + +menu "Broadcom specific AMBA" + depends on BCMA_POSSIBLE + +config BCMA + tristate "BCMA support" + depends on BCMA_POSSIBLE + help + Bus driver for Broadcom specific Advanced Microcontroller Bus + Architecture. + +config BCMA_HOST_PCI_POSSIBLE + bool + depends on BCMA && PCI = y + default y + +config BCMA_HOST_PCI + bool "Support for BCMA on PCI-host bus" + depends on BCMA_HOST_PCI_POSSIBLE + +config BCMA_DEBUG + bool "BCMA debugging" + depends on BCMA + help + This turns on additional debugging messages. + + If unsure, say N + +endmenu diff --git a/drivers/bcma/Makefile b/drivers/bcma/Makefile new file mode 100644 index 000000000000..0d56245bcb79 --- /dev/null +++ b/drivers/bcma/Makefile @@ -0,0 +1,7 @@ +bcma-y += main.o scan.o core.o +bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o +bcma-y += driver_pci.o +bcma-$(CONFIG_BCMA_HOST_PCI) += host_pci.o +obj-$(CONFIG_BCMA) += bcma.o + +ccflags-$(CONFIG_BCMA_DEBUG) := -DDEBUG diff --git a/drivers/bcma/README b/drivers/bcma/README new file mode 100644 index 000000000000..f7e7ce46c603 --- /dev/null +++ b/drivers/bcma/README @@ -0,0 +1,19 @@ +Broadcom introduced new bus as replacement for older SSB. It is based on AMBA, +however from programming point of view there is nothing AMBA specific we use. + +Standard AMBA drivers are platform specific, have hardcoded addresses and use +AMBA standard fields like CID and PID. + +In case of Broadcom's cards every device consists of: +1) Broadcom specific AMBA device. It is put on AMBA bus, but can not be treated + as standard AMBA device. Reading it's CID or PID can cause machine lockup. +2) AMBA standard devices called ports or wrappers. They have CIDs (AMBA_CID) + and PIDs (0x103BB369), but we do not use that info for anything. One of that + devices is used for managing Broadcom specific core. + +Addresses of AMBA devices are not hardcoded in driver and have to be read from +EPROM. + +In this situation we decided to introduce separated bus. It can contain up to +16 devices identified by Broadcom specific fields: manufacturer, id, revision +and class. diff --git a/drivers/bcma/TODO b/drivers/bcma/TODO new file mode 100644 index 000000000000..da7aa99fe81c --- /dev/null +++ b/drivers/bcma/TODO @@ -0,0 +1,3 @@ +- Interrupts +- Defines for PCI core driver +- Create kernel Documentation (use info from README) diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h new file mode 100644 index 000000000000..2f72e9c585fd --- /dev/null +++ b/drivers/bcma/bcma_private.h @@ -0,0 +1,28 @@ +#ifndef LINUX_BCMA_PRIVATE_H_ +#define LINUX_BCMA_PRIVATE_H_ + +#ifndef pr_fmt +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#endif + +#include +#include + +#define BCMA_CORE_SIZE 0x1000 + +struct bcma_bus; + +/* main.c */ +extern int bcma_bus_register(struct bcma_bus *bus); +extern void bcma_bus_unregister(struct bcma_bus *bus); + +/* scan.c */ +int bcma_bus_scan(struct bcma_bus *bus); + +#ifdef CONFIG_BCMA_HOST_PCI +/* host_pci.c */ +extern int __init bcma_host_pci_init(void); +extern void __exit bcma_host_pci_exit(void); +#endif /* CONFIG_BCMA_HOST_PCI */ + +#endif diff --git a/drivers/bcma/core.c b/drivers/bcma/core.c new file mode 100644 index 000000000000..ced379f7b371 --- /dev/null +++ b/drivers/bcma/core.c @@ -0,0 +1,51 @@ +/* + * Broadcom specific AMBA + * Core ops + * + * Licensed under the GNU/GPL. See COPYING for details. + */ + +#include "bcma_private.h" +#include + +bool bcma_core_is_enabled(struct bcma_device *core) +{ + if ((bcma_aread32(core, BCMA_IOCTL) & (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC)) + != BCMA_IOCTL_CLK) + return false; + if (bcma_aread32(core, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET) + return false; + return true; +} +EXPORT_SYMBOL_GPL(bcma_core_is_enabled); + +static void bcma_core_disable(struct bcma_device *core, u32 flags) +{ + if (bcma_aread32(core, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET) + return; + + bcma_awrite32(core, BCMA_IOCTL, flags); + bcma_aread32(core, BCMA_IOCTL); + udelay(10); + + bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET); + udelay(1); +} + +int bcma_core_enable(struct bcma_device *core, u32 flags) +{ + bcma_core_disable(core, flags); + + bcma_awrite32(core, BCMA_IOCTL, (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC | flags)); + bcma_aread32(core, BCMA_IOCTL); + + bcma_awrite32(core, BCMA_RESET_CTL, 0); + udelay(1); + + bcma_awrite32(core, BCMA_IOCTL, (BCMA_IOCTL_CLK | flags)); + bcma_aread32(core, BCMA_IOCTL); + udelay(1); + + return 0; +} +EXPORT_SYMBOL_GPL(bcma_core_enable); diff --git a/drivers/bcma/driver_chipcommon.c b/drivers/bcma/driver_chipcommon.c new file mode 100644 index 000000000000..caf596091d4d --- /dev/null +++ b/drivers/bcma/driver_chipcommon.c @@ -0,0 +1,87 @@ +/* + * Broadcom specific AMBA + * ChipCommon core driver + * + * Copyright 2005, Broadcom Corporation + * Copyright 2006, 2007, Michael Buesch + * + * Licensed under the GNU/GPL. See COPYING for details. + */ + +#include "bcma_private.h" +#include + +static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset, + u32 mask, u32 value) +{ + value &= mask; + value |= bcma_cc_read32(cc, offset) & ~mask; + bcma_cc_write32(cc, offset, value); + + return value; +} + +void bcma_core_chipcommon_init(struct bcma_drv_cc *cc) +{ + if (cc->core->id.rev >= 11) + cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT); + cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP); + if (cc->core->id.rev >= 35) + cc->capabilities_ext = bcma_cc_read32(cc, BCMA_CC_CAP_EXT); + + bcma_cc_write32(cc, 0x58, 0); + bcma_cc_write32(cc, 0x5C, 0); + + if (cc->capabilities & BCMA_CC_CAP_PMU) + bcma_pmu_init(cc); + if (cc->capabilities & BCMA_CC_CAP_PCTL) + pr_err("Power control not implemented!\n"); +} + +/* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */ +void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks) +{ + /* instant NMI */ + bcma_cc_write32(cc, BCMA_CC_WATCHDOG, ticks); +} + +void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value) +{ + bcma_cc_write32_masked(cc, BCMA_CC_IRQMASK, mask, value); +} + +u32 bcma_chipco_irq_status(struct bcma_drv_cc *cc, u32 mask) +{ + return bcma_cc_read32(cc, BCMA_CC_IRQSTAT) & mask; +} + +u32 bcma_chipco_gpio_in(struct bcma_drv_cc *cc, u32 mask) +{ + return bcma_cc_read32(cc, BCMA_CC_GPIOIN) & mask; +} + +u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value) +{ + return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUT, mask, value); +} + +u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value) +{ + return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUTEN, mask, value); +} + +u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value) +{ + return bcma_cc_write32_masked(cc, BCMA_CC_GPIOCTL, mask, value); +} +EXPORT_SYMBOL_GPL(bcma_chipco_gpio_control); + +u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value) +{ + return bcma_cc_write32_masked(cc, BCMA_CC_GPIOIRQ, mask, value); +} + +u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value) +{ + return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value); +} diff --git a/drivers/bcma/driver_chipcommon_pmu.c b/drivers/bcma/driver_chipcommon_pmu.c new file mode 100644 index 000000000000..f44177a644c7 --- /dev/null +++ b/drivers/bcma/driver_chipcommon_pmu.c @@ -0,0 +1,134 @@ +/* + * Broadcom specific AMBA + * ChipCommon Power Management Unit driver + * + * Copyright 2009, Michael Buesch + * Copyright 2007, Broadcom Corporation + * + * Licensed under the GNU/GPL. See COPYING for details. + */ + +#include "bcma_private.h" +#include + +static void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc, + u32 offset, u32 mask, u32 set) +{ + u32 value; + + bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR); + bcma_cc_write32(cc, BCMA_CC_CHIPCTL_ADDR, offset); + bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR); + value = bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA); + value &= mask; + value |= set; + bcma_cc_write32(cc, BCMA_CC_CHIPCTL_DATA, value); + bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA); +} + +static void bcma_pmu_pll_init(struct bcma_drv_cc *cc) +{ + struct bcma_bus *bus = cc->core->bus; + + switch (bus->chipinfo.id) { + case 0x4313: + case 0x4331: + case 43224: + case 43225: + break; + default: + pr_err("PLL init unknown for device 0x%04X\n", + bus->chipinfo.id); + } +} + +static void bcma_pmu_resources_init(struct bcma_drv_cc *cc) +{ + struct bcma_bus *bus = cc->core->bus; + u32 min_msk = 0, max_msk = 0; + + switch (bus->chipinfo.id) { + case 0x4313: + min_msk = 0x200D; + max_msk = 0xFFFF; + break; + case 43224: + break; + default: + pr_err("PMU resource config unknown for device 0x%04X\n", + bus->chipinfo.id); + } + + /* Set the resource masks. */ + if (min_msk) + bcma_cc_write32(cc, BCMA_CC_PMU_MINRES_MSK, min_msk); + if (max_msk) + bcma_cc_write32(cc, BCMA_CC_PMU_MAXRES_MSK, max_msk); +} + +void bcma_pmu_swreg_init(struct bcma_drv_cc *cc) +{ + struct bcma_bus *bus = cc->core->bus; + + switch (bus->chipinfo.id) { + case 0x4313: + case 0x4331: + case 43224: + break; + default: + pr_err("PMU switch/regulators init unknown for device " + "0x%04X\n", bus->chipinfo.id); + } +} + +void bcma_pmu_workarounds(struct bcma_drv_cc *cc) +{ + struct bcma_bus *bus = cc->core->bus; + + switch (bus->chipinfo.id) { + case 0x4313: + bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x7); + break; + case 0x4331: + pr_err("Enabling Ext PA lines not implemented\n"); + break; + case 43224: + if (bus->chipinfo.rev == 0) { + pr_err("Workarounds for 43224 rev 0 not fully " + "implemented\n"); + bcma_chipco_chipctl_maskset(cc, 0, ~0, 0xF0); + } else { + bcma_chipco_chipctl_maskset(cc, 0, ~0, 0xF0); + } + break; + default: + pr_err("Workarounds unknown for device 0x%04X\n", + bus->chipinfo.id); + } +} + +void bcma_pmu_init(struct bcma_drv_cc *cc) +{ + u32 pmucap; + + pmucap = bcma_cc_read32(cc, BCMA_CC_PMU_CAP); + cc->pmu.rev = (pmucap & BCMA_CC_PMU_CAP_REVISION); + + pr_debug("Found rev %u PMU (capabilities 0x%08X)\n", cc->pmu.rev, + pmucap); + + if (cc->pmu.rev == 1) + bcma_cc_mask32(cc, BCMA_CC_PMU_CTL, + ~BCMA_CC_PMU_CTL_NOILPONW); + else + bcma_cc_set32(cc, BCMA_CC_PMU_CTL, + BCMA_CC_PMU_CTL_NOILPONW); + + if (cc->core->id.id == 0x4329 && cc->core->id.rev == 2) + pr_err("Fix for 4329b0 bad LPOM state not implemented!\n"); + + bcma_pmu_pll_init(cc); + bcma_pmu_resources_init(cc); + bcma_pmu_swreg_init(cc); + bcma_pmu_workarounds(cc); +} diff --git a/drivers/bcma/driver_pci.c b/drivers/bcma/driver_pci.c new file mode 100644 index 000000000000..b98b8359bef5 --- /dev/null +++ b/drivers/bcma/driver_pci.c @@ -0,0 +1,163 @@ +/* + * Broadcom specific AMBA + * PCI Core + * + * Copyright 2005, Broadcom Corporation + * Copyright 2006, 2007, Michael Buesch + * + * Licensed under the GNU/GPL. See COPYING for details. + */ + +#include "bcma_private.h" +#include + +/************************************************** + * R/W ops. + **************************************************/ + +static u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address) +{ + pcicore_write32(pc, 0x130, address); + pcicore_read32(pc, 0x130); + return pcicore_read32(pc, 0x134); +} + +#if 0 +static void bcma_pcie_write(struct bcma_drv_pci *pc, u32 address, u32 data) +{ + pcicore_write32(pc, 0x130, address); + pcicore_read32(pc, 0x130); + pcicore_write32(pc, 0x134, data); +} +#endif + +static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u8 phy) +{ + const u16 mdio_control = 0x128; + const u16 mdio_data = 0x12C; + u32 v; + int i; + + v = (1 << 30); /* Start of Transaction */ + v |= (1 << 28); /* Write Transaction */ + v |= (1 << 17); /* Turnaround */ + v |= (0x1F << 18); + v |= (phy << 4); + pcicore_write32(pc, mdio_data, v); + + udelay(10); + for (i = 0; i < 200; i++) { + v = pcicore_read32(pc, mdio_control); + if (v & 0x100 /* Trans complete */) + break; + msleep(1); + } +} + +static u16 bcma_pcie_mdio_read(struct bcma_drv_pci *pc, u8 device, u8 address) +{ + const u16 mdio_control = 0x128; + const u16 mdio_data = 0x12C; + int max_retries = 10; + u16 ret = 0; + u32 v; + int i; + + v = 0x80; /* Enable Preamble Sequence */ + v |= 0x2; /* MDIO Clock Divisor */ + pcicore_write32(pc, mdio_control, v); + + if (pc->core->id.rev >= 10) { + max_retries = 200; + bcma_pcie_mdio_set_phy(pc, device); + } + + v = (1 << 30); /* Start of Transaction */ + v |= (1 << 29); /* Read Transaction */ + v |= (1 << 17); /* Turnaround */ + if (pc->core->id.rev < 10) + v |= (u32)device << 22; + v |= (u32)address << 18; + pcicore_write32(pc, mdio_data, v); + /* Wait for the device to complete the transaction */ + udelay(10); + for (i = 0; i < 200; i++) { + v = pcicore_read32(pc, mdio_control); + if (v & 0x100 /* Trans complete */) { + udelay(10); + ret = pcicore_read32(pc, mdio_data); + break; + } + msleep(1); + } + pcicore_write32(pc, mdio_control, 0); + return ret; +} + +static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u8 device, + u8 address, u16 data) +{ + const u16 mdio_control = 0x128; + const u16 mdio_data = 0x12C; + int max_retries = 10; + u32 v; + int i; + + v = 0x80; /* Enable Preamble Sequence */ + v |= 0x2; /* MDIO Clock Divisor */ + pcicore_write32(pc, mdio_control, v); + + if (pc->core->id.rev >= 10) { + max_retries = 200; + bcma_pcie_mdio_set_phy(pc, device); + } + + v = (1 << 30); /* Start of Transaction */ + v |= (1 << 28); /* Write Transaction */ + v |= (1 << 17); /* Turnaround */ + if (pc->core->id.rev < 10) + v |= (u32)device << 22; + v |= (u32)address << 18; + v |= data; + pcicore_write32(pc, mdio_data, v); + /* Wait for the device to complete the transaction */ + udelay(10); + for (i = 0; i < max_retries; i++) { + v = pcicore_read32(pc, mdio_control); + if (v & 0x100 /* Trans complete */) + break; + msleep(1); + } + pcicore_write32(pc, mdio_control, 0); +} + +/************************************************** + * Workarounds. + **************************************************/ + +static u8 bcma_pcicore_polarity_workaround(struct bcma_drv_pci *pc) +{ + return (bcma_pcie_read(pc, 0x204) & 0x10) ? 0xC0 : 0x80; +} + +static void bcma_pcicore_serdes_workaround(struct bcma_drv_pci *pc) +{ + const u8 serdes_pll_device = 0x1D; + const u8 serdes_rx_device = 0x1F; + u16 tmp; + + bcma_pcie_mdio_write(pc, serdes_rx_device, 1 /* Control */, + bcma_pcicore_polarity_workaround(pc)); + tmp = bcma_pcie_mdio_read(pc, serdes_pll_device, 1 /* Control */); + if (tmp & 0x4000) + bcma_pcie_mdio_write(pc, serdes_pll_device, 1, tmp & ~0x4000); +} + +/************************************************** + * Init. + **************************************************/ + +void bcma_core_pci_init(struct bcma_drv_pci *pc) +{ + bcma_pcicore_serdes_workaround(pc); +} diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c new file mode 100644 index 000000000000..99dd36e8500b --- /dev/null +++ b/drivers/bcma/host_pci.c @@ -0,0 +1,196 @@ +/* + * Broadcom specific AMBA + * PCI Host + * + * Licensed under the GNU/GPL. See COPYING for details. + */ + +#include "bcma_private.h" +#include +#include + +static void bcma_host_pci_switch_core(struct bcma_device *core) +{ + pci_write_config_dword(core->bus->host_pci, BCMA_PCI_BAR0_WIN, + core->addr); + pci_write_config_dword(core->bus->host_pci, BCMA_PCI_BAR0_WIN2, + core->wrap); + core->bus->mapped_core = core; + pr_debug("Switched to core: 0x%X\n", core->id.id); +} + +static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset) +{ + if (core->bus->mapped_core != core) + bcma_host_pci_switch_core(core); + return ioread8(core->bus->mmio + offset); +} + +static u16 bcma_host_pci_read16(struct bcma_device *core, u16 offset) +{ + if (core->bus->mapped_core != core) + bcma_host_pci_switch_core(core); + return ioread16(core->bus->mmio + offset); +} + +static u32 bcma_host_pci_read32(struct bcma_device *core, u16 offset) +{ + if (core->bus->mapped_core != core) + bcma_host_pci_switch_core(core); + return ioread32(core->bus->mmio + offset); +} + +static void bcma_host_pci_write8(struct bcma_device *core, u16 offset, + u8 value) +{ + if (core->bus->mapped_core != core) + bcma_host_pci_switch_core(core); + iowrite8(value, core->bus->mmio + offset); +} + +static void bcma_host_pci_write16(struct bcma_device *core, u16 offset, + u16 value) +{ + if (core->bus->mapped_core != core) + bcma_host_pci_switch_core(core); + iowrite16(value, core->bus->mmio + offset); +} + +static void bcma_host_pci_write32(struct bcma_device *core, u16 offset, + u32 value) +{ + if (core->bus->mapped_core != core) + bcma_host_pci_switch_core(core); + iowrite32(value, core->bus->mmio + offset); +} + +static u32 bcma_host_pci_aread32(struct bcma_device *core, u16 offset) +{ + if (core->bus->mapped_core != core) + bcma_host_pci_switch_core(core); + return ioread32(core->bus->mmio + (1 * BCMA_CORE_SIZE) + offset); +} + +static void bcma_host_pci_awrite32(struct bcma_device *core, u16 offset, + u32 value) +{ + if (core->bus->mapped_core != core) + bcma_host_pci_switch_core(core); + iowrite32(value, core->bus->mmio + (1 * BCMA_CORE_SIZE) + offset); +} + +const struct bcma_host_ops bcma_host_pci_ops = { + .read8 = bcma_host_pci_read8, + .read16 = bcma_host_pci_read16, + .read32 = bcma_host_pci_read32, + .write8 = bcma_host_pci_write8, + .write16 = bcma_host_pci_write16, + .write32 = bcma_host_pci_write32, + .aread32 = bcma_host_pci_aread32, + .awrite32 = bcma_host_pci_awrite32, +}; + +static int bcma_host_pci_probe(struct pci_dev *dev, + const struct pci_device_id *id) +{ + struct bcma_bus *bus; + int err = -ENOMEM; + const char *name; + u32 val; + + /* Alloc */ + bus = kzalloc(sizeof(*bus), GFP_KERNEL); + if (!bus) + goto out; + + /* Basic PCI configuration */ + err = pci_enable_device(dev); + if (err) + goto err_kfree_bus; + + name = dev_name(&dev->dev); + if (dev->driver && dev->driver->name) + name = dev->driver->name; + err = pci_request_regions(dev, name); + if (err) + goto err_pci_disable; + pci_set_master(dev); + + /* Disable the RETRY_TIMEOUT register (0x41) to keep + * PCI Tx retries from interfering with C3 CPU state */ + pci_read_config_dword(dev, 0x40, &val); + if ((val & 0x0000ff00) != 0) + pci_write_config_dword(dev, 0x40, val & 0xffff00ff); + + /* SSB needed additional powering up, do we have any AMBA PCI cards? */ + if (!pci_is_pcie(dev)) + pr_err("PCI card detected, report problems.\n"); + + /* Map MMIO */ + err = -ENOMEM; + bus->mmio = pci_iomap(dev, 0, ~0UL); + if (!bus->mmio) + goto err_pci_release_regions; + + /* Host specific */ + bus->host_pci = dev; + bus->hosttype = BCMA_HOSTTYPE_PCI; + bus->ops = &bcma_host_pci_ops; + + /* Register */ + err = bcma_bus_register(bus); + if (err) + goto err_pci_unmap_mmio; + + pci_set_drvdata(dev, bus); + +out: + return err; + +err_pci_unmap_mmio: + pci_iounmap(dev, bus->mmio); +err_pci_release_regions: + pci_release_regions(dev); +err_pci_disable: + pci_disable_device(dev); +err_kfree_bus: + kfree(bus); + return err; +} + +static void bcma_host_pci_remove(struct pci_dev *dev) +{ + struct bcma_bus *bus = pci_get_drvdata(dev); + + bcma_bus_unregister(bus); + pci_iounmap(dev, bus->mmio); + pci_release_regions(dev); + pci_disable_device(dev); + kfree(bus); + pci_set_drvdata(dev, NULL); +} + +static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = { + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) }, + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) }, + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) }, + { 0, }, +}; +MODULE_DEVICE_TABLE(pci, bcma_pci_bridge_tbl); + +static struct pci_driver bcma_pci_bridge_driver = { + .name = "bcma-pci-bridge", + .id_table = bcma_pci_bridge_tbl, + .probe = bcma_host_pci_probe, + .remove = bcma_host_pci_remove, +}; + +int __init bcma_host_pci_init(void) +{ + return pci_register_driver(&bcma_pci_bridge_driver); +} + +void __exit bcma_host_pci_exit(void) +{ + pci_unregister_driver(&bcma_pci_bridge_driver); +} diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c new file mode 100644 index 000000000000..be52344ed19d --- /dev/null +++ b/drivers/bcma/main.c @@ -0,0 +1,247 @@ +/* + * Broadcom specific AMBA + * Bus subsystem + * + * Licensed under the GNU/GPL. See COPYING for details. + */ + +#include "bcma_private.h" +#include + +MODULE_DESCRIPTION("Broadcom's specific AMBA driver"); +MODULE_LICENSE("GPL"); + +static int bcma_bus_match(struct device *dev, struct device_driver *drv); +static int bcma_device_probe(struct device *dev); +static int bcma_device_remove(struct device *dev); + +static ssize_t manuf_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct bcma_device *core = container_of(dev, struct bcma_device, dev); + return sprintf(buf, "0x%03X\n", core->id.manuf); +} +static ssize_t id_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct bcma_device *core = container_of(dev, struct bcma_device, dev); + return sprintf(buf, "0x%03X\n", core->id.id); +} +static ssize_t rev_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct bcma_device *core = container_of(dev, struct bcma_device, dev); + return sprintf(buf, "0x%02X\n", core->id.rev); +} +static ssize_t class_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct bcma_device *core = container_of(dev, struct bcma_device, dev); + return sprintf(buf, "0x%X\n", core->id.class); +} +static struct device_attribute bcma_device_attrs[] = { + __ATTR_RO(manuf), + __ATTR_RO(id), + __ATTR_RO(rev), + __ATTR_RO(class), + __ATTR_NULL, +}; + +static struct bus_type bcma_bus_type = { + .name = "bcma", + .match = bcma_bus_match, + .probe = bcma_device_probe, + .remove = bcma_device_remove, + .dev_attrs = bcma_device_attrs, +}; + +static struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid) +{ + struct bcma_device *core; + + list_for_each_entry(core, &bus->cores, list) { + if (core->id.id == coreid) + return core; + } + return NULL; +} + +static void bcma_release_core_dev(struct device *dev) +{ + struct bcma_device *core = container_of(dev, struct bcma_device, dev); + kfree(core); +} + +static int bcma_register_cores(struct bcma_bus *bus) +{ + struct bcma_device *core; + int err, dev_id = 0; + + list_for_each_entry(core, &bus->cores, list) { + /* We support that cores ourself */ + switch (core->id.id) { + case BCMA_CORE_CHIPCOMMON: + case BCMA_CORE_PCI: + case BCMA_CORE_PCIE: + continue; + } + + core->dev.release = bcma_release_core_dev; + core->dev.bus = &bcma_bus_type; + dev_set_name(&core->dev, "bcma%d:%d", 0/*bus->num*/, dev_id); + + switch (bus->hosttype) { + case BCMA_HOSTTYPE_PCI: + core->dev.parent = &bus->host_pci->dev; + break; + case BCMA_HOSTTYPE_NONE: + case BCMA_HOSTTYPE_SDIO: + break; + } + + err = device_register(&core->dev); + if (err) { + pr_err("Could not register dev for core 0x%03X\n", + core->id.id); + continue; + } + core->dev_registered = true; + dev_id++; + } + + return 0; +} + +static void bcma_unregister_cores(struct bcma_bus *bus) +{ + struct bcma_device *core; + + list_for_each_entry(core, &bus->cores, list) { + if (core->dev_registered) + device_unregister(&core->dev); + } +} + +int bcma_bus_register(struct bcma_bus *bus) +{ + int err; + struct bcma_device *core; + + /* Scan for devices (cores) */ + err = bcma_bus_scan(bus); + if (err) { + pr_err("Failed to scan: %d\n", err); + return -1; + } + + /* Init CC core */ + core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON); + if (core) { + bus->drv_cc.core = core; + bcma_core_chipcommon_init(&bus->drv_cc); + } + + /* Init PCIE core */ + core = bcma_find_core(bus, BCMA_CORE_PCIE); + if (core) { + bus->drv_pci.core = core; + bcma_core_pci_init(&bus->drv_pci); + } + + /* Register found cores */ + bcma_register_cores(bus); + + pr_info("Bus registered\n"); + + return 0; +} +EXPORT_SYMBOL_GPL(bcma_bus_register); + +void bcma_bus_unregister(struct bcma_bus *bus) +{ + bcma_unregister_cores(bus); +} +EXPORT_SYMBOL_GPL(bcma_bus_unregister); + +int __bcma_driver_register(struct bcma_driver *drv, struct module *owner) +{ + drv->drv.name = drv->name; + drv->drv.bus = &bcma_bus_type; + drv->drv.owner = owner; + + return driver_register(&drv->drv); +} +EXPORT_SYMBOL_GPL(__bcma_driver_register); + +void bcma_driver_unregister(struct bcma_driver *drv) +{ + driver_unregister(&drv->drv); +} +EXPORT_SYMBOL_GPL(bcma_driver_unregister); + +static int bcma_bus_match(struct device *dev, struct device_driver *drv) +{ + struct bcma_device *core = container_of(dev, struct bcma_device, dev); + struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv); + const struct bcma_device_id *cid = &core->id; + const struct bcma_device_id *did; + + for (did = adrv->id_table; did->manuf || did->id || did->rev; did++) { + if ((did->manuf == cid->manuf || did->manuf == BCMA_ANY_MANUF) && + (did->id == cid->id || did->id == BCMA_ANY_ID) && + (did->rev == cid->rev || did->rev == BCMA_ANY_REV) && + (did->class == cid->class || did->class == BCMA_ANY_CLASS)) + return 1; + } + return 0; +} + +static int bcma_device_probe(struct device *dev) +{ + struct bcma_device *core = container_of(dev, struct bcma_device, dev); + struct bcma_driver *adrv = container_of(dev->driver, struct bcma_driver, + drv); + int err = 0; + + if (adrv->probe) + err = adrv->probe(core); + + return err; +} + +static int bcma_device_remove(struct device *dev) +{ + struct bcma_device *core = container_of(dev, struct bcma_device, dev); + struct bcma_driver *adrv = container_of(dev->driver, struct bcma_driver, + drv); + + if (adrv->remove) + adrv->remove(core); + + return 0; +} + +static int __init bcma_modinit(void) +{ + int err; + + err = bus_register(&bcma_bus_type); + if (err) + return err; + +#ifdef CONFIG_BCMA_HOST_PCI + err = bcma_host_pci_init(); + if (err) { + pr_err("PCI host initialization failed\n"); + err = 0; + } +#endif + + return err; +} +fs_initcall(bcma_modinit); + +static void __exit bcma_modexit(void) +{ +#ifdef CONFIG_BCMA_HOST_PCI + bcma_host_pci_exit(); +#endif + bus_unregister(&bcma_bus_type); +} +module_exit(bcma_modexit) diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c new file mode 100644 index 000000000000..40d7dcce8933 --- /dev/null +++ b/drivers/bcma/scan.c @@ -0,0 +1,360 @@ +/* + * Broadcom specific AMBA + * Bus scanning + * + * Licensed under the GNU/GPL. See COPYING for details. + */ + +#include "scan.h" +#include "bcma_private.h" + +#include +#include +#include +#include +#include +#include + +struct bcma_device_id_name { + u16 id; + const char *name; +}; +struct bcma_device_id_name bcma_device_names[] = { + { BCMA_CORE_OOB_ROUTER, "OOB Router" }, + { BCMA_CORE_INVALID, "Invalid" }, + { BCMA_CORE_CHIPCOMMON, "ChipCommon" }, + { BCMA_CORE_ILINE20, "ILine 20" }, + { BCMA_CORE_SRAM, "SRAM" }, + { BCMA_CORE_SDRAM, "SDRAM" }, + { BCMA_CORE_PCI, "PCI" }, + { BCMA_CORE_MIPS, "MIPS" }, + { BCMA_CORE_ETHERNET, "Fast Ethernet" }, + { BCMA_CORE_V90, "V90" }, + { BCMA_CORE_USB11_HOSTDEV, "USB 1.1 Hostdev" }, + { BCMA_CORE_ADSL, "ADSL" }, + { BCMA_CORE_ILINE100, "ILine 100" }, + { BCMA_CORE_IPSEC, "IPSEC" }, + { BCMA_CORE_UTOPIA, "UTOPIA" }, + { BCMA_CORE_PCMCIA, "PCMCIA" }, + { BCMA_CORE_INTERNAL_MEM, "Internal Memory" }, + { BCMA_CORE_MEMC_SDRAM, "MEMC SDRAM" }, + { BCMA_CORE_OFDM, "OFDM" }, + { BCMA_CORE_EXTIF, "EXTIF" }, + { BCMA_CORE_80211, "IEEE 802.11" }, + { BCMA_CORE_PHY_A, "PHY A" }, + { BCMA_CORE_PHY_B, "PHY B" }, + { BCMA_CORE_PHY_G, "PHY G" }, + { BCMA_CORE_MIPS_3302, "MIPS 3302" }, + { BCMA_CORE_USB11_HOST, "USB 1.1 Host" }, + { BCMA_CORE_USB11_DEV, "USB 1.1 Device" }, + { BCMA_CORE_USB20_HOST, "USB 2.0 Host" }, + { BCMA_CORE_USB20_DEV, "USB 2.0 Device" }, + { BCMA_CORE_SDIO_HOST, "SDIO Host" }, + { BCMA_CORE_ROBOSWITCH, "Roboswitch" }, + { BCMA_CORE_PARA_ATA, "PATA" }, + { BCMA_CORE_SATA_XORDMA, "SATA XOR-DMA" }, + { BCMA_CORE_ETHERNET_GBIT, "GBit Ethernet" }, + { BCMA_CORE_PCIE, "PCIe" }, + { BCMA_CORE_PHY_N, "PHY N" }, + { BCMA_CORE_SRAM_CTL, "SRAM Controller" }, + { BCMA_CORE_MINI_MACPHY, "Mini MACPHY" }, + { BCMA_CORE_ARM_1176, "ARM 1176" }, + { BCMA_CORE_ARM_7TDMI, "ARM 7TDMI" }, + { BCMA_CORE_PHY_LP, "PHY LP" }, + { BCMA_CORE_PMU, "PMU" }, + { BCMA_CORE_PHY_SSN, "PHY SSN" }, + { BCMA_CORE_SDIO_DEV, "SDIO Device" }, + { BCMA_CORE_ARM_CM3, "ARM CM3" }, + { BCMA_CORE_PHY_HT, "PHY HT" }, + { BCMA_CORE_MIPS_74K, "MIPS 74K" }, + { BCMA_CORE_MAC_GBIT, "GBit MAC" }, + { BCMA_CORE_DDR12_MEM_CTL, "DDR1/DDR2 Memory Controller" }, + { BCMA_CORE_PCIE_RC, "PCIe Root Complex" }, + { BCMA_CORE_OCP_OCP_BRIDGE, "OCP to OCP Bridge" }, + { BCMA_CORE_SHARED_COMMON, "Common Shared" }, + { BCMA_CORE_OCP_AHB_BRIDGE, "OCP to AHB Bridge" }, + { BCMA_CORE_SPI_HOST, "SPI Host" }, + { BCMA_CORE_I2S, "I2S" }, + { BCMA_CORE_SDR_DDR1_MEM_CTL, "SDR/DDR1 Memory Controller" }, + { BCMA_CORE_SHIM, "SHIM" }, + { BCMA_CORE_DEFAULT, "Default" }, +}; +const char *bcma_device_name(struct bcma_device_id *id) +{ + int i; + + if (id->manuf == BCMA_MANUF_BCM) { + for (i = 0; i < ARRAY_SIZE(bcma_device_names); i++) { + if (bcma_device_names[i].id == id->id) + return bcma_device_names[i].name; + } + } + return "UNKNOWN"; +} + +static u32 bcma_scan_read32(struct bcma_bus *bus, u8 current_coreidx, + u16 offset) +{ + return readl(bus->mmio + offset); +} + +static void bcma_scan_switch_core(struct bcma_bus *bus, u32 addr) +{ + if (bus->hosttype == BCMA_HOSTTYPE_PCI) + pci_write_config_dword(bus->host_pci, BCMA_PCI_BAR0_WIN, + addr); +} + +static u32 bcma_erom_get_ent(struct bcma_bus *bus, u32 **eromptr) +{ + u32 ent = readl(*eromptr); + (*eromptr)++; + return ent; +} + +static void bcma_erom_push_ent(u32 **eromptr) +{ + (*eromptr)--; +} + +static s32 bcma_erom_get_ci(struct bcma_bus *bus, u32 **eromptr) +{ + u32 ent = bcma_erom_get_ent(bus, eromptr); + if (!(ent & SCAN_ER_VALID)) + return -ENOENT; + if ((ent & SCAN_ER_TAG) != SCAN_ER_TAG_CI) + return -ENOENT; + return ent; +} + +static bool bcma_erom_is_end(struct bcma_bus *bus, u32 **eromptr) +{ + u32 ent = bcma_erom_get_ent(bus, eromptr); + bcma_erom_push_ent(eromptr); + return (ent == (SCAN_ER_TAG_END | SCAN_ER_VALID)); +} + +static bool bcma_erom_is_bridge(struct bcma_bus *bus, u32 **eromptr) +{ + u32 ent = bcma_erom_get_ent(bus, eromptr); + bcma_erom_push_ent(eromptr); + return (((ent & SCAN_ER_VALID)) && + ((ent & SCAN_ER_TAGX) == SCAN_ER_TAG_ADDR) && + ((ent & SCAN_ADDR_TYPE) == SCAN_ADDR_TYPE_BRIDGE)); +} + +static void bcma_erom_skip_component(struct bcma_bus *bus, u32 **eromptr) +{ + u32 ent; + while (1) { + ent = bcma_erom_get_ent(bus, eromptr); + if ((ent & SCAN_ER_VALID) && + ((ent & SCAN_ER_TAG) == SCAN_ER_TAG_CI)) + break; + if (ent == (SCAN_ER_TAG_END | SCAN_ER_VALID)) + break; + } + bcma_erom_push_ent(eromptr); +} + +static s32 bcma_erom_get_mst_port(struct bcma_bus *bus, u32 **eromptr) +{ + u32 ent = bcma_erom_get_ent(bus, eromptr); + if (!(ent & SCAN_ER_VALID)) + return -ENOENT; + if ((ent & SCAN_ER_TAG) != SCAN_ER_TAG_MP) + return -ENOENT; + return ent; +} + +static s32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 **eromptr, + u32 type, u8 port) +{ + u32 addrl, addrh, sizel, sizeh = 0; + u32 size; + + u32 ent = bcma_erom_get_ent(bus, eromptr); + if ((!(ent & SCAN_ER_VALID)) || + ((ent & SCAN_ER_TAGX) != SCAN_ER_TAG_ADDR) || + ((ent & SCAN_ADDR_TYPE) != type) || + (((ent & SCAN_ADDR_PORT) >> SCAN_ADDR_PORT_SHIFT) != port)) { + bcma_erom_push_ent(eromptr); + return -EINVAL; + } + + addrl = ent & SCAN_ADDR_ADDR; + if (ent & SCAN_ADDR_AG32) + addrh = bcma_erom_get_ent(bus, eromptr); + else + addrh = 0; + + if ((ent & SCAN_ADDR_SZ) == SCAN_ADDR_SZ_SZD) { + size = bcma_erom_get_ent(bus, eromptr); + sizel = size & SCAN_SIZE_SZ; + if (size & SCAN_SIZE_SG32) + sizeh = bcma_erom_get_ent(bus, eromptr); + } else + sizel = SCAN_ADDR_SZ_BASE << + ((ent & SCAN_ADDR_SZ) >> SCAN_ADDR_SZ_SHIFT); + + return addrl; +} + +int bcma_bus_scan(struct bcma_bus *bus) +{ + u32 erombase; + u32 __iomem *eromptr, *eromend; + + s32 cia, cib; + u8 ports[2], wrappers[2]; + + s32 tmp; + u8 i, j; + + int err; + + INIT_LIST_HEAD(&bus->cores); + bus->nr_cores = 0; + + bcma_scan_switch_core(bus, BCMA_ADDR_BASE); + + tmp = bcma_scan_read32(bus, 0, BCMA_CC_ID); + bus->chipinfo.id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT; + bus->chipinfo.rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT; + bus->chipinfo.pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT; + + erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM); + eromptr = bus->mmio; + eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32); + + bcma_scan_switch_core(bus, erombase); + + while (eromptr < eromend) { + struct bcma_device *core = kzalloc(sizeof(*core), GFP_KERNEL); + if (!core) + return -ENOMEM; + INIT_LIST_HEAD(&core->list); + core->bus = bus; + + /* get CIs */ + cia = bcma_erom_get_ci(bus, &eromptr); + if (cia < 0) { + bcma_erom_push_ent(&eromptr); + if (bcma_erom_is_end(bus, &eromptr)) + break; + err= -EILSEQ; + goto out; + } + cib = bcma_erom_get_ci(bus, &eromptr); + if (cib < 0) { + err= -EILSEQ; + goto out; + } + + /* parse CIs */ + core->id.class = (cia & SCAN_CIA_CLASS) >> SCAN_CIA_CLASS_SHIFT; + core->id.id = (cia & SCAN_CIA_ID) >> SCAN_CIA_ID_SHIFT; + core->id.manuf = (cia & SCAN_CIA_MANUF) >> SCAN_CIA_MANUF_SHIFT; + ports[0] = (cib & SCAN_CIB_NMP) >> SCAN_CIB_NMP_SHIFT; + ports[1] = (cib & SCAN_CIB_NSP) >> SCAN_CIB_NSP_SHIFT; + wrappers[0] = (cib & SCAN_CIB_NMW) >> SCAN_CIB_NMW_SHIFT; + wrappers[1] = (cib & SCAN_CIB_NSW) >> SCAN_CIB_NSW_SHIFT; + core->id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT; + + if (((core->id.manuf == BCMA_MANUF_ARM) && + (core->id.id == 0xFFF)) || + (ports[1] == 0)) { + bcma_erom_skip_component(bus, &eromptr); + continue; + } + + /* check if component is a core at all */ + if (wrappers[0] + wrappers[1] == 0) { + /* we could save addrl of the router + if (cid == BCMA_CORE_OOB_ROUTER) + */ + bcma_erom_skip_component(bus, &eromptr); + continue; + } + + if (bcma_erom_is_bridge(bus, &eromptr)) { + bcma_erom_skip_component(bus, &eromptr); + continue; + } + + /* get & parse master ports */ + for (i = 0; i < ports[0]; i++) { + u32 mst_port_d = bcma_erom_get_mst_port(bus, &eromptr); + if (mst_port_d < 0) { + err= -EILSEQ; + goto out; + } + } + + /* get & parse slave ports */ + for (i = 0; i < ports[1]; i++) { + for (j = 0; ; j++) { + tmp = bcma_erom_get_addr_desc(bus, &eromptr, + SCAN_ADDR_TYPE_SLAVE, i); + if (tmp < 0) { + /* no more entries for port _i_ */ + /* pr_debug("erom: slave port %d " + * "has %d descriptors\n", i, j); */ + break; + } else { + if (i == 0 && j == 0) + core->addr = tmp; + } + } + } + + /* get & parse master wrappers */ + for (i = 0; i < wrappers[0]; i++) { + for (j = 0; ; j++) { + tmp = bcma_erom_get_addr_desc(bus, &eromptr, + SCAN_ADDR_TYPE_MWRAP, i); + if (tmp < 0) { + /* no more entries for port _i_ */ + /* pr_debug("erom: master wrapper %d " + * "has %d descriptors\n", i, j); */ + break; + } else { + if (i == 0 && j == 0) + core->wrap = tmp; + } + } + } + + /* get & parse slave wrappers */ + for (i = 0; i < wrappers[1]; i++) { + u8 hack = (ports[1] == 1) ? 0 : 1; + for (j = 0; ; j++) { + tmp = bcma_erom_get_addr_desc(bus, &eromptr, + SCAN_ADDR_TYPE_SWRAP, i + hack); + if (tmp < 0) { + /* no more entries for port _i_ */ + /* pr_debug("erom: master wrapper %d " + * has %d descriptors\n", i, j); */ + break; + } else { + if (wrappers[0] == 0 && !i && !j) + core->wrap = tmp; + } + } + } + + pr_info("Core %d found: %s " + "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n", + bus->nr_cores, bcma_device_name(&core->id), + core->id.manuf, core->id.id, core->id.rev, + core->id.class); + + core->core_index = bus->nr_cores++; + list_add(&core->list, &bus->cores); + continue; +out: + return err; + } + + return 0; +} diff --git a/drivers/bcma/scan.h b/drivers/bcma/scan.h new file mode 100644 index 000000000000..113e6a66884c --- /dev/null +++ b/drivers/bcma/scan.h @@ -0,0 +1,56 @@ +#ifndef BCMA_SCAN_H_ +#define BCMA_SCAN_H_ + +#define BCMA_ADDR_BASE 0x18000000 +#define BCMA_WRAP_BASE 0x18100000 + +#define SCAN_ER_VALID 0x00000001 +#define SCAN_ER_TAGX 0x00000006 /* we have to ignore 0x8 bit when checking tag for SCAN_ER_TAG_ADDR */ +#define SCAN_ER_TAG 0x0000000E +#define SCAN_ER_TAG_CI 0x00000000 +#define SCAN_ER_TAG_MP 0x00000002 +#define SCAN_ER_TAG_ADDR 0x00000004 +#define SCAN_ER_TAG_END 0x0000000E +#define SCAN_ER_BAD 0xFFFFFFFF + +#define SCAN_CIA_CLASS 0x000000F0 +#define SCAN_CIA_CLASS_SHIFT 4 +#define SCAN_CIA_ID 0x000FFF00 +#define SCAN_CIA_ID_SHIFT 8 +#define SCAN_CIA_MANUF 0xFFF00000 +#define SCAN_CIA_MANUF_SHIFT 20 + +#define SCAN_CIB_NMP 0x000001F0 +#define SCAN_CIB_NMP_SHIFT 4 +#define SCAN_CIB_NSP 0x00003E00 +#define SCAN_CIB_NSP_SHIFT 9 +#define SCAN_CIB_NMW 0x0007C000 +#define SCAN_CIB_NMW_SHIFT 14 +#define SCAN_CIB_NSW 0x00F80000 +#define SCAN_CIB_NSW_SHIFT 17 +#define SCAN_CIB_REV 0xFF000000 +#define SCAN_CIB_REV_SHIFT 24 + +#define SCAN_ADDR_AG32 0x00000008 +#define SCAN_ADDR_SZ 0x00000030 +#define SCAN_ADDR_SZ_SHIFT 4 +#define SCAN_ADDR_SZ_4K 0x00000000 +#define SCAN_ADDR_SZ_8K 0x00000010 +#define SCAN_ADDR_SZ_16K 0x00000020 +#define SCAN_ADDR_SZ_SZD 0x00000030 +#define SCAN_ADDR_TYPE 0x000000C0 +#define SCAN_ADDR_TYPE_SLAVE 0x00000000 +#define SCAN_ADDR_TYPE_BRIDGE 0x00000040 +#define SCAN_ADDR_TYPE_SWRAP 0x00000080 +#define SCAN_ADDR_TYPE_MWRAP 0x000000C0 +#define SCAN_ADDR_PORT 0x00000F00 +#define SCAN_ADDR_PORT_SHIFT 8 +#define SCAN_ADDR_ADDR 0xFFFFF000 + +#define SCAN_ADDR_SZ_BASE 0x00001000 /* 4KB */ + +#define SCAN_SIZE_SZ_ALIGN 0x00000FFF +#define SCAN_SIZE_SZ 0xFFFFF000 +#define SCAN_SIZE_SG32 0x00000008 + +#endif /* BCMA_SCAN_H_ */ diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h new file mode 100644 index 000000000000..08763e4e848f --- /dev/null +++ b/include/linux/bcma/bcma.h @@ -0,0 +1,224 @@ +#ifndef LINUX_BCMA_H_ +#define LINUX_BCMA_H_ + +#include +#include + +#include +#include + +#include "bcma_regs.h" + +struct bcma_device; +struct bcma_bus; + +enum bcma_hosttype { + BCMA_HOSTTYPE_NONE, + BCMA_HOSTTYPE_PCI, + BCMA_HOSTTYPE_SDIO, +}; + +struct bcma_chipinfo { + u16 id; + u8 rev; + u8 pkg; +}; + +struct bcma_host_ops { + u8 (*read8)(struct bcma_device *core, u16 offset); + u16 (*read16)(struct bcma_device *core, u16 offset); + u32 (*read32)(struct bcma_device *core, u16 offset); + void (*write8)(struct bcma_device *core, u16 offset, u8 value); + void (*write16)(struct bcma_device *core, u16 offset, u16 value); + void (*write32)(struct bcma_device *core, u16 offset, u32 value); + /* Agent ops */ + u32 (*aread32)(struct bcma_device *core, u16 offset); + void (*awrite32)(struct bcma_device *core, u16 offset, u32 value); +}; + +/* Core manufacturers */ +#define BCMA_MANUF_ARM 0x43B +#define BCMA_MANUF_MIPS 0x4A7 +#define BCMA_MANUF_BCM 0x4BF + +/* Core class values. */ +#define BCMA_CL_SIM 0x0 +#define BCMA_CL_EROM 0x1 +#define BCMA_CL_CORESIGHT 0x9 +#define BCMA_CL_VERIF 0xB +#define BCMA_CL_OPTIMO 0xD +#define BCMA_CL_GEN 0xE +#define BCMA_CL_PRIMECELL 0xF + +/* Core-ID values. */ +#define BCMA_CORE_OOB_ROUTER 0x367 /* Out of band */ +#define BCMA_CORE_INVALID 0x700 +#define BCMA_CORE_CHIPCOMMON 0x800 +#define BCMA_CORE_ILINE20 0x801 +#define BCMA_CORE_SRAM 0x802 +#define BCMA_CORE_SDRAM 0x803 +#define BCMA_CORE_PCI 0x804 +#define BCMA_CORE_MIPS 0x805 +#define BCMA_CORE_ETHERNET 0x806 +#define BCMA_CORE_V90 0x807 +#define BCMA_CORE_USB11_HOSTDEV 0x808 +#define BCMA_CORE_ADSL 0x809 +#define BCMA_CORE_ILINE100 0x80A +#define BCMA_CORE_IPSEC 0x80B +#define BCMA_CORE_UTOPIA 0x80C +#define BCMA_CORE_PCMCIA 0x80D +#define BCMA_CORE_INTERNAL_MEM 0x80E +#define BCMA_CORE_MEMC_SDRAM 0x80F +#define BCMA_CORE_OFDM 0x810 +#define BCMA_CORE_EXTIF 0x811 +#define BCMA_CORE_80211 0x812 +#define BCMA_CORE_PHY_A 0x813 +#define BCMA_CORE_PHY_B 0x814 +#define BCMA_CORE_PHY_G 0x815 +#define BCMA_CORE_MIPS_3302 0x816 +#define BCMA_CORE_USB11_HOST 0x817 +#define BCMA_CORE_USB11_DEV 0x818 +#define BCMA_CORE_USB20_HOST 0x819 +#define BCMA_CORE_USB20_DEV 0x81A +#define BCMA_CORE_SDIO_HOST 0x81B +#define BCMA_CORE_ROBOSWITCH 0x81C +#define BCMA_CORE_PARA_ATA 0x81D +#define BCMA_CORE_SATA_XORDMA 0x81E +#define BCMA_CORE_ETHERNET_GBIT 0x81F +#define BCMA_CORE_PCIE 0x820 +#define BCMA_CORE_PHY_N 0x821 +#define BCMA_CORE_SRAM_CTL 0x822 +#define BCMA_CORE_MINI_MACPHY 0x823 +#define BCMA_CORE_ARM_1176 0x824 +#define BCMA_CORE_ARM_7TDMI 0x825 +#define BCMA_CORE_PHY_LP 0x826 +#define BCMA_CORE_PMU 0x827 +#define BCMA_CORE_PHY_SSN 0x828 +#define BCMA_CORE_SDIO_DEV 0x829 +#define BCMA_CORE_ARM_CM3 0x82A +#define BCMA_CORE_PHY_HT 0x82B +#define BCMA_CORE_MIPS_74K 0x82C +#define BCMA_CORE_MAC_GBIT 0x82D +#define BCMA_CORE_DDR12_MEM_CTL 0x82E +#define BCMA_CORE_PCIE_RC 0x82F /* PCIe Root Complex */ +#define BCMA_CORE_OCP_OCP_BRIDGE 0x830 +#define BCMA_CORE_SHARED_COMMON 0x831 +#define BCMA_CORE_OCP_AHB_BRIDGE 0x832 +#define BCMA_CORE_SPI_HOST 0x833 +#define BCMA_CORE_I2S 0x834 +#define BCMA_CORE_SDR_DDR1_MEM_CTL 0x835 /* SDR/DDR1 memory controller core */ +#define BCMA_CORE_SHIM 0x837 /* SHIM component in ubus/6362 */ +#define BCMA_CORE_DEFAULT 0xFFF + +#define BCMA_MAX_NR_CORES 16 + +struct bcma_device { + struct bcma_bus *bus; + struct bcma_device_id id; + + struct device dev; + bool dev_registered; + + u8 core_index; + + u32 addr; + u32 wrap; + + void *drvdata; + struct list_head list; +}; + +static inline void *bcma_get_drvdata(struct bcma_device *core) +{ + return core->drvdata; +} +static inline void bcma_set_drvdata(struct bcma_device *core, void *drvdata) +{ + core->drvdata = drvdata; +} + +struct bcma_driver { + const char *name; + const struct bcma_device_id *id_table; + + int (*probe)(struct bcma_device *dev); + void (*remove)(struct bcma_device *dev); + int (*suspend)(struct bcma_device *dev, pm_message_t state); + int (*resume)(struct bcma_device *dev); + void (*shutdown)(struct bcma_device *dev); + + struct device_driver drv; +}; +extern +int __bcma_driver_register(struct bcma_driver *drv, struct module *owner); +static inline int bcma_driver_register(struct bcma_driver *drv) +{ + return __bcma_driver_register(drv, THIS_MODULE); +} +extern void bcma_driver_unregister(struct bcma_driver *drv); + +struct bcma_bus { + /* The MMIO area. */ + void __iomem *mmio; + + const struct bcma_host_ops *ops; + + enum bcma_hosttype hosttype; + union { + /* Pointer to the PCI bus (only for BCMA_HOSTTYPE_PCI) */ + struct pci_dev *host_pci; + /* Pointer to the SDIO device (only for BCMA_HOSTTYPE_SDIO) */ + struct sdio_func *host_sdio; + }; + + struct bcma_chipinfo chipinfo; + + struct bcma_device *mapped_core; + struct list_head cores; + u8 nr_cores; + + struct bcma_drv_cc drv_cc; + struct bcma_drv_pci drv_pci; +}; + +extern inline u32 bcma_read8(struct bcma_device *core, u16 offset) +{ + return core->bus->ops->read8(core, offset); +} +extern inline u32 bcma_read16(struct bcma_device *core, u16 offset) +{ + return core->bus->ops->read16(core, offset); +} +extern inline u32 bcma_read32(struct bcma_device *core, u16 offset) +{ + return core->bus->ops->read32(core, offset); +} +extern inline +void bcma_write8(struct bcma_device *core, u16 offset, u32 value) +{ + core->bus->ops->write8(core, offset, value); +} +extern inline +void bcma_write16(struct bcma_device *core, u16 offset, u32 value) +{ + core->bus->ops->write16(core, offset, value); +} +extern inline +void bcma_write32(struct bcma_device *core, u16 offset, u32 value) +{ + core->bus->ops->write32(core, offset, value); +} +extern inline u32 bcma_aread32(struct bcma_device *core, u16 offset) +{ + return core->bus->ops->aread32(core, offset); +} +extern inline +void bcma_awrite32(struct bcma_device *core, u16 offset, u32 value) +{ + core->bus->ops->awrite32(core, offset, value); +} + +extern bool bcma_core_is_enabled(struct bcma_device *core); +extern int bcma_core_enable(struct bcma_device *core, u32 flags); + +#endif /* LINUX_BCMA_H_ */ diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h new file mode 100644 index 000000000000..4f8fd6a4c1e6 --- /dev/null +++ b/include/linux/bcma/bcma_driver_chipcommon.h @@ -0,0 +1,297 @@ +#ifndef LINUX_BCMA_DRIVER_CC_H_ +#define LINUX_BCMA_DRIVER_CC_H_ + +/** ChipCommon core registers. **/ +#define BCMA_CC_ID 0x0000 +#define BCMA_CC_ID_ID 0x0000FFFF +#define BCMA_CC_ID_ID_SHIFT 0 +#define BCMA_CC_ID_REV 0x000F0000 +#define BCMA_CC_ID_REV_SHIFT 16 +#define BCMA_CC_ID_PKG 0x00F00000 +#define BCMA_CC_ID_PKG_SHIFT 20 +#define BCMA_CC_ID_NRCORES 0x0F000000 +#define BCMA_CC_ID_NRCORES_SHIFT 24 +#define BCMA_CC_ID_TYPE 0xF0000000 +#define BCMA_CC_ID_TYPE_SHIFT 28 +#define BCMA_CC_CAP 0x0004 /* Capabilities */ +#define BCMA_CC_CAP_NRUART 0x00000003 /* # of UARTs */ +#define BCMA_CC_CAP_MIPSEB 0x00000004 /* MIPS in BigEndian Mode */ +#define BCMA_CC_CAP_UARTCLK 0x00000018 /* UART clock select */ +#define BCMA_CC_CAP_UARTCLK_INT 0x00000008 /* UARTs are driven by internal divided clock */ +#define BCMA_CC_CAP_UARTGPIO 0x00000020 /* UARTs on GPIO 15-12 */ +#define BCMA_CC_CAP_EXTBUS 0x000000C0 /* External buses present */ +#define BCMA_CC_CAP_FLASHT 0x00000700 /* Flash Type */ +#define BCMA_CC_FLASHT_NONE 0x00000000 /* No flash */ +#define BCMA_CC_FLASHT_STSER 0x00000100 /* ST serial flash */ +#define BCMA_CC_FLASHT_ATSER 0x00000200 /* Atmel serial flash */ +#define BCMA_CC_FLASHT_PARA 0x00000700 /* Parallel flash */ +#define BCMA_CC_CAP_PLLT 0x00038000 /* PLL Type */ +#define BCMA_PLLTYPE_NONE 0x00000000 +#define BCMA_PLLTYPE_1 0x00010000 /* 48Mhz base, 3 dividers */ +#define BCMA_PLLTYPE_2 0x00020000 /* 48Mhz, 4 dividers */ +#define BCMA_PLLTYPE_3 0x00030000 /* 25Mhz, 2 dividers */ +#define BCMA_PLLTYPE_4 0x00008000 /* 48Mhz, 4 dividers */ +#define BCMA_PLLTYPE_5 0x00018000 /* 25Mhz, 4 dividers */ +#define BCMA_PLLTYPE_6 0x00028000 /* 100/200 or 120/240 only */ +#define BCMA_PLLTYPE_7 0x00038000 /* 25Mhz, 4 dividers */ +#define BCMA_CC_CAP_PCTL 0x00040000 /* Power Control */ +#define BCMA_CC_CAP_OTPS 0x00380000 /* OTP size */ +#define BCMA_CC_CAP_OTPS_SHIFT 19 +#define BCMA_CC_CAP_OTPS_BASE 5 +#define BCMA_CC_CAP_JTAGM 0x00400000 /* JTAG master present */ +#define BCMA_CC_CAP_BROM 0x00800000 /* Internal boot ROM active */ +#define BCMA_CC_CAP_64BIT 0x08000000 /* 64-bit Backplane */ +#define BCMA_CC_CAP_PMU 0x10000000 /* PMU available (rev >= 20) */ +#define BCMA_CC_CAP_ECI 0x20000000 /* ECI available (rev >= 20) */ +#define BCMA_CC_CAP_SPROM 0x40000000 /* SPROM present */ +#define BCMA_CC_CORECTL 0x0008 +#define BCMA_CC_CORECTL_UARTCLK0 0x00000001 /* Drive UART with internal clock */ +#define BCMA_CC_CORECTL_SE 0x00000002 /* sync clk out enable (corerev >= 3) */ +#define BCMA_CC_CORECTL_UARTCLKEN 0x00000008 /* UART clock enable (rev >= 21) */ +#define BCMA_CC_BIST 0x000C +#define BCMA_CC_OTPS 0x0010 /* OTP status */ +#define BCMA_CC_OTPS_PROGFAIL 0x80000000 +#define BCMA_CC_OTPS_PROTECT 0x00000007 +#define BCMA_CC_OTPS_HW_PROTECT 0x00000001 +#define BCMA_CC_OTPS_SW_PROTECT 0x00000002 +#define BCMA_CC_OTPS_CID_PROTECT 0x00000004 +#define BCMA_CC_OTPC 0x0014 /* OTP control */ +#define BCMA_CC_OTPC_RECWAIT 0xFF000000 +#define BCMA_CC_OTPC_PROGWAIT 0x00FFFF00 +#define BCMA_CC_OTPC_PRW_SHIFT 8 +#define BCMA_CC_OTPC_MAXFAIL 0x00000038 +#define BCMA_CC_OTPC_VSEL 0x00000006 +#define BCMA_CC_OTPC_SELVL 0x00000001 +#define BCMA_CC_OTPP 0x0018 /* OTP prog */ +#define BCMA_CC_OTPP_COL 0x000000FF +#define BCMA_CC_OTPP_ROW 0x0000FF00 +#define BCMA_CC_OTPP_ROW_SHIFT 8 +#define BCMA_CC_OTPP_READERR 0x10000000 +#define BCMA_CC_OTPP_VALUE 0x20000000 +#define BCMA_CC_OTPP_READ 0x40000000 +#define BCMA_CC_OTPP_START 0x80000000 +#define BCMA_CC_OTPP_BUSY 0x80000000 +#define BCMA_CC_IRQSTAT 0x0020 +#define BCMA_CC_IRQMASK 0x0024 +#define BCMA_CC_IRQ_GPIO 0x00000001 /* gpio intr */ +#define BCMA_CC_IRQ_EXT 0x00000002 /* ro: ext intr pin (corerev >= 3) */ +#define BCMA_CC_IRQ_WDRESET 0x80000000 /* watchdog reset occurred */ +#define BCMA_CC_CHIPCTL 0x0028 /* Rev >= 11 only */ +#define BCMA_CC_CHIPSTAT 0x002C /* Rev >= 11 only */ +#define BCMA_CC_JCMD 0x0030 /* Rev >= 10 only */ +#define BCMA_CC_JCMD_START 0x80000000 +#define BCMA_CC_JCMD_BUSY 0x80000000 +#define BCMA_CC_JCMD_PAUSE 0x40000000 +#define BCMA_CC_JCMD0_ACC_MASK 0x0000F000 +#define BCMA_CC_JCMD0_ACC_IRDR 0x00000000 +#define BCMA_CC_JCMD0_ACC_DR 0x00001000 +#define BCMA_CC_JCMD0_ACC_IR 0x00002000 +#define BCMA_CC_JCMD0_ACC_RESET 0x00003000 +#define BCMA_CC_JCMD0_ACC_IRPDR 0x00004000 +#define BCMA_CC_JCMD0_ACC_PDR 0x00005000 +#define BCMA_CC_JCMD0_IRW_MASK 0x00000F00 +#define BCMA_CC_JCMD_ACC_MASK 0x000F0000 /* Changes for corerev 11 */ +#define BCMA_CC_JCMD_ACC_IRDR 0x00000000 +#define BCMA_CC_JCMD_ACC_DR 0x00010000 +#define BCMA_CC_JCMD_ACC_IR 0x00020000 +#define BCMA_CC_JCMD_ACC_RESET 0x00030000 +#define BCMA_CC_JCMD_ACC_IRPDR 0x00040000 +#define BCMA_CC_JCMD_ACC_PDR 0x00050000 +#define BCMA_CC_JCMD_IRW_MASK 0x00001F00 +#define BCMA_CC_JCMD_IRW_SHIFT 8 +#define BCMA_CC_JCMD_DRW_MASK 0x0000003F +#define BCMA_CC_JIR 0x0034 /* Rev >= 10 only */ +#define BCMA_CC_JDR 0x0038 /* Rev >= 10 only */ +#define BCMA_CC_JCTL 0x003C /* Rev >= 10 only */ +#define BCMA_CC_JCTL_FORCE_CLK 4 /* Force clock */ +#define BCMA_CC_JCTL_EXT_EN 2 /* Enable external targets */ +#define BCMA_CC_JCTL_EN 1 /* Enable Jtag master */ +#define BCMA_CC_FLASHCTL 0x0040 +#define BCMA_CC_FLASHCTL_START 0x80000000 +#define BCMA_CC_FLASHCTL_BUSY BCMA_CC_FLASHCTL_START +#define BCMA_CC_FLASHADDR 0x0044 +#define BCMA_CC_FLASHDATA 0x0048 +#define BCMA_CC_BCAST_ADDR 0x0050 +#define BCMA_CC_BCAST_DATA 0x0054 +#define BCMA_CC_GPIOIN 0x0060 +#define BCMA_CC_GPIOOUT 0x0064 +#define BCMA_CC_GPIOOUTEN 0x0068 +#define BCMA_CC_GPIOCTL 0x006C +#define BCMA_CC_GPIOPOL 0x0070 +#define BCMA_CC_GPIOIRQ 0x0074 +#define BCMA_CC_WATCHDOG 0x0080 +#define BCMA_CC_GPIOTIMER 0x0088 /* LED powersave (corerev >= 16) */ +#define BCMA_CC_GPIOTIMER_ONTIME_SHIFT 16 +#define BCMA_CC_GPIOTOUTM 0x008C /* LED powersave (corerev >= 16) */ +#define BCMA_CC_CLOCK_N 0x0090 +#define BCMA_CC_CLOCK_SB 0x0094 +#define BCMA_CC_CLOCK_PCI 0x0098 +#define BCMA_CC_CLOCK_M2 0x009C +#define BCMA_CC_CLOCK_MIPS 0x00A0 +#define BCMA_CC_CLKDIV 0x00A4 /* Rev >= 3 only */ +#define BCMA_CC_CLKDIV_SFLASH 0x0F000000 +#define BCMA_CC_CLKDIV_SFLASH_SHIFT 24 +#define BCMA_CC_CLKDIV_OTP 0x000F0000 +#define BCMA_CC_CLKDIV_OTP_SHIFT 16 +#define BCMA_CC_CLKDIV_JTAG 0x00000F00 +#define BCMA_CC_CLKDIV_JTAG_SHIFT 8 +#define BCMA_CC_CLKDIV_UART 0x000000FF +#define BCMA_CC_CAP_EXT 0x00AC /* Capabilities */ +#define BCMA_CC_PLLONDELAY 0x00B0 /* Rev >= 4 only */ +#define BCMA_CC_FREFSELDELAY 0x00B4 /* Rev >= 4 only */ +#define BCMA_CC_SLOWCLKCTL 0x00B8 /* 6 <= Rev <= 9 only */ +#define BCMA_CC_SLOWCLKCTL_SRC 0x00000007 /* slow clock source mask */ +#define BCMA_CC_SLOWCLKCTL_SRC_LPO 0x00000000 /* source of slow clock is LPO */ +#define BCMA_CC_SLOWCLKCTL_SRC_XTAL 0x00000001 /* source of slow clock is crystal */ +#define BCMA_CC_SLOECLKCTL_SRC_PCI 0x00000002 /* source of slow clock is PCI */ +#define BCMA_CC_SLOWCLKCTL_LPOFREQ 0x00000200 /* LPOFreqSel, 1: 160Khz, 0: 32KHz */ +#define BCMA_CC_SLOWCLKCTL_LPOPD 0x00000400 /* LPOPowerDown, 1: LPO is disabled, 0: LPO is enabled */ +#define BCMA_CC_SLOWCLKCTL_FSLOW 0x00000800 /* ForceSlowClk, 1: sb/cores running on slow clock, 0: power logic control */ +#define BCMA_CC_SLOWCLKCTL_IPLL 0x00001000 /* IgnorePllOffReq, 1/0: power logic ignores/honors PLL clock disable requests from core */ +#define BCMA_CC_SLOWCLKCTL_ENXTAL 0x00002000 /* XtalControlEn, 1/0: power logic does/doesn't disable crystal when appropriate */ +#define BCMA_CC_SLOWCLKCTL_XTALPU 0x00004000 /* XtalPU (RO), 1/0: crystal running/disabled */ +#define BCMA_CC_SLOWCLKCTL_CLKDIV 0xFFFF0000 /* ClockDivider (SlowClk = 1/(4+divisor)) */ +#define BCMA_CC_SLOWCLKCTL_CLKDIV_SHIFT 16 +#define BCMA_CC_SYSCLKCTL 0x00C0 /* Rev >= 3 only */ +#define BCMA_CC_SYSCLKCTL_IDLPEN 0x00000001 /* ILPen: Enable Idle Low Power */ +#define BCMA_CC_SYSCLKCTL_ALPEN 0x00000002 /* ALPen: Enable Active Low Power */ +#define BCMA_CC_SYSCLKCTL_PLLEN 0x00000004 /* ForcePLLOn */ +#define BCMA_CC_SYSCLKCTL_FORCEALP 0x00000008 /* Force ALP (or HT if ALPen is not set */ +#define BCMA_CC_SYSCLKCTL_FORCEHT 0x00000010 /* Force HT */ +#define BCMA_CC_SYSCLKCTL_CLKDIV 0xFFFF0000 /* ClkDiv (ILP = 1/(4+divisor)) */ +#define BCMA_CC_SYSCLKCTL_CLKDIV_SHIFT 16 +#define BCMA_CC_CLKSTSTR 0x00C4 /* Rev >= 3 only */ +#define BCMA_CC_EROM 0x00FC +#define BCMA_CC_PCMCIA_CFG 0x0100 +#define BCMA_CC_PCMCIA_MEMWAIT 0x0104 +#define BCMA_CC_PCMCIA_ATTRWAIT 0x0108 +#define BCMA_CC_PCMCIA_IOWAIT 0x010C +#define BCMA_CC_IDE_CFG 0x0110 +#define BCMA_CC_IDE_MEMWAIT 0x0114 +#define BCMA_CC_IDE_ATTRWAIT 0x0118 +#define BCMA_CC_IDE_IOWAIT 0x011C +#define BCMA_CC_PROG_CFG 0x0120 +#define BCMA_CC_PROG_WAITCNT 0x0124 +#define BCMA_CC_FLASH_CFG 0x0128 +#define BCMA_CC_FLASH_WAITCNT 0x012C +#define BCMA_CC_CLKCTLST 0x01E0 /* Clock control and status (rev >= 20) */ +#define BCMA_CC_CLKCTLST_FORCEALP 0x00000001 /* Force ALP request */ +#define BCMA_CC_CLKCTLST_FORCEHT 0x00000002 /* Force HT request */ +#define BCMA_CC_CLKCTLST_FORCEILP 0x00000004 /* Force ILP request */ +#define BCMA_CC_CLKCTLST_HAVEALPREQ 0x00000008 /* ALP available request */ +#define BCMA_CC_CLKCTLST_HAVEHTREQ 0x00000010 /* HT available request */ +#define BCMA_CC_CLKCTLST_HWCROFF 0x00000020 /* Force HW clock request off */ +#define BCMA_CC_CLKCTLST_HAVEHT 0x00010000 /* HT available */ +#define BCMA_CC_CLKCTLST_HAVEALP 0x00020000 /* APL available */ +#define BCMA_CC_HW_WORKAROUND 0x01E4 /* Hardware workaround (rev >= 20) */ +#define BCMA_CC_UART0_DATA 0x0300 +#define BCMA_CC_UART0_IMR 0x0304 +#define BCMA_CC_UART0_FCR 0x0308 +#define BCMA_CC_UART0_LCR 0x030C +#define BCMA_CC_UART0_MCR 0x0310 +#define BCMA_CC_UART0_LSR 0x0314 +#define BCMA_CC_UART0_MSR 0x0318 +#define BCMA_CC_UART0_SCRATCH 0x031C +#define BCMA_CC_UART1_DATA 0x0400 +#define BCMA_CC_UART1_IMR 0x0404 +#define BCMA_CC_UART1_FCR 0x0408 +#define BCMA_CC_UART1_LCR 0x040C +#define BCMA_CC_UART1_MCR 0x0410 +#define BCMA_CC_UART1_LSR 0x0414 +#define BCMA_CC_UART1_MSR 0x0418 +#define BCMA_CC_UART1_SCRATCH 0x041C +/* PMU registers (rev >= 20) */ +#define BCMA_CC_PMU_CTL 0x0600 /* PMU control */ +#define BCMA_CC_PMU_CTL_ILP_DIV 0xFFFF0000 /* ILP div mask */ +#define BCMA_CC_PMU_CTL_ILP_DIV_SHIFT 16 +#define BCMA_CC_PMU_CTL_NOILPONW 0x00000200 /* No ILP on wait */ +#define BCMA_CC_PMU_CTL_HTREQEN 0x00000100 /* HT req enable */ +#define BCMA_CC_PMU_CTL_ALPREQEN 0x00000080 /* ALP req enable */ +#define BCMA_CC_PMU_CTL_XTALFREQ 0x0000007C /* Crystal freq */ +#define BCMA_CC_PMU_CTL_XTALFREQ_SHIFT 2 +#define BCMA_CC_PMU_CTL_ILPDIVEN 0x00000002 /* ILP div enable */ +#define BCMA_CC_PMU_CTL_LPOSEL 0x00000001 /* LPO sel */ +#define BCMA_CC_PMU_CAP 0x0604 /* PMU capabilities */ +#define BCMA_CC_PMU_CAP_REVISION 0x000000FF /* Revision mask */ +#define BCMA_CC_PMU_STAT 0x0608 /* PMU status */ +#define BCMA_CC_PMU_STAT_INTPEND 0x00000040 /* Interrupt pending */ +#define BCMA_CC_PMU_STAT_SBCLKST 0x00000030 /* Backplane clock status? */ +#define BCMA_CC_PMU_STAT_HAVEALP 0x00000008 /* ALP available */ +#define BCMA_CC_PMU_STAT_HAVEHT 0x00000004 /* HT available */ +#define BCMA_CC_PMU_STAT_RESINIT 0x00000003 /* Res init */ +#define BCMA_CC_PMU_RES_STAT 0x060C /* PMU res status */ +#define BCMA_CC_PMU_RES_PEND 0x0610 /* PMU res pending */ +#define BCMA_CC_PMU_TIMER 0x0614 /* PMU timer */ +#define BCMA_CC_PMU_MINRES_MSK 0x0618 /* PMU min res mask */ +#define BCMA_CC_PMU_MAXRES_MSK 0x061C /* PMU max res mask */ +#define BCMA_CC_PMU_RES_TABSEL 0x0620 /* PMU res table sel */ +#define BCMA_CC_PMU_RES_DEPMSK 0x0624 /* PMU res dep mask */ +#define BCMA_CC_PMU_RES_UPDNTM 0x0628 /* PMU res updown timer */ +#define BCMA_CC_PMU_RES_TIMER 0x062C /* PMU res timer */ +#define BCMA_CC_PMU_CLKSTRETCH 0x0630 /* PMU clockstretch */ +#define BCMA_CC_PMU_WATCHDOG 0x0634 /* PMU watchdog */ +#define BCMA_CC_PMU_RES_REQTS 0x0640 /* PMU res req timer sel */ +#define BCMA_CC_PMU_RES_REQT 0x0644 /* PMU res req timer */ +#define BCMA_CC_PMU_RES_REQM 0x0648 /* PMU res req mask */ +#define BCMA_CC_CHIPCTL_ADDR 0x0650 +#define BCMA_CC_CHIPCTL_DATA 0x0654 +#define BCMA_CC_REGCTL_ADDR 0x0658 +#define BCMA_CC_REGCTL_DATA 0x065C +#define BCMA_CC_PLLCTL_ADDR 0x0660 +#define BCMA_CC_PLLCTL_DATA 0x0664 + +/* Data for the PMU, if available. + * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU) + */ +struct bcma_chipcommon_pmu { + u8 rev; /* PMU revision */ + u32 crystalfreq; /* The active crystal frequency (in kHz) */ +}; + +struct bcma_drv_cc { + struct bcma_device *core; + u32 status; + u32 capabilities; + u32 capabilities_ext; + /* Fast Powerup Delay constant */ + u16 fast_pwrup_delay; + struct bcma_chipcommon_pmu pmu; +}; + +/* Register access */ +#define bcma_cc_read32(cc, offset) \ + bcma_read32((cc)->core, offset) +#define bcma_cc_write32(cc, offset, val) \ + bcma_write32((cc)->core, offset, val) + +#define bcma_cc_mask32(cc, offset, mask) \ + bcma_cc_write32(cc, offset, bcma_cc_read32(cc, offset) & (mask)) +#define bcma_cc_set32(cc, offset, set) \ + bcma_cc_write32(cc, offset, bcma_cc_read32(cc, offset) | (set)) +#define bcma_cc_maskset32(cc, offset, mask, set) \ + bcma_cc_write32(cc, offset, (bcma_cc_read32(cc, offset) & (mask)) | (set)) + +extern void bcma_core_chipcommon_init(struct bcma_drv_cc *cc); + +extern void bcma_chipco_suspend(struct bcma_drv_cc *cc); +extern void bcma_chipco_resume(struct bcma_drv_cc *cc); + +extern void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, + u32 ticks); + +void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value); + +u32 bcma_chipco_irq_status(struct bcma_drv_cc *cc, u32 mask); + +/* Chipcommon GPIO pin access. */ +u32 bcma_chipco_gpio_in(struct bcma_drv_cc *cc, u32 mask); +u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value); +u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value); +u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value); +u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value); +u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value); + +/* PMU support */ +extern void bcma_pmu_init(struct bcma_drv_cc *cc); + +#endif /* LINUX_BCMA_DRIVER_CC_H_ */ diff --git a/include/linux/bcma/bcma_driver_pci.h b/include/linux/bcma/bcma_driver_pci.h new file mode 100644 index 000000000000..b7e191cf00ec --- /dev/null +++ b/include/linux/bcma/bcma_driver_pci.h @@ -0,0 +1,89 @@ +#ifndef LINUX_BCMA_DRIVER_PCI_H_ +#define LINUX_BCMA_DRIVER_PCI_H_ + +#include + +struct pci_dev; + +/** PCI core registers. **/ +#define BCMA_CORE_PCI_CTL 0x0000 /* PCI Control */ +#define BCMA_CORE_PCI_CTL_RST_OE 0x00000001 /* PCI_RESET Output Enable */ +#define BCMA_CORE_PCI_CTL_RST 0x00000002 /* PCI_RESET driven out to pin */ +#define BCMA_CORE_PCI_CTL_CLK_OE 0x00000004 /* Clock gate Output Enable */ +#define BCMA_CORE_PCI_CTL_CLK 0x00000008 /* Gate for clock driven out to pin */ +#define BCMA_CORE_PCI_ARBCTL 0x0010 /* PCI Arbiter Control */ +#define BCMA_CORE_PCI_ARBCTL_INTERN 0x00000001 /* Use internal arbiter */ +#define BCMA_CORE_PCI_ARBCTL_EXTERN 0x00000002 /* Use external arbiter */ +#define BCMA_CORE_PCI_ARBCTL_PARKID 0x00000006 /* Mask, selects which agent is parked on an idle bus */ +#define BCMA_CORE_PCI_ARBCTL_PARKID_LAST 0x00000000 /* Last requestor */ +#define BCMA_CORE_PCI_ARBCTL_PARKID_4710 0x00000002 /* 4710 */ +#define BCMA_CORE_PCI_ARBCTL_PARKID_EXT0 0x00000004 /* External requestor 0 */ +#define BCMA_CORE_PCI_ARBCTL_PARKID_EXT1 0x00000006 /* External requestor 1 */ +#define BCMA_CORE_PCI_ISTAT 0x0020 /* Interrupt status */ +#define BCMA_CORE_PCI_ISTAT_INTA 0x00000001 /* PCI INTA# */ +#define BCMA_CORE_PCI_ISTAT_INTB 0x00000002 /* PCI INTB# */ +#define BCMA_CORE_PCI_ISTAT_SERR 0x00000004 /* PCI SERR# (write to clear) */ +#define BCMA_CORE_PCI_ISTAT_PERR 0x00000008 /* PCI PERR# (write to clear) */ +#define BCMA_CORE_PCI_ISTAT_PME 0x00000010 /* PCI PME# */ +#define BCMA_CORE_PCI_IMASK 0x0024 /* Interrupt mask */ +#define BCMA_CORE_PCI_IMASK_INTA 0x00000001 /* PCI INTA# */ +#define BCMA_CORE_PCI_IMASK_INTB 0x00000002 /* PCI INTB# */ +#define BCMA_CORE_PCI_IMASK_SERR 0x00000004 /* PCI SERR# */ +#define BCMA_CORE_PCI_IMASK_PERR 0x00000008 /* PCI PERR# */ +#define BCMA_CORE_PCI_IMASK_PME 0x00000010 /* PCI PME# */ +#define BCMA_CORE_PCI_MBOX 0x0028 /* Backplane to PCI Mailbox */ +#define BCMA_CORE_PCI_MBOX_F0_0 0x00000100 /* PCI function 0, INT 0 */ +#define BCMA_CORE_PCI_MBOX_F0_1 0x00000200 /* PCI function 0, INT 1 */ +#define BCMA_CORE_PCI_MBOX_F1_0 0x00000400 /* PCI function 1, INT 0 */ +#define BCMA_CORE_PCI_MBOX_F1_1 0x00000800 /* PCI function 1, INT 1 */ +#define BCMA_CORE_PCI_MBOX_F2_0 0x00001000 /* PCI function 2, INT 0 */ +#define BCMA_CORE_PCI_MBOX_F2_1 0x00002000 /* PCI function 2, INT 1 */ +#define BCMA_CORE_PCI_MBOX_F3_0 0x00004000 /* PCI function 3, INT 0 */ +#define BCMA_CORE_PCI_MBOX_F3_1 0x00008000 /* PCI function 3, INT 1 */ +#define BCMA_CORE_PCI_BCAST_ADDR 0x0050 /* Backplane Broadcast Address */ +#define BCMA_CORE_PCI_BCAST_ADDR_MASK 0x000000FF +#define BCMA_CORE_PCI_BCAST_DATA 0x0054 /* Backplane Broadcast Data */ +#define BCMA_CORE_PCI_GPIO_IN 0x0060 /* rev >= 2 only */ +#define BCMA_CORE_PCI_GPIO_OUT 0x0064 /* rev >= 2 only */ +#define BCMA_CORE_PCI_GPIO_ENABLE 0x0068 /* rev >= 2 only */ +#define BCMA_CORE_PCI_GPIO_CTL 0x006C /* rev >= 2 only */ +#define BCMA_CORE_PCI_SBTOPCI0 0x0100 /* Backplane to PCI translation 0 (sbtopci0) */ +#define BCMA_CORE_PCI_SBTOPCI0_MASK 0xFC000000 +#define BCMA_CORE_PCI_SBTOPCI1 0x0104 /* Backplane to PCI translation 1 (sbtopci1) */ +#define BCMA_CORE_PCI_SBTOPCI1_MASK 0xFC000000 +#define BCMA_CORE_PCI_SBTOPCI2 0x0108 /* Backplane to PCI translation 2 (sbtopci2) */ +#define BCMA_CORE_PCI_SBTOPCI2_MASK 0xC0000000 +#define BCMA_CORE_PCI_PCICFG0 0x0400 /* PCI config space 0 (rev >= 8) */ +#define BCMA_CORE_PCI_PCICFG1 0x0500 /* PCI config space 1 (rev >= 8) */ +#define BCMA_CORE_PCI_PCICFG2 0x0600 /* PCI config space 2 (rev >= 8) */ +#define BCMA_CORE_PCI_PCICFG3 0x0700 /* PCI config space 3 (rev >= 8) */ +#define BCMA_CORE_PCI_SPROM(wordoffset) (0x0800 + ((wordoffset) * 2)) /* SPROM shadow area (72 bytes) */ + +/* SBtoPCIx */ +#define BCMA_CORE_PCI_SBTOPCI_MEM 0x00000000 +#define BCMA_CORE_PCI_SBTOPCI_IO 0x00000001 +#define BCMA_CORE_PCI_SBTOPCI_CFG0 0x00000002 +#define BCMA_CORE_PCI_SBTOPCI_CFG1 0x00000003 +#define BCMA_CORE_PCI_SBTOPCI_PREF 0x00000004 /* Prefetch enable */ +#define BCMA_CORE_PCI_SBTOPCI_BURST 0x00000008 /* Burst enable */ +#define BCMA_CORE_PCI_SBTOPCI_MRM 0x00000020 /* Memory Read Multiple */ +#define BCMA_CORE_PCI_SBTOPCI_RC 0x00000030 /* Read Command mask (rev >= 11) */ +#define BCMA_CORE_PCI_SBTOPCI_RC_READ 0x00000000 /* Memory read */ +#define BCMA_CORE_PCI_SBTOPCI_RC_READL 0x00000010 /* Memory read line */ +#define BCMA_CORE_PCI_SBTOPCI_RC_READM 0x00000020 /* Memory read multiple */ + +/* PCIcore specific boardflags */ +#define BCMA_CORE_PCI_BFL_NOPCI 0x00000400 /* Board leaves PCI floating */ + +struct bcma_drv_pci { + struct bcma_device *core; + u8 setup_done:1; +}; + +/* Register access */ +#define pcicore_read32(pc, offset) bcma_read32((pc)->core, offset) +#define pcicore_write32(pc, offset, val) bcma_write32((pc)->core, offset, val) + +extern void bcma_core_pci_init(struct bcma_drv_pci *pc); + +#endif /* LINUX_BCMA_DRIVER_PCI_H_ */ diff --git a/include/linux/bcma/bcma_regs.h b/include/linux/bcma/bcma_regs.h new file mode 100644 index 000000000000..f82d88a960ce --- /dev/null +++ b/include/linux/bcma/bcma_regs.h @@ -0,0 +1,34 @@ +#ifndef LINUX_BCMA_REGS_H_ +#define LINUX_BCMA_REGS_H_ + +/* Agent registers (common for every core) */ +#define BCMA_IOCTL 0x0408 +#define BCMA_IOCTL_CLK 0x0001 +#define BCMA_IOCTL_FGC 0x0002 +#define BCMA_IOCTL_CORE_BITS 0x3FFC +#define BCMA_IOCTL_PME_EN 0x4000 +#define BCMA_IOCTL_BIST_EN 0x8000 +#define BCMA_RESET_CTL 0x0800 +#define BCMA_RESET_CTL_RESET 0x0001 + +/* BCMA PCI config space registers. */ +#define BCMA_PCI_PMCSR 0x44 +#define BCMA_PCI_PE 0x100 +#define BCMA_PCI_BAR0_WIN 0x80 /* Backplane address space 0 */ +#define BCMA_PCI_BAR1_WIN 0x84 /* Backplane address space 1 */ +#define BCMA_PCI_SPROMCTL 0x88 /* SPROM control */ +#define BCMA_PCI_SPROMCTL_WE 0x10 /* SPROM write enable */ +#define BCMA_PCI_BAR1_CONTROL 0x8c /* Address space 1 burst control */ +#define BCMA_PCI_IRQS 0x90 /* PCI interrupts */ +#define BCMA_PCI_IRQMASK 0x94 /* PCI IRQ control and mask (pcirev >= 6 only) */ +#define BCMA_PCI_BACKPLANE_IRQS 0x98 /* Backplane Interrupts */ +#define BCMA_PCI_BAR0_WIN2 0xAC +#define BCMA_PCI_GPIO_IN 0xB0 /* GPIO Input (pcirev >= 3 only) */ +#define BCMA_PCI_GPIO_OUT 0xB4 /* GPIO Output (pcirev >= 3 only) */ +#define BCMA_PCI_GPIO_OUT_ENABLE 0xB8 /* GPIO Output Enable/Disable (pcirev >= 3 only) */ +#define BCMA_PCI_GPIO_SCS 0x10 /* PCI config space bit 4 for 4306c0 slow clock source */ +#define BCMA_PCI_GPIO_HWRAD 0x20 /* PCI config space GPIO 13 for hw radio disable */ +#define BCMA_PCI_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal powerup */ +#define BCMA_PCI_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL powerdown */ + +#endif /* LINUX_BCMA_REGS_H_ */ diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 48c007dae476..ae28e93fd072 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -382,6 +382,23 @@ struct ssb_device_id { #define SSB_ANY_ID 0xFFFF #define SSB_ANY_REV 0xFF +/* Broadcom's specific AMBA core, see drivers/bcma/ */ +struct bcma_device_id { + __u16 manuf; + __u16 id; + __u8 rev; + __u8 class; +}; +#define BCMA_CORE(_manuf, _id, _rev, _class) \ + { .manuf = _manuf, .id = _id, .rev = _rev, .class = _class, } +#define BCMA_CORETABLE_END \ + { 0, }, + +#define BCMA_ANY_MANUF 0xFFFF +#define BCMA_ANY_ID 0xFFFF +#define BCMA_ANY_REV 0xFF +#define BCMA_ANY_CLASS 0xFF + struct virtio_device_id { __u32 device; __u32 vendor; diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 88f3f07205f8..e26e2fb462d4 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -702,6 +702,24 @@ static int do_ssb_entry(const char *filename, return 1; } +/* Looks like: bcma:mNidNrevNclN. */ +static int do_bcma_entry(const char *filename, + struct bcma_device_id *id, char *alias) +{ + id->manuf = TO_NATIVE(id->manuf); + id->id = TO_NATIVE(id->id); + id->rev = TO_NATIVE(id->rev); + id->class = TO_NATIVE(id->class); + + strcpy(alias, "bcma:"); + ADD(alias, "m", id->manuf != BCMA_ANY_MANUF, id->manuf); + ADD(alias, "id", id->id != BCMA_ANY_ID, id->id); + ADD(alias, "rev", id->rev != BCMA_ANY_REV, id->rev); + ADD(alias, "cl", id->class != BCMA_ANY_CLASS, id->class); + add_wildcard(alias); + return 1; +} + /* Looks like: virtio:dNvN */ static int do_virtio_entry(const char *filename, struct virtio_device_id *id, char *alias) @@ -968,6 +986,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, do_table(symval, sym->st_size, sizeof(struct ssb_device_id), "ssb", do_ssb_entry, mod); + else if (sym_is(symname, "__mod_bcma_device_table")) + do_table(symval, sym->st_size, + sizeof(struct bcma_device_id), "bcma", + do_bcma_entry, mod); else if (sym_is(symname, "__mod_virtio_device_table")) do_table(symval, sym->st_size, sizeof(struct virtio_device_id), "virtio", -- cgit From c29c3f70c9eb6f18090da5af9dbe9dcb4adece8c Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Tue, 20 Apr 2010 17:58:24 -0400 Subject: tipc: Abort excessive send requests as early as possible Adds checks to TIPC's socket send routines to promptly detect and abort attempts to send more than 66,000 bytes in a single TIPC message or more than 2**31-1 bytes in a single TIPC byte stream request. In addition, this ensures that the number of iovecs in a send request does not exceed the limits of a standard integer variable. Signed-off-by: Allan Stephens Signed-off-by: Paul Gortmaker --- include/linux/tipc.h | 2 +- net/tipc/socket.c | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/tipc.h b/include/linux/tipc.h index a5b994a204d2..f2d90091cc20 100644 --- a/include/linux/tipc.h +++ b/include/linux/tipc.h @@ -101,7 +101,7 @@ static inline unsigned int tipc_node(__u32 addr) * Limiting values for messages */ -#define TIPC_MAX_USER_MSG_SIZE 66000 +#define TIPC_MAX_USER_MSG_SIZE 66000U /* * Message importance levels diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 29d94d53198d..e1c791798ba1 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -535,6 +535,9 @@ static int send_msg(struct kiocb *iocb, struct socket *sock, if (unlikely((m->msg_namelen < sizeof(*dest)) || (dest->family != AF_TIPC))) return -EINVAL; + if ((total_len > TIPC_MAX_USER_MSG_SIZE) || + (m->msg_iovlen > (unsigned)INT_MAX)) + return -EMSGSIZE; if (iocb) lock_sock(sk); @@ -640,6 +643,10 @@ static int send_packet(struct kiocb *iocb, struct socket *sock, if (unlikely(dest)) return send_msg(iocb, sock, m, total_len); + if ((total_len > TIPC_MAX_USER_MSG_SIZE) || + (m->msg_iovlen > (unsigned)INT_MAX)) + return -EMSGSIZE; + if (iocb) lock_sock(sk); @@ -723,6 +730,12 @@ static int send_stream(struct kiocb *iocb, struct socket *sock, goto exit; } + if ((total_len > (unsigned)INT_MAX) || + (m->msg_iovlen > (unsigned)INT_MAX)) { + res = -EMSGSIZE; + goto exit; + } + /* * Send each iovec entry using one or more messages * -- cgit From f30e6d3e419bfb5540fa82ba7eca01d578556e6b Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Fri, 22 Apr 2011 15:13:54 +0200 Subject: firewire: octlet AT payloads can be stack-allocated We do not need slab allocations anymore in order to satisfy streaming DMA mapping constraints, thanks to commit da28947e7e36 "firewire: ohci: avoid separate DMA mapping for small AT payloads". (Besides, the slab-allocated buffers that firewire-core, firewire-sbp2, and firedtv used to provide for 8-byte write and lock requests were still not fully portable since they crossed cacheline boundaries or shared a cacheline with unrelated CPU-accessed data. snd-firewire-lib got this aspect right by using an extra kmalloc/ kfree just for the 8-byte transaction buffer.) This change replaces kmalloc'ed lock transaction scratch buffers in firewire-core, firedtv, and snd-firewire-lib by local stack allocations. Perhaps the most notable result of the change is simpler locking because there is no need to serialize usages of preallocated per-device buffers anymore. Also, allocations and deallocations are simpler. Signed-off-by: Stefan Richter Acked-by: Clemens Ladisch --- drivers/firewire/core-card.c | 16 ++++++++-------- drivers/firewire/core-cdev.c | 4 +--- drivers/firewire/core-iso.c | 21 +++++++++++---------- drivers/firewire/core-transaction.c | 7 ++++--- drivers/media/dvb/firewire/firedtv-avc.c | 15 +-------------- include/linux/firewire.h | 3 +-- sound/firewire/cmp.c | 3 +-- sound/firewire/iso-resources.c | 12 +++--------- sound/firewire/iso-resources.h | 1 - 9 files changed, 30 insertions(+), 52 deletions(-) (limited to 'include/linux') diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c index 3c44fbc81acb..e119f1e6ba47 100644 --- a/drivers/firewire/core-card.c +++ b/drivers/firewire/core-card.c @@ -258,8 +258,7 @@ static void allocate_broadcast_channel(struct fw_card *card, int generation) if (!card->broadcast_channel_allocated) { fw_iso_resource_manage(card, generation, 1ULL << 31, - &channel, &bandwidth, true, - card->bm_transaction_data); + &channel, &bandwidth, true); if (channel != 31) { fw_notify("failed to allocate broadcast channel\n"); return; @@ -294,6 +293,7 @@ static void bm_work(struct work_struct *work) bool root_device_is_cmc; bool irm_is_1394_1995_only; bool keep_this_irm; + __be32 transaction_data[2]; spin_lock_irq(&card->lock); @@ -355,21 +355,21 @@ static void bm_work(struct work_struct *work) goto pick_me; } - card->bm_transaction_data[0] = cpu_to_be32(0x3f); - card->bm_transaction_data[1] = cpu_to_be32(local_id); + transaction_data[0] = cpu_to_be32(0x3f); + transaction_data[1] = cpu_to_be32(local_id); spin_unlock_irq(&card->lock); rcode = fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP, irm_id, generation, SCODE_100, CSR_REGISTER_BASE + CSR_BUS_MANAGER_ID, - card->bm_transaction_data, 8); + transaction_data, 8); if (rcode == RCODE_GENERATION) /* Another bus reset, BM work has been rescheduled. */ goto out; - bm_id = be32_to_cpu(card->bm_transaction_data[0]); + bm_id = be32_to_cpu(transaction_data[0]); spin_lock_irq(&card->lock); if (rcode == RCODE_COMPLETE && generation == card->generation) @@ -490,11 +490,11 @@ static void bm_work(struct work_struct *work) /* * Make sure that the cycle master sends cycle start packets. */ - card->bm_transaction_data[0] = cpu_to_be32(CSR_STATE_BIT_CMSTR); + transaction_data[0] = cpu_to_be32(CSR_STATE_BIT_CMSTR); rcode = fw_run_transaction(card, TCODE_WRITE_QUADLET_REQUEST, root_id, generation, SCODE_100, CSR_REGISTER_BASE + CSR_STATE_SET, - card->bm_transaction_data, 4); + transaction_data, 4); if (rcode == RCODE_GENERATION) goto out; } diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c index 62ac111af243..2a3f1c4d6906 100644 --- a/drivers/firewire/core-cdev.c +++ b/drivers/firewire/core-cdev.c @@ -141,7 +141,6 @@ struct iso_resource { int generation; u64 channels; s32 bandwidth; - __be32 transaction_data[2]; struct iso_resource_event *e_alloc, *e_dealloc; }; @@ -1229,8 +1228,7 @@ static void iso_resource_work(struct work_struct *work) r->channels, &channel, &bandwidth, todo == ISO_RES_ALLOC || todo == ISO_RES_REALLOC || - todo == ISO_RES_ALLOC_ONCE, - r->transaction_data); + todo == ISO_RES_ALLOC_ONCE); /* * Is this generation outdated already? As long as this resource sticks * in the idr, it will be scheduled again for a newer generation or at diff --git a/drivers/firewire/core-iso.c b/drivers/firewire/core-iso.c index 481056df9268..f872ede5af37 100644 --- a/drivers/firewire/core-iso.c +++ b/drivers/firewire/core-iso.c @@ -196,9 +196,10 @@ EXPORT_SYMBOL(fw_iso_context_stop); */ static int manage_bandwidth(struct fw_card *card, int irm_id, int generation, - int bandwidth, bool allocate, __be32 data[2]) + int bandwidth, bool allocate) { int try, new, old = allocate ? BANDWIDTH_AVAILABLE_INITIAL : 0; + __be32 data[2]; /* * On a 1394a IRM with low contention, try < 1 is enough. @@ -233,9 +234,10 @@ static int manage_bandwidth(struct fw_card *card, int irm_id, int generation, } static int manage_channel(struct fw_card *card, int irm_id, int generation, - u32 channels_mask, u64 offset, bool allocate, __be32 data[2]) + u32 channels_mask, u64 offset, bool allocate) { __be32 bit, all, old; + __be32 data[2]; int channel, ret = -EIO, retry = 5; old = all = allocate ? cpu_to_be32(~0) : 0; @@ -284,7 +286,7 @@ static int manage_channel(struct fw_card *card, int irm_id, int generation, } static void deallocate_channel(struct fw_card *card, int irm_id, - int generation, int channel, __be32 buffer[2]) + int generation, int channel) { u32 mask; u64 offset; @@ -293,7 +295,7 @@ static void deallocate_channel(struct fw_card *card, int irm_id, offset = channel < 32 ? CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI : CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO; - manage_channel(card, irm_id, generation, mask, offset, false, buffer); + manage_channel(card, irm_id, generation, mask, offset, false); } /** @@ -322,7 +324,7 @@ static void deallocate_channel(struct fw_card *card, int irm_id, */ void fw_iso_resource_manage(struct fw_card *card, int generation, u64 channels_mask, int *channel, int *bandwidth, - bool allocate, __be32 buffer[2]) + bool allocate) { u32 channels_hi = channels_mask; /* channels 31...0 */ u32 channels_lo = channels_mask >> 32; /* channels 63...32 */ @@ -335,11 +337,11 @@ void fw_iso_resource_manage(struct fw_card *card, int generation, if (channels_hi) c = manage_channel(card, irm_id, generation, channels_hi, CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI, - allocate, buffer); + allocate); if (channels_lo && c < 0) { c = manage_channel(card, irm_id, generation, channels_lo, CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO, - allocate, buffer); + allocate); if (c >= 0) c += 32; } @@ -351,14 +353,13 @@ void fw_iso_resource_manage(struct fw_card *card, int generation, if (*bandwidth == 0) return; - ret = manage_bandwidth(card, irm_id, generation, *bandwidth, - allocate, buffer); + ret = manage_bandwidth(card, irm_id, generation, *bandwidth, allocate); if (ret < 0) *bandwidth = 0; if (allocate && ret < 0) { if (c >= 0) - deallocate_channel(card, irm_id, generation, c, buffer); + deallocate_channel(card, irm_id, generation, c); *channel = ret; } } diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c index d00f8ce902cc..77275fdf6c1f 100644 --- a/drivers/firewire/core-transaction.c +++ b/drivers/firewire/core-transaction.c @@ -326,8 +326,8 @@ static int allocate_tlabel(struct fw_card *card) * It will contain tag, channel, and sy data instead of a node ID then. * * The payload buffer at @data is going to be DMA-mapped except in case of - * quadlet-sized payload or of local (loopback) requests. Hence make sure that - * the buffer complies with the restrictions for DMA-mapped memory. The + * @length <= 8 or of local (loopback) requests. Hence make sure that the + * buffer complies with the restrictions of the streaming DMA mapping API. * @payload must not be freed before the @callback is called. * * In case of request types without payload, @data is NULL and @length is 0. @@ -411,7 +411,8 @@ static void transaction_callback(struct fw_card *card, int rcode, * * Returns the RCODE. See fw_send_request() for parameter documentation. * Unlike fw_send_request(), @data points to the payload of the request or/and - * to the payload of the response. + * to the payload of the response. DMA mapping restrictions apply to outbound + * request payloads of >= 8 bytes but not to inbound response payloads. */ int fw_run_transaction(struct fw_card *card, int tcode, int destination_id, int generation, int speed, unsigned long long offset, diff --git a/drivers/media/dvb/firewire/firedtv-avc.c b/drivers/media/dvb/firewire/firedtv-avc.c index fc5ccd8c923a..21c52e3b522e 100644 --- a/drivers/media/dvb/firewire/firedtv-avc.c +++ b/drivers/media/dvb/firewire/firedtv-avc.c @@ -1320,14 +1320,10 @@ static int cmp_read(struct firedtv *fdtv, u64 addr, __be32 *data) { int ret; - mutex_lock(&fdtv->avc_mutex); - ret = fdtv_read(fdtv, addr, data); if (ret < 0) dev_err(fdtv->device, "CMP: read I/O error\n"); - mutex_unlock(&fdtv->avc_mutex); - return ret; } @@ -1335,18 +1331,9 @@ static int cmp_lock(struct firedtv *fdtv, u64 addr, __be32 data[]) { int ret; - mutex_lock(&fdtv->avc_mutex); - - /* data[] is stack-allocated and should not be DMA-mapped. */ - memcpy(fdtv->avc_data, data, 8); - - ret = fdtv_lock(fdtv, addr, fdtv->avc_data); + ret = fdtv_lock(fdtv, addr, data); if (ret < 0) dev_err(fdtv->device, "CMP: lock I/O error\n"); - else - memcpy(data, fdtv->avc_data, 8); - - mutex_unlock(&fdtv->avc_mutex); return ret; } diff --git a/include/linux/firewire.h b/include/linux/firewire.h index c64f3680d4f1..de90e1ff8488 100644 --- a/include/linux/firewire.h +++ b/include/linux/firewire.h @@ -125,7 +125,6 @@ struct fw_card { struct delayed_work bm_work; /* bus manager job */ int bm_retries; int bm_generation; - __be32 bm_transaction_data[2]; int bm_node_id; bool bm_abdicate; @@ -447,6 +446,6 @@ int fw_iso_context_stop(struct fw_iso_context *ctx); void fw_iso_context_destroy(struct fw_iso_context *ctx); void fw_iso_resource_manage(struct fw_card *card, int generation, u64 channels_mask, int *channel, int *bandwidth, - bool allocate, __be32 buffer[2]); + bool allocate); #endif /* _LINUX_FIREWIRE_H */ diff --git a/sound/firewire/cmp.c b/sound/firewire/cmp.c index 4a37f3a6fab9..14cacbc655dd 100644 --- a/sound/firewire/cmp.c +++ b/sound/firewire/cmp.c @@ -49,10 +49,9 @@ static int pcr_modify(struct cmp_connection *c, enum bus_reset_handling bus_reset_handling) { struct fw_device *device = fw_parent_device(c->resources.unit); - __be32 *buffer = c->resources.buffer; int generation = c->resources.generation; int rcode, errors = 0; - __be32 old_arg; + __be32 old_arg, buffer[2]; int err; buffer[0] = c->last_pcr_value; diff --git a/sound/firewire/iso-resources.c b/sound/firewire/iso-resources.c index 775dbd5f3445..bb9c0c1fb529 100644 --- a/sound/firewire/iso-resources.c +++ b/sound/firewire/iso-resources.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include "iso-resources.h" @@ -25,10 +24,6 @@ */ int fw_iso_resources_init(struct fw_iso_resources *r, struct fw_unit *unit) { - r->buffer = kmalloc(2 * 4, GFP_KERNEL); - if (!r->buffer) - return -ENOMEM; - r->channels_mask = ~0uLL; r->unit = fw_unit_get(unit); mutex_init(&r->mutex); @@ -44,7 +39,6 @@ int fw_iso_resources_init(struct fw_iso_resources *r, struct fw_unit *unit) void fw_iso_resources_destroy(struct fw_iso_resources *r) { WARN_ON(r->allocated); - kfree(r->buffer); mutex_destroy(&r->mutex); fw_unit_put(r->unit); } @@ -131,7 +125,7 @@ retry_after_bus_reset: bandwidth = r->bandwidth + r->bandwidth_overhead; fw_iso_resource_manage(card, r->generation, r->channels_mask, - &channel, &bandwidth, true, r->buffer); + &channel, &bandwidth, true); if (channel == -EAGAIN) { mutex_unlock(&r->mutex); goto retry_after_bus_reset; @@ -184,7 +178,7 @@ int fw_iso_resources_update(struct fw_iso_resources *r) bandwidth = r->bandwidth + r->bandwidth_overhead; fw_iso_resource_manage(card, r->generation, 1uLL << r->channel, - &channel, &bandwidth, true, r->buffer); + &channel, &bandwidth, true); /* * When another bus reset happens, pretend that the allocation * succeeded; we will try again for the new generation later. @@ -220,7 +214,7 @@ void fw_iso_resources_free(struct fw_iso_resources *r) if (r->allocated) { bandwidth = r->bandwidth + r->bandwidth_overhead; fw_iso_resource_manage(card, r->generation, 1uLL << r->channel, - &channel, &bandwidth, false, r->buffer); + &channel, &bandwidth, false); if (channel < 0) dev_err(&r->unit->device, "isochronous resource deallocation failed\n"); diff --git a/sound/firewire/iso-resources.h b/sound/firewire/iso-resources.h index 3f0730e4d841..5a9af7c61657 100644 --- a/sound/firewire/iso-resources.h +++ b/sound/firewire/iso-resources.h @@ -24,7 +24,6 @@ struct fw_iso_resources { unsigned int bandwidth_overhead; int generation; /* in which allocation is valid */ bool allocated; - __be32 *buffer; }; int fw_iso_resources_init(struct fw_iso_resources *r, -- cgit From 13882a82ee1646336c3996c93b4a560a55d2a419 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 2 May 2011 09:33:56 +0200 Subject: firewire: optimize iso queueing by setting wake only after the last packet When queueing iso packets, the run time is dominated by the two MMIO accesses that set the DMA context's wake bit. Because most drivers submit packets in batches, we can save much time by removing all but the last wakeup. The internal kernel API is changed to require a call to fw_iso_context_queue_flush() after a batch of queued packets. The user space API does not change, so one call to FW_CDEV_IOC_QUEUE_ISO must specify multiple packets to take advantage of this optimization. In my measurements, this patch reduces the time needed to queue fifty skip packets from userspace to one sixth on a 2.5 GHz CPU, or to one third at 800 MHz. Signed-off-by: Clemens Ladisch Signed-off-by: Stefan Richter --- drivers/firewire/core-card.c | 5 +++++ drivers/firewire/core-cdev.c | 1 + drivers/firewire/core-iso.c | 6 ++++++ drivers/firewire/core.h | 2 ++ drivers/firewire/net.c | 4 +++- drivers/firewire/ohci.c | 19 +++++++++++++++---- drivers/media/dvb/firewire/firedtv-fw.c | 1 + include/linux/firewire.h | 1 + sound/firewire/amdtp.c | 1 + 9 files changed, 35 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c index e119f1e6ba47..f05fc7bfceeb 100644 --- a/drivers/firewire/core-card.c +++ b/drivers/firewire/core-card.c @@ -630,6 +630,10 @@ static int dummy_queue_iso(struct fw_iso_context *ctx, struct fw_iso_packet *p, return -ENODEV; } +static void dummy_flush_queue_iso(struct fw_iso_context *ctx) +{ +} + static const struct fw_card_driver dummy_driver_template = { .read_phy_reg = dummy_read_phy_reg, .update_phy_reg = dummy_update_phy_reg, @@ -641,6 +645,7 @@ static const struct fw_card_driver dummy_driver_template = { .start_iso = dummy_start_iso, .set_iso_channels = dummy_set_iso_channels, .queue_iso = dummy_queue_iso, + .flush_queue_iso = dummy_flush_queue_iso, }; void fw_card_release(struct kref *kref) diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c index 2a3f1c4d6906..64768c2194f1 100644 --- a/drivers/firewire/core-cdev.c +++ b/drivers/firewire/core-cdev.c @@ -1107,6 +1107,7 @@ static int ioctl_queue_iso(struct client *client, union ioctl_arg *arg) payload += u.packet.payload_length; count++; } + fw_iso_context_queue_flush(ctx); a->size -= uptr_to_u64(p) - a->packets; a->packets = uptr_to_u64(p); diff --git a/drivers/firewire/core-iso.c b/drivers/firewire/core-iso.c index f872ede5af37..57c3973093ad 100644 --- a/drivers/firewire/core-iso.c +++ b/drivers/firewire/core-iso.c @@ -185,6 +185,12 @@ int fw_iso_context_queue(struct fw_iso_context *ctx, } EXPORT_SYMBOL(fw_iso_context_queue); +void fw_iso_context_queue_flush(struct fw_iso_context *ctx) +{ + ctx->card->driver->flush_queue_iso(ctx); +} +EXPORT_SYMBOL(fw_iso_context_queue_flush); + int fw_iso_context_stop(struct fw_iso_context *ctx) { return ctx->card->driver->stop_iso(ctx); diff --git a/drivers/firewire/core.h b/drivers/firewire/core.h index 25e729cde2f7..0fe4e4e6eda7 100644 --- a/drivers/firewire/core.h +++ b/drivers/firewire/core.h @@ -97,6 +97,8 @@ struct fw_card_driver { struct fw_iso_buffer *buffer, unsigned long payload); + void (*flush_queue_iso)(struct fw_iso_context *ctx); + int (*stop_iso)(struct fw_iso_context *ctx); }; diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index 3f04dd3681cf..b9762d07198d 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -881,7 +881,9 @@ static void fwnet_receive_broadcast(struct fw_iso_context *context, spin_unlock_irqrestore(&dev->lock, flags); - if (retval < 0) + if (retval >= 0) + fw_iso_context_queue_flush(dev->broadcast_rcv_context); + else fw_error("requeue failed\n"); } diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index f9f55703375e..438e6c831170 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -1192,9 +1192,6 @@ static void context_append(struct context *ctx, wmb(); /* finish init of new descriptors before branch_address update */ ctx->prev->branch_address = cpu_to_le32(d_bus | z); ctx->prev = find_branch_descriptor(d, z); - - reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_WAKE); - flush_writes(ctx->ohci); } static void context_stop(struct context *ctx) @@ -1348,8 +1345,12 @@ static int at_context_queue_packet(struct context *ctx, context_append(ctx, d, z, 4 - z); - if (!ctx->running) + if (ctx->running) { + reg_write(ohci, CONTROL_SET(ctx->regs), CONTEXT_WAKE); + flush_writes(ohci); + } else { context_run(ctx, 0); + } return 0; } @@ -3121,6 +3122,15 @@ static int ohci_queue_iso(struct fw_iso_context *base, return ret; } +static void ohci_flush_queue_iso(struct fw_iso_context *base) +{ + struct context *ctx = + &container_of(base, struct iso_context, base)->context; + + reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_WAKE); + flush_writes(ctx->ohci); +} + static const struct fw_card_driver ohci_driver = { .enable = ohci_enable, .read_phy_reg = ohci_read_phy_reg, @@ -3137,6 +3147,7 @@ static const struct fw_card_driver ohci_driver = { .free_iso_context = ohci_free_iso_context, .set_iso_channels = ohci_set_iso_channels, .queue_iso = ohci_queue_iso, + .flush_queue_iso = ohci_flush_queue_iso, .start_iso = ohci_start_iso, .stop_iso = ohci_stop_iso, }; diff --git a/drivers/media/dvb/firewire/firedtv-fw.c b/drivers/media/dvb/firewire/firedtv-fw.c index 8022b743af91..864b6274c729 100644 --- a/drivers/media/dvb/firewire/firedtv-fw.c +++ b/drivers/media/dvb/firewire/firedtv-fw.c @@ -125,6 +125,7 @@ static void handle_iso(struct fw_iso_context *context, u32 cycle, i = (i + 1) & (N_PACKETS - 1); } + fw_iso_context_queue_flush(ctx->context); ctx->current_packet = i; } diff --git a/include/linux/firewire.h b/include/linux/firewire.h index de90e1ff8488..c0fb405bb435 100644 --- a/include/linux/firewire.h +++ b/include/linux/firewire.h @@ -440,6 +440,7 @@ int fw_iso_context_queue(struct fw_iso_context *ctx, struct fw_iso_packet *packet, struct fw_iso_buffer *buffer, unsigned long payload); +void fw_iso_context_queue_flush(struct fw_iso_context *ctx); int fw_iso_context_start(struct fw_iso_context *ctx, int cycle, int sync, int tags); int fw_iso_context_stop(struct fw_iso_context *ctx); diff --git a/sound/firewire/amdtp.c b/sound/firewire/amdtp.c index b18140ff2b93..87657dd7714c 100644 --- a/sound/firewire/amdtp.c +++ b/sound/firewire/amdtp.c @@ -396,6 +396,7 @@ static void out_packet_callback(struct fw_iso_context *context, u32 cycle, for (i = 0; i < packets; ++i) queue_out_packet(s, ++cycle); + fw_iso_context_queue_flush(s->context); } static int queue_initial_skip_packets(struct amdtp_out_stream *s) -- cgit From 105e53f863c04e1d9e5bb34bf753c9fdbce6a60c Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 1 May 2011 20:50:31 +0200 Subject: firewire: sbp2: parallelize login, reconnect, logout The struct sbp2_logical_unit.work items can all be executed in parallel but are not reentrant. Furthermore, reconnect or re-login work must be executed in a WQ_MEM_RECLAIM workqueue. Hence replace the old single-threaded firewire-sbp2 workqueue by a concurrency-managed but non-reentrant workqueue with rescuer. firewire-core already maintains one, hence use this one. In earlier versions of this change, I observed occasional failures of parallel INQUIRY to an Initio INIC-2430 FireWire 800 to dual IDE bridge. More testing indicates that parallel INQUIRY is not actually a problem, but too quick successions of logout and login + INQUIRY, e.g. a quick sequence of cable plugout and plugin, can result in failed INQUIRY. This does not seem to be something that should or could be addressed by serialization. Another dual-LU device to which I currently have access to, an OXUF924DSB FireWire 800 to dual SATA bridge with firmware from MacPower, has been successfully tested with this too. This change is beneficial to environments with two or more FireWire storage devices, especially if they are located on the same bus. Management tasks that should be performed as soon and as quickly as possible, especially reconnect, are no longer held up by tasks on other devices that may take a long time, especially login with INQUIRY and sd or sr driver probe. Signed-off-by: Stefan Richter --- drivers/firewire/core-card.c | 4 ++-- drivers/firewire/core-cdev.c | 2 +- drivers/firewire/core-device.c | 5 +++-- drivers/firewire/core-transaction.c | 12 ++++++------ drivers/firewire/core.h | 2 -- drivers/firewire/sbp2.c | 9 +-------- include/linux/firewire.h | 2 ++ 7 files changed, 15 insertions(+), 21 deletions(-) (limited to 'include/linux') diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c index bb8c4d22b03e..29d2423fae6d 100644 --- a/drivers/firewire/core-card.c +++ b/drivers/firewire/core-card.c @@ -228,7 +228,7 @@ void fw_schedule_bus_reset(struct fw_card *card, bool delayed, bool short_reset) /* Use an arbitrary short delay to combine multiple reset requests. */ fw_card_get(card); - if (!queue_delayed_work(fw_wq, &card->br_work, + if (!queue_delayed_work(fw_workqueue, &card->br_work, delayed ? DIV_ROUND_UP(HZ, 100) : 0)) fw_card_put(card); } @@ -241,7 +241,7 @@ static void br_work(struct work_struct *work) /* Delay for 2s after last reset per IEEE 1394 clause 8.2.1. */ if (card->reset_jiffies != 0 && time_before64(get_jiffies_64(), card->reset_jiffies + 2 * HZ)) { - if (!queue_delayed_work(fw_wq, &card->br_work, 2 * HZ)) + if (!queue_delayed_work(fw_workqueue, &card->br_work, 2 * HZ)) fw_card_put(card); return; } diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c index aa1131d26e30..b1c11775839c 100644 --- a/drivers/firewire/core-cdev.c +++ b/drivers/firewire/core-cdev.c @@ -149,7 +149,7 @@ static void release_iso_resource(struct client *, struct client_resource *); static void schedule_iso_resource(struct iso_resource *r, unsigned long delay) { client_get(r->client); - if (!queue_delayed_work(fw_wq, &r->work, delay)) + if (!queue_delayed_work(fw_workqueue, &r->work, delay)) client_put(r->client); } diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c index ef900d923f15..95a471401892 100644 --- a/drivers/firewire/core-device.c +++ b/drivers/firewire/core-device.c @@ -725,12 +725,13 @@ struct fw_device *fw_device_get_by_devt(dev_t devt) return device; } -struct workqueue_struct *fw_wq; +struct workqueue_struct *fw_workqueue; +EXPORT_SYMBOL(fw_workqueue); static void fw_schedule_device_work(struct fw_device *device, unsigned long delay) { - queue_delayed_work(fw_wq, &device->work, delay); + queue_delayed_work(fw_workqueue, &device->work, delay); } /* diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c index d4c28a217b2c..334b82a3542c 100644 --- a/drivers/firewire/core-transaction.c +++ b/drivers/firewire/core-transaction.c @@ -1214,21 +1214,21 @@ static int __init fw_core_init(void) { int ret; - fw_wq = alloc_workqueue(KBUILD_MODNAME, - WQ_NON_REENTRANT | WQ_MEM_RECLAIM, 0); - if (!fw_wq) + fw_workqueue = alloc_workqueue("firewire", + WQ_NON_REENTRANT | WQ_MEM_RECLAIM, 0); + if (!fw_workqueue) return -ENOMEM; ret = bus_register(&fw_bus_type); if (ret < 0) { - destroy_workqueue(fw_wq); + destroy_workqueue(fw_workqueue); return ret; } fw_cdev_major = register_chrdev(0, "firewire", &fw_device_ops); if (fw_cdev_major < 0) { bus_unregister(&fw_bus_type); - destroy_workqueue(fw_wq); + destroy_workqueue(fw_workqueue); return fw_cdev_major; } @@ -1244,7 +1244,7 @@ static void __exit fw_core_cleanup(void) { unregister_chrdev(fw_cdev_major, "firewire"); bus_unregister(&fw_bus_type); - destroy_workqueue(fw_wq); + destroy_workqueue(fw_workqueue); idr_destroy(&fw_device_idr); } diff --git a/drivers/firewire/core.h b/drivers/firewire/core.h index 00ea7730c6a7..0fe4e4e6eda7 100644 --- a/drivers/firewire/core.h +++ b/drivers/firewire/core.h @@ -140,8 +140,6 @@ void fw_cdev_handle_phy_packet(struct fw_card *card, struct fw_packet *p); extern struct rw_semaphore fw_device_rwsem; extern struct idr fw_device_idr; extern int fw_cdev_major; -struct workqueue_struct; -extern struct workqueue_struct *fw_wq; struct fw_device *fw_device_get_by_devt(dev_t devt); int fw_device_set_broadcast_channel(struct device *dev, void *gen); diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c index 2aafc614ae14..41841a3e3f99 100644 --- a/drivers/firewire/sbp2.c +++ b/drivers/firewire/sbp2.c @@ -826,8 +826,6 @@ static void sbp2_target_put(struct sbp2_target *tgt) kref_put(&tgt->kref, sbp2_release_target); } -static struct workqueue_struct *sbp2_wq; - /* * Always get the target's kref when scheduling work on one its units. * Each workqueue job is responsible to call sbp2_target_put() upon return. @@ -835,7 +833,7 @@ static struct workqueue_struct *sbp2_wq; static void sbp2_queue_work(struct sbp2_logical_unit *lu, unsigned long delay) { sbp2_target_get(lu->tgt); - if (!queue_delayed_work(sbp2_wq, &lu->work, delay)) + if (!queue_delayed_work(fw_workqueue, &lu->work, delay)) sbp2_target_put(lu->tgt); } @@ -1645,17 +1643,12 @@ MODULE_ALIAS("sbp2"); static int __init sbp2_init(void) { - sbp2_wq = create_singlethread_workqueue(KBUILD_MODNAME); - if (!sbp2_wq) - return -ENOMEM; - return driver_register(&sbp2_driver.driver); } static void __exit sbp2_cleanup(void) { driver_unregister(&sbp2_driver.driver); - destroy_workqueue(sbp2_wq); } module_init(sbp2_init); diff --git a/include/linux/firewire.h b/include/linux/firewire.h index c0fb405bb435..5e6f42789afe 100644 --- a/include/linux/firewire.h +++ b/include/linux/firewire.h @@ -449,4 +449,6 @@ void fw_iso_resource_manage(struct fw_card *card, int generation, u64 channels_mask, int *channel, int *bandwidth, bool allocate); +extern struct workqueue_struct *fw_workqueue; + #endif /* _LINUX_FIREWIRE_H */ -- cgit From 1b9ba000177ee47bcc5b44c7c34e48e735f5f9b1 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Mon, 9 May 2011 13:08:06 +0300 Subject: usb: gadget: composite: Allow function drivers to pause control transfers Some USB function drivers (e.g. f_mass_storage.c) need to delay or defer the data/status stages of standard control requests like SET_CONFIGURATION or SET_INTERFACE till they are done with their bookkeeping and are actually ready for accepting new commands to their interface. They can now achieve this functionality by returning USB_GADGET_DELAYED_STATUS in their setup handlers (e.g. set_alt()). The composite framework will then defer completion of the control transfer by not completing the data/status stages. This ensures that the host does not send new packets to the interface till the function driver is ready to take them. When the function driver that requested for USB_GADGET_DELAYED_STATUS is done with its bookkeeping, it should signal the composite framework to continue with the data/status stages of the control transfer. It can do so by invoking the new API usb_composite_setup_continue(). This is where the control transfer's data/status stages are completed and host can initiate new transfers. The DELAYED_STATUS mechanism is currently only supported if the expected data phase is 0 bytes (i.e. w_length == 0). Since SET_CONFIGURATION and SET_INTERFACE are the only cases that will use this mechanism, this is not a limitation. Signed-off-by: Roger Quadros Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/composite.c | 62 +++++++++++++++++++++++++++++++++++++++++- include/linux/usb/composite.h | 16 ++++++++++- 2 files changed, 76 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 82314ed22506..5cbb1a41c223 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -461,12 +461,23 @@ static int set_config(struct usb_composite_dev *cdev, reset_config(cdev); goto done; } + + if (result == USB_GADGET_DELAYED_STATUS) { + DBG(cdev, + "%s: interface %d (%s) requested delayed status\n", + __func__, tmp, f->name); + cdev->delayed_status++; + DBG(cdev, "delayed_status count %d\n", + cdev->delayed_status); + } } /* when we return, be sure our power usage is valid */ power = c->bMaxPower ? (2 * c->bMaxPower) : CONFIG_USB_GADGET_VBUS_DRAW; done: usb_gadget_vbus_draw(gadget, power); + if (result >= 0 && cdev->delayed_status) + result = USB_GADGET_DELAYED_STATUS; return result; } @@ -895,6 +906,14 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) if (w_value && !f->set_alt) break; value = f->set_alt(f, w_index, w_value); + if (value == USB_GADGET_DELAYED_STATUS) { + DBG(cdev, + "%s: interface %d (%s) requested delayed status\n", + __func__, intf, f->name); + cdev->delayed_status++; + DBG(cdev, "delayed_status count %d\n", + cdev->delayed_status); + } break; case USB_REQ_GET_INTERFACE: if (ctrl->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE)) @@ -958,7 +977,7 @@ unknown: } /* respond with data transfer before status phase? */ - if (value >= 0) { + if (value >= 0 && value != USB_GADGET_DELAYED_STATUS) { req->length = value; req->zero = value < w_length; value = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC); @@ -967,6 +986,10 @@ unknown: req->status = 0; composite_setup_complete(gadget->ep0, req); } + } else if (value == USB_GADGET_DELAYED_STATUS && w_length != 0) { + WARN(cdev, + "%s: Delayed status not supported for w_length != 0", + __func__); } done: @@ -1289,3 +1312,40 @@ void usb_composite_unregister(struct usb_composite_driver *driver) return; usb_gadget_unregister_driver(&composite_driver); } + +/** + * usb_composite_setup_continue() - Continue with the control transfer + * @cdev: the composite device who's control transfer was kept waiting + * + * This function must be called by the USB function driver to continue + * with the control transfer's data/status stage in case it had requested to + * delay the data/status stages. A USB function's setup handler (e.g. set_alt()) + * can request the composite framework to delay the setup request's data/status + * stages by returning USB_GADGET_DELAYED_STATUS. + */ +void usb_composite_setup_continue(struct usb_composite_dev *cdev) +{ + int value; + struct usb_request *req = cdev->req; + unsigned long flags; + + DBG(cdev, "%s\n", __func__); + spin_lock_irqsave(&cdev->lock, flags); + + if (cdev->delayed_status == 0) { + WARN(cdev, "%s: Unexpected call\n", __func__); + + } else if (--cdev->delayed_status == 0) { + DBG(cdev, "%s: Completing delayed status\n", __func__); + req->length = 0; + value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC); + if (value < 0) { + DBG(cdev, "ep_queue --> %d\n", value); + req->status = 0; + composite_setup_complete(cdev->gadget->ep0, req); + } + } + + spin_unlock_irqrestore(&cdev->lock, flags); +} + diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 882a084a8411..b78cba466d3d 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -37,6 +37,14 @@ #include #include +/* + * USB function drivers should return USB_GADGET_DELAYED_STATUS if they + * wish to delay the data/status stages of the control transfer till they + * are ready. The control transfer will then be kept from completing till + * all the function drivers that requested for USB_GADGET_DELAYED_STAUS + * invoke usb_composite_setup_continue(). + */ +#define USB_GADGET_DELAYED_STATUS 0x7fff /* Impossibly large value */ struct usb_configuration; @@ -285,6 +293,7 @@ struct usb_composite_driver { extern int usb_composite_probe(struct usb_composite_driver *driver, int (*bind)(struct usb_composite_dev *cdev)); extern void usb_composite_unregister(struct usb_composite_driver *driver); +extern void usb_composite_setup_continue(struct usb_composite_dev *cdev); /** @@ -342,7 +351,12 @@ struct usb_composite_dev { */ unsigned deactivations; - /* protects at least deactivation count */ + /* the composite driver won't complete the control transfer's + * data/status stages till delayed_status is zero. + */ + int delayed_status; + + /* protects deactivations and delayed_status counts*/ spinlock_t lock; }; -- cgit From 6b4e306aa3dc94a0545eb9279475b1ab6209a31f Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Sun, 7 Mar 2010 16:41:34 -0800 Subject: ns: proc files for namespace naming policy. Create files under /proc//ns/ to allow controlling the namespaces of a process. This addresses three specific problems that can make namespaces hard to work with. - Namespaces require a dedicated process to pin them in memory. - It is not possible to use a namespace unless you are the child of the original creator. - Namespaces don't have names that userspace can use to talk about them. The namespace files under /proc//ns/ can be opened and the file descriptor can be used to talk about a specific namespace, and to keep the specified namespace alive. A namespace can be kept alive by either holding the file descriptor open or bind mounting the file someplace else. aka: mount --bind /proc/self/ns/net /some/filesystem/path mount --bind /proc/self/fd/ /some/filesystem/path This allows namespaces to be named with userspace policy. It requires additional support to make use of these filedescriptors and that will be comming in the following patches. Acked-by: Daniel Lezcano Signed-off-by: Eric W. Biederman --- fs/proc/Makefile | 1 + fs/proc/base.c | 20 +++--- fs/proc/inode.c | 7 ++ fs/proc/internal.h | 18 +++++ fs/proc/namespaces.c | 188 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/proc_fs.h | 18 +++++ 6 files changed, 241 insertions(+), 11 deletions(-) create mode 100644 fs/proc/namespaces.c (limited to 'include/linux') diff --git a/fs/proc/Makefile b/fs/proc/Makefile index df434c5f28fb..c1c729335924 100644 --- a/fs/proc/Makefile +++ b/fs/proc/Makefile @@ -20,6 +20,7 @@ proc-y += stat.o proc-y += uptime.o proc-y += version.o proc-y += softirqs.o +proc-y += namespaces.o proc-$(CONFIG_PROC_SYSCTL) += proc_sysctl.o proc-$(CONFIG_NET) += proc_net.o proc-$(CONFIG_PROC_KCORE) += kcore.o diff --git a/fs/proc/base.c b/fs/proc/base.c index dfa532730e55..dc8bca72b002 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -600,7 +600,7 @@ static int proc_fd_access_allowed(struct inode *inode) return allowed; } -static int proc_setattr(struct dentry *dentry, struct iattr *attr) +int proc_setattr(struct dentry *dentry, struct iattr *attr) { int error; struct inode *inode = dentry->d_inode; @@ -1736,8 +1736,7 @@ static int task_dumpable(struct task_struct *task) return 0; } - -static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *task) +struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *task) { struct inode * inode; struct proc_inode *ei; @@ -1779,7 +1778,7 @@ out_unlock: return NULL; } -static int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) +int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) { struct inode *inode = dentry->d_inode; struct task_struct *task; @@ -1820,7 +1819,7 @@ static int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat * made this apply to all per process world readable and executable * directories. */ -static int pid_revalidate(struct dentry *dentry, struct nameidata *nd) +int pid_revalidate(struct dentry *dentry, struct nameidata *nd) { struct inode *inode; struct task_struct *task; @@ -1862,7 +1861,7 @@ static int pid_delete_dentry(const struct dentry * dentry) return !proc_pid(dentry->d_inode)->tasks[PIDTYPE_PID].first; } -static const struct dentry_operations pid_dentry_operations = +const struct dentry_operations pid_dentry_operations = { .d_revalidate = pid_revalidate, .d_delete = pid_delete_dentry, @@ -1870,9 +1869,6 @@ static const struct dentry_operations pid_dentry_operations = /* Lookups */ -typedef struct dentry *instantiate_t(struct inode *, struct dentry *, - struct task_struct *, const void *); - /* * Fill a directory entry. * @@ -1885,8 +1881,8 @@ typedef struct dentry *instantiate_t(struct inode *, struct dentry *, * reported by readdir in sync with the inode numbers reported * by stat. */ -static int proc_fill_cache(struct file *filp, void *dirent, filldir_t filldir, - char *name, int len, +int proc_fill_cache(struct file *filp, void *dirent, filldir_t filldir, + const char *name, int len, instantiate_t instantiate, struct task_struct *task, const void *ptr) { struct dentry *child, *dir = filp->f_path.dentry; @@ -2820,6 +2816,7 @@ static const struct pid_entry tgid_base_stuff[] = { DIR("task", S_IRUGO|S_IXUGO, proc_task_inode_operations, proc_task_operations), DIR("fd", S_IRUSR|S_IXUSR, proc_fd_inode_operations, proc_fd_operations), DIR("fdinfo", S_IRUSR|S_IXUSR, proc_fdinfo_inode_operations, proc_fdinfo_operations), + DIR("ns", S_IRUSR|S_IXUGO, proc_ns_dir_inode_operations, proc_ns_dir_operations), #ifdef CONFIG_NET DIR("net", S_IRUGO|S_IXUGO, proc_net_inode_operations, proc_net_operations), #endif @@ -3168,6 +3165,7 @@ out_no_task: static const struct pid_entry tid_base_stuff[] = { DIR("fd", S_IRUSR|S_IXUSR, proc_fd_inode_operations, proc_fd_operations), DIR("fdinfo", S_IRUSR|S_IXUSR, proc_fdinfo_inode_operations, proc_fdinfo_operations), + DIR("ns", S_IRUSR|S_IXUGO, proc_ns_dir_inode_operations, proc_ns_dir_operations), REG("environ", S_IRUSR, proc_environ_operations), INF("auxv", S_IRUSR, proc_pid_auxv), ONE("status", S_IRUGO, proc_pid_status), diff --git a/fs/proc/inode.c b/fs/proc/inode.c index d15aa1b1cc8f..74b48cfa1bb2 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c @@ -28,6 +28,7 @@ static void proc_evict_inode(struct inode *inode) { struct proc_dir_entry *de; struct ctl_table_header *head; + const struct proc_ns_operations *ns_ops; truncate_inode_pages(&inode->i_data, 0); end_writeback(inode); @@ -44,6 +45,10 @@ static void proc_evict_inode(struct inode *inode) rcu_assign_pointer(PROC_I(inode)->sysctl, NULL); sysctl_head_put(head); } + /* Release any associated namespace */ + ns_ops = PROC_I(inode)->ns_ops; + if (ns_ops && ns_ops->put) + ns_ops->put(PROC_I(inode)->ns); } static struct kmem_cache * proc_inode_cachep; @@ -62,6 +67,8 @@ static struct inode *proc_alloc_inode(struct super_block *sb) ei->pde = NULL; ei->sysctl = NULL; ei->sysctl_entry = NULL; + ei->ns = NULL; + ei->ns_ops = NULL; inode = &ei->vfs_inode; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; return inode; diff --git a/fs/proc/internal.h b/fs/proc/internal.h index c03e8d3a3a5b..96245a1b1a7c 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h @@ -119,3 +119,21 @@ struct inode *proc_get_inode(struct super_block *, struct proc_dir_entry *); */ int proc_readdir(struct file *, void *, filldir_t); struct dentry *proc_lookup(struct inode *, struct dentry *, struct nameidata *); + + + +/* Lookups */ +typedef struct dentry *instantiate_t(struct inode *, struct dentry *, + struct task_struct *, const void *); +int proc_fill_cache(struct file *filp, void *dirent, filldir_t filldir, + const char *name, int len, + instantiate_t instantiate, struct task_struct *task, const void *ptr); +int pid_revalidate(struct dentry *dentry, struct nameidata *nd); +struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *task); +extern const struct dentry_operations pid_dentry_operations; +int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat); +int proc_setattr(struct dentry *dentry, struct iattr *attr); + +extern const struct inode_operations proc_ns_dir_inode_operations; +extern const struct file_operations proc_ns_dir_operations; + diff --git a/fs/proc/namespaces.c b/fs/proc/namespaces.c new file mode 100644 index 000000000000..6ae9f07d59ee --- /dev/null +++ b/fs/proc/namespaces.c @@ -0,0 +1,188 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "internal.h" + + +static const struct proc_ns_operations *ns_entries[] = { +}; + +static const struct file_operations ns_file_operations = { + .llseek = no_llseek, +}; + +static struct dentry *proc_ns_instantiate(struct inode *dir, + struct dentry *dentry, struct task_struct *task, const void *ptr) +{ + const struct proc_ns_operations *ns_ops = ptr; + struct inode *inode; + struct proc_inode *ei; + struct dentry *error = ERR_PTR(-ENOENT); + + inode = proc_pid_make_inode(dir->i_sb, task); + if (!inode) + goto out; + + ei = PROC_I(inode); + inode->i_mode = S_IFREG|S_IRUSR; + inode->i_fop = &ns_file_operations; + ei->ns_ops = ns_ops; + ei->ns = ns_ops->get(task); + if (!ei->ns) + goto out_iput; + + dentry->d_op = &pid_dentry_operations; + d_add(dentry, inode); + /* Close the race of the process dying before we return the dentry */ + if (pid_revalidate(dentry, NULL)) + error = NULL; +out: + return error; +out_iput: + iput(inode); + goto out; +} + +static int proc_ns_fill_cache(struct file *filp, void *dirent, + filldir_t filldir, struct task_struct *task, + const struct proc_ns_operations *ops) +{ + return proc_fill_cache(filp, dirent, filldir, + ops->name, strlen(ops->name), + proc_ns_instantiate, task, ops); +} + +static int proc_ns_dir_readdir(struct file *filp, void *dirent, + filldir_t filldir) +{ + int i; + struct dentry *dentry = filp->f_path.dentry; + struct inode *inode = dentry->d_inode; + struct task_struct *task = get_proc_task(inode); + const struct proc_ns_operations **entry, **last; + ino_t ino; + int ret; + + ret = -ENOENT; + if (!task) + goto out_no_task; + + ret = -EPERM; + if (!ptrace_may_access(task, PTRACE_MODE_READ)) + goto out; + + ret = 0; + i = filp->f_pos; + switch (i) { + case 0: + ino = inode->i_ino; + if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0) + goto out; + i++; + filp->f_pos++; + /* fall through */ + case 1: + ino = parent_ino(dentry); + if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0) + goto out; + i++; + filp->f_pos++; + /* fall through */ + default: + i -= 2; + if (i >= ARRAY_SIZE(ns_entries)) { + ret = 1; + goto out; + } + entry = ns_entries + i; + last = &ns_entries[ARRAY_SIZE(ns_entries) - 1]; + while (entry <= last) { + if (proc_ns_fill_cache(filp, dirent, filldir, + task, *entry) < 0) + goto out; + filp->f_pos++; + entry++; + } + } + + ret = 1; +out: + put_task_struct(task); +out_no_task: + return ret; +} + +const struct file_operations proc_ns_dir_operations = { + .read = generic_read_dir, + .readdir = proc_ns_dir_readdir, +}; + +static struct dentry *proc_ns_dir_lookup(struct inode *dir, + struct dentry *dentry, struct nameidata *nd) +{ + struct dentry *error; + struct task_struct *task = get_proc_task(dir); + const struct proc_ns_operations **entry, **last; + unsigned int len = dentry->d_name.len; + + error = ERR_PTR(-ENOENT); + + if (!task) + goto out_no_task; + + error = ERR_PTR(-EPERM); + if (!ptrace_may_access(task, PTRACE_MODE_READ)) + goto out; + + last = &ns_entries[ARRAY_SIZE(ns_entries) - 1]; + for (entry = ns_entries; entry <= last; entry++) { + if (strlen((*entry)->name) != len) + continue; + if (!memcmp(dentry->d_name.name, (*entry)->name, len)) + break; + } + if (entry > last) + goto out; + + error = proc_ns_instantiate(dir, dentry, task, *entry); +out: + put_task_struct(task); +out_no_task: + return error; +} + +const struct inode_operations proc_ns_dir_inode_operations = { + .lookup = proc_ns_dir_lookup, + .getattr = pid_getattr, + .setattr = proc_setattr, +}; + +struct file *proc_ns_fget(int fd) +{ + struct file *file; + + file = fget(fd); + if (!file) + return ERR_PTR(-EBADF); + + if (file->f_op != &ns_file_operations) + goto out_invalid; + + return file; + +out_invalid: + fput(file); + return ERR_PTR(-EINVAL); +} + diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index 838c1149251a..a6d2c6da5e5a 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -179,6 +179,8 @@ extern void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file); extern struct file *get_mm_exe_file(struct mm_struct *mm); extern void dup_mm_exe_file(struct mm_struct *oldmm, struct mm_struct *newmm); +extern struct file *proc_ns_fget(int fd); + #else #define proc_net_fops_create(net, name, mode, fops) ({ (void)(mode), NULL; }) @@ -239,6 +241,11 @@ static inline void dup_mm_exe_file(struct mm_struct *oldmm, struct mm_struct *newmm) {} +static inline struct file *proc_ns_fget(int fd) +{ + return ERR_PTR(-EINVAL); +} + #endif /* CONFIG_PROC_FS */ #if !defined(CONFIG_PROC_KCORE) @@ -250,6 +257,15 @@ kclist_add(struct kcore_list *new, void *addr, size_t size, int type) extern void kclist_add(struct kcore_list *, void *, size_t, int type); #endif +struct nsproxy; +struct proc_ns_operations { + const char *name; + int type; + void *(*get)(struct task_struct *task); + void (*put)(void *ns); + int (*install)(struct nsproxy *nsproxy, void *ns); +}; + union proc_op { int (*proc_get_link)(struct inode *, struct path *); int (*proc_read)(struct task_struct *task, char *page); @@ -268,6 +284,8 @@ struct proc_inode { struct proc_dir_entry *pde; struct ctl_table_header *sysctl; struct ctl_table *sysctl_entry; + void *ns; + const struct proc_ns_operations *ns_ops; struct inode vfs_inode; }; -- cgit From 13b6f57623bc485e116344fe91fbcb29f149242b Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Sun, 7 Mar 2010 18:14:23 -0800 Subject: ns proc: Add support for the network namespace. Implementing file descriptors for the network namespace is simple and straight forward. Acked-by: David S. Miller Acked-by: Daniel Lezcano Signed-off-by: Eric W. Biederman --- fs/proc/namespaces.c | 3 +++ include/linux/proc_fs.h | 1 + net/core/net_namespace.c | 31 +++++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+) (limited to 'include/linux') diff --git a/fs/proc/namespaces.c b/fs/proc/namespaces.c index 6ae9f07d59ee..dcbd483e9915 100644 --- a/fs/proc/namespaces.c +++ b/fs/proc/namespaces.c @@ -16,6 +16,9 @@ static const struct proc_ns_operations *ns_entries[] = { +#ifdef CONFIG_NET_NS + &netns_operations, +#endif }; static const struct file_operations ns_file_operations = { diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index a6d2c6da5e5a..62126ec6ede9 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -265,6 +265,7 @@ struct proc_ns_operations { void (*put)(void *ns); int (*install)(struct nsproxy *nsproxy, void *ns); }; +extern const struct proc_ns_operations netns_operations; union proc_op { int (*proc_get_link)(struct inode *, struct path *); diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 3f860261c5ee..bf7707e09a80 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -573,3 +573,34 @@ void unregister_pernet_device(struct pernet_operations *ops) mutex_unlock(&net_mutex); } EXPORT_SYMBOL_GPL(unregister_pernet_device); + +#ifdef CONFIG_NET_NS +static void *netns_get(struct task_struct *task) +{ + struct net *net; + rcu_read_lock(); + net = get_net(task->nsproxy->net_ns); + rcu_read_unlock(); + return net; +} + +static void netns_put(void *ns) +{ + put_net(ns); +} + +static int netns_install(struct nsproxy *nsproxy, void *ns) +{ + put_net(nsproxy->net_ns); + nsproxy->net_ns = get_net(ns); + return 0; +} + +const struct proc_ns_operations netns_operations = { + .name = "net", + .type = CLONE_NEWNET, + .get = netns_get, + .put = netns_put, + .install = netns_install, +}; +#endif -- cgit From 34482e89a5218f0f9317abf1cfba3bb38b5c29dd Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Sun, 7 Mar 2010 18:43:27 -0800 Subject: ns proc: Add support for the uts namespace Acked-by: Daniel Lezcano Signed-off-by: Eric W. Biederman --- fs/proc/namespaces.c | 3 +++ include/linux/proc_fs.h | 1 + kernel/utsname.c | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+) (limited to 'include/linux') diff --git a/fs/proc/namespaces.c b/fs/proc/namespaces.c index dcbd483e9915..b017181f1273 100644 --- a/fs/proc/namespaces.c +++ b/fs/proc/namespaces.c @@ -19,6 +19,9 @@ static const struct proc_ns_operations *ns_entries[] = { #ifdef CONFIG_NET_NS &netns_operations, #endif +#ifdef CONFIG_UTS_NS + &utsns_operations, +#endif }; static const struct file_operations ns_file_operations = { diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index 62126ec6ede9..52aa89df8a6d 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -266,6 +266,7 @@ struct proc_ns_operations { int (*install)(struct nsproxy *nsproxy, void *ns); }; extern const struct proc_ns_operations netns_operations; +extern const struct proc_ns_operations utsns_operations; union proc_op { int (*proc_get_link)(struct inode *, struct path *); diff --git a/kernel/utsname.c b/kernel/utsname.c index 44646179eaba..bff131b9510a 100644 --- a/kernel/utsname.c +++ b/kernel/utsname.c @@ -15,6 +15,7 @@ #include #include #include +#include static struct uts_namespace *create_uts_ns(void) { @@ -79,3 +80,41 @@ void free_uts_ns(struct kref *kref) put_user_ns(ns->user_ns); kfree(ns); } + +static void *utsns_get(struct task_struct *task) +{ + struct uts_namespace *ns = NULL; + struct nsproxy *nsproxy; + + rcu_read_lock(); + nsproxy = task_nsproxy(task); + if (nsproxy) { + ns = nsproxy->uts_ns; + get_uts_ns(ns); + } + rcu_read_unlock(); + + return ns; +} + +static void utsns_put(void *ns) +{ + put_uts_ns(ns); +} + +static int utsns_install(struct nsproxy *nsproxy, void *ns) +{ + get_uts_ns(ns); + put_uts_ns(nsproxy->uts_ns); + nsproxy->uts_ns = ns; + return 0; +} + +const struct proc_ns_operations utsns_operations = { + .name = "uts", + .type = CLONE_NEWUTS, + .get = utsns_get, + .put = utsns_put, + .install = utsns_install, +}; + -- cgit From a00eaf11a223c63fbb212369d6db69ce4c55a2d1 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Sun, 7 Mar 2010 18:48:39 -0800 Subject: ns proc: Add support for the ipc namespace Acked-by: Daniel Lezcano Signed-off-by: Eric W. Biederman --- fs/proc/namespaces.c | 3 +++ include/linux/proc_fs.h | 1 + ipc/namespace.c | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+) (limited to 'include/linux') diff --git a/fs/proc/namespaces.c b/fs/proc/namespaces.c index b017181f1273..f18d6d58bf79 100644 --- a/fs/proc/namespaces.c +++ b/fs/proc/namespaces.c @@ -22,6 +22,9 @@ static const struct proc_ns_operations *ns_entries[] = { #ifdef CONFIG_UTS_NS &utsns_operations, #endif +#ifdef CONFIG_IPC_NS + &ipcns_operations, +#endif }; static const struct file_operations ns_file_operations = { diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index 52aa89df8a6d..a23f0b72a023 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -267,6 +267,7 @@ struct proc_ns_operations { }; extern const struct proc_ns_operations netns_operations; extern const struct proc_ns_operations utsns_operations; +extern const struct proc_ns_operations ipcns_operations; union proc_op { int (*proc_get_link)(struct inode *, struct path *); diff --git a/ipc/namespace.c b/ipc/namespace.c index 8054c8e5faf1..ce0a647869b1 100644 --- a/ipc/namespace.c +++ b/ipc/namespace.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "util.h" @@ -140,3 +141,39 @@ void put_ipc_ns(struct ipc_namespace *ns) free_ipc_ns(ns); } } + +static void *ipcns_get(struct task_struct *task) +{ + struct ipc_namespace *ns = NULL; + struct nsproxy *nsproxy; + + rcu_read_lock(); + nsproxy = task_nsproxy(task); + if (nsproxy) + ns = get_ipc_ns(nsproxy->ipc_ns); + rcu_read_unlock(); + + return ns; +} + +static void ipcns_put(void *ns) +{ + return put_ipc_ns(ns); +} + +static int ipcns_install(struct nsproxy *nsproxy, void *ns) +{ + /* Ditch state from the old ipc namespace */ + exit_sem(current); + put_ipc_ns(nsproxy->ipc_ns); + nsproxy->ipc_ns = get_ipc_ns(ns); + return 0; +} + +const struct proc_ns_operations ipcns_operations = { + .name = "ipc", + .type = CLONE_NEWIPC, + .get = ipcns_get, + .put = ipcns_put, + .install = ipcns_install, +}; -- cgit From f063052947f770845a6252f7fa24f6f624592a24 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Wed, 4 May 2011 17:51:50 -0700 Subject: net: Allow setting the network namespace by fd Take advantage of the new abstraction and allow network devices to be placed in any network namespace that we have a fd to talk about. Acked-by: David S. Miller Acked-by: Daniel Lezcano Signed-off-by: Eric W. Biederman --- include/linux/if_link.h | 1 + include/net/net_namespace.h | 1 + net/core/net_namespace.c | 33 +++++++++++++++++++++++++++++++-- net/core/rtnetlink.c | 5 ++++- 4 files changed, 37 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/if_link.h b/include/linux/if_link.h index f4a2e6b1b864..0ee969a5593d 100644 --- a/include/linux/if_link.h +++ b/include/linux/if_link.h @@ -136,6 +136,7 @@ enum { IFLA_PORT_SELF, IFLA_AF_SPEC, IFLA_GROUP, /* Group the device belongs to */ + IFLA_NET_NS_FD, __IFLA_MAX }; diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index 3ae491932bc8..dcc8f5749d3f 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -119,6 +119,7 @@ static inline struct net *copy_net_ns(unsigned long flags, struct net *net_ns) extern struct list_head net_namespace_list; extern struct net *get_net_ns_by_pid(pid_t pid); +extern struct net *get_net_ns_by_fd(int pid); #ifdef CONFIG_NET_NS extern void __put_net(struct net *net); diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index bf7707e09a80..b7403ff4d6c6 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include #include @@ -343,6 +345,28 @@ struct net *get_net_ns_by_pid(pid_t pid) } EXPORT_SYMBOL_GPL(get_net_ns_by_pid); +struct net *get_net_ns_by_fd(int fd) +{ + struct proc_inode *ei; + struct file *file; + struct net *net; + + net = ERR_PTR(-EINVAL); + file = proc_ns_fget(fd); + if (!file) + goto out; + + ei = PROC_I(file->f_dentry->d_inode); + if (ei->ns_ops != &netns_operations) + goto out; + + net = get_net(ei->ns); +out: + if (file) + fput(file); + return net; +} + static int __init net_ns_init(void) { struct net_generic *ng; @@ -577,10 +601,15 @@ EXPORT_SYMBOL_GPL(unregister_pernet_device); #ifdef CONFIG_NET_NS static void *netns_get(struct task_struct *task) { - struct net *net; + struct net *net = NULL; + struct nsproxy *nsproxy; + rcu_read_lock(); - net = get_net(task->nsproxy->net_ns); + nsproxy = task_nsproxy(task); + if (nsproxy) + net = get_net(nsproxy->net_ns); rcu_read_unlock(); + return net; } diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index d7c4bb4b1820..dca9602c62e4 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -1043,6 +1043,7 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = { [IFLA_LINKMODE] = { .type = NLA_U8 }, [IFLA_LINKINFO] = { .type = NLA_NESTED }, [IFLA_NET_NS_PID] = { .type = NLA_U32 }, + [IFLA_NET_NS_FD] = { .type = NLA_U32 }, [IFLA_IFALIAS] = { .type = NLA_STRING, .len = IFALIASZ-1 }, [IFLA_VFINFO_LIST] = {. type = NLA_NESTED }, [IFLA_VF_PORTS] = { .type = NLA_NESTED }, @@ -1091,6 +1092,8 @@ struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[]) */ if (tb[IFLA_NET_NS_PID]) net = get_net_ns_by_pid(nla_get_u32(tb[IFLA_NET_NS_PID])); + else if (tb[IFLA_NET_NS_FD]) + net = get_net_ns_by_fd(nla_get_u32(tb[IFLA_NET_NS_FD])); else net = get_net(src_net); return net; @@ -1221,7 +1224,7 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, int send_addr_notify = 0; int err; - if (tb[IFLA_NET_NS_PID]) { + if (tb[IFLA_NET_NS_PID] || tb[IFLA_NET_NS_FD]) { struct net *net = rtnl_link_get_net(dev_net(dev), tb); if (IS_ERR(net)) { err = PTR_ERR(net); -- cgit From c0a86a9bea55d505574120f3e9775e3844276505 Mon Sep 17 00:00:00 2001 From: Seth Heasley Date: Tue, 19 Apr 2011 16:35:15 -0700 Subject: x86/PCI: irq and pci_ids patch for Intel Panther Point DeviceIDs This patch adds the LPC Controller DeviceIDs for the Intel Panther Point PCH. Acked-by: Jean Delvare Signed-off-by: Seth Heasley Signed-off-by: Jesse Barnes --- arch/x86/pci/irq.c | 4 +++- include/linux/pci_ids.h | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c index 8201165bae28..372e9b8989b3 100644 --- a/arch/x86/pci/irq.c +++ b/arch/x86/pci/irq.c @@ -602,7 +602,9 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route || (device >= PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MIN && device <= PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX) || (device >= PCI_DEVICE_ID_INTEL_DH89XXCC_LPC_MIN && - device <= PCI_DEVICE_ID_INTEL_DH89XXCC_LPC_MAX)) { + device <= PCI_DEVICE_ID_INTEL_DH89XXCC_LPC_MAX) + || (device >= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MIN && + device <= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MAX)) { r->name = "PIIX/ICH"; r->get = pirq_piix_get; r->set = pirq_piix_set; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 4e2c9150a785..52f4ed4de490 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2480,6 +2480,9 @@ #define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS 0x1c22 #define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MIN 0x1c41 #define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX 0x1c5f +#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS 0x1e22 +#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MIN 0x1e40 +#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MAX 0x1e5f #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22 #define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_0 0x1d40 #define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_1 0x1d41 -- cgit From 81f8115305f821335cf9e16110bf0806f7b93283 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 28 Apr 2011 13:25:36 +0900 Subject: i2c: i2c-sh_mobile bus speed platform data V2 Add support to the i2c-sh_mobile driver for setting the I2C bus speed using platform data. Signed-off-by: Magnus Damm Signed-off-by: Ben Dooks --- drivers/i2c/busses/i2c-sh_mobile.c | 13 +++++++++++-- include/linux/i2c/i2c-sh_mobile.h | 10 ++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 include/linux/i2c/i2c-sh_mobile.h (limited to 'include/linux') diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c index 5a1d37d0b62f..d917dd1cc091 100644 --- a/drivers/i2c/busses/i2c-sh_mobile.c +++ b/drivers/i2c/busses/i2c-sh_mobile.c @@ -32,6 +32,7 @@ #include #include #include +#include /* Transmit operation: */ /* */ @@ -117,7 +118,7 @@ struct sh_mobile_i2c_data { struct device *dev; void __iomem *reg; struct i2c_adapter adap; - + unsigned long bus_speed; struct clk *clk; u_int8_t icic; u_int8_t iccl; @@ -205,7 +206,7 @@ static void activate_ch(struct sh_mobile_i2c_data *pd) * We also round off the result. */ num = i2c_clk * 5; - denom = NORMAL_SPEED * 9; + denom = pd->bus_speed * 9; tmp = num * 10 / denom; if (tmp % 10 >= 5) pd->iccl = (u_int8_t)((num/denom) + 1); @@ -574,6 +575,7 @@ static int sh_mobile_i2c_hook_irqs(struct platform_device *dev, int hook) static int sh_mobile_i2c_probe(struct platform_device *dev) { + struct i2c_sh_mobile_platform_data *pdata = dev->dev.platform_data; struct sh_mobile_i2c_data *pd; struct i2c_adapter *adap; struct resource *res; @@ -618,6 +620,11 @@ static int sh_mobile_i2c_probe(struct platform_device *dev) goto err_irq; } + /* Use platformd data bus speed or NORMAL_SPEED */ + pd->bus_speed = NORMAL_SPEED; + if (pdata && pdata->bus_speed) + pd->bus_speed = pdata->bus_speed; + /* The IIC blocks on SH-Mobile ARM processors * come with two new bits in ICIC. */ @@ -658,6 +665,8 @@ static int sh_mobile_i2c_probe(struct platform_device *dev) goto err_all; } + dev_info(&dev->dev, "I2C adapter %d with bus speed %lu Hz\n", + adap->nr, pd->bus_speed); return 0; err_all: diff --git a/include/linux/i2c/i2c-sh_mobile.h b/include/linux/i2c/i2c-sh_mobile.h new file mode 100644 index 000000000000..beda7081aead --- /dev/null +++ b/include/linux/i2c/i2c-sh_mobile.h @@ -0,0 +1,10 @@ +#ifndef __I2C_SH_MOBILE_H__ +#define __I2C_SH_MOBILE_H__ + +#include + +struct i2c_sh_mobile_platform_data { + unsigned long bus_speed; +}; + +#endif /* __I2C_SH_MOBILE_H__ */ -- cgit From 0ee8dcb87e403397e575674d0e79272b06dea12e Mon Sep 17 00:00:00 2001 From: Xiao Guangrong Date: Wed, 9 Mar 2011 15:41:59 +0800 Subject: KVM: cleanup memslot_id function We can get memslot id from memslot->id directly Signed-off-by: Xiao Guangrong Signed-off-by: Avi Kivity --- include/linux/kvm_host.h | 6 +++++- virt/kvm/kvm_main.c | 17 ----------------- 2 files changed, 5 insertions(+), 18 deletions(-) (limited to 'include/linux') diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index ab428552af8e..57d7092d7717 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -365,7 +365,6 @@ pfn_t gfn_to_pfn_prot(struct kvm *kvm, gfn_t gfn, bool write_fault, bool *writable); pfn_t gfn_to_pfn_memslot(struct kvm *kvm, struct kvm_memory_slot *slot, gfn_t gfn); -int memslot_id(struct kvm *kvm, gfn_t gfn); void kvm_release_pfn_dirty(pfn_t); void kvm_release_pfn_clean(pfn_t pfn); void kvm_set_pfn_dirty(pfn_t pfn); @@ -597,6 +596,11 @@ static inline void kvm_guest_exit(void) current->flags &= ~PF_VCPU; } +static inline int memslot_id(struct kvm *kvm, gfn_t gfn) +{ + return gfn_to_memslot(kvm, gfn)->id; +} + static inline unsigned long gfn_to_hva_memslot(struct kvm_memory_slot *slot, gfn_t gfn) { diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 6330653480e4..58146457bf97 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -996,23 +996,6 @@ out: return size; } -int memslot_id(struct kvm *kvm, gfn_t gfn) -{ - int i; - struct kvm_memslots *slots = kvm_memslots(kvm); - struct kvm_memory_slot *memslot = NULL; - - for (i = 0; i < slots->nmemslots; ++i) { - memslot = &slots->memslots[i]; - - if (gfn >= memslot->base_gfn - && gfn < memslot->base_gfn + memslot->npages) - break; - } - - return memslot - slots->memslots; -} - static unsigned long gfn_to_hva_many(struct kvm_memory_slot *slot, gfn_t gfn, gfn_t *nr_pages) { -- cgit From c761e5868e6737abe0464636ebd7fcbb6814c626 Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti Date: Fri, 1 Apr 2011 11:25:03 -0300 Subject: Revert "KVM: Fix race between nmi injection and enabling nmi window" This reverts commit f86368493ec038218e8663cc1b6e5393cd8e008a. Simpler fix to follow. Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/x86.c | 4 +--- include/linux/kvm_host.h | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) (limited to 'include/linux') diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index a38fb9bb342b..b9402d5fa0e9 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -361,8 +361,8 @@ void kvm_propagate_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault) void kvm_inject_nmi(struct kvm_vcpu *vcpu) { - kvm_make_request(KVM_REQ_NMI, vcpu); kvm_make_request(KVM_REQ_EVENT, vcpu); + vcpu->arch.nmi_pending = 1; } EXPORT_SYMBOL_GPL(kvm_inject_nmi); @@ -5208,8 +5208,6 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) r = 1; goto out; } - if (kvm_check_request(KVM_REQ_NMI, vcpu)) - vcpu->arch.nmi_pending = true; } r = kvm_mmu_reload(vcpu); diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 57d7092d7717..7ca831e55186 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -43,7 +43,6 @@ #define KVM_REQ_DEACTIVATE_FPU 10 #define KVM_REQ_EVENT 11 #define KVM_REQ_APF_HALT 12 -#define KVM_REQ_NMI 13 #define KVM_USERSPACE_IRQ_SOURCE_ID 0 -- cgit From cef4dea07f6720b36cc93e18a2e68be4bdb71a92 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Wed, 20 Jan 2010 12:01:20 +0200 Subject: KVM: 16-byte mmio support Since sse instructions can issue 16-byte mmios, we need to support them. We can't increase the kvm_run mmio buffer size to 16 bytes without breaking compatibility, so instead we break the large mmios into two smaller 8-byte ones. Since the bus is 64-bit we aren't breaking any atomicity guarantees. Signed-off-by: Avi Kivity --- arch/x86/include/asm/kvm_host.h | 1 + arch/x86/kvm/x86.c | 34 +++++++++++++++++++++++++--------- include/linux/kvm_host.h | 7 ++++++- 3 files changed, 32 insertions(+), 10 deletions(-) (limited to 'include/linux') diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 35f81b110260..e820c6339b8b 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -30,6 +30,7 @@ #define KVM_MEMORY_SLOTS 32 /* memory slots that does not exposed to userspace */ #define KVM_PRIVATE_MEM_SLOTS 4 +#define KVM_MMIO_SIZE 16 #define KVM_PIO_PAGE_OFFSET 1 #define KVM_COALESCED_MMIO_PAGE_OFFSET 2 diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index bb6b9d3f5e93..11d692c7018d 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3833,8 +3833,10 @@ mmio: vcpu->mmio_needed = 1; vcpu->run->exit_reason = KVM_EXIT_MMIO; vcpu->run->mmio.phys_addr = vcpu->mmio_phys_addr = gpa; - vcpu->run->mmio.len = vcpu->mmio_size = bytes; + vcpu->mmio_size = bytes; + vcpu->run->mmio.len = min(vcpu->mmio_size, 8); vcpu->run->mmio.is_write = vcpu->mmio_is_write = 0; + vcpu->mmio_index = 0; return X86EMUL_IO_NEEDED; } @@ -3886,11 +3888,14 @@ mmio: val += handled; vcpu->mmio_needed = 1; + memcpy(vcpu->mmio_data, val, bytes); vcpu->run->exit_reason = KVM_EXIT_MMIO; vcpu->run->mmio.phys_addr = vcpu->mmio_phys_addr = gpa; - vcpu->run->mmio.len = vcpu->mmio_size = bytes; + vcpu->mmio_size = bytes; + vcpu->run->mmio.len = min(vcpu->mmio_size, 8); vcpu->run->mmio.is_write = vcpu->mmio_is_write = 1; - memcpy(vcpu->run->mmio.data, val, bytes); + memcpy(vcpu->run->mmio.data, vcpu->mmio_data, 8); + vcpu->mmio_index = 0; return X86EMUL_CONTINUE; } @@ -4498,11 +4503,9 @@ restart: if (!vcpu->arch.pio.in) vcpu->arch.pio.count = 0; r = EMULATE_DO_MMIO; - } else if (vcpu->mmio_needed) { - if (vcpu->mmio_is_write) - vcpu->mmio_needed = 0; + } else if (vcpu->mmio_needed) r = EMULATE_DO_MMIO; - } else if (r == EMULATION_RESTART) + else if (r == EMULATION_RESTART) goto restart; else r = EMULATE_DONE; @@ -5450,9 +5453,22 @@ static int complete_mmio(struct kvm_vcpu *vcpu) return 1; if (vcpu->mmio_needed) { - memcpy(vcpu->mmio_data, run->mmio.data, 8); - vcpu->mmio_read_completed = 1; vcpu->mmio_needed = 0; + if (!vcpu->mmio_is_write) + memcpy(vcpu->mmio_data, run->mmio.data, 8); + vcpu->mmio_index += 8; + if (vcpu->mmio_index < vcpu->mmio_size) { + run->exit_reason = KVM_EXIT_MMIO; + run->mmio.phys_addr = vcpu->mmio_phys_addr + vcpu->mmio_index; + memcpy(run->mmio.data, vcpu->mmio_data + vcpu->mmio_index, 8); + run->mmio.len = min(vcpu->mmio_size - vcpu->mmio_index, 8); + run->mmio.is_write = vcpu->mmio_is_write; + vcpu->mmio_needed = 1; + return 0; + } + if (vcpu->mmio_is_write) + return 1; + vcpu->mmio_read_completed = 1; } vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); r = emulate_instruction(vcpu, EMULTYPE_NO_DECODE); diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 7ca831e55186..d1f507567068 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -27,6 +27,10 @@ #include +#ifndef KVM_MMIO_SIZE +#define KVM_MMIO_SIZE 8 +#endif + /* * vcpu->requests bit members */ @@ -132,7 +136,8 @@ struct kvm_vcpu { int mmio_read_completed; int mmio_is_write; int mmio_size; - unsigned char mmio_data[8]; + int mmio_index; + unsigned char mmio_data[KVM_MMIO_SIZE]; gpa_t mmio_phys_addr; #endif -- cgit From 92a1f12d2598f429bd8639e21d89305e787115c5 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Fri, 25 Mar 2011 09:44:51 +0100 Subject: KVM: X86: Implement userspace interface to set virtual_tsc_khz This patch implements two new vm-ioctls to get and set the virtual_tsc_khz if the machine supports tsc-scaling. Setting the tsc-frequency is only possible before userspace creates any vcpu. Signed-off-by: Joerg Roedel Signed-off-by: Avi Kivity --- Documentation/kvm/api.txt | 23 +++++++++++++++++++++++ arch/x86/include/asm/kvm_host.h | 7 +++++++ arch/x86/kvm/svm.c | 20 ++++++++++++++++++++ arch/x86/kvm/x86.c | 35 +++++++++++++++++++++++++++++++++++ include/linux/kvm.h | 5 +++++ 5 files changed, 90 insertions(+) (limited to 'include/linux') diff --git a/Documentation/kvm/api.txt b/Documentation/kvm/api.txt index 9bef4e4cec50..1b9eaa7e8856 100644 --- a/Documentation/kvm/api.txt +++ b/Documentation/kvm/api.txt @@ -1263,6 +1263,29 @@ struct kvm_assigned_msix_entry { __u16 padding[3]; }; +4.54 KVM_SET_TSC_KHZ + +Capability: KVM_CAP_TSC_CONTROL +Architectures: x86 +Type: vcpu ioctl +Parameters: virtual tsc_khz +Returns: 0 on success, -1 on error + +Specifies the tsc frequency for the virtual machine. The unit of the +frequency is KHz. + +4.55 KVM_GET_TSC_KHZ + +Capability: KVM_CAP_GET_TSC_KHZ +Architectures: x86 +Type: vcpu ioctl +Parameters: none +Returns: virtual tsc-khz on success, negative value on error + +Returns the tsc frequency of the guest. The unit of the return value is +KHz. If the host has unstable tsc this ioctl returns -EIO instead as an +error. + 5. The kvm_run structure Application code obtains a pointer to the kvm_run structure by diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index da0a8ce3a139..bd57639fd5db 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -655,6 +655,13 @@ u8 kvm_get_guest_memory_type(struct kvm_vcpu *vcpu, gfn_t gfn); extern bool tdp_enabled; +/* control of guest tsc rate supported? */ +extern bool kvm_has_tsc_control; +/* minimum supported tsc_khz for guests */ +extern u32 kvm_min_guest_tsc_khz; +/* maximum supported tsc_khz for guests */ +extern u32 kvm_max_guest_tsc_khz; + enum emulation_result { EMULATE_DONE, /* no further processing */ EMULATE_DO_MMIO, /* kvm_run filled with mmio request */ diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 8c4549bef4ed..a98873762433 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -64,6 +64,8 @@ MODULE_LICENSE("GPL"); #define DEBUGCTL_RESERVED_BITS (~(0x3fULL)) #define TSC_RATIO_RSVD 0xffffff0000000000ULL +#define TSC_RATIO_MIN 0x0000000000000001ULL +#define TSC_RATIO_MAX 0x000000ffffffffffULL static bool erratum_383_found __read_mostly; @@ -189,6 +191,7 @@ static int nested_svm_intercept(struct vcpu_svm *svm); static int nested_svm_vmexit(struct vcpu_svm *svm); static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr, bool has_error_code, u32 error_code); +static u64 __scale_tsc(u64 ratio, u64 tsc); enum { VMCB_INTERCEPTS, /* Intercept vectors, TSC offset, @@ -798,6 +801,23 @@ static __init int svm_hardware_setup(void) if (boot_cpu_has(X86_FEATURE_FXSR_OPT)) kvm_enable_efer_bits(EFER_FFXSR); + if (boot_cpu_has(X86_FEATURE_TSCRATEMSR)) { + u64 max; + + kvm_has_tsc_control = true; + + /* + * Make sure the user can only configure tsc_khz values that + * fit into a signed integer. + * A min value is not calculated needed because it will always + * be 1 on all machines and a value of 0 is used to disable + * tsc-scaling for the vcpu. + */ + max = min(0x7fffffffULL, __scale_tsc(tsc_khz, TSC_RATIO_MAX)); + + kvm_max_guest_tsc_khz = max; + } + if (nested) { printk(KERN_INFO "kvm: Nested Virtualization enabled\n"); kvm_enable_efer_bits(EFER_SVME | EFER_LMSLE); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 579ce34e7904..1d5a7f418795 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -87,6 +87,11 @@ EXPORT_SYMBOL_GPL(kvm_x86_ops); int ignore_msrs = 0; module_param_named(ignore_msrs, ignore_msrs, bool, S_IRUGO | S_IWUSR); +bool kvm_has_tsc_control; +EXPORT_SYMBOL_GPL(kvm_has_tsc_control); +u32 kvm_max_guest_tsc_khz; +EXPORT_SYMBOL_GPL(kvm_max_guest_tsc_khz); + #define KVM_NR_SHARED_MSRS 16 struct kvm_shared_msrs_global { @@ -1986,6 +1991,7 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_X86_ROBUST_SINGLESTEP: case KVM_CAP_XSAVE: case KVM_CAP_ASYNC_PF: + case KVM_CAP_GET_TSC_KHZ: r = 1; break; case KVM_CAP_COALESCED_MMIO: @@ -2012,6 +2018,9 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_XCRS: r = cpu_has_xsave; break; + case KVM_CAP_TSC_CONTROL: + r = kvm_has_tsc_control; + break; default: r = 0; break; @@ -3045,6 +3054,32 @@ long kvm_arch_vcpu_ioctl(struct file *filp, r = kvm_vcpu_ioctl_x86_set_xcrs(vcpu, u.xcrs); break; } + case KVM_SET_TSC_KHZ: { + u32 user_tsc_khz; + + r = -EINVAL; + if (!kvm_has_tsc_control) + break; + + user_tsc_khz = (u32)arg; + + if (user_tsc_khz >= kvm_max_guest_tsc_khz) + goto out; + + kvm_x86_ops->set_tsc_khz(vcpu, user_tsc_khz); + + r = 0; + goto out; + } + case KVM_GET_TSC_KHZ: { + r = -EIO; + if (check_tsc_unstable()) + goto out; + + r = vcpu_tsc_khz(vcpu); + + goto out; + } default: r = -EINVAL; } diff --git a/include/linux/kvm.h b/include/linux/kvm.h index ea2dc1a2e13d..2f63ebeac639 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -541,6 +541,8 @@ struct kvm_ppc_pvinfo { #define KVM_CAP_PPC_GET_PVINFO 57 #define KVM_CAP_PPC_IRQ_LEVEL 58 #define KVM_CAP_ASYNC_PF 59 +#define KVM_CAP_TSC_CONTROL 60 +#define KVM_CAP_GET_TSC_KHZ 61 #ifdef KVM_CAP_IRQ_ROUTING @@ -677,6 +679,9 @@ struct kvm_clock_data { #define KVM_SET_PIT2 _IOW(KVMIO, 0xa0, struct kvm_pit_state2) /* Available with KVM_CAP_PPC_GET_PVINFO */ #define KVM_PPC_GET_PVINFO _IOW(KVMIO, 0xa1, struct kvm_ppc_pvinfo) +/* Available with KVM_CAP_TSC_CONTROL */ +#define KVM_SET_TSC_KHZ _IO(KVMIO, 0xa2) +#define KVM_GET_TSC_KHZ _IO(KVMIO, 0xa3) /* * ioctls for vcpu fds -- cgit From b42fc3cbc3d6e284463e93896679379443e19d56 Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Tue, 12 Apr 2011 21:30:17 -0400 Subject: KVM: Fix off by one in kvm_for_each_vcpu iteration This patch avoids gcc issuing the following warning when KVM_MAX_VCPUS=1: warning: array subscript is above array bounds kvm_for_each_vcpu currently checks to see if the index for the vcpu is valid /after/ loading it. We don't run into problems because the address is still inside the enclosing struct kvm and we never deference or write to it, so this isn't a security issue. The warning occurs when KVM_MAX_VCPUS=1 because the increment portion of the loop will *always* cause the loop to load an invalid location since ++idx will always be > 0. This patch moves the load so that the check occurs before the load and we don't run into the compiler warning. Signed-off-by: Neil Brown Signed-off-by: Jeff Mahoney Signed-off-by: Avi Kivity --- include/linux/kvm_host.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index d1f507567068..0bc3d372e3cb 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -296,9 +296,10 @@ static inline struct kvm_vcpu *kvm_get_vcpu(struct kvm *kvm, int i) } #define kvm_for_each_vcpu(idx, vcpup, kvm) \ - for (idx = 0, vcpup = kvm_get_vcpu(kvm, idx); \ - idx < atomic_read(&kvm->online_vcpus) && vcpup; \ - vcpup = kvm_get_vcpu(kvm, ++idx)) + for (idx = 0; \ + idx < atomic_read(&kvm->online_vcpus) && \ + (vcpup = kvm_get_vcpu(kvm, idx)) != NULL; \ + idx++) int kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned id); void kvm_vcpu_uninit(struct kvm_vcpu *vcpu); -- cgit From b130e5cec958bae3867cf6ab09a9b24ba8fada01 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Tue, 3 May 2011 16:57:07 -0700 Subject: nl80211: Introduce NL80211_MESH_SETUP_USERSPACE_AMPE Introduce a new configuration option to support AMPE from userspace. Prior to this series we only supported authentication in userspace: an authentication daemon would authenticate peer candidates in userspace and hand them over to the kernel. From that point the mesh stack would take over and establish a peer link (Mesh Peering Management). These patches introduce support for Authenticated Mesh Peering Exchange in userspace. The userspace daemon implements the AMPE protocol and on successfull completion create mesh peers and install encryption keys. Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- include/linux/nl80211.h | 10 ++++++++++ include/net/cfg80211.h | 4 +++- net/mac80211/cfg.c | 6 +++++- net/mac80211/ieee80211_i.h | 6 +++++- net/mac80211/mesh.c | 2 +- net/mac80211/mesh_plink.c | 5 +++-- net/wireless/nl80211.c | 4 +++- 7 files changed, 30 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index a75dea9c416e..c53b916036c5 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -1769,6 +1769,15 @@ enum nl80211_meshconf_params { * @NL80211_MESH_SETUP_USERSPACE_AUTH: Enable this option if an authentication * daemon will be authenticating mesh candidates. * + * @NL80211_MESH_SETUP_USERSPACE_AMPE: Enable this option if an authentication + * daemon will be securing peer link frames. AMPE is a secured version of Mesh + * Peering Management (MPM) and is implemented with the assistance of a + * userspace daemon. When this flag is set, the kernel will send peer + * management frames to a userspace daemon that will implement AMPE + * functionality (security capabilities selection, key confirmation, and key + * management). When the flag is unset (default), the kernel can autonomously + * complete (unsecured) mesh peering without the need of a userspace daemon. + * * @NL80211_MESH_SETUP_ATTR_MAX: highest possible mesh setup attribute number * @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use */ @@ -1778,6 +1787,7 @@ enum nl80211_mesh_setup_params { NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC, NL80211_MESH_SETUP_IE, NL80211_MESH_SETUP_USERSPACE_AUTH, + NL80211_MESH_SETUP_USERSPACE_AMPE, /* keep last */ __NL80211_MESH_SETUP_ATTR_AFTER_LAST, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 0920daf36807..10c17d68059f 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -695,7 +695,8 @@ struct mesh_config { * @path_metric: which metric to use * @ie: vendor information elements (optional) * @ie_len: length of vendor information elements - * @is_secure: or not + * @is_authenticated: this mesh requires authentication + * @is_secure: this mesh uses security * * These parameters are fixed when the mesh is created. */ @@ -706,6 +707,7 @@ struct mesh_setup { u8 path_metric; const u8 *ie; u8 ie_len; + bool is_authenticated; bool is_secure; }; diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 1ebc13383ae7..18c2555e04e6 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1064,7 +1064,11 @@ static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh, memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len); ifmsh->mesh_pp_id = setup->path_sel_proto; ifmsh->mesh_pm_id = setup->path_metric; - ifmsh->is_secure = setup->is_secure; + ifmsh->security = IEEE80211_MESH_SEC_NONE; + if (setup->is_authenticated) + ifmsh->security |= IEEE80211_MESH_SEC_AUTHED; + if (setup->is_secure) + ifmsh->security |= IEEE80211_MESH_SEC_SECURED; return 0; } diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index e89bc27f8dc3..7f4d0dc1d534 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -490,7 +490,11 @@ struct ieee80211_if_mesh { bool accepting_plinks; const u8 *ie; u8 ie_len; - bool is_secure; + enum { + IEEE80211_MESH_SEC_NONE = 0x0, + IEEE80211_MESH_SEC_AUTHED = 0x1, + IEEE80211_MESH_SEC_SECURED = 0x2, + } security; }; #ifdef CONFIG_MAC80211_MESH diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index c1299e249541..2a59eb345131 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -574,7 +574,7 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, &elems); /* ignore beacons from secure mesh peers if our security is off */ - if (elems.rsn_len && !sdata->u.mesh.is_secure) + if (elems.rsn_len && sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) return; if (elems.ds_params && elems.ds_params_len == 1) diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 84e5b056af02..87abf8deb369 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -251,7 +251,7 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates, rcu_read_unlock(); /* Userspace handles peer allocation when security is enabled * */ - if (sdata->u.mesh.is_secure) + if (sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED) cfg80211_notify_new_peer_candidate(sdata->dev, hw_addr, elems->ie_start, elems->total_len, GFP_KERNEL); @@ -460,7 +460,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m mpl_dbg("Mesh plink: missing necessary peer link ie\n"); return; } - if (elems.rsn_len && !sdata->u.mesh.is_secure) { + if (elems.rsn_len && + sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) { mpl_dbg("Mesh plink: can't establish link with secure peer\n"); return; } diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 0a199a1ca9b6..64efc2d7a7ad 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -2871,6 +2871,7 @@ static const struct nla_policy [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG }, [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY, .len = IEEE80211_MAX_DATA_LEN }, + [NL80211_MESH_SETUP_USERSPACE_AMPE] = { .type = NLA_FLAG }, }; static int nl80211_parse_mesh_config(struct genl_info *info, @@ -2980,7 +2981,8 @@ static int nl80211_parse_mesh_setup(struct genl_info *info, setup->ie = nla_data(ieattr); setup->ie_len = nla_len(ieattr); } - setup->is_secure = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AUTH]); + setup->is_authenticated = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AUTH]); + setup->is_secure = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AMPE]); return 0; } -- cgit From d3aaec8ab76c2d604c2ba7332e1338674607597b Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Tue, 3 May 2011 16:57:09 -0700 Subject: mac80211: Drop MESH_PLINK category and use new ANA-approved MESH_ACTION Note: This breaks compatibility with previous mesh protocol instances. Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- include/linux/ieee80211.h | 5 ++--- net/mac80211/mesh.c | 2 +- net/mac80211/mesh_plink.c | 2 +- net/mac80211/rx.c | 7 +++++-- 4 files changed, 9 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 79690b710665..ee1c96a866cc 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -1261,9 +1261,8 @@ enum ieee80211_category { WLAN_CATEGORY_MULTIHOP_ACTION = 14, WLAN_CATEGORY_SELF_PROTECTED = 15, WLAN_CATEGORY_WMM = 17, - /* TODO: remove MESH_PLINK and MESH_PATH_SEL after */ - /* mesh is updated to current 802.11s draft */ - WLAN_CATEGORY_MESH_PLINK = 30, + /* TODO: remove MESH_PATH_SEL after mesh is updated + * to current 802.11s draft */ WLAN_CATEGORY_MESH_PATH_SEL = 32, WLAN_CATEGORY_VENDOR_SPECIFIC_PROTECTED = 126, WLAN_CATEGORY_VENDOR_SPECIFIC = 127, diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 2a59eb345131..75378e852f00 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -600,7 +600,7 @@ static void ieee80211_mesh_rx_mgmt_action(struct ieee80211_sub_if_data *sdata, struct ieee80211_rx_status *rx_status) { switch (mgmt->u.action.category) { - case WLAN_CATEGORY_MESH_PLINK: + case WLAN_CATEGORY_MESH_ACTION: mesh_rx_plink_frame(sdata, mgmt, len, rx_status); break; case WLAN_CATEGORY_MESH_PATH_SEL: diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 87abf8deb369..0120e9e36286 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -182,7 +182,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, memcpy(mgmt->da, da, ETH_ALEN); memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); /* BSSID is left zeroed, wildcard value */ - mgmt->u.action.category = WLAN_CATEGORY_MESH_PLINK; + mgmt->u.action.category = WLAN_CATEGORY_MESH_ACTION; mgmt->u.action.u.plink_action.action_code = action; if (action == PLINK_CLOSE) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 81241e18f3a4..634f3d97a279 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -495,8 +495,11 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) return RX_DROP_MONITOR; if (ieee80211_is_action(hdr->frame_control)) { + u8 category; mgmt = (struct ieee80211_mgmt *)hdr; - if (mgmt->u.action.category != WLAN_CATEGORY_MESH_PLINK) + category = mgmt->u.action.category; + if (category != WLAN_CATEGORY_MESH_ACTION && + category != WLAN_CATEGORY_SELF_PROTECTED) return RX_DROP_MONITOR; return RX_CONTINUE; } @@ -2205,7 +2208,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) goto handled; } break; - case WLAN_CATEGORY_MESH_PLINK: + case WLAN_CATEGORY_MESH_ACTION: if (!ieee80211_vif_is_mesh(&sdata->vif)) break; goto queue; -- cgit From 0a35d36d6f019bde6c98812456798275b02e5aee Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Wed, 4 May 2011 10:24:56 -0700 Subject: cfg80211: Use capability info to detect mesh beacons. Mesh beacons no longer use all-zeroes BSSID. Beacon frames for MBSS, infrastructure BSS, or IBSS are differentiated by the Capability Information field in the Beacon frame. A mesh STA sets the ESS and IBSS subfields to 0 in transmitted Beacon or Probe Response management frames. Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- include/linux/ieee80211.h | 5 +++++ net/wireless/scan.c | 14 +++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index ee1c96a866cc..d527fb7bd67a 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -1002,6 +1002,11 @@ struct ieee80211_ht_info { #define WLAN_CAPABILITY_ESS (1<<0) #define WLAN_CAPABILITY_IBSS (1<<1) + +/* A mesh STA sets the ESS and IBSS capability bits to zero */ +#define WLAN_CAPABILITY_IS_MBSS(cap) \ + (!((cap) & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS))) + #define WLAN_CAPABILITY_CF_POLLABLE (1<<2) #define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3) #define WLAN_CAPABILITY_PRIVACY (1<<4) diff --git a/net/wireless/scan.c b/net/wireless/scan.c index fbf6f33ae4d0..62e542a2b192 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -210,7 +210,7 @@ static bool is_mesh(struct cfg80211_bss *a, { const u8 *ie; - if (!is_zero_ether_addr(a->bssid)) + if (!WLAN_CAPABILITY_IS_MBSS(a->capability)) return false; ie = cfg80211_find_ie(WLAN_EID_MESH_ID, @@ -248,11 +248,7 @@ static int cmp_bss(struct cfg80211_bss *a, if (a->channel != b->channel) return b->channel->center_freq - a->channel->center_freq; - r = memcmp(a->bssid, b->bssid, ETH_ALEN); - if (r) - return r; - - if (is_zero_ether_addr(a->bssid)) { + if (WLAN_CAPABILITY_IS_MBSS(a->capability | b->capability)) { r = cmp_ies(WLAN_EID_MESH_ID, a->information_elements, a->len_information_elements, @@ -267,6 +263,10 @@ static int cmp_bss(struct cfg80211_bss *a, b->len_information_elements); } + r = memcmp(a->bssid, b->bssid, ETH_ALEN); + if (r) + return r; + return cmp_ies(WLAN_EID_SSID, a->information_elements, a->len_information_elements, @@ -407,7 +407,7 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev, res->ts = jiffies; - if (is_zero_ether_addr(res->pub.bssid)) { + if (WLAN_CAPABILITY_IS_MBSS(res->pub.capability)) { /* must be mesh, verify */ meshid = cfg80211_find_ie(WLAN_EID_MESH_ID, res->pub.information_elements, -- cgit From 9c3990aaec0ad9f686ef6480f6861f2df89b2a7a Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Tue, 3 May 2011 16:57:11 -0700 Subject: nl80211: Let userspace drive the peer link management states. Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- include/linux/nl80211.h | 4 ++++ include/net/cfg80211.h | 29 +++++++++++++++++++++++++++++ net/mac80211/cfg.c | 30 +++++++++++++++++++++--------- net/mac80211/sta_info.h | 23 ----------------------- net/wireless/nl80211.c | 6 ++++++ 5 files changed, 60 insertions(+), 32 deletions(-) (limited to 'include/linux') diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index c53b916036c5..de96783954a1 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -913,6 +913,9 @@ enum nl80211_commands { * @NL80211_ATTR_SUPPORT_MESH_AUTH: Currently, this means the underlying driver * allows auth frames in a mesh to be passed to userspace for processing via * the @NL80211_MESH_SETUP_USERSPACE_AUTH flag. + * @NL80211_ATTR_STA_PLINK_STATE: The state of a mesh peer link. Used when + * userspace is driving the peer link management state machine. + * @NL80211_MESH_SETUP_USERSPACE_AMPE must be enabled. * * @NL80211_ATTR_WOWLAN_SUPPORTED: indicates, as part of the wiphy capabilities, * the supported WoWLAN triggers @@ -1109,6 +1112,7 @@ enum nl80211_attrs { NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX, NL80211_ATTR_SUPPORT_MESH_AUTH, + NL80211_ATTR_STA_PLINK_STATE, NL80211_ATTR_WOWLAN_TRIGGERS, NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 10c17d68059f..4b0d035be64f 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -371,6 +371,33 @@ enum plink_actions { PLINK_ACTION_BLOCK, }; +/** + * enum plink_states - state of a mesh peer link finite state machine + * + * @PLINK_LISTEN: initial state, considered the implicit state of non + * existant mesh peer links + * @PLINK_OPN_SNT: mesh plink open frame has been sent to this mesh + * peer @PLINK_OPN_RCVD: mesh plink open frame has been received from + * this mesh peer + * @PLINK_CNF_RCVD: mesh plink confirm frame has been received from + * this mesh peer + * @PLINK_ESTAB: mesh peer link is established + * @PLINK_HOLDING: mesh peer link is being closed or cancelled + * @PLINK_BLOCKED: all frames transmitted from this mesh plink are + * discarded + * @PLINK_INVALID: reserved + */ +enum plink_state { + PLINK_LISTEN, + PLINK_OPN_SNT, + PLINK_OPN_RCVD, + PLINK_CNF_RCVD, + PLINK_ESTAB, + PLINK_HOLDING, + PLINK_BLOCKED, + PLINK_INVALID, +}; + /** * struct station_parameters - station parameters * @@ -387,6 +414,7 @@ enum plink_actions { * @listen_interval: listen interval or -1 for no change * @aid: AID or zero for no change * @plink_action: plink action to take + * @plink_state: set the peer link state for a station * @ht_capa: HT capabilities of station */ struct station_parameters { @@ -397,6 +425,7 @@ struct station_parameters { u16 aid; u8 supported_rates_len; u8 plink_action; + u8 plink_state; struct ieee80211_ht_cap *ht_capa; }; diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 18c2555e04e6..51f775772d9e 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -734,15 +734,27 @@ static void sta_apply_parameters(struct ieee80211_local *local, params->ht_capa, &sta->sta.ht_cap); - if (ieee80211_vif_is_mesh(&sdata->vif) && params->plink_action) { - switch (params->plink_action) { - case PLINK_ACTION_OPEN: - mesh_plink_open(sta); - break; - case PLINK_ACTION_BLOCK: - mesh_plink_block(sta); - break; - } + if (ieee80211_vif_is_mesh(&sdata->vif)) { + if (sdata->u.mesh.security & IEEE80211_MESH_SEC_SECURED) + switch (params->plink_state) { + case PLINK_LISTEN: + case PLINK_ESTAB: + case PLINK_BLOCKED: + sta->plink_state = params->plink_state; + break; + default: + /* nothing */ + break; + } + else + switch (params->plink_action) { + case PLINK_ACTION_OPEN: + mesh_plink_open(sta); + break; + case PLINK_ACTION_BLOCK: + mesh_plink_block(sta); + break; + } } } diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index af1a7f8c8675..f00b4dcb49d7 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -173,29 +173,6 @@ struct sta_ampdu_mlme { }; -/** - * enum plink_state - state of a mesh peer link finite state machine - * - * @PLINK_LISTEN: initial state, considered the implicit state of non existant - * mesh peer links - * @PLINK_OPN_SNT: mesh plink open frame has been sent to this mesh peer - * @PLINK_OPN_RCVD: mesh plink open frame has been received from this mesh peer - * @PLINK_CNF_RCVD: mesh plink confirm frame has been received from this mesh - * peer - * @PLINK_ESTAB: mesh peer link is established - * @PLINK_HOLDING: mesh peer link is being closed or cancelled - * @PLINK_BLOCKED: all frames transmitted from this mesh plink are discarded - */ -enum plink_state { - PLINK_LISTEN, - PLINK_OPN_SNT, - PLINK_OPN_RCVD, - PLINK_CNF_RCVD, - PLINK_ESTAB, - PLINK_HOLDING, - PLINK_BLOCKED -}; - /** * struct sta_info - STA information * diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 64efc2d7a7ad..f698c1d116e4 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -174,6 +174,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG }, [NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED }, [NL80211_ATTR_WOWLAN_TRIGGERS] = { .type = NLA_NESTED }, + [NL80211_ATTR_STA_PLINK_STATE] = { .type = NLA_U8 }, }; /* policy for the key attributes */ @@ -2247,6 +2248,7 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) memset(¶ms, 0, sizeof(params)); params.listen_interval = -1; + params.plink_state = PLINK_INVALID; if (info->attrs[NL80211_ATTR_STA_AID]) return -EINVAL; @@ -2278,6 +2280,10 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) params.plink_action = nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]); + if (info->attrs[NL80211_ATTR_STA_PLINK_STATE]) + params.plink_state = + nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]); + err = get_vlan(info, rdev, ¶ms.vlan); if (err) goto out; -- cgit From 8f9cb77d6d213c153b0571f494df0c24456aaf47 Mon Sep 17 00:00:00 2001 From: Thomas Pedersen Date: Tue, 3 May 2011 16:57:14 -0700 Subject: mac80211: Self-protected management frames are not robust They may contain encrypted information elements (as AMPE frames do) but they are not encrypted. Signed-off-by: Thomas Pedersen Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- include/linux/ieee80211.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index d527fb7bd67a..b2eee5879883 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -1520,6 +1520,7 @@ static inline bool ieee80211_is_robust_mgmt_frame(struct ieee80211_hdr *hdr) category = ((u8 *) hdr) + 24; return *category != WLAN_CATEGORY_PUBLIC && *category != WLAN_CATEGORY_HT && + *category != WLAN_CATEGORY_SELF_PROTECTED && *category != WLAN_CATEGORY_VENDOR_SPECIFIC; } -- cgit From 1073e4ee595265086a592a056d903bf4fcc8885a Mon Sep 17 00:00:00 2001 From: RafaÅ‚ MiÅ‚ecki Date: Wed, 11 May 2011 02:08:09 +0200 Subject: bcma: add missing GPIO defines, use PULL register only when available MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Similar patch was commited to ssb. Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/bcma/driver_chipcommon.c | 6 ++++-- include/linux/bcma/bcma_driver_chipcommon.h | 5 +++++ 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/drivers/bcma/driver_chipcommon.c b/drivers/bcma/driver_chipcommon.c index caf596091d4d..606102256b44 100644 --- a/drivers/bcma/driver_chipcommon.c +++ b/drivers/bcma/driver_chipcommon.c @@ -29,8 +29,10 @@ void bcma_core_chipcommon_init(struct bcma_drv_cc *cc) if (cc->core->id.rev >= 35) cc->capabilities_ext = bcma_cc_read32(cc, BCMA_CC_CAP_EXT); - bcma_cc_write32(cc, 0x58, 0); - bcma_cc_write32(cc, 0x5C, 0); + if (cc->core->id.rev >= 20) { + bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, 0); + bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, 0); + } if (cc->capabilities & BCMA_CC_CAP_PMU) bcma_pmu_init(cc); diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h index 4f8fd6a4c1e6..083c3b6cd5ce 100644 --- a/include/linux/bcma/bcma_driver_chipcommon.h +++ b/include/linux/bcma/bcma_driver_chipcommon.h @@ -113,6 +113,8 @@ #define BCMA_CC_FLASHDATA 0x0048 #define BCMA_CC_BCAST_ADDR 0x0050 #define BCMA_CC_BCAST_DATA 0x0054 +#define BCMA_CC_GPIOPULLUP 0x0058 /* Rev >= 20 only */ +#define BCMA_CC_GPIOPULLDOWN 0x005C /* Rev >= 20 only */ #define BCMA_CC_GPIOIN 0x0060 #define BCMA_CC_GPIOOUT 0x0064 #define BCMA_CC_GPIOOUTEN 0x0068 @@ -121,6 +123,9 @@ #define BCMA_CC_GPIOIRQ 0x0074 #define BCMA_CC_WATCHDOG 0x0080 #define BCMA_CC_GPIOTIMER 0x0088 /* LED powersave (corerev >= 16) */ +#define BCMA_CC_GPIOTIMER_OFFTIME 0x0000FFFF +#define BCMA_CC_GPIOTIMER_OFFTIME_SHIFT 0 +#define BCMA_CC_GPIOTIMER_ONTIME 0xFFFF0000 #define BCMA_CC_GPIOTIMER_ONTIME_SHIFT 16 #define BCMA_CC_GPIOTOUTM 0x008C /* LED powersave (corerev >= 16) */ #define BCMA_CC_CLOCK_N 0x0090 -- cgit From 8576f815d5c8beb8b10f96abe31831b90af3d352 Mon Sep 17 00:00:00 2001 From: RafaÅ‚ MiÅ‚ecki Date: Wed, 11 May 2011 02:10:58 +0200 Subject: ssb: move ssb_commit_settings and export it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commiting settings is possible on devices without PCI core (but with CC core). Export it for usage in drivers supporting other cores. Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/ssb/driver_pcicore.c | 26 -------------------------- drivers/ssb/main.c | 25 +++++++++++++++++++++++++ include/linux/ssb/ssb.h | 1 + 3 files changed, 26 insertions(+), 26 deletions(-) (limited to 'include/linux') diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c index 8fde1220bc89..82feb348c8bb 100644 --- a/drivers/ssb/driver_pcicore.c +++ b/drivers/ssb/driver_pcicore.c @@ -21,8 +21,6 @@ static u16 ssb_pcie_mdio_read(struct ssb_pcicore *pc, u8 device, u8 address); static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device, u8 address, u16 data); -static void ssb_commit_settings(struct ssb_bus *bus); - static inline u32 pcicore_read32(struct ssb_pcicore *pc, u16 offset) { @@ -659,30 +657,6 @@ static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device, pcicore_write32(pc, mdio_control, 0); } -static void ssb_broadcast_value(struct ssb_device *dev, - u32 address, u32 data) -{ - /* This is used for both, PCI and ChipCommon core, so be careful. */ - BUILD_BUG_ON(SSB_PCICORE_BCAST_ADDR != SSB_CHIPCO_BCAST_ADDR); - BUILD_BUG_ON(SSB_PCICORE_BCAST_DATA != SSB_CHIPCO_BCAST_DATA); - - ssb_write32(dev, SSB_PCICORE_BCAST_ADDR, address); - ssb_read32(dev, SSB_PCICORE_BCAST_ADDR); /* flush */ - ssb_write32(dev, SSB_PCICORE_BCAST_DATA, data); - ssb_read32(dev, SSB_PCICORE_BCAST_DATA); /* flush */ -} - -static void ssb_commit_settings(struct ssb_bus *bus) -{ - struct ssb_device *dev; - - dev = bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev; - if (WARN_ON(!dev)) - return; - /* This forces an update of the cached registers. */ - ssb_broadcast_value(dev, 0xFD8, 0); -} - int ssb_pcicore_dev_irqvecs_enable(struct ssb_pcicore *pc, struct ssb_device *dev) { diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index ad3da93a428c..ee2937c41424 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c @@ -1329,6 +1329,31 @@ error: } EXPORT_SYMBOL(ssb_bus_powerup); +static void ssb_broadcast_value(struct ssb_device *dev, + u32 address, u32 data) +{ + /* This is used for both, PCI and ChipCommon core, so be careful. */ + BUILD_BUG_ON(SSB_PCICORE_BCAST_ADDR != SSB_CHIPCO_BCAST_ADDR); + BUILD_BUG_ON(SSB_PCICORE_BCAST_DATA != SSB_CHIPCO_BCAST_DATA); + + ssb_write32(dev, SSB_PCICORE_BCAST_ADDR, address); + ssb_read32(dev, SSB_PCICORE_BCAST_ADDR); /* flush */ + ssb_write32(dev, SSB_PCICORE_BCAST_DATA, data); + ssb_read32(dev, SSB_PCICORE_BCAST_DATA); /* flush */ +} + +void ssb_commit_settings(struct ssb_bus *bus) +{ + struct ssb_device *dev; + + dev = bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev; + if (WARN_ON(!dev)) + return; + /* This forces an update of the cached registers. */ + ssb_broadcast_value(dev, 0xFD8, 0); +} +EXPORT_SYMBOL(ssb_commit_settings); + u32 ssb_admatch_base(u32 adm) { u32 base = 0; diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h index 7e99b348834c..f017b8900f78 100644 --- a/include/linux/ssb/ssb.h +++ b/include/linux/ssb/ssb.h @@ -518,6 +518,7 @@ extern int ssb_bus_may_powerdown(struct ssb_bus *bus); * Otherwise static always-on powercontrol will be used. */ extern int ssb_bus_powerup(struct ssb_bus *bus, bool dynamic_pctl); +extern void ssb_commit_settings(struct ssb_bus *bus); /* Various helper functions */ extern u32 ssb_admatch_base(u32 adm); -- cgit From 807f8a8c300435d5483e8d78df9dcdbc27333166 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Wed, 11 May 2011 17:09:35 +0300 Subject: cfg80211/nl80211: add support for scheduled scans Implement new functionality for scheduled scan offload. With this feature we can scan automatically at certain intervals. The idea is that the hardware can perform scan automatically and filter on desired results without waking up the host unnecessarily. Add NL80211_CMD_START_SCHED_SCAN and NL80211_CMD_STOP_SCHED_SCAN commands to the nl80211 interface. When results are available they are reported by NL80211_CMD_SCHED_SCAN_RESULTS events. The userspace is informed when the scheduled scan has stopped with a NL80211_CMD_SCHED_SCAN_STOPPED event, which can be triggered either by the driver or by a call to NL80211_CMD_STOP_SCHED_SCAN. Signed-off-by: Luciano Coelho Signed-off-by: John W. Linville --- include/linux/nl80211.h | 25 +++++ include/net/cfg80211.h | 57 +++++++++++ net/wireless/core.c | 12 ++- net/wireless/core.h | 7 ++ net/wireless/nl80211.c | 250 ++++++++++++++++++++++++++++++++++++++++++++++++ net/wireless/nl80211.h | 4 + net/wireless/scan.c | 70 ++++++++++++++ 7 files changed, 424 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index de96783954a1..f8b5595ba4af 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -203,6 +203,26 @@ * @NL80211_CMD_SCAN_ABORTED: scan was aborted, for unspecified reasons, * partial scan results may be available * + * @NL80211_CMD_START_SCHED_SCAN: start a scheduled scan. Like with normal + * scans, if SSIDs (%NL80211_ATTR_SCAN_SSIDS) are passed, they are used + * in the probe requests. For broadcast, a broadcast SSID must be + * passed (ie. an empty string). If no SSID is passed, no probe + * requests are sent and a passive scan is performed. + * %NL80211_ATTR_SCAN_FREQUENCIES, if passed, define which channels + * should be scanned; if not passed, all channels allowed for the + * current regulatory domain are used. Extra IEs can also be passed + * from the userspace by using the %NL80211_ATTR_IE attribute. + * @NL80211_CMD_STOP_SCHED_SCAN: stop a scheduled scan + * @NL80211_CMD_SCHED_SCAN_RESULTS: indicates that there are scheduled scan + * results available. + * @NL80211_CMD_SCHED_SCAN_STOPPED: indicates that the scheduled scan has + * stopped. The driver may issue this event at any time during a + * scheduled scan. One reason for stopping the scan is if the hardware + * does not support starting an association or a normal scan while running + * a scheduled scan. This event is also sent when the + * %NL80211_CMD_STOP_SCHED_SCAN command is received or when the interface + * is brought down while a scheduled scan was running. + * * @NL80211_CMD_GET_SURVEY: get survey resuls, e.g. channel occupation * or noise level * @NL80211_CMD_NEW_SURVEY_RESULTS: survey data notification (as a reply to @@ -545,6 +565,11 @@ enum nl80211_commands { NL80211_CMD_GET_WOWLAN, NL80211_CMD_SET_WOWLAN, + NL80211_CMD_START_SCHED_SCAN, + NL80211_CMD_STOP_SCHED_SCAN, + NL80211_CMD_SCHED_SCAN_RESULTS, + NL80211_CMD_SCHED_SCAN_STOPPED, + /* add new commands above here */ /* used to define NL80211_CMD_MAX below */ diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 4b0d035be64f..e214c85b74d2 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -823,6 +823,33 @@ struct cfg80211_scan_request { struct ieee80211_channel *channels[0]; }; +/** + * struct cfg80211_sched_scan_request - scheduled scan request description + * + * @ssids: SSIDs to scan for (passed in the probe_reqs in active scans) + * @n_ssids: number of SSIDs + * @n_channels: total number of channels to scan + * @ie: optional information element(s) to add into Probe Request or %NULL + * @ie_len: length of ie in octets + * @wiphy: the wiphy this was for + * @dev: the interface + * @channels: channels to scan + */ +struct cfg80211_sched_scan_request { + struct cfg80211_ssid *ssids; + int n_ssids; + u32 n_channels; + const u8 *ie; + size_t ie_len; + + /* internal */ + struct wiphy *wiphy; + struct net_device *dev; + + /* keep last */ + struct ieee80211_channel *channels[0]; +}; + /** * enum cfg80211_signal_type - signal type * @@ -1292,6 +1319,10 @@ struct cfg80211_wowlan { * @set_power_mgmt: Configure WLAN power management. A timeout value of -1 * allows the driver to adjust the dynamic ps timeout value. * @set_cqm_rssi_config: Configure connection quality monitor RSSI threshold. + * @sched_scan_start: Tell the driver to start a scheduled scan. + * @sched_scan_stop: Tell the driver to stop an ongoing scheduled + * scan. The driver_initiated flag specifies whether the driver + * itself has informed that the scan has stopped. * * @mgmt_frame_register: Notify driver that a management frame type was * registered. Note that this callback may not sleep, and cannot run @@ -1478,6 +1509,12 @@ struct cfg80211_ops { int (*set_ringparam)(struct wiphy *wiphy, u32 tx, u32 rx); void (*get_ringparam)(struct wiphy *wiphy, u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max); + + int (*sched_scan_start)(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_sched_scan_request *request); + int (*sched_scan_stop)(struct wiphy *wiphy, struct net_device *dev, + bool driver_initiated); }; /* @@ -1522,6 +1559,7 @@ struct cfg80211_ops { * @WIPHY_FLAG_IBSS_RSN: The device supports IBSS RSN. * @WIPHY_FLAG_MESH_AUTH: The device supports mesh authentication by routing * auth frames to userspace. See @NL80211_MESH_SETUP_USERSPACE_AUTH. + * @WIPHY_FLAG_SCHED_SCAN: The device supports scheduled scans. */ enum wiphy_flags { WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), @@ -1534,6 +1572,7 @@ enum wiphy_flags { WIPHY_FLAG_CONTROL_PORT_PROTOCOL = BIT(7), WIPHY_FLAG_IBSS_RSN = BIT(8), WIPHY_FLAG_MESH_AUTH = BIT(10), + WIPHY_FLAG_SUPPORTS_SCHED_SCAN = BIT(11), }; struct mac_address { @@ -2354,6 +2393,24 @@ int cfg80211_wext_siwpmksa(struct net_device *dev, */ void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted); +/** + * cfg80211_sched_scan_results - notify that new scan results are available + * + * @wiphy: the wiphy which got scheduled scan results + */ +void cfg80211_sched_scan_results(struct wiphy *wiphy); + +/** + * cfg80211_sched_scan_stopped - notify that the scheduled scan has stopped + * + * @wiphy: the wiphy on which the scheduled scan stopped + * + * The driver can call this function to inform cfg80211 that the + * scheduled scan had to be stopped, for whatever reason. The driver + * is then called back via the sched_scan_stop operation when done. + */ +void cfg80211_sched_scan_stopped(struct wiphy *wiphy); + /** * cfg80211_inform_bss_frame - inform cfg80211 of a received BSS frame * diff --git a/net/wireless/core.c b/net/wireless/core.c index bea0d80710c8..f924a49b2425 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -370,7 +370,8 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) spin_lock_init(&rdev->bss_lock); INIT_LIST_HEAD(&rdev->bss_list); INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done); - + INIT_WORK(&rdev->sched_scan_results_wk, __cfg80211_sched_scan_results); + INIT_WORK(&rdev->sched_scan_stopped_wk, __cfg80211_sched_scan_stopped); #ifdef CONFIG_CFG80211_WEXT rdev->wiphy.wext = &cfg80211_wext_handler; #endif @@ -672,6 +673,11 @@ static void wdev_cleanup_work(struct work_struct *work) ___cfg80211_scan_done(rdev, true); } + if (WARN_ON(rdev->sched_scan_req && + rdev->sched_scan_req->dev == wdev->netdev)) { + __cfg80211_stop_sched_scan(rdev, false); + } + cfg80211_unlock_rdev(rdev); mutex_lock(&rdev->devlist_mtx); @@ -759,6 +765,10 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb, break; case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_STATION: + cfg80211_lock_rdev(rdev); + __cfg80211_stop_sched_scan(rdev, false); + cfg80211_unlock_rdev(rdev); + wdev_lock(wdev); #ifdef CONFIG_CFG80211_WEXT kfree(wdev->wext.ie); diff --git a/net/wireless/core.h b/net/wireless/core.h index 7a18c10a7fb6..e3f7b1d995cd 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -60,8 +60,11 @@ struct cfg80211_registered_device { struct rb_root bss_tree; u32 bss_generation; struct cfg80211_scan_request *scan_req; /* protected by RTNL */ + struct cfg80211_sched_scan_request *sched_scan_req; unsigned long suspend_at; struct work_struct scan_done_wk; + struct work_struct sched_scan_results_wk; + struct work_struct sched_scan_stopped_wk; #ifdef CONFIG_NL80211_TESTMODE struct genl_info *testmode_info; @@ -411,6 +414,10 @@ void cfg80211_sme_rx_auth(struct net_device *dev, const u8 *buf, size_t len); void cfg80211_sme_disassoc(struct net_device *dev, int idx); void __cfg80211_scan_done(struct work_struct *wk); void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak); +void __cfg80211_sched_scan_results(struct work_struct *wk); +int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev, + bool driver_initiated); +void __cfg80211_sched_scan_stopped(struct work_struct *wk); void cfg80211_upload_connect_keys(struct wireless_dev *wdev); int cfg80211_change_iface(struct cfg80211_registered_device *rdev, struct net_device *dev, enum nl80211_iftype ntype, diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 95dd5832e719..4fac370284c0 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -761,6 +761,8 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, } CMD(set_channel, SET_CHANNEL); CMD(set_wds_peer, SET_WDS_PEER); + if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) + CMD(sched_scan_start, START_SCHED_SCAN); #undef CMD @@ -3357,6 +3359,179 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) return err; } +static int nl80211_start_sched_scan(struct sk_buff *skb, + struct genl_info *info) +{ + struct cfg80211_sched_scan_request *request; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; + struct cfg80211_ssid *ssid; + struct ieee80211_channel *channel; + struct nlattr *attr; + struct wiphy *wiphy; + int err, tmp, n_ssids = 0, n_channels, i; + enum ieee80211_band band; + size_t ie_len; + + if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) || + !rdev->ops->sched_scan_start) + return -EOPNOTSUPP; + + if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) + return -EINVAL; + + if (rdev->sched_scan_req) + return -EINPROGRESS; + + wiphy = &rdev->wiphy; + + if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { + n_channels = validate_scan_freqs( + info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]); + if (!n_channels) + return -EINVAL; + } else { + n_channels = 0; + + for (band = 0; band < IEEE80211_NUM_BANDS; band++) + if (wiphy->bands[band]) + n_channels += wiphy->bands[band]->n_channels; + } + + if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) + nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], + tmp) + n_ssids++; + + if (n_ssids > wiphy->max_scan_ssids) + return -EINVAL; + + if (info->attrs[NL80211_ATTR_IE]) + ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); + else + ie_len = 0; + + if (ie_len > wiphy->max_scan_ie_len) + return -EINVAL; + + request = kzalloc(sizeof(*request) + + sizeof(*ssid) * n_ssids + + sizeof(channel) * n_channels + + ie_len, GFP_KERNEL); + if (!request) + return -ENOMEM; + + if (n_ssids) + request->ssids = (void *)&request->channels[n_channels]; + request->n_ssids = n_ssids; + if (ie_len) { + if (request->ssids) + request->ie = (void *)(request->ssids + n_ssids); + else + request->ie = (void *)(request->channels + n_channels); + } + + i = 0; + if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { + /* user specified, bail out if channel not found */ + nla_for_each_nested(attr, + info->attrs[NL80211_ATTR_SCAN_FREQUENCIES], + tmp) { + struct ieee80211_channel *chan; + + chan = ieee80211_get_channel(wiphy, nla_get_u32(attr)); + + if (!chan) { + err = -EINVAL; + goto out_free; + } + + /* ignore disabled channels */ + if (chan->flags & IEEE80211_CHAN_DISABLED) + continue; + + request->channels[i] = chan; + i++; + } + } else { + /* all channels */ + for (band = 0; band < IEEE80211_NUM_BANDS; band++) { + int j; + if (!wiphy->bands[band]) + continue; + for (j = 0; j < wiphy->bands[band]->n_channels; j++) { + struct ieee80211_channel *chan; + + chan = &wiphy->bands[band]->channels[j]; + + if (chan->flags & IEEE80211_CHAN_DISABLED) + continue; + + request->channels[i] = chan; + i++; + } + } + } + + if (!i) { + err = -EINVAL; + goto out_free; + } + + request->n_channels = i; + + i = 0; + if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) { + nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], + tmp) { + if (request->ssids[i].ssid_len > + IEEE80211_MAX_SSID_LEN) { + err = -EINVAL; + goto out_free; + } + memcpy(request->ssids[i].ssid, nla_data(attr), + nla_len(attr)); + request->ssids[i].ssid_len = nla_len(attr); + i++; + } + } + + if (info->attrs[NL80211_ATTR_IE]) { + request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); + memcpy((void *)request->ie, + nla_data(info->attrs[NL80211_ATTR_IE]), + request->ie_len); + } + + request->dev = dev; + request->wiphy = &rdev->wiphy; + + err = rdev->ops->sched_scan_start(&rdev->wiphy, dev, request); + if (!err) { + rdev->sched_scan_req = request; + nl80211_send_sched_scan(rdev, dev, + NL80211_CMD_START_SCHED_SCAN); + goto out; + } + +out_free: + kfree(request); +out: + return err; +} + +static int nl80211_stop_sched_scan(struct sk_buff *skb, + struct genl_info *info) +{ + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + + if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) || + !rdev->ops->sched_scan_stop) + return -EOPNOTSUPP; + + return __cfg80211_stop_sched_scan(rdev, false); +} + static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags, struct cfg80211_registered_device *rdev, struct wireless_dev *wdev, @@ -5326,6 +5501,22 @@ static struct genl_ops nl80211_ops[] = { .policy = nl80211_policy, .dumpit = nl80211_dump_scan, }, + { + .cmd = NL80211_CMD_START_SCHED_SCAN, + .doit = nl80211_start_sched_scan, + .policy = nl80211_policy, + .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_NEED_RTNL, + }, + { + .cmd = NL80211_CMD_STOP_SCHED_SCAN, + .doit = nl80211_stop_sched_scan, + .policy = nl80211_policy, + .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_NEED_RTNL, + }, { .cmd = NL80211_CMD_AUTHENTICATE, .doit = nl80211_authenticate, @@ -5652,6 +5843,28 @@ static int nl80211_send_scan_msg(struct sk_buff *msg, return -EMSGSIZE; } +static int +nl80211_send_sched_scan_msg(struct sk_buff *msg, + struct cfg80211_registered_device *rdev, + struct net_device *netdev, + u32 pid, u32 seq, int flags, u32 cmd) +{ + void *hdr; + + hdr = nl80211hdr_put(msg, pid, seq, flags, cmd); + if (!hdr) + return -1; + + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); + NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); + + return genlmsg_end(msg, hdr); + + nla_put_failure: + genlmsg_cancel(msg, hdr); + return -EMSGSIZE; +} + void nl80211_send_scan_start(struct cfg80211_registered_device *rdev, struct net_device *netdev) { @@ -5709,6 +5922,43 @@ void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev, nl80211_scan_mcgrp.id, GFP_KERNEL); } +void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev, + struct net_device *netdev) +{ + struct sk_buff *msg; + + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (!msg) + return; + + if (nl80211_send_sched_scan_msg(msg, rdev, netdev, 0, 0, 0, + NL80211_CMD_SCHED_SCAN_RESULTS) < 0) { + nlmsg_free(msg); + return; + } + + genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, + nl80211_scan_mcgrp.id, GFP_KERNEL); +} + +void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev, + struct net_device *netdev, u32 cmd) +{ + struct sk_buff *msg; + + msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + if (!msg) + return; + + if (nl80211_send_sched_scan_msg(msg, rdev, netdev, 0, 0, 0, cmd) < 0) { + nlmsg_free(msg); + return; + } + + genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, + nl80211_scan_mcgrp.id, GFP_KERNEL); +} + /* * This can happen on global regulatory changes or device specific settings * based on custom world regulatory domains. diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index f2af6955a665..2f1bfb87a651 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h @@ -12,6 +12,10 @@ void nl80211_send_scan_done(struct cfg80211_registered_device *rdev, struct net_device *netdev); void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev, struct net_device *netdev); +void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev, + struct net_device *netdev, u32 cmd); +void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev, + struct net_device *netdev); void nl80211_send_reg_change_event(struct regulatory_request *request); void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev, struct net_device *netdev, diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 62e542a2b192..65dfae3b9d41 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -93,6 +93,76 @@ void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted) } EXPORT_SYMBOL(cfg80211_scan_done); +void __cfg80211_sched_scan_results(struct work_struct *wk) +{ + struct cfg80211_registered_device *rdev; + + rdev = container_of(wk, struct cfg80211_registered_device, + sched_scan_results_wk); + + cfg80211_lock_rdev(rdev); + + /* we don't have sched_scan_req anymore if the scan is stopping */ + if (rdev->sched_scan_req) + nl80211_send_sched_scan_results(rdev, + rdev->sched_scan_req->dev); + + cfg80211_unlock_rdev(rdev); +} + +void cfg80211_sched_scan_results(struct wiphy *wiphy) +{ + /* ignore if we're not scanning */ + if (wiphy_to_dev(wiphy)->sched_scan_req) + queue_work(cfg80211_wq, + &wiphy_to_dev(wiphy)->sched_scan_results_wk); +} +EXPORT_SYMBOL(cfg80211_sched_scan_results); + +void __cfg80211_sched_scan_stopped(struct work_struct *wk) +{ + struct cfg80211_registered_device *rdev; + + rdev = container_of(wk, struct cfg80211_registered_device, + sched_scan_stopped_wk); + + cfg80211_lock_rdev(rdev); + __cfg80211_stop_sched_scan(rdev, true); + cfg80211_unlock_rdev(rdev); +} + +void cfg80211_sched_scan_stopped(struct wiphy *wiphy) +{ + queue_work(cfg80211_wq, &wiphy_to_dev(wiphy)->sched_scan_stopped_wk); +} +EXPORT_SYMBOL(cfg80211_sched_scan_stopped); + +int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev, + bool driver_initiated) +{ + int err; + struct net_device *dev; + + ASSERT_RDEV_LOCK(rdev); + + if (!rdev->sched_scan_req) + return 0; + + dev = rdev->sched_scan_req->dev; + + err = rdev->ops->sched_scan_stop(&rdev->wiphy, dev, + driver_initiated); + if (err) + return err; + + nl80211_send_sched_scan(rdev, dev, NL80211_CMD_SCHED_SCAN_STOPPED); + + kfree(rdev->sched_scan_req); + rdev->sched_scan_req = NULL; + + return err; +} + static void bss_release(struct kref *ref) { struct cfg80211_internal_bss *bss; -- cgit From bbe6ad6dcb1eb26bd12ec85320f402721c3383ae Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Wed, 11 May 2011 17:09:37 +0300 Subject: cfg80211/nl80211: add interval attribute for scheduled scans Introduce NL80211_ATTR_SCHED_SCAN_INTERVAL as a required attribute for NL80211_CMD_START_SCHED_SCAN. This value informs the driver at which intervals the scheduled scan cycles should be executed. Signed-off-by: Luciano Coelho Signed-off-by: John W. Linville --- include/linux/nl80211.h | 25 ++++++++++++++++--------- include/net/cfg80211.h | 2 ++ net/wireless/nl80211.c | 10 ++++++++++ 3 files changed, 28 insertions(+), 9 deletions(-) (limited to 'include/linux') diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index f8b5595ba4af..281a2bb6a6ec 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -203,15 +203,17 @@ * @NL80211_CMD_SCAN_ABORTED: scan was aborted, for unspecified reasons, * partial scan results may be available * - * @NL80211_CMD_START_SCHED_SCAN: start a scheduled scan. Like with normal - * scans, if SSIDs (%NL80211_ATTR_SCAN_SSIDS) are passed, they are used - * in the probe requests. For broadcast, a broadcast SSID must be - * passed (ie. an empty string). If no SSID is passed, no probe - * requests are sent and a passive scan is performed. - * %NL80211_ATTR_SCAN_FREQUENCIES, if passed, define which channels - * should be scanned; if not passed, all channels allowed for the - * current regulatory domain are used. Extra IEs can also be passed - * from the userspace by using the %NL80211_ATTR_IE attribute. + * @NL80211_CMD_START_SCHED_SCAN: start a scheduled scan at certain + * intervals, as specified by %NL80211_ATTR_SCHED_SCAN_INTERVAL. + * Like with normal scans, if SSIDs (%NL80211_ATTR_SCAN_SSIDS) + * are passed, they are used in the probe requests. For + * broadcast, a broadcast SSID must be passed (ie. an empty + * string). If no SSID is passed, no probe requests are sent and + * a passive scan is performed. %NL80211_ATTR_SCAN_FREQUENCIES, + * if passed, define which channels should be scanned; if not + * passed, all channels allowed for the current regulatory domain + * are used. Extra IEs can also be passed from the userspace by + * using the %NL80211_ATTR_IE attribute. * @NL80211_CMD_STOP_SCHED_SCAN: stop a scheduled scan * @NL80211_CMD_SCHED_SCAN_RESULTS: indicates that there are scheduled scan * results available. @@ -948,6 +950,9 @@ enum nl80211_commands { * indicate which WoW triggers should be enabled. This is also * used by %NL80211_CMD_GET_WOWLAN to get the currently enabled WoWLAN * triggers. + + * @NL80211_ATTR_SCHED_SCAN_INTERVAL: Interval between scheduled scan + * cycles, in msecs. * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use @@ -1142,6 +1147,8 @@ enum nl80211_attrs { NL80211_ATTR_WOWLAN_TRIGGERS, NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED, + NL80211_ATTR_SCHED_SCAN_INTERVAL, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index e214c85b74d2..1f1e221b6ce3 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -829,6 +829,7 @@ struct cfg80211_scan_request { * @ssids: SSIDs to scan for (passed in the probe_reqs in active scans) * @n_ssids: number of SSIDs * @n_channels: total number of channels to scan + * @interval: interval between each scheduled scan cycle * @ie: optional information element(s) to add into Probe Request or %NULL * @ie_len: length of ie in octets * @wiphy: the wiphy this was for @@ -839,6 +840,7 @@ struct cfg80211_sched_scan_request { struct cfg80211_ssid *ssids; int n_ssids; u32 n_channels; + u32 interval; const u8 *ie; size_t ie_len; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 4fac370284c0..b5b050b62f2a 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -175,6 +175,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { [NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED }, [NL80211_ATTR_WOWLAN_TRIGGERS] = { .type = NLA_NESTED }, [NL80211_ATTR_STA_PLINK_STATE] = { .type = NLA_U8 }, + [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 }, }; /* policy for the key attributes */ @@ -3370,6 +3371,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, struct nlattr *attr; struct wiphy *wiphy; int err, tmp, n_ssids = 0, n_channels, i; + u32 interval; enum ieee80211_band band; size_t ie_len; @@ -3383,6 +3385,13 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, if (rdev->sched_scan_req) return -EINPROGRESS; + if (!info->attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL]) + return -EINVAL; + + interval = nla_get_u32(info->attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL]); + if (interval == 0) + return -EINVAL; + wiphy = &rdev->wiphy; if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { @@ -3505,6 +3514,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, request->dev = dev; request->wiphy = &rdev->wiphy; + request->interval = interval; err = rdev->ops->sched_scan_start(&rdev->wiphy, dev, request); if (!err) { -- cgit From 2e711c04dbbf7a7732a3f7073b1fc285d12b369d Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 26 Apr 2011 19:15:07 +0200 Subject: PM: Remove sysdev suspend, resume and shutdown operations Since suspend, resume and shutdown operations in struct sysdev_class and struct sysdev_driver are not used any more, remove them. Also drop sysdev_suspend(), sysdev_resume() and sysdev_shutdown() used for executing those operations and modify all of their users accordingly. This reduces kernel code size quite a bit and reduces its complexity. Signed-off-by: Rafael J. Wysocki Acked-by: Greg Kroah-Hartman --- arch/sh/Kconfig | 1 - arch/x86/Kconfig | 1 - arch/x86/kernel/apm_32.c | 4 - drivers/base/Kconfig | 7 -- drivers/base/base.h | 2 - drivers/base/sys.c | 202 +---------------------------------------------- drivers/xen/manage.c | 8 +- include/linux/device.h | 7 -- include/linux/pm.h | 8 -- include/linux/sysdev.h | 11 --- kernel/kexec.c | 9 +-- kernel/power/hibernate.c | 18 +---- kernel/power/suspend.c | 8 +- kernel/sys.c | 3 - 14 files changed, 7 insertions(+), 282 deletions(-) (limited to 'include/linux') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 4b89da248d17..bc439de48cd1 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -24,7 +24,6 @@ config SUPERH select RTC_LIB select GENERIC_ATOMIC64 select GENERIC_IRQ_SHOW - select ARCH_NO_SYSDEV_OPS help The SuperH is a RISC processor targeted for use in embedded systems and consumer electronics; it was also used in the Sega Dreamcast diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index cc6c53a95bfd..140e254fe546 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -71,7 +71,6 @@ config X86 select GENERIC_IRQ_SHOW select IRQ_FORCED_THREADING select USE_GENERIC_SMP_HELPERS if SMP - select ARCH_NO_SYSDEV_OPS config INSTRUCTION_DECODER def_bool (KPROBES || PERF_EVENTS) diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c index adee12e0da1f..3bfa02235965 100644 --- a/arch/x86/kernel/apm_32.c +++ b/arch/x86/kernel/apm_32.c @@ -1238,7 +1238,6 @@ static int suspend(int vetoable) dpm_suspend_noirq(PMSG_SUSPEND); local_irq_disable(); - sysdev_suspend(PMSG_SUSPEND); syscore_suspend(); local_irq_enable(); @@ -1258,7 +1257,6 @@ static int suspend(int vetoable) err = (err == APM_SUCCESS) ? 0 : -EIO; syscore_resume(); - sysdev_resume(); local_irq_enable(); dpm_resume_noirq(PMSG_RESUME); @@ -1282,7 +1280,6 @@ static void standby(void) dpm_suspend_noirq(PMSG_SUSPEND); local_irq_disable(); - sysdev_suspend(PMSG_SUSPEND); syscore_suspend(); local_irq_enable(); @@ -1292,7 +1289,6 @@ static void standby(void) local_irq_disable(); syscore_resume(); - sysdev_resume(); local_irq_enable(); dpm_resume_noirq(PMSG_RESUME); diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index e9e5238f3106..d57e8d0fb823 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig @@ -168,11 +168,4 @@ config SYS_HYPERVISOR bool default n -config ARCH_NO_SYSDEV_OPS - bool - ---help--- - To be selected by architectures that don't use sysdev class or - sysdev driver power management (suspend/resume) and shutdown - operations. - endmenu diff --git a/drivers/base/base.h b/drivers/base/base.h index 19f49e41ce5d..a34dca0ad041 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -111,8 +111,6 @@ static inline int driver_match_device(struct device_driver *drv, return drv->bus->match ? drv->bus->match(dev, drv) : 1; } -extern void sysdev_shutdown(void); - extern char *make_class_name(const char *name, struct kobject *kobj); extern int devres_release_all(struct device *dev); diff --git a/drivers/base/sys.c b/drivers/base/sys.c index acde9b5ee131..9dff77bfe1e3 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c @@ -328,203 +328,8 @@ void sysdev_unregister(struct sys_device *sysdev) kobject_put(&sysdev->kobj); } - -#ifndef CONFIG_ARCH_NO_SYSDEV_OPS -/** - * sysdev_shutdown - Shut down all system devices. - * - * Loop over each class of system devices, and the devices in each - * of those classes. For each device, we call the shutdown method for - * each driver registered for the device - the auxiliaries, - * and the class driver. - * - * Note: The list is iterated in reverse order, so that we shut down - * child devices before we shut down their parents. The list ordering - * is guaranteed by virtue of the fact that child devices are registered - * after their parents. - */ -void sysdev_shutdown(void) -{ - struct sysdev_class *cls; - - pr_debug("Shutting Down System Devices\n"); - - mutex_lock(&sysdev_drivers_lock); - list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) { - struct sys_device *sysdev; - - pr_debug("Shutting down type '%s':\n", - kobject_name(&cls->kset.kobj)); - - list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) { - struct sysdev_driver *drv; - pr_debug(" %s\n", kobject_name(&sysdev->kobj)); - - /* Call auxiliary drivers first */ - list_for_each_entry(drv, &cls->drivers, entry) { - if (drv->shutdown) - drv->shutdown(sysdev); - } - - /* Now call the generic one */ - if (cls->shutdown) - cls->shutdown(sysdev); - } - } - mutex_unlock(&sysdev_drivers_lock); -} - -static void __sysdev_resume(struct sys_device *dev) -{ - struct sysdev_class *cls = dev->cls; - struct sysdev_driver *drv; - - /* First, call the class-specific one */ - if (cls->resume) - cls->resume(dev); - WARN_ONCE(!irqs_disabled(), - "Interrupts enabled after %pF\n", cls->resume); - - /* Call auxiliary drivers next. */ - list_for_each_entry(drv, &cls->drivers, entry) { - if (drv->resume) - drv->resume(dev); - WARN_ONCE(!irqs_disabled(), - "Interrupts enabled after %pF\n", drv->resume); - } -} - -/** - * sysdev_suspend - Suspend all system devices. - * @state: Power state to enter. - * - * We perform an almost identical operation as sysdev_shutdown() - * above, though calling ->suspend() instead. Interrupts are disabled - * when this called. Devices are responsible for both saving state and - * quiescing or powering down the device. - * - * This is only called by the device PM core, so we let them handle - * all synchronization. - */ -int sysdev_suspend(pm_message_t state) -{ - struct sysdev_class *cls; - struct sys_device *sysdev, *err_dev; - struct sysdev_driver *drv, *err_drv; - int ret; - - pr_debug("Checking wake-up interrupts\n"); - - /* Return error code if there are any wake-up interrupts pending */ - ret = check_wakeup_irqs(); - if (ret) - return ret; - - WARN_ONCE(!irqs_disabled(), - "Interrupts enabled while suspending system devices\n"); - - pr_debug("Suspending System Devices\n"); - - list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) { - pr_debug("Suspending type '%s':\n", - kobject_name(&cls->kset.kobj)); - - list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) { - pr_debug(" %s\n", kobject_name(&sysdev->kobj)); - - /* Call auxiliary drivers first */ - list_for_each_entry(drv, &cls->drivers, entry) { - if (drv->suspend) { - ret = drv->suspend(sysdev, state); - if (ret) - goto aux_driver; - } - WARN_ONCE(!irqs_disabled(), - "Interrupts enabled after %pF\n", - drv->suspend); - } - - /* Now call the generic one */ - if (cls->suspend) { - ret = cls->suspend(sysdev, state); - if (ret) - goto cls_driver; - WARN_ONCE(!irqs_disabled(), - "Interrupts enabled after %pF\n", - cls->suspend); - } - } - } - return 0; - /* resume current sysdev */ -cls_driver: - drv = NULL; - printk(KERN_ERR "Class suspend failed for %s: %d\n", - kobject_name(&sysdev->kobj), ret); - -aux_driver: - if (drv) - printk(KERN_ERR "Class driver suspend failed for %s: %d\n", - kobject_name(&sysdev->kobj), ret); - list_for_each_entry(err_drv, &cls->drivers, entry) { - if (err_drv == drv) - break; - if (err_drv->resume) - err_drv->resume(sysdev); - } - - /* resume other sysdevs in current class */ - list_for_each_entry(err_dev, &cls->kset.list, kobj.entry) { - if (err_dev == sysdev) - break; - pr_debug(" %s\n", kobject_name(&err_dev->kobj)); - __sysdev_resume(err_dev); - } - - /* resume other classes */ - list_for_each_entry_continue(cls, &system_kset->list, kset.kobj.entry) { - list_for_each_entry(err_dev, &cls->kset.list, kobj.entry) { - pr_debug(" %s\n", kobject_name(&err_dev->kobj)); - __sysdev_resume(err_dev); - } - } - return ret; -} -EXPORT_SYMBOL_GPL(sysdev_suspend); - -/** - * sysdev_resume - Bring system devices back to life. - * - * Similar to sysdev_suspend(), but we iterate the list forwards - * to guarantee that parent devices are resumed before their children. - * - * Note: Interrupts are disabled when called. - */ -int sysdev_resume(void) -{ - struct sysdev_class *cls; - - WARN_ONCE(!irqs_disabled(), - "Interrupts enabled while resuming system devices\n"); - - pr_debug("Resuming System Devices\n"); - - list_for_each_entry(cls, &system_kset->list, kset.kobj.entry) { - struct sys_device *sysdev; - - pr_debug("Resuming type '%s':\n", - kobject_name(&cls->kset.kobj)); - - list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) { - pr_debug(" %s\n", kobject_name(&sysdev->kobj)); - - __sysdev_resume(sysdev); - } - } - return 0; -} -EXPORT_SYMBOL_GPL(sysdev_resume); -#endif /* CONFIG_ARCH_NO_SYSDEV_OPS */ +EXPORT_SYMBOL_GPL(sysdev_register); +EXPORT_SYMBOL_GPL(sysdev_unregister); int __init system_bus_init(void) { @@ -534,9 +339,6 @@ int __init system_bus_init(void) return 0; } -EXPORT_SYMBOL_GPL(sysdev_register); -EXPORT_SYMBOL_GPL(sysdev_unregister); - #define to_ext_attr(x) container_of(x, struct sysdev_ext_attribute, attr) ssize_t sysdev_store_ulong(struct sys_device *sysdev, diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index a2eee574784e..0b5366b5be20 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c @@ -70,12 +70,7 @@ static int xen_suspend(void *data) BUG_ON(!irqs_disabled()); - err = sysdev_suspend(PMSG_FREEZE); - if (!err) { - err = syscore_suspend(); - if (err) - sysdev_resume(); - } + err = syscore_suspend(); if (err) { printk(KERN_ERR "xen_suspend: system core suspend failed: %d\n", err); @@ -102,7 +97,6 @@ static int xen_suspend(void *data) } syscore_resume(); - sysdev_resume(); return 0; } diff --git a/include/linux/device.h b/include/linux/device.h index ab8dfc095709..ea9db9b0f248 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -633,13 +633,6 @@ static inline int devtmpfs_mount(const char *mountpoint) { return 0; } /* drivers/base/power/shutdown.c */ extern void device_shutdown(void); -#ifndef CONFIG_ARCH_NO_SYSDEV_OPS -/* drivers/base/sys.c */ -extern void sysdev_shutdown(void); -#else -static inline void sysdev_shutdown(void) { } -#endif - /* debugging and troubleshooting/diagnostic helpers. */ extern const char *dev_driver_string(const struct device *dev); diff --git a/include/linux/pm.h b/include/linux/pm.h index 512e09177e57..3c053e2beb84 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -529,14 +529,6 @@ struct dev_power_domain { */ #ifdef CONFIG_PM_SLEEP -#ifndef CONFIG_ARCH_NO_SYSDEV_OPS -extern int sysdev_suspend(pm_message_t state); -extern int sysdev_resume(void); -#else -static inline int sysdev_suspend(pm_message_t state) { return 0; } -static inline int sysdev_resume(void) { return 0; } -#endif - extern void device_pm_lock(void); extern void dpm_resume_noirq(pm_message_t state); extern void dpm_resume_end(pm_message_t state); diff --git a/include/linux/sysdev.h b/include/linux/sysdev.h index dfb078db8ebb..d35e783a598c 100644 --- a/include/linux/sysdev.h +++ b/include/linux/sysdev.h @@ -34,12 +34,6 @@ struct sysdev_class { struct list_head drivers; struct sysdev_class_attribute **attrs; struct kset kset; -#ifndef CONFIG_ARCH_NO_SYSDEV_OPS - /* Default operations for these types of devices */ - int (*shutdown)(struct sys_device *); - int (*suspend)(struct sys_device *, pm_message_t state); - int (*resume)(struct sys_device *); -#endif }; struct sysdev_class_attribute { @@ -77,11 +71,6 @@ struct sysdev_driver { struct list_head entry; int (*add)(struct sys_device *); int (*remove)(struct sys_device *); -#ifndef CONFIG_ARCH_NO_SYSDEV_OPS - int (*shutdown)(struct sys_device *); - int (*suspend)(struct sys_device *, pm_message_t state); - int (*resume)(struct sys_device *); -#endif }; diff --git a/kernel/kexec.c b/kernel/kexec.c index 87b77de03dd3..8d814cbc8109 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c @@ -1531,13 +1531,7 @@ int kernel_kexec(void) if (error) goto Enable_cpus; local_irq_disable(); - /* Suspend system devices */ - error = sysdev_suspend(PMSG_FREEZE); - if (!error) { - error = syscore_suspend(); - if (error) - sysdev_resume(); - } + error = syscore_suspend(); if (error) goto Enable_irqs; } else @@ -1553,7 +1547,6 @@ int kernel_kexec(void) #ifdef CONFIG_KEXEC_JUMP if (kexec_image->preserve_context) { syscore_resume(); - sysdev_resume(); Enable_irqs: local_irq_enable(); Enable_cpus: diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index 50aae660174d..554d3b049f35 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c @@ -272,12 +272,7 @@ static int create_image(int platform_mode) local_irq_disable(); - error = sysdev_suspend(PMSG_FREEZE); - if (!error) { - error = syscore_suspend(); - if (error) - sysdev_resume(); - } + error = syscore_suspend(); if (error) { printk(KERN_ERR "PM: Some system devices failed to power down, " "aborting hibernation\n"); @@ -302,7 +297,6 @@ static int create_image(int platform_mode) Power_up: syscore_resume(); - sysdev_resume(); /* NOTE: dpm_resume_noirq() is just a resume() for devices * that suspended with irqs off ... no overall powerup. */ @@ -409,12 +403,7 @@ static int resume_target_kernel(bool platform_mode) local_irq_disable(); - error = sysdev_suspend(PMSG_QUIESCE); - if (!error) { - error = syscore_suspend(); - if (error) - sysdev_resume(); - } + error = syscore_suspend(); if (error) goto Enable_irqs; @@ -442,7 +431,6 @@ static int resume_target_kernel(bool platform_mode) touch_softlockup_watchdog(); syscore_resume(); - sysdev_resume(); Enable_irqs: local_irq_enable(); @@ -528,7 +516,6 @@ int hibernation_platform_enter(void) goto Platform_finish; local_irq_disable(); - sysdev_suspend(PMSG_HIBERNATE); syscore_suspend(); if (pm_wakeup_pending()) { error = -EAGAIN; @@ -541,7 +528,6 @@ int hibernation_platform_enter(void) Power_up: syscore_resume(); - sysdev_resume(); local_irq_enable(); enable_nonboot_cpus(); diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index 8935369d503a..732d77a957e7 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c @@ -163,19 +163,13 @@ static int suspend_enter(suspend_state_t state) arch_suspend_disable_irqs(); BUG_ON(!irqs_disabled()); - error = sysdev_suspend(PMSG_SUSPEND); - if (!error) { - error = syscore_suspend(); - if (error) - sysdev_resume(); - } + error = syscore_suspend(); if (!error) { if (!(suspend_test(TEST_CORE) || pm_wakeup_pending())) { error = suspend_ops->enter(state); events_check_enabled = false; } syscore_resume(); - sysdev_resume(); } arch_suspend_enable_irqs(); diff --git a/kernel/sys.c b/kernel/sys.c index af468edf096a..f0c10385f30c 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -315,7 +315,6 @@ void kernel_restart_prepare(char *cmd) blocking_notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd); system_state = SYSTEM_RESTART; device_shutdown(); - sysdev_shutdown(); syscore_shutdown(); } @@ -354,7 +353,6 @@ static void kernel_shutdown_prepare(enum system_states state) void kernel_halt(void) { kernel_shutdown_prepare(SYSTEM_HALT); - sysdev_shutdown(); syscore_shutdown(); printk(KERN_EMERG "System halted.\n"); kmsg_dump(KMSG_DUMP_HALT); @@ -374,7 +372,6 @@ void kernel_power_off(void) if (pm_power_off_prepare) pm_power_off_prepare(); disable_nonboot_cpus(); - sysdev_shutdown(); syscore_shutdown(); printk(KERN_EMERG "Power down.\n"); kmsg_dump(KMSG_DUMP_POWEROFF); -- cgit From b48d4425b602f5f4978299474743dbea130d940d Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 19 Oct 2010 13:07:57 -0700 Subject: PCI: add ID-based ordering enable/disable support Add support to allow drivers to enable/disable ID-based ordering. Where supported, ID-based ordering can significantly improve the latency of individual requests by preventing them from queueing up behind unrelated traffic. Signed-off-by: Jesse Barnes --- drivers/pci/pci.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/pci.h | 13 ++++++++++++ include/linux/pci_regs.h | 2 ++ 3 files changed, 68 insertions(+) (limited to 'include/linux') diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 44d1c7c3876b..d0182bed7acc 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1834,6 +1834,59 @@ void pci_enable_ari(struct pci_dev *dev) bridge->ari_enabled = 1; } +/** + * pci_enable_ido - enable ID-based ordering on a device + * @dev: the PCI device + * @type: which types of IDO to enable + * + * Enable ID-based ordering on @dev. @type can contain the bits + * %PCI_EXP_IDO_REQUEST and/or %PCI_EXP_IDO_COMPLETION to indicate + * which types of transactions are allowed to be re-ordered. + */ +void pci_enable_ido(struct pci_dev *dev, unsigned long type) +{ + int pos; + u16 ctrl; + + pos = pci_pcie_cap(dev); + if (!pos) + return; + + pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl); + if (type & PCI_EXP_IDO_REQUEST) + ctrl |= PCI_EXP_IDO_REQ_EN; + if (type & PCI_EXP_IDO_COMPLETION) + ctrl |= PCI_EXP_IDO_CMP_EN; + pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl); +} +EXPORT_SYMBOL(pci_enable_ido); + +/** + * pci_disable_ido - disable ID-based ordering on a device + * @dev: the PCI device + * @type: which types of IDO to disable + */ +void pci_disable_ido(struct pci_dev *dev, unsigned long type) +{ + int pos; + u16 ctrl; + + if (!pci_is_pcie(dev)) + return; + + pos = pci_pcie_cap(dev); + if (!pos) + return; + + pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl); + if (type & PCI_EXP_IDO_REQUEST) + ctrl &= ~PCI_EXP_IDO_REQ_EN; + if (type & PCI_EXP_IDO_COMPLETION) + ctrl &= ~PCI_EXP_IDO_CMP_EN; + pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl); +} +EXPORT_SYMBOL(pci_disable_ido); + static int pci_acs_enable; /** diff --git a/include/linux/pci.h b/include/linux/pci.h index 96f70d7e058d..551ddcb5f940 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -828,6 +828,11 @@ static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state, return __pci_enable_wake(dev, state, false, enable); } +#define PCI_EXP_IDO_REQUEST (1<<0) +#define PCI_EXP_IDO_COMPLETION (1<<1) +void pci_enable_ido(struct pci_dev *dev, unsigned long type); +void pci_disable_ido(struct pci_dev *dev, unsigned long type); + /* For use by arch with custom probe code */ void set_pcie_port_type(struct pci_dev *pdev); void set_pcie_hotplug_bridge(struct pci_dev *pdev); @@ -1207,6 +1212,14 @@ static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state, return 0; } +static inline void pci_enable_ido(struct pci_dev *dev, unsigned long type) +{ +} + +static inline void pci_disable_ido(struct pci_dev *dev, unsigned long type) +{ +} + static inline int pci_request_regions(struct pci_dev *dev, const char *res_name) { return -EIO; diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h index be01380f798a..d9acf9b99814 100644 --- a/include/linux/pci_regs.h +++ b/include/linux/pci_regs.h @@ -510,6 +510,8 @@ #define PCI_EXP_DEVCAP2_ARI 0x20 /* Alternative Routing-ID */ #define PCI_EXP_DEVCTL2 40 /* Device Control 2 */ #define PCI_EXP_DEVCTL2_ARI 0x20 /* Alternative Routing-ID */ +#define PCI_EXP_IDO_REQ_EN 0x100 /* ID-based ordering request enable */ +#define PCI_EXP_IDO_CMP_EN 0x200 /* ID-based ordering completion enable */ #define PCI_EXP_LNKCTL2 48 /* Link Control 2 */ #define PCI_EXP_SLTCTL2 56 /* Slot Control 2 */ -- cgit From 48a92a8179b3e677fac07db7bd109e68f020468c Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 10 Jan 2011 12:46:36 -0800 Subject: PCI: add OBFF enable/disable support OBFF (optimized buffer flush/fill), where supported, can help improve energy efficiency by giving devices information about when interrupts and other activity will have a reduced power impact. It requires support from both the device and system (i.e. not only does the device need to respond to OBFF messages, but the platform must be capable of generating and routing them to the end point). Signed-off-by: Jesse Barnes --- drivers/pci/pci.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/pci.h | 16 +++++++++ include/linux/pci_regs.h | 6 ++++ 3 files changed, 114 insertions(+) (limited to 'include/linux') diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index d0182bed7acc..01e4cab2e5cb 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1887,6 +1887,98 @@ void pci_disable_ido(struct pci_dev *dev, unsigned long type) } EXPORT_SYMBOL(pci_disable_ido); +/** + * pci_enable_obff - enable optimized buffer flush/fill + * @dev: PCI device + * @type: type of signaling to use + * + * Try to enable @type OBFF signaling on @dev. It will try using WAKE# + * signaling if possible, falling back to message signaling only if + * WAKE# isn't supported. @type should indicate whether the PCIe link + * be brought out of L0s or L1 to send the message. It should be either + * %PCI_EXP_OBFF_SIGNAL_ALWAYS or %PCI_OBFF_SIGNAL_L0. + * + * If your device can benefit from receiving all messages, even at the + * power cost of bringing the link back up from a low power state, use + * %PCI_EXP_OBFF_SIGNAL_ALWAYS. Otherwise, use %PCI_OBFF_SIGNAL_L0 (the + * preferred type). + * + * RETURNS: + * Zero on success, appropriate error number on failure. + */ +int pci_enable_obff(struct pci_dev *dev, enum pci_obff_signal_type type) +{ + int pos; + u32 cap; + u16 ctrl; + int ret; + + if (!pci_is_pcie(dev)) + return -ENOTSUPP; + + pos = pci_pcie_cap(dev); + if (!pos) + return -ENOTSUPP; + + pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP2, &cap); + if (!(cap & PCI_EXP_OBFF_MASK)) + return -ENOTSUPP; /* no OBFF support at all */ + + /* Make sure the topology supports OBFF as well */ + if (dev->bus) { + ret = pci_enable_obff(dev->bus->self, type); + if (ret) + return ret; + } + + pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl); + if (cap & PCI_EXP_OBFF_WAKE) + ctrl |= PCI_EXP_OBFF_WAKE_EN; + else { + switch (type) { + case PCI_EXP_OBFF_SIGNAL_L0: + if (!(ctrl & PCI_EXP_OBFF_WAKE_EN)) + ctrl |= PCI_EXP_OBFF_MSGA_EN; + break; + case PCI_EXP_OBFF_SIGNAL_ALWAYS: + ctrl &= ~PCI_EXP_OBFF_WAKE_EN; + ctrl |= PCI_EXP_OBFF_MSGB_EN; + break; + default: + WARN(1, "bad OBFF signal type\n"); + return -ENOTSUPP; + } + } + pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl); + + return 0; +} +EXPORT_SYMBOL(pci_enable_obff); + +/** + * pci_disable_obff - disable optimized buffer flush/fill + * @dev: PCI device + * + * Disable OBFF on @dev. + */ +void pci_disable_obff(struct pci_dev *dev) +{ + int pos; + u16 ctrl; + + if (!pci_is_pcie(dev)) + return; + + pos = pci_pcie_cap(dev); + if (!pos) + return; + + pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl); + ctrl &= ~PCI_EXP_OBFF_WAKE_EN; + pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl); +} +EXPORT_SYMBOL(pci_disable_obff); + static int pci_acs_enable; /** diff --git a/include/linux/pci.h b/include/linux/pci.h index 551ddcb5f940..45a035cccd93 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -833,6 +833,13 @@ static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state, void pci_enable_ido(struct pci_dev *dev, unsigned long type); void pci_disable_ido(struct pci_dev *dev, unsigned long type); +enum pci_obff_signal_type { + PCI_EXP_OBFF_SIGNAL_L0, + PCI_EXP_OBFF_SIGNAL_ALWAYS, +}; +int pci_enable_obff(struct pci_dev *dev, enum pci_obff_signal_type); +void pci_disable_obff(struct pci_dev *dev); + /* For use by arch with custom probe code */ void set_pcie_port_type(struct pci_dev *pdev); void set_pcie_hotplug_bridge(struct pci_dev *pdev); @@ -1220,6 +1227,15 @@ static inline void pci_disable_ido(struct pci_dev *dev, unsigned long type) { } +static inline int pci_enable_obff(struct pci_dev *dev, unsigned long type) +{ + return 0; +} + +static inline void pci_disable_obff(struct pci_dev *dev) +{ +} + static inline int pci_request_regions(struct pci_dev *dev, const char *res_name) { return -EIO; diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h index d9acf9b99814..aa420261843d 100644 --- a/include/linux/pci_regs.h +++ b/include/linux/pci_regs.h @@ -508,10 +508,16 @@ #define PCI_EXP_RTSTA_PENDING 0x20000 /* PME pending */ #define PCI_EXP_DEVCAP2 36 /* Device Capabilities 2 */ #define PCI_EXP_DEVCAP2_ARI 0x20 /* Alternative Routing-ID */ +#define PCI_EXP_OBFF_MASK 0xc0000 /* OBFF support mechanism */ +#define PCI_EXP_OBFF_MSG 0x40000 /* New message signaling */ +#define PCI_EXP_OBFF_WAKE 0x80000 /* Re-use WAKE# for OBFF */ #define PCI_EXP_DEVCTL2 40 /* Device Control 2 */ #define PCI_EXP_DEVCTL2_ARI 0x20 /* Alternative Routing-ID */ #define PCI_EXP_IDO_REQ_EN 0x100 /* ID-based ordering request enable */ #define PCI_EXP_IDO_CMP_EN 0x200 /* ID-based ordering completion enable */ +#define PCI_EXP_OBFF_MSGA_EN 0x2000 /* OBFF enable with Message type A */ +#define PCI_EXP_OBFF_MSGB_EN 0x4000 /* OBFF enable with Message type B */ +#define PCI_EXP_OBFF_WAKE_EN 0x6000 /* OBFF using WAKE# signaling */ #define PCI_EXP_LNKCTL2 48 /* Link Control 2 */ #define PCI_EXP_SLTCTL2 56 /* Slot Control 2 */ -- cgit From 51c2e0a7e5bc7ed1384cc68cfb95e702571500c9 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 14 Jan 2011 08:53:04 -0800 Subject: PCI: add latency tolerance reporting enable/disable support Latency tolerance reporting allows devices to send messages to the root complex indicating their latency tolerance for snooped & unsnooped memory transactions. Add support for enabling & disabling this feature, along with a routine to set the max latencies a device should send upstream. Signed-off-by: Jesse Barnes --- drivers/pci/pci.c | 149 +++++++++++++++++++++++++++++++++++++++++++++++ include/linux/pci.h | 5 ++ include/linux/pci_regs.h | 9 +++ 3 files changed, 163 insertions(+) (limited to 'include/linux') diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 01e4cab2e5cb..53302cbdb94c 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1979,6 +1979,155 @@ void pci_disable_obff(struct pci_dev *dev) } EXPORT_SYMBOL(pci_disable_obff); +/** + * pci_ltr_supported - check whether a device supports LTR + * @dev: PCI device + * + * RETURNS: + * True if @dev supports latency tolerance reporting, false otherwise. + */ +bool pci_ltr_supported(struct pci_dev *dev) +{ + int pos; + u32 cap; + + if (!pci_is_pcie(dev)) + return false; + + pos = pci_pcie_cap(dev); + if (!pos) + return false; + + pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP2, &cap); + + return cap & PCI_EXP_DEVCAP2_LTR; +} +EXPORT_SYMBOL(pci_ltr_supported); + +/** + * pci_enable_ltr - enable latency tolerance reporting + * @dev: PCI device + * + * Enable LTR on @dev if possible, which means enabling it first on + * upstream ports. + * + * RETURNS: + * Zero on success, errno on failure. + */ +int pci_enable_ltr(struct pci_dev *dev) +{ + int pos; + u16 ctrl; + int ret; + + if (!pci_ltr_supported(dev)) + return -ENOTSUPP; + + pos = pci_pcie_cap(dev); + if (!pos) + return -ENOTSUPP; + + /* Only primary function can enable/disable LTR */ + if (PCI_FUNC(dev->devfn) != 0) + return -EINVAL; + + /* Enable upstream ports first */ + if (dev->bus) { + ret = pci_enable_ltr(dev->bus->self); + if (ret) + return ret; + } + + pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl); + ctrl |= PCI_EXP_LTR_EN; + pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl); + + return 0; +} +EXPORT_SYMBOL(pci_enable_ltr); + +/** + * pci_disable_ltr - disable latency tolerance reporting + * @dev: PCI device + */ +void pci_disable_ltr(struct pci_dev *dev) +{ + int pos; + u16 ctrl; + + if (!pci_ltr_supported(dev)) + return; + + pos = pci_pcie_cap(dev); + if (!pos) + return; + + /* Only primary function can enable/disable LTR */ + if (PCI_FUNC(dev->devfn) != 0) + return; + + pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl); + ctrl &= ~PCI_EXP_LTR_EN; + pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl); +} +EXPORT_SYMBOL(pci_disable_ltr); + +static int __pci_ltr_scale(int *val) +{ + int scale = 0; + + while (*val > 1023) { + *val = (*val + 31) / 32; + scale++; + } + return scale; +} + +/** + * pci_set_ltr - set LTR latency values + * @dev: PCI device + * @snoop_lat_ns: snoop latency in nanoseconds + * @nosnoop_lat_ns: nosnoop latency in nanoseconds + * + * Figure out the scale and set the LTR values accordingly. + */ +int pci_set_ltr(struct pci_dev *dev, int snoop_lat_ns, int nosnoop_lat_ns) +{ + int pos, ret, snoop_scale, nosnoop_scale; + u16 val; + + if (!pci_ltr_supported(dev)) + return -ENOTSUPP; + + snoop_scale = __pci_ltr_scale(&snoop_lat_ns); + nosnoop_scale = __pci_ltr_scale(&nosnoop_lat_ns); + + if (snoop_lat_ns > PCI_LTR_VALUE_MASK || + nosnoop_lat_ns > PCI_LTR_VALUE_MASK) + return -EINVAL; + + if ((snoop_scale > (PCI_LTR_SCALE_MASK >> PCI_LTR_SCALE_SHIFT)) || + (nosnoop_scale > (PCI_LTR_SCALE_MASK >> PCI_LTR_SCALE_SHIFT))) + return -EINVAL; + + pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_LTR); + if (!pos) + return -ENOTSUPP; + + val = (snoop_scale << PCI_LTR_SCALE_SHIFT) | snoop_lat_ns; + ret = pci_write_config_word(dev, pos + PCI_LTR_MAX_SNOOP_LAT, val); + if (ret != 4) + return -EIO; + + val = (nosnoop_scale << PCI_LTR_SCALE_SHIFT) | nosnoop_lat_ns; + ret = pci_write_config_word(dev, pos + PCI_LTR_MAX_NOSNOOP_LAT, val); + if (ret != 4) + return -EIO; + + return 0; +} +EXPORT_SYMBOL(pci_set_ltr); + static int pci_acs_enable; /** diff --git a/include/linux/pci.h b/include/linux/pci.h index 45a035cccd93..df4d69b82144 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -840,6 +840,11 @@ enum pci_obff_signal_type { int pci_enable_obff(struct pci_dev *dev, enum pci_obff_signal_type); void pci_disable_obff(struct pci_dev *dev); +bool pci_ltr_supported(struct pci_dev *dev); +int pci_enable_ltr(struct pci_dev *dev); +void pci_disable_ltr(struct pci_dev *dev); +int pci_set_ltr(struct pci_dev *dev, int snoop_lat_ns, int nosnoop_lat_ns); + /* For use by arch with custom probe code */ void set_pcie_port_type(struct pci_dev *pdev); void set_pcie_hotplug_bridge(struct pci_dev *pdev); diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h index aa420261843d..e8840964aca1 100644 --- a/include/linux/pci_regs.h +++ b/include/linux/pci_regs.h @@ -508,6 +508,7 @@ #define PCI_EXP_RTSTA_PENDING 0x20000 /* PME pending */ #define PCI_EXP_DEVCAP2 36 /* Device Capabilities 2 */ #define PCI_EXP_DEVCAP2_ARI 0x20 /* Alternative Routing-ID */ +#define PCI_EXP_DEVCAP2_LTR 0x800 /* Latency tolerance reporting */ #define PCI_EXP_OBFF_MASK 0xc0000 /* OBFF support mechanism */ #define PCI_EXP_OBFF_MSG 0x40000 /* New message signaling */ #define PCI_EXP_OBFF_WAKE 0x80000 /* Re-use WAKE# for OBFF */ @@ -515,6 +516,7 @@ #define PCI_EXP_DEVCTL2_ARI 0x20 /* Alternative Routing-ID */ #define PCI_EXP_IDO_REQ_EN 0x100 /* ID-based ordering request enable */ #define PCI_EXP_IDO_CMP_EN 0x200 /* ID-based ordering completion enable */ +#define PCI_EXP_LTR_EN 0x400 /* Latency tolerance reporting */ #define PCI_EXP_OBFF_MSGA_EN 0x2000 /* OBFF enable with Message type A */ #define PCI_EXP_OBFF_MSGB_EN 0x4000 /* OBFF enable with Message type B */ #define PCI_EXP_OBFF_WAKE_EN 0x6000 /* OBFF using WAKE# signaling */ @@ -535,6 +537,7 @@ #define PCI_EXT_CAP_ID_ARI 14 #define PCI_EXT_CAP_ID_ATS 15 #define PCI_EXT_CAP_ID_SRIOV 16 +#define PCI_EXT_CAP_ID_LTR 24 /* Advanced Error Reporting */ #define PCI_ERR_UNCOR_STATUS 4 /* Uncorrectable Error Status */ @@ -691,6 +694,12 @@ #define PCI_SRIOV_VFM_MO 0x2 /* Active.MigrateOut */ #define PCI_SRIOV_VFM_AV 0x3 /* Active.Available */ +#define PCI_LTR_MAX_SNOOP_LAT 0x4 +#define PCI_LTR_MAX_NOSNOOP_LAT 0x6 +#define PCI_LTR_VALUE_MASK 0x000003ff +#define PCI_LTR_SCALE_MASK 0x00001c00 +#define PCI_LTR_SCALE_SHIFT 10 + /* Access Control Service */ #define PCI_ACS_CAP 0x04 /* ACS Capability Register */ #define PCI_ACS_SV 0x01 /* Source Validation */ -- cgit From 8f389a99b652aab5b42297280bd94d95933ad12f Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Wed, 11 May 2011 15:13:32 -0700 Subject: mm: use alloc_bootmem_node_nopanic() on really needed path Stefan found nobootmem does not work on his system that has only 8M of RAM. This causes an early panic: BIOS-provided physical RAM map: BIOS-88: 0000000000000000 - 000000000009f000 (usable) BIOS-88: 0000000000100000 - 0000000000840000 (usable) bootconsole [earlyser0] enabled Notice: NX (Execute Disable) protection missing in CPU or disabled in BIOS! DMI not present or invalid. last_pfn = 0x840 max_arch_pfn = 0x100000 init_memory_mapping: 0000000000000000-0000000000840000 8MB LOWMEM available. mapped low ram: 0 - 00840000 low ram: 0 - 00840000 Zone PFN ranges: DMA 0x00000001 -> 0x00001000 Normal empty Movable zone start PFN for each node early_node_map[2] active PFN ranges 0: 0x00000001 -> 0x0000009f 0: 0x00000100 -> 0x00000840 BUG: Int 6: CR2 (null) EDI c034663c ESI (null) EBP c0329f38 ESP c0329ef4 EBX c0346380 EDX 00000006 ECX ffffffff EAX fffffff4 err (null) EIP c0353191 CS c0320060 flg 00010082 Stack: (null) c030c533 000007cd (null) c030c533 00000001 (null) (null) 00000003 0000083f 00000018 00000002 00000002 c0329f6c c03534d6 (null) (null) 00000100 00000840 (null) c0329f64 00000001 00001000 (null) Pid: 0, comm: swapper Not tainted 2.6.36 #5 Call Trace: [] ? 0xc02e3707 [] 0xc035e6e5 [] ? 0xc0353191 [] 0xc03534d6 [] 0xc034f1cd [] 0xc034a824 [] ? 0xc03513cb [] 0xc0349432 [] 0xc0349066 It turns out that we should ignore the low limit of 16M. Use alloc_bootmem_node_nopanic() in this case. [akpm@linux-foundation.org: less mess] Signed-off-by: Yinghai LU Reported-by: Stefan Hellermann Tested-by: Stefan Hellermann Cc: Ingo Molnar Cc: "H. Peter Anvin" Cc: Thomas Gleixner Cc: [2.6.34+] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/bootmem.h | 2 ++ mm/page_alloc.c | 7 ++++--- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h index b8613e806aa9..01eca1794e14 100644 --- a/include/linux/bootmem.h +++ b/include/linux/bootmem.h @@ -111,6 +111,8 @@ extern void *__alloc_bootmem_low_node(pg_data_t *pgdat, __alloc_bootmem_nopanic(x, PAGE_SIZE, __pa(MAX_DMA_ADDRESS)) #define alloc_bootmem_node(pgdat, x) \ __alloc_bootmem_node(pgdat, x, SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS)) +#define alloc_bootmem_node_nopanic(pgdat, x) \ + __alloc_bootmem_node_nopanic(pgdat, x, SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS)) #define alloc_bootmem_pages_node(pgdat, x) \ __alloc_bootmem_node(pgdat, x, PAGE_SIZE, __pa(MAX_DMA_ADDRESS)) #define alloc_bootmem_pages_node_nopanic(pgdat, x) \ diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 9f8a97b9a350..454191a25173 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -3564,7 +3564,7 @@ int zone_wait_table_init(struct zone *zone, unsigned long zone_size_pages) if (!slab_is_available()) { zone->wait_table = (wait_queue_head_t *) - alloc_bootmem_node(pgdat, alloc_size); + alloc_bootmem_node_nopanic(pgdat, alloc_size); } else { /* * This case means that a zone whose size was 0 gets new memory @@ -4141,7 +4141,8 @@ static void __init setup_usemap(struct pglist_data *pgdat, unsigned long usemapsize = usemap_size(zonesize); zone->pageblock_flags = NULL; if (usemapsize) - zone->pageblock_flags = alloc_bootmem_node(pgdat, usemapsize); + zone->pageblock_flags = alloc_bootmem_node_nopanic(pgdat, + usemapsize); } #else static inline void setup_usemap(struct pglist_data *pgdat, @@ -4307,7 +4308,7 @@ static void __init_refok alloc_node_mem_map(struct pglist_data *pgdat) size = (end - start) * sizeof(struct page); map = alloc_remap(pgdat->node_id, size); if (!map) - map = alloc_bootmem_node(pgdat, size); + map = alloc_bootmem_node_nopanic(pgdat, size); pgdat->node_mem_map = map + (pgdat->node_start_pfn - start); } #ifndef CONFIG_NEED_MULTIPLE_NODES -- cgit From ee85c2e1454603ebb9f8d87223ac79dcdc87fa32 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 11 May 2011 15:13:34 -0700 Subject: mm: add alloc_pages_exact_nid() Add a alloc_pages_exact_nid() that allocates on a specific node. The naming is quite broken, but fixing that would need a larger renaming action. [akpm@linux-foundation.org: coding-style fixes] [akpm@linux-foundation.org: tweak comment] Signed-off-by: Andi Kleen Cc: Michal Hocko Cc: Balbir Singh Cc: KOSAKI Motohiro Cc: Dave Hansen Cc: David Rientjes Acked-by: Johannes Weiner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/gfp.h | 2 ++ mm/page_alloc.c | 49 +++++++++++++++++++++++++++++++++++++------------ 2 files changed, 39 insertions(+), 12 deletions(-) (limited to 'include/linux') diff --git a/include/linux/gfp.h b/include/linux/gfp.h index bfb8f934521e..56d8fc87fbbc 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -353,6 +353,8 @@ extern unsigned long get_zeroed_page(gfp_t gfp_mask); void *alloc_pages_exact(size_t size, gfp_t gfp_mask); void free_pages_exact(void *virt, size_t size); +/* This is different from alloc_pages_exact_node !!! */ +void *alloc_pages_exact_nid(int nid, size_t size, gfp_t gfp_mask); #define __get_free_page(gfp_mask) \ __get_free_pages((gfp_mask), 0) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 454191a25173..570d944daeb5 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -2317,6 +2317,21 @@ void free_pages(unsigned long addr, unsigned int order) EXPORT_SYMBOL(free_pages); +static void *make_alloc_exact(unsigned long addr, unsigned order, size_t size) +{ + if (addr) { + unsigned long alloc_end = addr + (PAGE_SIZE << order); + unsigned long used = addr + PAGE_ALIGN(size); + + split_page(virt_to_page((void *)addr), order); + while (used < alloc_end) { + free_page(used); + used += PAGE_SIZE; + } + } + return (void *)addr; +} + /** * alloc_pages_exact - allocate an exact number physically-contiguous pages. * @size: the number of bytes to allocate @@ -2336,21 +2351,31 @@ void *alloc_pages_exact(size_t size, gfp_t gfp_mask) unsigned long addr; addr = __get_free_pages(gfp_mask, order); - if (addr) { - unsigned long alloc_end = addr + (PAGE_SIZE << order); - unsigned long used = addr + PAGE_ALIGN(size); - - split_page(virt_to_page((void *)addr), order); - while (used < alloc_end) { - free_page(used); - used += PAGE_SIZE; - } - } - - return (void *)addr; + return make_alloc_exact(addr, order, size); } EXPORT_SYMBOL(alloc_pages_exact); +/** + * alloc_pages_exact_nid - allocate an exact number of physically-contiguous + * pages on a node. + * @size: the number of bytes to allocate + * @gfp_mask: GFP flags for the allocation + * + * Like alloc_pages_exact(), but try to allocate on node nid first before falling + * back. + * Note this is not alloc_pages_exact_node() which allocates on a specific node, + * but is not exact. + */ +void *alloc_pages_exact_nid(int nid, size_t size, gfp_t gfp_mask) +{ + unsigned order = get_order(size); + struct page *p = alloc_pages_node(nid, gfp_mask, order); + if (!p) + return NULL; + return make_alloc_exact((unsigned long)page_address(p), order, size); +} +EXPORT_SYMBOL(alloc_pages_exact_nid); + /** * free_pages_exact - release memory allocated via alloc_pages_exact() * @virt: the value returned by alloc_pages_exact. -- cgit From a75b9df9d3bfc3cd1083974c045ae31ce5f3434f Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 11 May 2011 18:00:51 -0400 Subject: NFSv4.1: Ensure that layoutget uses the correct gfp modes Currently, writebacks may end up recursing back into the filesystem due to GFP_KERNEL direct reclaims in the pnfs subsystem. Signed-off-by: Trond Myklebust --- fs/nfs/nfs4filelayout.c | 25 ++++++++++++++----------- fs/nfs/nfs4filelayout.h | 2 +- fs/nfs/nfs4filelayoutdev.c | 34 +++++++++++++++++----------------- fs/nfs/pnfs.c | 33 +++++++++++++++++++-------------- fs/nfs/pnfs.h | 6 +++--- fs/nfs/read.c | 4 ++-- fs/nfs/write.c | 4 ++-- include/linux/nfs_xdr.h | 1 + 8 files changed, 59 insertions(+), 50 deletions(-) (limited to 'include/linux') diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c index 7841ea603c91..be79dc9f386d 100644 --- a/fs/nfs/nfs4filelayout.c +++ b/fs/nfs/nfs4filelayout.c @@ -418,7 +418,8 @@ static int filelayout_check_layout(struct pnfs_layout_hdr *lo, struct nfs4_filelayout_segment *fl, struct nfs4_layoutget_res *lgr, - struct nfs4_deviceid *id) + struct nfs4_deviceid *id, + gfp_t gfp_flags) { struct nfs4_file_layout_dsaddr *dsaddr; int status = -EINVAL; @@ -441,7 +442,7 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo, /* find and reference the deviceid */ dsaddr = nfs4_fl_find_get_deviceid(id); if (dsaddr == NULL) { - dsaddr = get_device_info(lo->plh_inode, id); + dsaddr = get_device_info(lo->plh_inode, id, gfp_flags); if (dsaddr == NULL) goto out; } @@ -502,7 +503,8 @@ static int filelayout_decode_layout(struct pnfs_layout_hdr *flo, struct nfs4_filelayout_segment *fl, struct nfs4_layoutget_res *lgr, - struct nfs4_deviceid *id) + struct nfs4_deviceid *id, + gfp_t gfp_flags) { struct xdr_stream stream; struct xdr_buf buf = { @@ -518,7 +520,7 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo, dprintk("%s: set_layout_map Begin\n", __func__); - scratch = alloc_page(GFP_KERNEL); + scratch = alloc_page(gfp_flags); if (!scratch) return -ENOMEM; @@ -556,13 +558,13 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo, goto out_err; fl->fh_array = kzalloc(fl->num_fh * sizeof(struct nfs_fh *), - GFP_KERNEL); + gfp_flags); if (!fl->fh_array) goto out_err; for (i = 0; i < fl->num_fh; i++) { /* Do we want to use a mempool here? */ - fl->fh_array[i] = kmalloc(sizeof(struct nfs_fh), GFP_KERNEL); + fl->fh_array[i] = kmalloc(sizeof(struct nfs_fh), gfp_flags); if (!fl->fh_array[i]) goto out_err_free; @@ -607,19 +609,20 @@ filelayout_free_lseg(struct pnfs_layout_segment *lseg) static struct pnfs_layout_segment * filelayout_alloc_lseg(struct pnfs_layout_hdr *layoutid, - struct nfs4_layoutget_res *lgr) + struct nfs4_layoutget_res *lgr, + gfp_t gfp_flags) { struct nfs4_filelayout_segment *fl; int rc; struct nfs4_deviceid id; dprintk("--> %s\n", __func__); - fl = kzalloc(sizeof(*fl), GFP_KERNEL); + fl = kzalloc(sizeof(*fl), gfp_flags); if (!fl) return NULL; - rc = filelayout_decode_layout(layoutid, fl, lgr, &id); - if (rc != 0 || filelayout_check_layout(layoutid, fl, lgr, &id)) { + rc = filelayout_decode_layout(layoutid, fl, lgr, &id, gfp_flags); + if (rc != 0 || filelayout_check_layout(layoutid, fl, lgr, &id, gfp_flags)) { _filelayout_free_lseg(fl); return NULL; } @@ -635,7 +638,7 @@ filelayout_alloc_lseg(struct pnfs_layout_hdr *layoutid, int size = (fl->stripe_type == STRIPE_SPARSE) ? fl->dsaddr->ds_num : fl->dsaddr->stripe_count; - fl->commit_buckets = kcalloc(size, sizeof(struct list_head), GFP_KERNEL); + fl->commit_buckets = kcalloc(size, sizeof(struct list_head), gfp_flags); if (!fl->commit_buckets) { filelayout_free_lseg(&fl->generic_hdr); return NULL; diff --git a/fs/nfs/nfs4filelayout.h b/fs/nfs/nfs4filelayout.h index 7c44579f5832..2b461d77b43a 100644 --- a/fs/nfs/nfs4filelayout.h +++ b/fs/nfs/nfs4filelayout.h @@ -104,6 +104,6 @@ extern struct nfs4_file_layout_dsaddr * nfs4_fl_find_get_deviceid(struct nfs4_deviceid *dev_id); extern void nfs4_fl_put_deviceid(struct nfs4_file_layout_dsaddr *dsaddr); struct nfs4_file_layout_dsaddr * -get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id); +get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_flags); #endif /* FS_NFS_NFS4FILELAYOUT_H */ diff --git a/fs/nfs/nfs4filelayoutdev.c b/fs/nfs/nfs4filelayoutdev.c index de5350f2b249..db07c7af1395 100644 --- a/fs/nfs/nfs4filelayoutdev.c +++ b/fs/nfs/nfs4filelayoutdev.c @@ -225,11 +225,11 @@ nfs4_fl_free_deviceid(struct nfs4_file_layout_dsaddr *dsaddr) } static struct nfs4_pnfs_ds * -nfs4_pnfs_ds_add(struct inode *inode, u32 ip_addr, u32 port) +nfs4_pnfs_ds_add(struct inode *inode, u32 ip_addr, u32 port, gfp_t gfp_flags) { struct nfs4_pnfs_ds *tmp_ds, *ds; - ds = kzalloc(sizeof(*tmp_ds), GFP_KERNEL); + ds = kzalloc(sizeof(*tmp_ds), gfp_flags); if (!ds) goto out; @@ -261,7 +261,7 @@ out: * Currently only support ipv4, and one multi-path address. */ static struct nfs4_pnfs_ds * -decode_and_add_ds(struct xdr_stream *streamp, struct inode *inode) +decode_and_add_ds(struct xdr_stream *streamp, struct inode *inode, gfp_t gfp_flags) { struct nfs4_pnfs_ds *ds = NULL; char *buf; @@ -303,7 +303,7 @@ decode_and_add_ds(struct xdr_stream *streamp, struct inode *inode) rlen); goto out_err; } - buf = kmalloc(rlen + 1, GFP_KERNEL); + buf = kmalloc(rlen + 1, gfp_flags); if (!buf) { dprintk("%s: Not enough memory\n", __func__); goto out_err; @@ -333,7 +333,7 @@ decode_and_add_ds(struct xdr_stream *streamp, struct inode *inode) sscanf(pstr, "-%d-%d", &tmp[0], &tmp[1]); port = htons((tmp[0] << 8) | (tmp[1])); - ds = nfs4_pnfs_ds_add(inode, ip_addr, port); + ds = nfs4_pnfs_ds_add(inode, ip_addr, port, gfp_flags); dprintk("%s: Decoded address and port %s\n", __func__, buf); out_free: kfree(buf); @@ -343,7 +343,7 @@ out_err: /* Decode opaque device data and return the result */ static struct nfs4_file_layout_dsaddr* -decode_device(struct inode *ino, struct pnfs_device *pdev) +decode_device(struct inode *ino, struct pnfs_device *pdev, gfp_t gfp_flags) { int i; u32 cnt, num; @@ -362,7 +362,7 @@ decode_device(struct inode *ino, struct pnfs_device *pdev) struct page *scratch; /* set up xdr stream */ - scratch = alloc_page(GFP_KERNEL); + scratch = alloc_page(gfp_flags); if (!scratch) goto out_err; @@ -384,7 +384,7 @@ decode_device(struct inode *ino, struct pnfs_device *pdev) } /* read stripe indices */ - stripe_indices = kcalloc(cnt, sizeof(u8), GFP_KERNEL); + stripe_indices = kcalloc(cnt, sizeof(u8), gfp_flags); if (!stripe_indices) goto out_err_free_scratch; @@ -423,7 +423,7 @@ decode_device(struct inode *ino, struct pnfs_device *pdev) dsaddr = kzalloc(sizeof(*dsaddr) + (sizeof(struct nfs4_pnfs_ds *) * (num - 1)), - GFP_KERNEL); + gfp_flags); if (!dsaddr) goto out_err_free_stripe_indices; @@ -452,7 +452,7 @@ decode_device(struct inode *ino, struct pnfs_device *pdev) for (j = 0; j < mp_count; j++) { if (j == 0) { dsaddr->ds_list[i] = decode_and_add_ds(&stream, - ino); + ino, gfp_flags); if (dsaddr->ds_list[i] == NULL) goto out_err_free_deviceid; } else { @@ -503,12 +503,12 @@ out_err: * available devices. */ static struct nfs4_file_layout_dsaddr * -decode_and_add_device(struct inode *inode, struct pnfs_device *dev) +decode_and_add_device(struct inode *inode, struct pnfs_device *dev, gfp_t gfp_flags) { struct nfs4_file_layout_dsaddr *d, *new; long hash; - new = decode_device(inode, dev); + new = decode_device(inode, dev, gfp_flags); if (!new) { printk(KERN_WARNING "%s: Could not decode or add device\n", __func__); @@ -537,7 +537,7 @@ decode_and_add_device(struct inode *inode, struct pnfs_device *dev) * of available devices, and return it. */ struct nfs4_file_layout_dsaddr * -get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id) +get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_flags) { struct pnfs_device *pdev = NULL; u32 max_resp_sz; @@ -556,17 +556,17 @@ get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id) dprintk("%s inode %p max_resp_sz %u max_pages %d\n", __func__, inode, max_resp_sz, max_pages); - pdev = kzalloc(sizeof(struct pnfs_device), GFP_KERNEL); + pdev = kzalloc(sizeof(struct pnfs_device), gfp_flags); if (pdev == NULL) return NULL; - pages = kzalloc(max_pages * sizeof(struct page *), GFP_KERNEL); + pages = kzalloc(max_pages * sizeof(struct page *), gfp_flags); if (pages == NULL) { kfree(pdev); return NULL; } for (i = 0; i < max_pages; i++) { - pages[i] = alloc_page(GFP_KERNEL); + pages[i] = alloc_page(gfp_flags); if (!pages[i]) goto out_free; } @@ -587,7 +587,7 @@ get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id) * Found new device, need to decode it and then add it to the * list of known devices for this mountpoint. */ - dsaddr = decode_and_add_device(inode, pdev); + dsaddr = decode_and_add_device(inode, pdev, gfp_flags); out_free: for (i = 0; i < max_pages; i++) __free_page(pages[i]); diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 65455f58b109..f57f5281a520 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -467,7 +467,8 @@ pnfs_choose_layoutget_stateid(nfs4_stateid *dst, struct pnfs_layout_hdr *lo, static struct pnfs_layout_segment * send_layoutget(struct pnfs_layout_hdr *lo, struct nfs_open_context *ctx, - u32 iomode) + u32 iomode, + gfp_t gfp_flags) { struct inode *ino = lo->plh_inode; struct nfs_server *server = NFS_SERVER(ino); @@ -480,7 +481,7 @@ send_layoutget(struct pnfs_layout_hdr *lo, dprintk("--> %s\n", __func__); BUG_ON(ctx == NULL); - lgp = kzalloc(sizeof(*lgp), GFP_KERNEL); + lgp = kzalloc(sizeof(*lgp), gfp_flags); if (lgp == NULL) return NULL; @@ -488,12 +489,12 @@ send_layoutget(struct pnfs_layout_hdr *lo, max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz; max_pages = max_resp_sz >> PAGE_SHIFT; - pages = kzalloc(max_pages * sizeof(struct page *), GFP_KERNEL); + pages = kzalloc(max_pages * sizeof(struct page *), gfp_flags); if (!pages) goto out_err_free; for (i = 0; i < max_pages; i++) { - pages[i] = alloc_page(GFP_KERNEL); + pages[i] = alloc_page(gfp_flags); if (!pages[i]) goto out_err_free; } @@ -509,6 +510,7 @@ send_layoutget(struct pnfs_layout_hdr *lo, lgp->args.layout.pages = pages; lgp->args.layout.pglen = max_pages * PAGE_SIZE; lgp->lsegpp = &lseg; + lgp->gfp_flags = gfp_flags; /* Synchronously retrieve layout information from server and * store in lseg. @@ -666,11 +668,11 @@ pnfs_insert_layout(struct pnfs_layout_hdr *lo, } static struct pnfs_layout_hdr * -alloc_init_layout_hdr(struct inode *ino) +alloc_init_layout_hdr(struct inode *ino, gfp_t gfp_flags) { struct pnfs_layout_hdr *lo; - lo = kzalloc(sizeof(struct pnfs_layout_hdr), GFP_KERNEL); + lo = kzalloc(sizeof(struct pnfs_layout_hdr), gfp_flags); if (!lo) return NULL; atomic_set(&lo->plh_refcount, 1); @@ -682,7 +684,7 @@ alloc_init_layout_hdr(struct inode *ino) } static struct pnfs_layout_hdr * -pnfs_find_alloc_layout(struct inode *ino) +pnfs_find_alloc_layout(struct inode *ino, gfp_t gfp_flags) { struct nfs_inode *nfsi = NFS_I(ino); struct pnfs_layout_hdr *new = NULL; @@ -697,7 +699,7 @@ pnfs_find_alloc_layout(struct inode *ino) return nfsi->layout; } spin_unlock(&ino->i_lock); - new = alloc_init_layout_hdr(ino); + new = alloc_init_layout_hdr(ino, gfp_flags); spin_lock(&ino->i_lock); if (likely(nfsi->layout == NULL)) /* Won the race? */ @@ -757,7 +759,8 @@ pnfs_find_lseg(struct pnfs_layout_hdr *lo, u32 iomode) struct pnfs_layout_segment * pnfs_update_layout(struct inode *ino, struct nfs_open_context *ctx, - enum pnfs_iomode iomode) + enum pnfs_iomode iomode, + gfp_t gfp_flags) { struct nfs_inode *nfsi = NFS_I(ino); struct nfs_client *clp = NFS_SERVER(ino)->nfs_client; @@ -768,7 +771,7 @@ pnfs_update_layout(struct inode *ino, if (!pnfs_enabled_sb(NFS_SERVER(ino))) return NULL; spin_lock(&ino->i_lock); - lo = pnfs_find_alloc_layout(ino); + lo = pnfs_find_alloc_layout(ino, gfp_flags); if (lo == NULL) { dprintk("%s ERROR: can't get pnfs_layout_hdr\n", __func__); goto out_unlock; @@ -808,7 +811,7 @@ pnfs_update_layout(struct inode *ino, spin_unlock(&clp->cl_lock); } - lseg = send_layoutget(lo, ctx, iomode); + lseg = send_layoutget(lo, ctx, iomode, gfp_flags); if (!lseg && first) { spin_lock(&clp->cl_lock); list_del_init(&lo->plh_layouts); @@ -847,7 +850,7 @@ pnfs_layout_process(struct nfs4_layoutget *lgp) goto out; } /* Inject layout blob into I/O device driver */ - lseg = NFS_SERVER(ino)->pnfs_curr_ld->alloc_lseg(lo, res); + lseg = NFS_SERVER(ino)->pnfs_curr_ld->alloc_lseg(lo, res, lgp->gfp_flags); if (!lseg || IS_ERR(lseg)) { if (!lseg) status = -ENOMEM; @@ -900,7 +903,8 @@ static int pnfs_read_pg_test(struct nfs_pageio_descriptor *pgio, /* This is first coelesce call for a series of nfs_pages */ pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, prev->wb_context, - IOMODE_READ); + IOMODE_READ, + GFP_KERNEL); } return NFS_SERVER(pgio->pg_inode)->pnfs_curr_ld->pg_test(pgio, prev, req); } @@ -922,7 +926,8 @@ static int pnfs_write_pg_test(struct nfs_pageio_descriptor *pgio, /* This is first coelesce call for a series of nfs_pages */ pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, prev->wb_context, - IOMODE_RW); + IOMODE_RW, + GFP_NOFS); } return NFS_SERVER(pgio->pg_inode)->pnfs_curr_ld->pg_test(pgio, prev, req); } diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h index bc4827202e7a..0c015bad9e7a 100644 --- a/fs/nfs/pnfs.h +++ b/fs/nfs/pnfs.h @@ -70,7 +70,7 @@ struct pnfs_layoutdriver_type { const u32 id; const char *name; struct module *owner; - struct pnfs_layout_segment * (*alloc_lseg) (struct pnfs_layout_hdr *layoutid, struct nfs4_layoutget_res *lgr); + struct pnfs_layout_segment * (*alloc_lseg) (struct pnfs_layout_hdr *layoutid, struct nfs4_layoutget_res *lgr, gfp_t gfp_flags); void (*free_lseg) (struct pnfs_layout_segment *lseg); /* test for nfs page cache coalescing */ @@ -126,7 +126,7 @@ void get_layout_hdr(struct pnfs_layout_hdr *lo); void put_lseg(struct pnfs_layout_segment *lseg); struct pnfs_layout_segment * pnfs_update_layout(struct inode *ino, struct nfs_open_context *ctx, - enum pnfs_iomode access_type); + enum pnfs_iomode access_type, gfp_t gfp_flags); void set_pnfs_layoutdriver(struct nfs_server *, u32 id); void unset_pnfs_layoutdriver(struct nfs_server *); enum pnfs_try_status pnfs_try_to_write_data(struct nfs_write_data *, @@ -245,7 +245,7 @@ static inline void put_lseg(struct pnfs_layout_segment *lseg) static inline struct pnfs_layout_segment * pnfs_update_layout(struct inode *ino, struct nfs_open_context *ctx, - enum pnfs_iomode access_type) + enum pnfs_iomode access_type, gfp_t gfp_flags) { return NULL; } diff --git a/fs/nfs/read.c b/fs/nfs/read.c index 7cded2b12a05..2bcf0dc306a1 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c @@ -288,7 +288,7 @@ static int nfs_pagein_multi(struct nfs_pageio_descriptor *desc) atomic_set(&req->wb_complete, requests); BUG_ON(desc->pg_lseg != NULL); - lseg = pnfs_update_layout(desc->pg_inode, req->wb_context, IOMODE_READ); + lseg = pnfs_update_layout(desc->pg_inode, req->wb_context, IOMODE_READ, GFP_KERNEL); ClearPageError(page); offset = 0; nbytes = desc->pg_count; @@ -351,7 +351,7 @@ static int nfs_pagein_one(struct nfs_pageio_descriptor *desc) } req = nfs_list_entry(data->pages.next); if ((!lseg) && list_is_singular(&data->pages)) - lseg = pnfs_update_layout(desc->pg_inode, req->wb_context, IOMODE_READ); + lseg = pnfs_update_layout(desc->pg_inode, req->wb_context, IOMODE_READ, GFP_KERNEL); ret = nfs_read_rpcsetup(req, data, &nfs_read_full_ops, desc->pg_count, 0, lseg); diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 3bd5d7e80f6c..49c715b4ac92 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -939,7 +939,7 @@ static int nfs_flush_multi(struct nfs_pageio_descriptor *desc) atomic_set(&req->wb_complete, requests); BUG_ON(desc->pg_lseg); - lseg = pnfs_update_layout(desc->pg_inode, req->wb_context, IOMODE_RW); + lseg = pnfs_update_layout(desc->pg_inode, req->wb_context, IOMODE_RW, GFP_NOFS); ClearPageError(page); offset = 0; nbytes = desc->pg_count; @@ -1013,7 +1013,7 @@ static int nfs_flush_one(struct nfs_pageio_descriptor *desc) } req = nfs_list_entry(data->pages.next); if ((!lseg) && list_is_singular(&data->pages)) - lseg = pnfs_update_layout(desc->pg_inode, req->wb_context, IOMODE_RW); + lseg = pnfs_update_layout(desc->pg_inode, req->wb_context, IOMODE_RW, GFP_NOFS); if ((desc->pg_ioflags & FLUSH_COND_STABLE) && (desc->pg_moreio || NFS_I(desc->pg_inode)->ncommit)) diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 890dce242639..7e371f7df9c4 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -233,6 +233,7 @@ struct nfs4_layoutget { struct nfs4_layoutget_args args; struct nfs4_layoutget_res res; struct pnfs_layout_segment **lsegpp; + gfp_t gfp_flags; }; struct nfs4_getdeviceinfo_args { -- cgit From 3e51e3edfd81bfd9853ad7de91167e4ce33d0fe7 Mon Sep 17 00:00:00 2001 From: Samir Bellabes Date: Wed, 11 May 2011 18:18:05 +0200 Subject: sched: Remove unused parameters from sched_fork() and wake_up_new_task() sched_fork() and wake_up_new_task() are defined with a parameter 'unsigned long clone_flags', which is unused. This patch removes the parameters. Signed-off-by: Samir Bellabes Acked-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1305130685-1047-1-git-send-email-sam@synack.fr Signed-off-by: Ingo Molnar --- include/linux/sched.h | 5 ++--- kernel/fork.c | 4 ++-- kernel/sched.c | 4 ++-- 3 files changed, 6 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index 6b4280b23ee6..12211e1666e2 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -2051,14 +2051,13 @@ extern void xtime_update(unsigned long ticks); extern int wake_up_state(struct task_struct *tsk, unsigned int state); extern int wake_up_process(struct task_struct *tsk); -extern void wake_up_new_task(struct task_struct *tsk, - unsigned long clone_flags); +extern void wake_up_new_task(struct task_struct *tsk); #ifdef CONFIG_SMP extern void kick_process(struct task_struct *tsk); #else static inline void kick_process(struct task_struct *tsk) { } #endif -extern void sched_fork(struct task_struct *p, int clone_flags); +extern void sched_fork(struct task_struct *p); extern void sched_dead(struct task_struct *p); extern void proc_caches_init(void); diff --git a/kernel/fork.c b/kernel/fork.c index aca62871a4f9..2b44d82b8237 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1152,7 +1152,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, #endif /* Perform scheduler related setup. Assign this task to a CPU. */ - sched_fork(p, clone_flags); + sched_fork(p); retval = perf_event_init_task(p); if (retval) @@ -1463,7 +1463,7 @@ long do_fork(unsigned long clone_flags, */ p->flags &= ~PF_STARTING; - wake_up_new_task(p, clone_flags); + wake_up_new_task(p); tracehook_report_clone_complete(trace, regs, clone_flags, nr, p); diff --git a/kernel/sched.c b/kernel/sched.c index da9338150484..f9778c0d91e2 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2741,7 +2741,7 @@ static void __sched_fork(struct task_struct *p) /* * fork()/clone()-time setup: */ -void sched_fork(struct task_struct *p, int clone_flags) +void sched_fork(struct task_struct *p) { unsigned long flags; int cpu = get_cpu(); @@ -2823,7 +2823,7 @@ void sched_fork(struct task_struct *p, int clone_flags) * that must be done for every newly created context, then puts the task * on the runqueue and wakes it. */ -void wake_up_new_task(struct task_struct *p, unsigned long clone_flags) +void wake_up_new_task(struct task_struct *p) { unsigned long flags; struct rq *rq; -- cgit From 5db1256a5131d3b133946fa02ac9770a784e6eb2 Mon Sep 17 00:00:00 2001 From: Milton Miller Date: Thu, 12 May 2011 04:13:54 -0500 Subject: seqlock: Don't smp_rmb in seqlock reader spin loop Move the smp_rmb after cpu_relax loop in read_seqlock and add ACCESS_ONCE to make sure the test and return are consistent. A multi-threaded core in the lab didn't like the update from 2.6.35 to 2.6.36, to the point it would hang during boot when multiple threads were active. Bisection showed af5ab277ded04bd9bc6b048c5a2f0e7d70ef0867 (clockevents: Remove the per cpu tick skew) as the culprit and it is supported with stack traces showing xtime_lock waits including tick_do_update_jiffies64 and/or update_vsyscall. Experimentation showed the combination of cpu_relax and smp_rmb was significantly slowing the progress of other threads sharing the core, and this patch is effective in avoiding the hang. A theory is the rmb is affecting the whole core while the cpu_relax is causing a resource rebalance flush, together they cause an interfernce cadance that is unbroken when the seqlock reader has interrupts disabled. At first I was confused why the refactor in 3c22cd5709e8143444a6d08682a87f4c57902df3 (kernel: optimise seqlock) didn't affect this patch application, but after some study that affected seqcount not seqlock. The new seqcount was not factored back into the seqlock. I defer that the future. While the removal of the timer interrupt offset created contention for the xtime lock while a cpu does the additonal work to update the system clock, the seqlock implementation with the tight rmb spin loop goes back much further, and is just waiting for the right trigger. Cc: Signed-off-by: Milton Miller Cc: Cc: Linus Torvalds Cc: Andi Kleen Cc: Nick Piggin Cc: Benjamin Herrenschmidt Cc: Anton Blanchard Cc: Paul McKenney Acked-by: Eric Dumazet Link: http://lkml.kernel.org/r/%3Cseqlock-rmb%40mdm.bga.com%3E Signed-off-by: Thomas Gleixner --- include/linux/seqlock.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/seqlock.h b/include/linux/seqlock.h index e98cd2e57194..06d69648fc86 100644 --- a/include/linux/seqlock.h +++ b/include/linux/seqlock.h @@ -88,12 +88,12 @@ static __always_inline unsigned read_seqbegin(const seqlock_t *sl) unsigned ret; repeat: - ret = sl->sequence; - smp_rmb(); + ret = ACCESS_ONCE(sl->sequence); if (unlikely(ret & 1)) { cpu_relax(); goto repeat; } + smp_rmb(); return ret; } -- cgit From 698b368275c3fa98261159253cfc79653f9dffc6 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 11 May 2011 14:49:36 -0700 Subject: fbcon: add lifetime refcount to opened frame buffers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This just adds the refcount and the new registration lock logic. It does not (for example) actually change the read/write/ioctl routines to actually use the frame buffer that was opened: those function still end up alway susing whatever the current frame buffer is at the time of the call. Without this, if something holds the frame buffer open over a framebuffer switch, the close() operation after the switch will access a fb_info that has been free'd by the unregistering of the old frame buffer. (The read/write/ioctl operations will normally not cause problems, because they will - illogically - pick up the new fbcon instead. But a switch that happens just as one of those is going on might see problems too, the window is just much smaller: one individual op rather than the whole open-close sequence.) This use-after-free is apparently fairly easily triggered by the Ubuntu 11.04 boot sequence. Acked-by: Tim Gardner Tested-by: Daniel J Blueman Tested-by: Anca Emanuel Cc: Bruno Prémont Cc: Alan Cox Cc: Paul Mundt Cc: Dave Airlie Cc: Andy Whitcroft Signed-off-by: Linus Torvalds --- drivers/video/fbmem.c | 56 ++++++++++++++++++++++++++++++++++++++++++--------- include/linux/fb.h | 1 + 2 files changed, 47 insertions(+), 10 deletions(-) (limited to 'include/linux') diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index e0c2284924b6..eec14d2ca1c7 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -42,9 +42,34 @@ #define FBPIXMAPSIZE (1024 * 8) +static DEFINE_MUTEX(registration_lock); struct fb_info *registered_fb[FB_MAX] __read_mostly; int num_registered_fb __read_mostly; +static struct fb_info *get_fb_info(unsigned int idx) +{ + struct fb_info *fb_info; + + if (idx >= FB_MAX) + return ERR_PTR(-ENODEV); + + mutex_lock(®istration_lock); + fb_info = registered_fb[idx]; + if (fb_info) + atomic_inc(&fb_info->count); + mutex_unlock(®istration_lock); + + return fb_info; +} + +static void put_fb_info(struct fb_info *fb_info) +{ + if (!atomic_dec_and_test(&fb_info->count)) + return; + if (fb_info->fbops->fb_destroy) + fb_info->fbops->fb_destroy(fb_info); +} + int lock_fb_info(struct fb_info *info) { mutex_lock(&info->lock); @@ -647,6 +672,7 @@ int fb_show_logo(struct fb_info *info, int rotate) { return 0; } static void *fb_seq_start(struct seq_file *m, loff_t *pos) { + mutex_lock(®istration_lock); return (*pos < FB_MAX) ? pos : NULL; } @@ -658,6 +684,7 @@ static void *fb_seq_next(struct seq_file *m, void *v, loff_t *pos) static void fb_seq_stop(struct seq_file *m, void *v) { + mutex_unlock(®istration_lock); } static int fb_seq_show(struct seq_file *m, void *v) @@ -1361,14 +1388,16 @@ __releases(&info->lock) struct fb_info *info; int res = 0; - if (fbidx >= FB_MAX) - return -ENODEV; - info = registered_fb[fbidx]; - if (!info) + info = get_fb_info(fbidx); + if (!info) { request_module("fb%d", fbidx); - info = registered_fb[fbidx]; - if (!info) - return -ENODEV; + info = get_fb_info(fbidx); + if (!info) + return -ENODEV; + } + if (IS_ERR(info)) + return PTR_ERR(info); + mutex_lock(&info->lock); if (!try_module_get(info->fbops->owner)) { res = -ENODEV; @@ -1386,6 +1415,8 @@ __releases(&info->lock) #endif out: mutex_unlock(&info->lock); + if (res) + put_fb_info(info); return res; } @@ -1401,6 +1432,7 @@ __releases(&info->lock) info->fbops->fb_release(info,1); module_put(info->fbops->owner); mutex_unlock(&info->lock); + put_fb_info(info); return 0; } @@ -1542,11 +1574,13 @@ register_framebuffer(struct fb_info *fb_info) remove_conflicting_framebuffers(fb_info->apertures, fb_info->fix.id, fb_is_primary_device(fb_info)); + mutex_lock(®istration_lock); num_registered_fb++; for (i = 0 ; i < FB_MAX; i++) if (!registered_fb[i]) break; fb_info->node = i; + atomic_set(&fb_info->count, 1); mutex_init(&fb_info->lock); mutex_init(&fb_info->mm_lock); @@ -1583,6 +1617,7 @@ register_framebuffer(struct fb_info *fb_info) fb_var_to_videomode(&mode, &fb_info->var); fb_add_videomode(&mode, &fb_info->modelist); registered_fb[i] = fb_info; + mutex_unlock(®istration_lock); event.info = fb_info; if (!lock_fb_info(fb_info)) @@ -1616,6 +1651,7 @@ unregister_framebuffer(struct fb_info *fb_info) struct fb_event event; int i, ret = 0; + mutex_lock(®istration_lock); i = fb_info->node; if (!registered_fb[i]) { ret = -EINVAL; @@ -1638,7 +1674,7 @@ unregister_framebuffer(struct fb_info *fb_info) (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT)) kfree(fb_info->pixmap.addr); fb_destroy_modelist(&fb_info->modelist); - registered_fb[i]=NULL; + registered_fb[i] = NULL; num_registered_fb--; fb_cleanup_device(fb_info); device_destroy(fb_class, MKDEV(FB_MAJOR, i)); @@ -1646,9 +1682,9 @@ unregister_framebuffer(struct fb_info *fb_info) fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event); /* this may free fb info */ - if (fb_info->fbops->fb_destroy) - fb_info->fbops->fb_destroy(fb_info); + put_fb_info(fb_info); done: + mutex_unlock(®istration_lock); return ret; } diff --git a/include/linux/fb.h b/include/linux/fb.h index df728c1c29ed..6a8274877171 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -832,6 +832,7 @@ struct fb_tile_ops { #define FBINFO_CAN_FORCE_OUTPUT 0x200000 struct fb_info { + atomic_t count; int node; int flags; struct mutex lock; /* Lock for open/release/ioctl funcs */ -- cgit From e70bdd41bd0ead91b4a43e9d656ac1569d7c8779 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 11 May 2011 16:35:30 -0700 Subject: Input: rotary-encoder - add support for half-period encoders Add support for encoders that have two detents per input signal period. Signed-off-by: Johan Hovold Acked-by: Daniel Mack Signed-off-by: Dmitry Torokhov --- Documentation/input/rotary-encoder.txt | 13 +++++++++++ drivers/input/misc/rotary_encoder.c | 42 +++++++++++++++++++++++++++++++--- include/linux/rotary_encoder.h | 1 + 3 files changed, 53 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/Documentation/input/rotary-encoder.txt b/Documentation/input/rotary-encoder.txt index 943e8f6f2b15..92e68bce13a4 100644 --- a/Documentation/input/rotary-encoder.txt +++ b/Documentation/input/rotary-encoder.txt @@ -9,6 +9,9 @@ peripherals with two wires. The outputs are phase-shifted by 90 degrees and by triggering on falling and rising edges, the turn direction can be determined. +Some encoders have both outputs low in stable states, whereas others also have +a stable state with both outputs high (half-period mode). + The phase diagram of these two outputs look like this: _____ _____ _____ @@ -26,6 +29,8 @@ The phase diagram of these two outputs look like this: |<-------->| one step + |<-->| + one step (half-period mode) For more information, please see http://en.wikipedia.org/wiki/Rotary_encoder @@ -34,6 +39,13 @@ For more information, please see 1. Events / state machine ------------------------- +In half-period mode, state a) and c) above are used to determine the +rotational direction based on the last stable state. Events are reported in +states b) and d) given that the new stable state is different from the last +(i.e. the rotation was not reversed half-way). + +Otherwise, the following apply: + a) Rising edge on channel A, channel B in low state This state is used to recognize a clockwise turn @@ -96,6 +108,7 @@ static struct rotary_encoder_platform_data my_rotary_encoder_info = { .gpio_b = GPIO_ROTARY_B, .inverted_a = 0, .inverted_b = 0, + .half_period = false, }; static struct platform_device rotary_encoder_device = { diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c index 077b80bdca69..2c8b84dd9dac 100644 --- a/drivers/input/misc/rotary_encoder.c +++ b/drivers/input/misc/rotary_encoder.c @@ -2,6 +2,7 @@ * rotary_encoder.c * * (c) 2009 Daniel Mack + * Copyright (C) 2011 Johan Hovold * * state machine code inspired by code from Tim Ruetz * @@ -38,6 +39,8 @@ struct rotary_encoder { bool armed; unsigned char dir; /* 0 - clockwise, 1 - CCW */ + + char last_stable; }; static int rotary_encoder_get_state(struct rotary_encoder_platform_data *pdata) @@ -112,11 +115,37 @@ static irqreturn_t rotary_encoder_irq(int irq, void *dev_id) return IRQ_HANDLED; } +static irqreturn_t rotary_encoder_half_period_irq(int irq, void *dev_id) +{ + struct rotary_encoder *encoder = dev_id; + int state; + + state = rotary_encoder_get_state(encoder->pdata); + + switch (state) { + case 0x00: + case 0x03: + if (state != encoder->last_stable) { + rotary_encoder_report_event(encoder); + encoder->last_stable = state; + } + break; + + case 0x01: + case 0x02: + encoder->dir = (encoder->last_stable + state) & 0x01; + break; + } + + return IRQ_HANDLED; +} + static int __devinit rotary_encoder_probe(struct platform_device *pdev) { struct rotary_encoder_platform_data *pdata = pdev->dev.platform_data; struct rotary_encoder *encoder; struct input_dev *input; + irq_handler_t handler; int err; if (!pdata) { @@ -187,7 +216,14 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev) } /* request the IRQs */ - err = request_irq(encoder->irq_a, &rotary_encoder_irq, + if (pdata->half_period) { + handler = &rotary_encoder_half_period_irq; + encoder->last_stable = rotary_encoder_get_state(pdata); + } else { + handler = &rotary_encoder_irq; + } + + err = request_irq(encoder->irq_a, handler, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, DRV_NAME, encoder); if (err) { @@ -196,7 +232,7 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev) goto exit_free_gpio_b; } - err = request_irq(encoder->irq_b, &rotary_encoder_irq, + err = request_irq(encoder->irq_b, handler, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, DRV_NAME, encoder); if (err) { @@ -264,5 +300,5 @@ module_exit(rotary_encoder_exit); MODULE_ALIAS("platform:" DRV_NAME); MODULE_DESCRIPTION("GPIO rotary encoder driver"); -MODULE_AUTHOR("Daniel Mack "); +MODULE_AUTHOR("Daniel Mack , Johan Hovold"); MODULE_LICENSE("GPL v2"); diff --git a/include/linux/rotary_encoder.h b/include/linux/rotary_encoder.h index 215278b8df2a..3f594dce5716 100644 --- a/include/linux/rotary_encoder.h +++ b/include/linux/rotary_encoder.h @@ -10,6 +10,7 @@ struct rotary_encoder_platform_data { unsigned int inverted_b; bool relative_axis; bool rollover; + bool half_period; }; #endif /* __ROTARY_ENCODER_H__ */ -- cgit From ebcaaad9d5e8fd284b8dcf25a24999420f0f56d8 Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Wed, 11 May 2011 16:24:08 -0700 Subject: Input: ads7846 - add possibility to use external vref on ads7846 Just set vref_mv in your platform config to use external vref. Otherwise the internal one is used. Signed-off-by: Alexander Stein Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ads7846.c | 19 +++++++++++-------- include/linux/spi/ads7846.h | 3 ++- 2 files changed, 13 insertions(+), 9 deletions(-) (limited to 'include/linux') diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index c24946f51256..e4ee43e159d2 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -109,6 +109,7 @@ struct ads7846 { u16 pressure_max; bool swap_xy; + bool use_internal; struct ads7846_packet *packet; @@ -300,7 +301,6 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) struct ads7846 *ts = dev_get_drvdata(dev); struct ser_req *req; int status; - int use_internal; req = kzalloc(sizeof *req, GFP_KERNEL); if (!req) @@ -308,11 +308,8 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) spi_message_init(&req->msg); - /* FIXME boards with ads7846 might use external vref instead ... */ - use_internal = (ts->model == 7846); - /* maybe turn on internal vREF, and let it settle */ - if (use_internal) { + if (ts->use_internal) { req->ref_on = REF_ON; req->xfer[0].tx_buf = &req->ref_on; req->xfer[0].len = 1; @@ -324,8 +321,14 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) /* for 1uF, settle for 800 usec; no cap, 100 usec. */ req->xfer[1].delay_usecs = ts->vref_delay_usecs; spi_message_add_tail(&req->xfer[1], &req->msg); + + /* Enable reference voltage */ + command |= ADS_PD10_REF_ON; } + /* Enable ADC in every case */ + command |= ADS_PD10_ADC_ON; + /* take sample */ req->command = (u8) command; req->xfer[2].tx_buf = &req->command; @@ -409,7 +412,7 @@ name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \ { \ struct ads7846 *ts = dev_get_drvdata(dev); \ ssize_t v = ads7846_read12_ser(dev, \ - READ_12BIT_SER(var) | ADS_PD10_ALL_ON); \ + READ_12BIT_SER(var)); \ if (v < 0) \ return v; \ return sprintf(buf, "%u\n", adjust(ts, v)); \ @@ -502,6 +505,7 @@ static int ads784x_hwmon_register(struct spi_device *spi, struct ads7846 *ts) if (!ts->vref_mv) { dev_dbg(&spi->dev, "assuming 2.5V internal vREF\n"); ts->vref_mv = 2500; + ts->use_internal = true; } break; case 7845: @@ -1333,8 +1337,7 @@ static int __devinit ads7846_probe(struct spi_device *spi) if (ts->model == 7845) ads7845_read12_ser(&spi->dev, PWRDOWN); else - (void) ads7846_read12_ser(&spi->dev, - READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON); + (void) ads7846_read12_ser(&spi->dev, READ_12BIT_SER(vaux)); err = sysfs_create_group(&spi->dev.kobj, &ads784x_attr_group); if (err) diff --git a/include/linux/spi/ads7846.h b/include/linux/spi/ads7846.h index 92bd0839d5b4..c64de9dd7631 100644 --- a/include/linux/spi/ads7846.h +++ b/include/linux/spi/ads7846.h @@ -14,7 +14,8 @@ enum ads7846_filter { struct ads7846_platform_data { u16 model; /* 7843, 7845, 7846, 7873. */ u16 vref_delay_usecs; /* 0 for external vref; etc */ - u16 vref_mv; /* external vref value, milliVolts */ + u16 vref_mv; /* external vref value, milliVolts + * ads7846: if 0, use internal vref */ bool keep_vref_on; /* set to keep vref on for differential * measurements as well */ bool swap_xy; /* swap x and y axes */ -- cgit From 36682b81de32090f5c9fac165e71ab8939aab8c0 Mon Sep 17 00:00:00 2001 From: Zhang Jiejing Date: Wed, 11 May 2011 14:32:01 -0700 Subject: Input: add driver FSL MPR121 capacitive touch sensor This patch adds basic support for Freescale MPR121 capacitive touch sensor. It's an i2c controller with up to 12 capacitance sensing inputs. Product information (data sheet, application notes) can be found here: http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=MPR121 Signed-off-by: Zhang Jiejing Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/Kconfig | 12 ++ drivers/input/keyboard/Makefile | 1 + drivers/input/keyboard/mpr121_touchkey.c | 339 +++++++++++++++++++++++++++++++ include/linux/i2c/mpr121_touchkey.h | 20 ++ 4 files changed, 372 insertions(+) create mode 100644 drivers/input/keyboard/mpr121_touchkey.c create mode 100644 include/linux/i2c/mpr121_touchkey.h (limited to 'include/linux') diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index b16bed038f72..dec090ac7d31 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -325,6 +325,18 @@ config KEYBOARD_MCS To compile this driver as a module, choose M here: the module will be called mcs_touchkey. +config KEYBOARD_MPR121 + tristate "Freescale MPR121 Touchkey" + depends on I2C + help + Say Y here if you have Freescale MPR121 touchkey controller + chip in your system. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called mpr121_touchkey. + config KEYBOARD_IMX tristate "IMX keypad support" depends on ARCH_MXC diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 878e6c20deb0..b45361009f2e 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_KEYBOARD_MAPLE) += maple_keyb.o obj-$(CONFIG_KEYBOARD_MATRIX) += matrix_keypad.o obj-$(CONFIG_KEYBOARD_MAX7359) += max7359_keypad.o obj-$(CONFIG_KEYBOARD_MCS) += mcs_touchkey.o +obj-$(CONFIG_KEYBOARD_MPR121) += mpr121_touchkey.o obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o obj-$(CONFIG_KEYBOARD_NOMADIK) += nomadik-ske-keypad.o obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o diff --git a/drivers/input/keyboard/mpr121_touchkey.c b/drivers/input/keyboard/mpr121_touchkey.c new file mode 100644 index 000000000000..0a9e81194888 --- /dev/null +++ b/drivers/input/keyboard/mpr121_touchkey.c @@ -0,0 +1,339 @@ +/* + * Touchkey driver for Freescale MPR121 Controllor + * + * Copyright (C) 2011 Freescale Semiconductor, Inc. + * Author: Zhang Jiejing + * + * Based on mcs_touchkey.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Register definitions */ +#define ELE_TOUCH_STATUS_0_ADDR 0x0 +#define ELE_TOUCH_STATUS_1_ADDR 0X1 +#define MHD_RISING_ADDR 0x2b +#define NHD_RISING_ADDR 0x2c +#define NCL_RISING_ADDR 0x2d +#define FDL_RISING_ADDR 0x2e +#define MHD_FALLING_ADDR 0x2f +#define NHD_FALLING_ADDR 0x30 +#define NCL_FALLING_ADDR 0x31 +#define FDL_FALLING_ADDR 0x32 +#define ELE0_TOUCH_THRESHOLD_ADDR 0x41 +#define ELE0_RELEASE_THRESHOLD_ADDR 0x42 +#define AFE_CONF_ADDR 0x5c +#define FILTER_CONF_ADDR 0x5d + +/* + * ELECTRODE_CONF_ADDR: This register configures the number of + * enabled capacitance sensing inputs and its run/suspend mode. + */ +#define ELECTRODE_CONF_ADDR 0x5e +#define AUTO_CONFIG_CTRL_ADDR 0x7b +#define AUTO_CONFIG_USL_ADDR 0x7d +#define AUTO_CONFIG_LSL_ADDR 0x7e +#define AUTO_CONFIG_TL_ADDR 0x7f + +/* Threshold of touch/release trigger */ +#define TOUCH_THRESHOLD 0x0f +#define RELEASE_THRESHOLD 0x0a +/* Masks for touch and release triggers */ +#define TOUCH_STATUS_MASK 0xfff +/* MPR121 has 12 keys */ +#define MPR121_MAX_KEY_COUNT 12 + +struct mpr121_touchkey { + struct i2c_client *client; + struct input_dev *input_dev; + unsigned int key_val; + unsigned int statusbits; + unsigned int keycount; + u16 keycodes[MPR121_MAX_KEY_COUNT]; +}; + +struct mpr121_init_register { + int addr; + u8 val; +}; + +static const struct mpr121_init_register init_reg_table[] __devinitconst = { + { MHD_RISING_ADDR, 0x1 }, + { NHD_RISING_ADDR, 0x1 }, + { MHD_FALLING_ADDR, 0x1 }, + { NHD_FALLING_ADDR, 0x1 }, + { NCL_FALLING_ADDR, 0xff }, + { FDL_FALLING_ADDR, 0x02 }, + { FILTER_CONF_ADDR, 0x04 }, + { AFE_CONF_ADDR, 0x0b }, + { AUTO_CONFIG_CTRL_ADDR, 0x0b }, +}; + +static irqreturn_t mpr_touchkey_interrupt(int irq, void *dev_id) +{ + struct mpr121_touchkey *mpr121 = dev_id; + struct i2c_client *client = mpr121->client; + struct input_dev *input = mpr121->input_dev; + unsigned int key_num, key_val, pressed; + int reg; + + reg = i2c_smbus_read_byte_data(client, ELE_TOUCH_STATUS_1_ADDR); + if (reg < 0) { + dev_err(&client->dev, "i2c read error [%d]\n", reg); + goto out; + } + + reg <<= 8; + reg |= i2c_smbus_read_byte_data(client, ELE_TOUCH_STATUS_0_ADDR); + if (reg < 0) { + dev_err(&client->dev, "i2c read error [%d]\n", reg); + goto out; + } + + reg &= TOUCH_STATUS_MASK; + /* use old press bit to figure out which bit changed */ + key_num = ffs(reg ^ mpr121->statusbits) - 1; + pressed = reg & (1 << key_num); + mpr121->statusbits = reg; + + key_val = mpr121->keycodes[key_num]; + + input_event(input, EV_MSC, MSC_SCAN, key_num); + input_report_key(input, key_val, pressed); + input_sync(input); + + dev_dbg(&client->dev, "key %d %d %s\n", key_num, key_val, + pressed ? "pressed" : "released"); + +out: + return IRQ_HANDLED; +} + +static int __devinit mpr121_phys_init(const struct mpr121_platform_data *pdata, + struct mpr121_touchkey *mpr121, + struct i2c_client *client) +{ + const struct mpr121_init_register *reg; + unsigned char usl, lsl, tl; + int i, t, vdd, ret; + + /* Set up touch/release threshold for ele0-ele11 */ + for (i = 0; i <= MPR121_MAX_KEY_COUNT; i++) { + t = ELE0_TOUCH_THRESHOLD_ADDR + (i * 2); + ret = i2c_smbus_write_byte_data(client, t, TOUCH_THRESHOLD); + if (ret < 0) + goto err_i2c_write; + ret = i2c_smbus_write_byte_data(client, t + 1, + RELEASE_THRESHOLD); + if (ret < 0) + goto err_i2c_write; + } + + /* Set up init register */ + for (i = 0; i < ARRAY_SIZE(init_reg_table); i++) { + reg = &init_reg_table[i]; + ret = i2c_smbus_write_byte_data(client, reg->addr, reg->val); + if (ret < 0) + goto err_i2c_write; + } + + + /* + * Capacitance on sensing input varies and needs to be compensated. + * The internal MPR121-auto-configuration can do this if it's + * registers are set properly (based on pdata->vdd_uv). + */ + vdd = pdata->vdd_uv / 1000; + usl = ((vdd - 700) * 256) / vdd; + lsl = (usl * 65) / 100; + tl = (usl * 90) / 100; + ret = i2c_smbus_write_byte_data(client, AUTO_CONFIG_USL_ADDR, usl); + ret |= i2c_smbus_write_byte_data(client, AUTO_CONFIG_LSL_ADDR, lsl); + ret |= i2c_smbus_write_byte_data(client, AUTO_CONFIG_TL_ADDR, tl); + ret |= i2c_smbus_write_byte_data(client, ELECTRODE_CONF_ADDR, + mpr121->keycount); + if (ret != 0) + goto err_i2c_write; + + dev_dbg(&client->dev, "set up with %x keys.\n", mpr121->keycount); + + return 0; + +err_i2c_write: + dev_err(&client->dev, "i2c write error: %d\n", ret); + return ret; +} + +static int __devinit mpr_touchkey_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + const struct mpr121_platform_data *pdata = client->dev.platform_data; + struct mpr121_touchkey *mpr121; + struct input_dev *input_dev; + int error; + int i; + + if (!pdata) { + dev_err(&client->dev, "no platform data defined\n"); + return -EINVAL; + } + + if (!pdata->keymap || !pdata->keymap_size) { + dev_err(&client->dev, "missing keymap data\n"); + return -EINVAL; + } + + if (pdata->keymap_size > MPR121_MAX_KEY_COUNT) { + dev_err(&client->dev, "too many keys defined\n"); + return -EINVAL; + } + + if (!client->irq) { + dev_err(&client->dev, "irq number should not be zero\n"); + return -EINVAL; + } + + mpr121 = kzalloc(sizeof(struct mpr121_touchkey), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!mpr121 || !input_dev) { + dev_err(&client->dev, "Failed to allocate memory\n"); + error = -ENOMEM; + goto err_free_mem; + } + + mpr121->client = client; + mpr121->input_dev = input_dev; + mpr121->keycount = pdata->keymap_size; + + input_dev->name = "Freescale MPR121 Touchkey"; + input_dev->id.bustype = BUS_I2C; + input_dev->dev.parent = &client->dev; + input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); + + input_dev->keycode = mpr121->keycodes; + input_dev->keycodesize = sizeof(mpr121->keycodes[0]); + input_dev->keycodemax = mpr121->keycount; + + for (i = 0; i < pdata->keymap_size; i++) { + input_set_capability(input_dev, EV_KEY, pdata->keymap[i]); + mpr121->keycodes[i] = pdata->keymap[i]; + } + + error = mpr121_phys_init(pdata, mpr121, client); + if (error) { + dev_err(&client->dev, "Failed to init register\n"); + goto err_free_mem; + } + + error = request_threaded_irq(client->irq, NULL, + mpr_touchkey_interrupt, + IRQF_TRIGGER_FALLING, + client->dev.driver->name, mpr121); + if (error) { + dev_err(&client->dev, "Failed to register interrupt\n"); + goto err_free_mem; + } + + error = input_register_device(input_dev); + if (error) + goto err_free_irq; + + i2c_set_clientdata(client, mpr121); + device_init_wakeup(&client->dev, pdata->wakeup); + + return 0; + +err_free_irq: + free_irq(client->irq, mpr121); +err_free_mem: + input_free_device(input_dev); + kfree(mpr121); + return error; +} + +static int __devexit mpr_touchkey_remove(struct i2c_client *client) +{ + struct mpr121_touchkey *mpr121 = i2c_get_clientdata(client); + + free_irq(client->irq, mpr121); + input_unregister_device(mpr121->input_dev); + kfree(mpr121); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int mpr_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + + if (device_may_wakeup(&client->dev)) + enable_irq_wake(client->irq); + + i2c_smbus_write_byte_data(client, ELECTRODE_CONF_ADDR, 0x00); + + return 0; +} + +static int mpr_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct mpr121_touchkey *mpr121 = i2c_get_clientdata(client); + + if (device_may_wakeup(&client->dev)) + disable_irq_wake(client->irq); + + i2c_smbus_write_byte_data(client, ELECTRODE_CONF_ADDR, + mpr121->keycount); + + return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(mpr121_touchkey_pm_ops, mpr_suspend, mpr_resume); + +static const struct i2c_device_id mpr121_id[] = { + { "mpr121_touchkey", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, mpr121_id); + +static struct i2c_driver mpr_touchkey_driver = { + .driver = { + .name = "mpr121", + .owner = THIS_MODULE, + .pm = &mpr121_touchkey_pm_ops, + }, + .id_table = mpr121_id, + .probe = mpr_touchkey_probe, + .remove = __devexit_p(mpr_touchkey_remove), +}; + +static int __init mpr_touchkey_init(void) +{ + return i2c_add_driver(&mpr_touchkey_driver); +} +module_init(mpr_touchkey_init); + +static void __exit mpr_touchkey_exit(void) +{ + i2c_del_driver(&mpr_touchkey_driver); +} +module_exit(mpr_touchkey_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Zhang Jiejing "); +MODULE_DESCRIPTION("Touch Key driver for Freescale MPR121 Chip"); diff --git a/include/linux/i2c/mpr121_touchkey.h b/include/linux/i2c/mpr121_touchkey.h new file mode 100644 index 000000000000..f0bcc38bbb97 --- /dev/null +++ b/include/linux/i2c/mpr121_touchkey.h @@ -0,0 +1,20 @@ +/* Header file for Freescale MPR121 Capacitive Touch Sensor */ + +#ifndef _MPR121_TOUCHKEY_H +#define _MPR121_TOUCHKEY_H + +/** + * struct mpr121_platform_data - platform data for mpr121 sensor + * @keymap: pointer to array of KEY_* values representing keymap + * @keymap_size: size of the keymap + * @wakeup: configure the button as a wake-up source + * @vdd_uv: VDD voltage in uV + */ +struct mpr121_platform_data { + const unsigned short *keymap; + unsigned int keymap_size; + bool wakeup; + int vdd_uv; +}; + +#endif /* _MPR121_TOUCHKEY_H */ -- cgit From be84cb43833ee40a42e08f5425d20310f16229c7 Mon Sep 17 00:00:00 2001 From: Chris Metcalf Date: Mon, 9 May 2011 13:12:30 -0400 Subject: compat: fixes to allow working with tile arch The existing mechanism doesn't really provide enough to create the 64-bit "compat" ABI properly in a generic way, since the compat ABI is a mix of things were you can re-use the 64-bit versions of syscalls and things where you need a compat wrapper. To provide this in the most direct way possible, I added two new macros to go along with the existing __SYSCALL and __SC_3264 macros: __SC_COMP and SC_COMP_3264. These macros take an additional argument, typically a "compat_sys_xxx" function, which is passed to __SYSCALL if you define __SYSCALL_COMPAT when including the header, resulting in a pointer to the compat function being placed in the generated syscall table. The change also adds some missing definitions to so that it actually has declarations for all the compat syscalls, since the "[nr] = ##call" approach requires proper C declarations for all the functions included in the syscall table. Finally, compat.c defines compat_sys_sigpending() and compat_sys_sigprocmask() even if the underlying architecture doesn't request it, which tries to pull in undefined compat_old_sigset_t defines. We need to guard those compat syscall definitions with appropriate __ARCH_WANT_SYS_xxx ifdefs. Acked-by: Arnd Bergmann Signed-off-by: Chris Metcalf --- arch/tile/kernel/compat.c | 2 +- include/asm-generic/unistd.h | 221 ++++++++++++++++++++++++------------------- include/linux/compat.h | 187 ++++++++++++++++++++++++++++++++++++ kernel/compat.c | 8 ++ 4 files changed, 320 insertions(+), 98 deletions(-) (limited to 'include/linux') diff --git a/arch/tile/kernel/compat.c b/arch/tile/kernel/compat.c index dbc213adf5e1..e35a3975ca3b 100644 --- a/arch/tile/kernel/compat.c +++ b/arch/tile/kernel/compat.c @@ -135,7 +135,7 @@ long tile_compat_sys_msgrcv(int msqid, /* Provide the compat syscall number to call mapping. */ #undef __SYSCALL -#define __SYSCALL(nr, call) [nr] = (compat_##call), +#define __SYSCALL(nr, call) [nr] = (call), /* The generic versions of these don't work for Tile. */ #define compat_sys_msgrcv tile_compat_sys_msgrcv diff --git a/include/asm-generic/unistd.h b/include/asm-generic/unistd.h index 07c40d5149de..33d524704883 100644 --- a/include/asm-generic/unistd.h +++ b/include/asm-generic/unistd.h @@ -24,16 +24,24 @@ #define __SC_3264(_nr, _32, _64) __SYSCALL(_nr, _64) #endif +#ifdef __SYSCALL_COMPAT +#define __SC_COMP(_nr, _sys, _comp) __SYSCALL(_nr, _comp) +#define __SC_COMP_3264(_nr, _32, _64, _comp) __SYSCALL(_nr, _comp) +#else +#define __SC_COMP(_nr, _sys, _comp) __SYSCALL(_nr, _sys) +#define __SC_COMP_3264(_nr, _32, _64, _comp) __SC_3264(_nr, _32, _64) +#endif + #define __NR_io_setup 0 -__SYSCALL(__NR_io_setup, sys_io_setup) +__SC_COMP(__NR_io_setup, sys_io_setup, compat_sys_io_setup) #define __NR_io_destroy 1 __SYSCALL(__NR_io_destroy, sys_io_destroy) #define __NR_io_submit 2 -__SYSCALL(__NR_io_submit, sys_io_submit) +__SC_COMP(__NR_io_submit, sys_io_submit, compat_sys_io_submit) #define __NR_io_cancel 3 __SYSCALL(__NR_io_cancel, sys_io_cancel) #define __NR_io_getevents 4 -__SYSCALL(__NR_io_getevents, sys_io_getevents) +__SC_COMP(__NR_io_getevents, sys_io_getevents, compat_sys_io_getevents) /* fs/xattr.c */ #define __NR_setxattr 5 @@ -67,7 +75,7 @@ __SYSCALL(__NR_getcwd, sys_getcwd) /* fs/cookies.c */ #define __NR_lookup_dcookie 18 -__SYSCALL(__NR_lookup_dcookie, sys_lookup_dcookie) +__SC_COMP(__NR_lookup_dcookie, sys_lookup_dcookie, compat_sys_lookup_dcookie) /* fs/eventfd.c */ #define __NR_eventfd2 19 @@ -79,7 +87,7 @@ __SYSCALL(__NR_epoll_create1, sys_epoll_create1) #define __NR_epoll_ctl 21 __SYSCALL(__NR_epoll_ctl, sys_epoll_ctl) #define __NR_epoll_pwait 22 -__SYSCALL(__NR_epoll_pwait, sys_epoll_pwait) +__SC_COMP(__NR_epoll_pwait, sys_epoll_pwait, compat_sys_epoll_pwait) /* fs/fcntl.c */ #define __NR_dup 23 @@ -87,7 +95,7 @@ __SYSCALL(__NR_dup, sys_dup) #define __NR_dup3 24 __SYSCALL(__NR_dup3, sys_dup3) #define __NR3264_fcntl 25 -__SC_3264(__NR3264_fcntl, sys_fcntl64, sys_fcntl) +__SC_COMP_3264(__NR3264_fcntl, sys_fcntl64, sys_fcntl, compat_sys_fcntl64) /* fs/inotify_user.c */ #define __NR_inotify_init1 26 @@ -99,7 +107,7 @@ __SYSCALL(__NR_inotify_rm_watch, sys_inotify_rm_watch) /* fs/ioctl.c */ #define __NR_ioctl 29 -__SYSCALL(__NR_ioctl, sys_ioctl) +__SC_COMP(__NR_ioctl, sys_ioctl, compat_sys_ioctl) /* fs/ioprio.c */ #define __NR_ioprio_set 30 @@ -129,26 +137,30 @@ __SYSCALL(__NR_renameat, sys_renameat) #define __NR_umount2 39 __SYSCALL(__NR_umount2, sys_umount) #define __NR_mount 40 -__SYSCALL(__NR_mount, sys_mount) +__SC_COMP(__NR_mount, sys_mount, compat_sys_mount) #define __NR_pivot_root 41 __SYSCALL(__NR_pivot_root, sys_pivot_root) /* fs/nfsctl.c */ #define __NR_nfsservctl 42 -__SYSCALL(__NR_nfsservctl, sys_nfsservctl) +__SC_COMP(__NR_nfsservctl, sys_nfsservctl, compat_sys_nfsservctl) /* fs/open.c */ #define __NR3264_statfs 43 -__SC_3264(__NR3264_statfs, sys_statfs64, sys_statfs) +__SC_COMP_3264(__NR3264_statfs, sys_statfs64, sys_statfs, \ + compat_sys_statfs64) #define __NR3264_fstatfs 44 -__SC_3264(__NR3264_fstatfs, sys_fstatfs64, sys_fstatfs) +__SC_COMP_3264(__NR3264_fstatfs, sys_fstatfs64, sys_fstatfs, \ + compat_sys_fstatfs64) #define __NR3264_truncate 45 -__SC_3264(__NR3264_truncate, sys_truncate64, sys_truncate) +__SC_COMP_3264(__NR3264_truncate, sys_truncate64, sys_truncate, \ + compat_sys_truncate64) #define __NR3264_ftruncate 46 -__SC_3264(__NR3264_ftruncate, sys_ftruncate64, sys_ftruncate) +__SC_COMP_3264(__NR3264_ftruncate, sys_ftruncate64, sys_ftruncate, \ + compat_sys_ftruncate64) #define __NR_fallocate 47 -__SYSCALL(__NR_fallocate, sys_fallocate) +__SC_COMP(__NR_fallocate, sys_fallocate, compat_sys_fallocate) #define __NR_faccessat 48 __SYSCALL(__NR_faccessat, sys_faccessat) #define __NR_chdir 49 @@ -166,7 +178,7 @@ __SYSCALL(__NR_fchownat, sys_fchownat) #define __NR_fchown 55 __SYSCALL(__NR_fchown, sys_fchown) #define __NR_openat 56 -__SYSCALL(__NR_openat, sys_openat) +__SC_COMP(__NR_openat, sys_openat, compat_sys_openat) #define __NR_close 57 __SYSCALL(__NR_close, sys_close) #define __NR_vhangup 58 @@ -182,7 +194,7 @@ __SYSCALL(__NR_quotactl, sys_quotactl) /* fs/readdir.c */ #define __NR_getdents64 61 -__SYSCALL(__NR_getdents64, sys_getdents64) +__SC_COMP(__NR_getdents64, sys_getdents64, compat_sys_getdents64) /* fs/read_write.c */ #define __NR3264_lseek 62 @@ -192,17 +204,17 @@ __SYSCALL(__NR_read, sys_read) #define __NR_write 64 __SYSCALL(__NR_write, sys_write) #define __NR_readv 65 -__SYSCALL(__NR_readv, sys_readv) +__SC_COMP(__NR_readv, sys_readv, compat_sys_readv) #define __NR_writev 66 -__SYSCALL(__NR_writev, sys_writev) +__SC_COMP(__NR_writev, sys_writev, compat_sys_writev) #define __NR_pread64 67 -__SYSCALL(__NR_pread64, sys_pread64) +__SC_COMP(__NR_pread64, sys_pread64, compat_sys_pread64) #define __NR_pwrite64 68 -__SYSCALL(__NR_pwrite64, sys_pwrite64) +__SC_COMP(__NR_pwrite64, sys_pwrite64, compat_sys_pwrite64) #define __NR_preadv 69 -__SYSCALL(__NR_preadv, sys_preadv) +__SC_COMP(__NR_preadv, sys_preadv, compat_sys_preadv) #define __NR_pwritev 70 -__SYSCALL(__NR_pwritev, sys_pwritev) +__SC_COMP(__NR_pwritev, sys_pwritev, compat_sys_pwritev) /* fs/sendfile.c */ #define __NR3264_sendfile 71 @@ -210,17 +222,17 @@ __SC_3264(__NR3264_sendfile, sys_sendfile64, sys_sendfile) /* fs/select.c */ #define __NR_pselect6 72 -__SYSCALL(__NR_pselect6, sys_pselect6) +__SC_COMP(__NR_pselect6, sys_pselect6, compat_sys_pselect6) #define __NR_ppoll 73 -__SYSCALL(__NR_ppoll, sys_ppoll) +__SC_COMP(__NR_ppoll, sys_ppoll, compat_sys_ppoll) /* fs/signalfd.c */ #define __NR_signalfd4 74 -__SYSCALL(__NR_signalfd4, sys_signalfd4) +__SC_COMP(__NR_signalfd4, sys_signalfd4, compat_sys_signalfd4) /* fs/splice.c */ #define __NR_vmsplice 75 -__SYSCALL(__NR_vmsplice, sys_vmsplice) +__SC_COMP(__NR_vmsplice, sys_vmsplice, compat_sys_vmsplice) #define __NR_splice 76 __SYSCALL(__NR_splice, sys_splice) #define __NR_tee 77 @@ -243,23 +255,27 @@ __SYSCALL(__NR_fsync, sys_fsync) __SYSCALL(__NR_fdatasync, sys_fdatasync) #ifdef __ARCH_WANT_SYNC_FILE_RANGE2 #define __NR_sync_file_range2 84 -__SYSCALL(__NR_sync_file_range2, sys_sync_file_range2) +__SC_COMP(__NR_sync_file_range2, sys_sync_file_range2, \ + compat_sys_sync_file_range2) #else #define __NR_sync_file_range 84 -__SYSCALL(__NR_sync_file_range, sys_sync_file_range) +__SC_COMP(__NR_sync_file_range, sys_sync_file_range, \ + compat_sys_sync_file_range) #endif /* fs/timerfd.c */ #define __NR_timerfd_create 85 __SYSCALL(__NR_timerfd_create, sys_timerfd_create) #define __NR_timerfd_settime 86 -__SYSCALL(__NR_timerfd_settime, sys_timerfd_settime) +__SC_COMP(__NR_timerfd_settime, sys_timerfd_settime, \ + compat_sys_timerfd_settime) #define __NR_timerfd_gettime 87 -__SYSCALL(__NR_timerfd_gettime, sys_timerfd_gettime) +__SC_COMP(__NR_timerfd_gettime, sys_timerfd_gettime, \ + compat_sys_timerfd_gettime) /* fs/utimes.c */ #define __NR_utimensat 88 -__SYSCALL(__NR_utimensat, sys_utimensat) +__SC_COMP(__NR_utimensat, sys_utimensat, compat_sys_utimensat) /* kernel/acct.c */ #define __NR_acct 89 @@ -281,7 +297,7 @@ __SYSCALL(__NR_exit, sys_exit) #define __NR_exit_group 94 __SYSCALL(__NR_exit_group, sys_exit_group) #define __NR_waitid 95 -__SYSCALL(__NR_waitid, sys_waitid) +__SC_COMP(__NR_waitid, sys_waitid, compat_sys_waitid) /* kernel/fork.c */ #define __NR_set_tid_address 96 @@ -291,25 +307,27 @@ __SYSCALL(__NR_unshare, sys_unshare) /* kernel/futex.c */ #define __NR_futex 98 -__SYSCALL(__NR_futex, sys_futex) +__SC_COMP(__NR_futex, sys_futex, compat_sys_futex) #define __NR_set_robust_list 99 -__SYSCALL(__NR_set_robust_list, sys_set_robust_list) +__SC_COMP(__NR_set_robust_list, sys_set_robust_list, \ + compat_sys_set_robust_list) #define __NR_get_robust_list 100 -__SYSCALL(__NR_get_robust_list, sys_get_robust_list) +__SC_COMP(__NR_get_robust_list, sys_get_robust_list, \ + compat_sys_get_robust_list) /* kernel/hrtimer.c */ #define __NR_nanosleep 101 -__SYSCALL(__NR_nanosleep, sys_nanosleep) +__SC_COMP(__NR_nanosleep, sys_nanosleep, compat_sys_nanosleep) /* kernel/itimer.c */ #define __NR_getitimer 102 -__SYSCALL(__NR_getitimer, sys_getitimer) +__SC_COMP(__NR_getitimer, sys_getitimer, compat_sys_getitimer) #define __NR_setitimer 103 -__SYSCALL(__NR_setitimer, sys_setitimer) +__SC_COMP(__NR_setitimer, sys_setitimer, compat_sys_setitimer) /* kernel/kexec.c */ #define __NR_kexec_load 104 -__SYSCALL(__NR_kexec_load, sys_kexec_load) +__SC_COMP(__NR_kexec_load, sys_kexec_load, compat_sys_kexec_load) /* kernel/module.c */ #define __NR_init_module 105 @@ -319,23 +337,24 @@ __SYSCALL(__NR_delete_module, sys_delete_module) /* kernel/posix-timers.c */ #define __NR_timer_create 107 -__SYSCALL(__NR_timer_create, sys_timer_create) +__SC_COMP(__NR_timer_create, sys_timer_create, compat_sys_timer_create) #define __NR_timer_gettime 108 -__SYSCALL(__NR_timer_gettime, sys_timer_gettime) +__SC_COMP(__NR_timer_gettime, sys_timer_gettime, compat_sys_timer_gettime) #define __NR_timer_getoverrun 109 __SYSCALL(__NR_timer_getoverrun, sys_timer_getoverrun) #define __NR_timer_settime 110 -__SYSCALL(__NR_timer_settime, sys_timer_settime) +__SC_COMP(__NR_timer_settime, sys_timer_settime, compat_sys_timer_settime) #define __NR_timer_delete 111 __SYSCALL(__NR_timer_delete, sys_timer_delete) #define __NR_clock_settime 112 -__SYSCALL(__NR_clock_settime, sys_clock_settime) +__SC_COMP(__NR_clock_settime, sys_clock_settime, compat_sys_clock_settime) #define __NR_clock_gettime 113 -__SYSCALL(__NR_clock_gettime, sys_clock_gettime) +__SC_COMP(__NR_clock_gettime, sys_clock_gettime, compat_sys_clock_gettime) #define __NR_clock_getres 114 -__SYSCALL(__NR_clock_getres, sys_clock_getres) +__SC_COMP(__NR_clock_getres, sys_clock_getres, compat_sys_clock_getres) #define __NR_clock_nanosleep 115 -__SYSCALL(__NR_clock_nanosleep, sys_clock_nanosleep) +__SC_COMP(__NR_clock_nanosleep, sys_clock_nanosleep, \ + compat_sys_clock_nanosleep) /* kernel/printk.c */ #define __NR_syslog 116 @@ -355,9 +374,11 @@ __SYSCALL(__NR_sched_getscheduler, sys_sched_getscheduler) #define __NR_sched_getparam 121 __SYSCALL(__NR_sched_getparam, sys_sched_getparam) #define __NR_sched_setaffinity 122 -__SYSCALL(__NR_sched_setaffinity, sys_sched_setaffinity) +__SC_COMP(__NR_sched_setaffinity, sys_sched_setaffinity, \ + compat_sys_sched_setaffinity) #define __NR_sched_getaffinity 123 -__SYSCALL(__NR_sched_getaffinity, sys_sched_getaffinity) +__SC_COMP(__NR_sched_getaffinity, sys_sched_getaffinity, \ + compat_sys_sched_getaffinity) #define __NR_sched_yield 124 __SYSCALL(__NR_sched_yield, sys_sched_yield) #define __NR_sched_get_priority_max 125 @@ -365,7 +386,8 @@ __SYSCALL(__NR_sched_get_priority_max, sys_sched_get_priority_max) #define __NR_sched_get_priority_min 126 __SYSCALL(__NR_sched_get_priority_min, sys_sched_get_priority_min) #define __NR_sched_rr_get_interval 127 -__SYSCALL(__NR_sched_rr_get_interval, sys_sched_rr_get_interval) +__SC_COMP(__NR_sched_rr_get_interval, sys_sched_rr_get_interval, \ + compat_sys_sched_rr_get_interval) /* kernel/signal.c */ #define __NR_restart_syscall 128 @@ -377,21 +399,23 @@ __SYSCALL(__NR_tkill, sys_tkill) #define __NR_tgkill 131 __SYSCALL(__NR_tgkill, sys_tgkill) #define __NR_sigaltstack 132 -__SYSCALL(__NR_sigaltstack, sys_sigaltstack) +__SC_COMP(__NR_sigaltstack, sys_sigaltstack, compat_sys_sigaltstack) #define __NR_rt_sigsuspend 133 -__SYSCALL(__NR_rt_sigsuspend, sys_rt_sigsuspend) /* __ARCH_WANT_SYS_RT_SIGSUSPEND */ +__SC_COMP(__NR_rt_sigsuspend, sys_rt_sigsuspend, compat_sys_rt_sigsuspend) #define __NR_rt_sigaction 134 -__SYSCALL(__NR_rt_sigaction, sys_rt_sigaction) /* __ARCH_WANT_SYS_RT_SIGACTION */ +__SC_COMP(__NR_rt_sigaction, sys_rt_sigaction, compat_sys_rt_sigaction) #define __NR_rt_sigprocmask 135 __SYSCALL(__NR_rt_sigprocmask, sys_rt_sigprocmask) #define __NR_rt_sigpending 136 __SYSCALL(__NR_rt_sigpending, sys_rt_sigpending) #define __NR_rt_sigtimedwait 137 -__SYSCALL(__NR_rt_sigtimedwait, sys_rt_sigtimedwait) +__SC_COMP(__NR_rt_sigtimedwait, sys_rt_sigtimedwait, \ + compat_sys_rt_sigtimedwait) #define __NR_rt_sigqueueinfo 138 -__SYSCALL(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo) +__SC_COMP(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo, \ + compat_sys_rt_sigqueueinfo) #define __NR_rt_sigreturn 139 -__SYSCALL(__NR_rt_sigreturn, sys_rt_sigreturn) /* sys_rt_sigreturn_wrapper, */ +__SC_COMP(__NR_rt_sigreturn, sys_rt_sigreturn, compat_sys_rt_sigreturn) /* kernel/sys.c */ #define __NR_setpriority 140 @@ -421,7 +445,7 @@ __SYSCALL(__NR_setfsuid, sys_setfsuid) #define __NR_setfsgid 152 __SYSCALL(__NR_setfsgid, sys_setfsgid) #define __NR_times 153 -__SYSCALL(__NR_times, sys_times) +__SC_COMP(__NR_times, sys_times, compat_sys_times) #define __NR_setpgid 154 __SYSCALL(__NR_setpgid, sys_setpgid) #define __NR_getpgid 155 @@ -441,11 +465,11 @@ __SYSCALL(__NR_sethostname, sys_sethostname) #define __NR_setdomainname 162 __SYSCALL(__NR_setdomainname, sys_setdomainname) #define __NR_getrlimit 163 -__SYSCALL(__NR_getrlimit, sys_getrlimit) +__SC_COMP(__NR_getrlimit, sys_getrlimit, compat_sys_getrlimit) #define __NR_setrlimit 164 -__SYSCALL(__NR_setrlimit, sys_setrlimit) +__SC_COMP(__NR_setrlimit, sys_setrlimit, compat_sys_setrlimit) #define __NR_getrusage 165 -__SYSCALL(__NR_getrusage, sys_getrusage) +__SC_COMP(__NR_getrusage, sys_getrusage, compat_sys_getrusage) #define __NR_umask 166 __SYSCALL(__NR_umask, sys_umask) #define __NR_prctl 167 @@ -455,11 +479,11 @@ __SYSCALL(__NR_getcpu, sys_getcpu) /* kernel/time.c */ #define __NR_gettimeofday 169 -__SYSCALL(__NR_gettimeofday, sys_gettimeofday) +__SC_COMP(__NR_gettimeofday, sys_gettimeofday, compat_sys_gettimeofday) #define __NR_settimeofday 170 -__SYSCALL(__NR_settimeofday, sys_settimeofday) +__SC_COMP(__NR_settimeofday, sys_settimeofday, compat_sys_settimeofday) #define __NR_adjtimex 171 -__SYSCALL(__NR_adjtimex, sys_adjtimex) +__SC_COMP(__NR_adjtimex, sys_adjtimex, compat_sys_adjtimex) /* kernel/timer.c */ #define __NR_getpid 172 @@ -477,39 +501,40 @@ __SYSCALL(__NR_getegid, sys_getegid) #define __NR_gettid 178 __SYSCALL(__NR_gettid, sys_gettid) #define __NR_sysinfo 179 -__SYSCALL(__NR_sysinfo, sys_sysinfo) +__SC_COMP(__NR_sysinfo, sys_sysinfo, compat_sys_sysinfo) /* ipc/mqueue.c */ #define __NR_mq_open 180 -__SYSCALL(__NR_mq_open, sys_mq_open) +__SC_COMP(__NR_mq_open, sys_mq_open, compat_sys_mq_open) #define __NR_mq_unlink 181 __SYSCALL(__NR_mq_unlink, sys_mq_unlink) #define __NR_mq_timedsend 182 -__SYSCALL(__NR_mq_timedsend, sys_mq_timedsend) +__SC_COMP(__NR_mq_timedsend, sys_mq_timedsend, compat_sys_mq_timedsend) #define __NR_mq_timedreceive 183 -__SYSCALL(__NR_mq_timedreceive, sys_mq_timedreceive) +__SC_COMP(__NR_mq_timedreceive, sys_mq_timedreceive, \ + compat_sys_mq_timedreceive) #define __NR_mq_notify 184 -__SYSCALL(__NR_mq_notify, sys_mq_notify) +__SC_COMP(__NR_mq_notify, sys_mq_notify, compat_sys_mq_notify) #define __NR_mq_getsetattr 185 -__SYSCALL(__NR_mq_getsetattr, sys_mq_getsetattr) +__SC_COMP(__NR_mq_getsetattr, sys_mq_getsetattr, compat_sys_mq_getsetattr) /* ipc/msg.c */ #define __NR_msgget 186 __SYSCALL(__NR_msgget, sys_msgget) #define __NR_msgctl 187 -__SYSCALL(__NR_msgctl, sys_msgctl) +__SC_COMP(__NR_msgctl, sys_msgctl, compat_sys_msgctl) #define __NR_msgrcv 188 -__SYSCALL(__NR_msgrcv, sys_msgrcv) +__SC_COMP(__NR_msgrcv, sys_msgrcv, compat_sys_msgrcv) #define __NR_msgsnd 189 -__SYSCALL(__NR_msgsnd, sys_msgsnd) +__SC_COMP(__NR_msgsnd, sys_msgsnd, compat_sys_msgsnd) /* ipc/sem.c */ #define __NR_semget 190 __SYSCALL(__NR_semget, sys_semget) #define __NR_semctl 191 -__SYSCALL(__NR_semctl, sys_semctl) +__SC_COMP(__NR_semctl, sys_semctl, compat_sys_semctl) #define __NR_semtimedop 192 -__SYSCALL(__NR_semtimedop, sys_semtimedop) +__SC_COMP(__NR_semtimedop, sys_semtimedop, compat_sys_semtimedop) #define __NR_semop 193 __SYSCALL(__NR_semop, sys_semop) @@ -517,9 +542,9 @@ __SYSCALL(__NR_semop, sys_semop) #define __NR_shmget 194 __SYSCALL(__NR_shmget, sys_shmget) #define __NR_shmctl 195 -__SYSCALL(__NR_shmctl, sys_shmctl) +__SC_COMP(__NR_shmctl, sys_shmctl, compat_sys_shmctl) #define __NR_shmat 196 -__SYSCALL(__NR_shmat, sys_shmat) +__SC_COMP(__NR_shmat, sys_shmat, compat_sys_shmat) #define __NR_shmdt 197 __SYSCALL(__NR_shmdt, sys_shmdt) @@ -543,21 +568,21 @@ __SYSCALL(__NR_getpeername, sys_getpeername) #define __NR_sendto 206 __SYSCALL(__NR_sendto, sys_sendto) #define __NR_recvfrom 207 -__SYSCALL(__NR_recvfrom, sys_recvfrom) +__SC_COMP(__NR_recvfrom, sys_recvfrom, compat_sys_recvfrom) #define __NR_setsockopt 208 -__SYSCALL(__NR_setsockopt, sys_setsockopt) +__SC_COMP(__NR_setsockopt, sys_setsockopt, compat_sys_setsockopt) #define __NR_getsockopt 209 -__SYSCALL(__NR_getsockopt, sys_getsockopt) +__SC_COMP(__NR_getsockopt, sys_getsockopt, compat_sys_getsockopt) #define __NR_shutdown 210 __SYSCALL(__NR_shutdown, sys_shutdown) #define __NR_sendmsg 211 -__SYSCALL(__NR_sendmsg, sys_sendmsg) +__SC_COMP(__NR_sendmsg, sys_sendmsg, compat_sys_sendmsg) #define __NR_recvmsg 212 -__SYSCALL(__NR_recvmsg, sys_recvmsg) +__SC_COMP(__NR_recvmsg, sys_recvmsg, compat_sys_recvmsg) /* mm/filemap.c */ #define __NR_readahead 213 -__SYSCALL(__NR_readahead, sys_readahead) +__SC_COMP(__NR_readahead, sys_readahead, compat_sys_readahead) /* mm/nommu.c, also with MMU */ #define __NR_brk 214 @@ -573,19 +598,19 @@ __SYSCALL(__NR_add_key, sys_add_key) #define __NR_request_key 218 __SYSCALL(__NR_request_key, sys_request_key) #define __NR_keyctl 219 -__SYSCALL(__NR_keyctl, sys_keyctl) +__SC_COMP(__NR_keyctl, sys_keyctl, compat_sys_keyctl) /* arch/example/kernel/sys_example.c */ #define __NR_clone 220 -__SYSCALL(__NR_clone, sys_clone) /* .long sys_clone_wrapper */ +__SYSCALL(__NR_clone, sys_clone) #define __NR_execve 221 -__SYSCALL(__NR_execve, sys_execve) /* .long sys_execve_wrapper */ +__SC_COMP(__NR_execve, sys_execve, compat_sys_execve) #define __NR3264_mmap 222 __SC_3264(__NR3264_mmap, sys_mmap2, sys_mmap) /* mm/fadvise.c */ #define __NR3264_fadvise64 223 -__SYSCALL(__NR3264_fadvise64, sys_fadvise64_64) +__SC_COMP(__NR3264_fadvise64, sys_fadvise64_64, compat_sys_fadvise64_64) /* mm/, CONFIG_MMU only */ #ifndef __ARCH_NOMMU @@ -612,25 +637,26 @@ __SYSCALL(__NR_madvise, sys_madvise) #define __NR_remap_file_pages 234 __SYSCALL(__NR_remap_file_pages, sys_remap_file_pages) #define __NR_mbind 235 -__SYSCALL(__NR_mbind, sys_mbind) +__SC_COMP(__NR_mbind, sys_mbind, compat_sys_mbind) #define __NR_get_mempolicy 236 -__SYSCALL(__NR_get_mempolicy, sys_get_mempolicy) +__SC_COMP(__NR_get_mempolicy, sys_get_mempolicy, compat_sys_get_mempolicy) #define __NR_set_mempolicy 237 -__SYSCALL(__NR_set_mempolicy, sys_set_mempolicy) +__SC_COMP(__NR_set_mempolicy, sys_set_mempolicy, compat_sys_set_mempolicy) #define __NR_migrate_pages 238 -__SYSCALL(__NR_migrate_pages, sys_migrate_pages) +__SC_COMP(__NR_migrate_pages, sys_migrate_pages, compat_sys_migrate_pages) #define __NR_move_pages 239 -__SYSCALL(__NR_move_pages, sys_move_pages) +__SC_COMP(__NR_move_pages, sys_move_pages, compat_sys_move_pages) #endif #define __NR_rt_tgsigqueueinfo 240 -__SYSCALL(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo) +__SC_COMP(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo, \ + compat_sys_rt_tgsigqueueinfo) #define __NR_perf_event_open 241 __SYSCALL(__NR_perf_event_open, sys_perf_event_open) #define __NR_accept4 242 __SYSCALL(__NR_accept4, sys_accept4) #define __NR_recvmmsg 243 -__SYSCALL(__NR_recvmmsg, sys_recvmmsg) +__SC_COMP(__NR_recvmmsg, sys_recvmmsg, compat_sys_recvmmsg) /* * Architectures may provide up to 16 syscalls of their own @@ -639,19 +665,20 @@ __SYSCALL(__NR_recvmmsg, sys_recvmmsg) #define __NR_arch_specific_syscall 244 #define __NR_wait4 260 -__SYSCALL(__NR_wait4, sys_wait4) +__SC_COMP(__NR_wait4, sys_wait4, compat_sys_wait4) #define __NR_prlimit64 261 __SYSCALL(__NR_prlimit64, sys_prlimit64) #define __NR_fanotify_init 262 __SYSCALL(__NR_fanotify_init, sys_fanotify_init) #define __NR_fanotify_mark 263 __SYSCALL(__NR_fanotify_mark, sys_fanotify_mark) -#define __NR_name_to_handle_at 264 +#define __NR_name_to_handle_at 264 __SYSCALL(__NR_name_to_handle_at, sys_name_to_handle_at) -#define __NR_open_by_handle_at 265 -__SYSCALL(__NR_open_by_handle_at, sys_open_by_handle_at) +#define __NR_open_by_handle_at 265 +__SC_COMP(__NR_open_by_handle_at, sys_open_by_handle_at, \ + compat_sys_open_by_handle_at) #define __NR_clock_adjtime 266 -__SYSCALL(__NR_clock_adjtime, sys_clock_adjtime) +__SC_COMP(__NR_clock_adjtime, sys_clock_adjtime, compat_sys_clock_adjtime) #define __NR_syncfs 267 __SYSCALL(__NR_syncfs, sys_syncfs) diff --git a/include/linux/compat.h b/include/linux/compat.h index 5778b559d59c..e94184834b71 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -209,6 +210,18 @@ struct compat_robust_list_head { compat_uptr_t list_op_pending; }; +struct compat_statfs; +struct compat_statfs64; +struct compat_old_linux_dirent; +struct compat_linux_dirent; +struct linux_dirent64; +struct compat_msghdr; +struct compat_mmsghdr; +struct compat_sysinfo; +struct compat_sysctl_args; +struct compat_kexec_segment; +struct compat_mq_attr; + extern void compat_exit_robust_list(struct task_struct *curr); asmlinkage long @@ -331,9 +344,13 @@ asmlinkage long compat_sys_epoll_pwait(int epfd, const compat_sigset_t __user *sigmask, compat_size_t sigsetsize); +asmlinkage long compat_sys_utime(const char __user *filename, + struct compat_utimbuf __user *t); asmlinkage long compat_sys_utimensat(unsigned int dfd, const char __user *filename, struct compat_timespec __user *t, int flags); +asmlinkage long compat_sys_time(compat_time_t __user *tloc); +asmlinkage long compat_sys_stime(compat_time_t __user *tptr); asmlinkage long compat_sys_signalfd(int ufd, const compat_sigset_t __user *sigmask, compat_size_t sigsetsize); @@ -350,11 +367,181 @@ asmlinkage long compat_sys_move_pages(pid_t pid, unsigned long nr_page, int flags); asmlinkage long compat_sys_futimesat(unsigned int dfd, const char __user *filename, struct compat_timeval __user *t); +asmlinkage long compat_sys_utimes(const char __user *filename, + struct compat_timeval __user *t); +asmlinkage long compat_sys_newstat(const char __user * filename, + struct compat_stat __user *statbuf); +asmlinkage long compat_sys_newlstat(const char __user * filename, + struct compat_stat __user *statbuf); asmlinkage long compat_sys_newfstatat(unsigned int dfd, const char __user * filename, struct compat_stat __user *statbuf, int flag); +asmlinkage long compat_sys_newfstat(unsigned int fd, + struct compat_stat __user * statbuf); +asmlinkage long compat_sys_statfs(const char __user *pathname, + struct compat_statfs __user *buf); +asmlinkage long compat_sys_fstatfs(unsigned int fd, + struct compat_statfs __user *buf); +asmlinkage long compat_sys_statfs64(const char __user *pathname, + compat_size_t sz, + struct compat_statfs64 __user *buf); +asmlinkage long compat_sys_fstatfs64(unsigned int fd, compat_size_t sz, + struct compat_statfs64 __user *buf); +asmlinkage long compat_sys_fcntl64(unsigned int fd, unsigned int cmd, + unsigned long arg); +asmlinkage long compat_sys_fcntl(unsigned int fd, unsigned int cmd, + unsigned long arg); +asmlinkage long compat_sys_io_setup(unsigned nr_reqs, u32 __user *ctx32p); +asmlinkage long compat_sys_io_getevents(aio_context_t ctx_id, + unsigned long min_nr, + unsigned long nr, + struct io_event __user *events, + struct compat_timespec __user *timeout); +asmlinkage long compat_sys_io_submit(aio_context_t ctx_id, int nr, + u32 __user *iocb); +asmlinkage long compat_sys_mount(const char __user * dev_name, + const char __user * dir_name, + const char __user * type, unsigned long flags, + const void __user * data); +asmlinkage long compat_sys_old_readdir(unsigned int fd, + struct compat_old_linux_dirent __user *, + unsigned int count); +asmlinkage long compat_sys_getdents(unsigned int fd, + struct compat_linux_dirent __user *dirent, + unsigned int count); +asmlinkage long compat_sys_getdents64(unsigned int fd, + struct linux_dirent64 __user * dirent, + unsigned int count); +asmlinkage long compat_sys_vmsplice(int fd, const struct compat_iovec __user *, + unsigned int nr_segs, unsigned int flags); +asmlinkage long compat_sys_open(const char __user *filename, int flags, + int mode); asmlinkage long compat_sys_openat(unsigned int dfd, const char __user *filename, int flags, int mode); +asmlinkage long compat_sys_open_by_handle_at(int mountdirfd, + struct file_handle __user *handle, + int flags); +asmlinkage long compat_sys_pselect6(int n, compat_ulong_t __user *inp, + compat_ulong_t __user *outp, + compat_ulong_t __user *exp, + struct compat_timespec __user *tsp, + void __user *sig); +asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds, + unsigned int nfds, + struct compat_timespec __user *tsp, + const compat_sigset_t __user *sigmask, + compat_size_t sigsetsize); +#if (defined(CONFIG_NFSD) || defined(CONFIG_NFSD_MODULE)) && !defined(CONFIG_NFSD_DEPRECATED) +union compat_nfsctl_res; +struct compat_nfsctl_arg; +asmlinkage long compat_sys_nfsservctl(int cmd, + struct compat_nfsctl_arg __user *arg, + union compat_nfsctl_res __user *res); +#else +long asmlinkage compat_sys_nfsservctl(int cmd, void *notused, void *notused2); +#endif +asmlinkage long compat_sys_signalfd4(int ufd, + const compat_sigset_t __user *sigmask, + compat_size_t sigsetsize, int flags); +asmlinkage long compat_sys_get_mempolicy(int __user *policy, + compat_ulong_t __user *nmask, + compat_ulong_t maxnode, + compat_ulong_t addr, + compat_ulong_t flags); +asmlinkage long compat_sys_set_mempolicy(int mode, compat_ulong_t __user *nmask, + compat_ulong_t maxnode); +asmlinkage long compat_sys_mbind(compat_ulong_t start, compat_ulong_t len, + compat_ulong_t mode, + compat_ulong_t __user *nmask, + compat_ulong_t maxnode, compat_ulong_t flags); + +asmlinkage long compat_sys_setsockopt(int fd, int level, int optname, + char __user *optval, unsigned int optlen); +asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg, + unsigned flags); +asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg, + unsigned int flags); +asmlinkage long compat_sys_recv(int fd, void __user *buf, size_t len, + unsigned flags); +asmlinkage long compat_sys_recvfrom(int fd, void __user *buf, size_t len, + unsigned flags, struct sockaddr __user *addr, + int __user *addrlen); +asmlinkage long compat_sys_recvmmsg(int fd, struct compat_mmsghdr __user *mmsg, + unsigned vlen, unsigned int flags, + struct compat_timespec __user *timeout); +asmlinkage long compat_sys_nanosleep(struct compat_timespec __user *rqtp, + struct compat_timespec __user *rmtp); +asmlinkage long compat_sys_getitimer(int which, + struct compat_itimerval __user *it); +asmlinkage long compat_sys_setitimer(int which, + struct compat_itimerval __user *in, + struct compat_itimerval __user *out); +asmlinkage long compat_sys_times(struct compat_tms __user *tbuf); +asmlinkage long compat_sys_setrlimit(unsigned int resource, + struct compat_rlimit __user *rlim); +asmlinkage long compat_sys_getrlimit (unsigned int resource, + struct compat_rlimit __user *rlim); +asmlinkage long compat_sys_getrusage(int who, struct compat_rusage __user *ru); +asmlinkage long compat_sys_sched_setaffinity(compat_pid_t pid, + unsigned int len, + compat_ulong_t __user *user_mask_ptr); +asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid, + unsigned int len, + compat_ulong_t __user *user_mask_ptr); +asmlinkage long compat_sys_timer_create(clockid_t which_clock, + struct compat_sigevent __user *timer_event_spec, + timer_t __user *created_timer_id); +asmlinkage long compat_sys_timer_settime(timer_t timer_id, int flags, + struct compat_itimerspec __user *new, + struct compat_itimerspec __user *old); +asmlinkage long compat_sys_timer_gettime(timer_t timer_id, + struct compat_itimerspec __user *setting); +asmlinkage long compat_sys_clock_settime(clockid_t which_clock, + struct compat_timespec __user *tp); +asmlinkage long compat_sys_clock_gettime(clockid_t which_clock, + struct compat_timespec __user *tp); +asmlinkage long compat_sys_clock_adjtime(clockid_t which_clock, + struct compat_timex __user *tp); +asmlinkage long compat_sys_clock_getres(clockid_t which_clock, + struct compat_timespec __user *tp); +asmlinkage long compat_sys_clock_nanosleep(clockid_t which_clock, int flags, + struct compat_timespec __user *rqtp, + struct compat_timespec __user *rmtp); +asmlinkage long compat_sys_rt_sigtimedwait (compat_sigset_t __user *uthese, + struct compat_siginfo __user *uinfo, + struct compat_timespec __user *uts, compat_size_t sigsetsize); +asmlinkage long compat_sys_rt_sigsuspend(compat_sigset_t __user *unewset, + compat_size_t sigsetsize); +asmlinkage long compat_sys_sysinfo(struct compat_sysinfo __user *info); +asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, + unsigned long arg); +asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, u32 val, + struct compat_timespec __user *utime, u32 __user *uaddr2, + u32 val3); +asmlinkage long compat_sys_getsockopt(int fd, int level, int optname, + char __user *optval, int __user *optlen); +asmlinkage long compat_sys_kexec_load(unsigned long entry, + unsigned long nr_segments, + struct compat_kexec_segment __user *, + unsigned long flags); +asmlinkage long compat_sys_mq_getsetattr(mqd_t mqdes, + const struct compat_mq_attr __user *u_mqstat, + struct compat_mq_attr __user *u_omqstat); +asmlinkage long compat_sys_mq_notify(mqd_t mqdes, + const struct compat_sigevent __user *u_notification); +asmlinkage long compat_sys_mq_open(const char __user *u_name, + int oflag, compat_mode_t mode, + struct compat_mq_attr __user *u_attr); +asmlinkage long compat_sys_mq_timedsend(mqd_t mqdes, + const char __user *u_msg_ptr, + size_t msg_len, unsigned int msg_prio, + const struct compat_timespec __user *u_abs_timeout); +asmlinkage ssize_t compat_sys_mq_timedreceive(mqd_t mqdes, + char __user *u_msg_ptr, + size_t msg_len, unsigned int __user *u_msg_prio, + const struct compat_timespec __user *u_abs_timeout); +asmlinkage long compat_sys_socketcall(int call, u32 __user *args); +asmlinkage long compat_sys_sysctl(struct compat_sysctl_args __user *args); extern ssize_t compat_rw_copy_check_uvector(int type, const struct compat_iovec __user *uvector, unsigned long nr_segs, diff --git a/kernel/compat.c b/kernel/compat.c index 38b1d2c1cbe8..80c28562f57b 100644 --- a/kernel/compat.c +++ b/kernel/compat.c @@ -293,6 +293,8 @@ asmlinkage long compat_sys_times(struct compat_tms __user *tbuf) return compat_jiffies_to_clock_t(jiffies); } +#ifdef __ARCH_WANT_SYS_SIGPENDING + /* * Assumption: old_sigset_t and compat_old_sigset_t are both * types that can be passed to put_user()/get_user(). @@ -312,6 +314,10 @@ asmlinkage long compat_sys_sigpending(compat_old_sigset_t __user *set) return ret; } +#endif + +#ifdef __ARCH_WANT_SYS_SIGPROCMASK + asmlinkage long compat_sys_sigprocmask(int how, compat_old_sigset_t __user *set, compat_old_sigset_t __user *oset) { @@ -333,6 +339,8 @@ asmlinkage long compat_sys_sigprocmask(int how, compat_old_sigset_t __user *set, return ret; } +#endif + asmlinkage long compat_sys_setrlimit(unsigned int resource, struct compat_rlimit __user *rlim) { -- cgit From 7f267051bd7a280265b1b5ead58e9c6e4e1ac3a4 Mon Sep 17 00:00:00 2001 From: Yi Zou Date: Mon, 9 May 2011 11:53:27 +0000 Subject: net: group FCoE related feature flags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MichaÅ‚ MirosÅ‚aw's patch (http://patchwork.ozlabs.org/patch/94421/) fixes the issue (http://patchwork.ozlabs.org/patch/94188/) about not populating FCoE related flags correctly on vlan devices. However, only NETIF_F_FCOE_CRC is part of the NETIF_F_ALL_TX_OFFLOADS right now, where weed NETIF_F_FCOE_MTU and NETIF_F_FSO as well. Therefore, add NETIF_F_ALL_FCOE to indicate feature flags used by FCoE TX offloads. These include NETIF_F_FCOE_CRC, NETIF_F_FCOE_MTU, and NETIF_F_FSO and add them to be part of NETIF_F_ALL_TX_OFFLOADS. This would eventually make sure all FCoE needed flags are populated properly to vlan devices. Signed-off-by: Yi Zou Signed-off-by: David S. Miller --- include/linux/netdevice.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index e7244ed1f9a8..00d650c74800 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1097,10 +1097,14 @@ struct net_device { #define NETIF_F_ALL_TSO (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN) +#define NETIF_F_ALL_FCOE (NETIF_F_FCOE_CRC | NETIF_F_FCOE_MTU | \ + NETIF_F_FSO) + #define NETIF_F_ALL_TX_OFFLOADS (NETIF_F_ALL_CSUM | NETIF_F_SG | \ NETIF_F_FRAGLIST | NETIF_F_ALL_TSO | \ NETIF_F_HIGHDMA | \ - NETIF_F_SCTP_CSUM | NETIF_F_FCOE_CRC) + NETIF_F_SCTP_CSUM | \ + NETIF_F_ALL_FCOE) /* * If one device supports one of these features, then enable them -- cgit From afe12cc86b0ba545a01ad8716539ab07ab6e9e89 Mon Sep 17 00:00:00 2001 From: MichaÅ‚ MirosÅ‚aw Date: Sat, 7 May 2011 03:22:17 +0000 Subject: net: introduce netdev_change_features() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It will be needed by bonding and other drivers changing vlan_features after ndo_init callback. As a bonus, this includes kernel-doc for netdev_update_features(). Signed-off-by: MichaÅ‚ MirosÅ‚aw Signed-off-by: David S. Miller --- include/linux/netdevice.h | 1 + net/core/dev.c | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+) (limited to 'include/linux') diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 00d650c74800..1d9696a9ee4d 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2565,6 +2565,7 @@ u32 netdev_increment_features(u32 all, u32 one, u32 mask); u32 netdev_fix_features(struct net_device *dev, u32 features); int __netdev_update_features(struct net_device *dev); void netdev_update_features(struct net_device *dev); +void netdev_change_features(struct net_device *dev); void netif_stacked_transfer_operstate(const struct net_device *rootdev, struct net_device *dev); diff --git a/net/core/dev.c b/net/core/dev.c index 75898a32c038..ea23353e6251 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -5289,6 +5289,14 @@ int __netdev_update_features(struct net_device *dev) return 1; } +/** + * netdev_update_features - recalculate device features + * @dev: the device to check + * + * Recalculate dev->features set and send notifications if it + * has changed. Should be called after driver or hardware dependent + * conditions might have changed that influence the features. + */ void netdev_update_features(struct net_device *dev) { if (__netdev_update_features(dev)) @@ -5296,6 +5304,23 @@ void netdev_update_features(struct net_device *dev) } EXPORT_SYMBOL(netdev_update_features); +/** + * netdev_change_features - recalculate device features + * @dev: the device to check + * + * Recalculate dev->features set and send notifications even + * if they have not changed. Should be called instead of + * netdev_update_features() if also dev->vlan_features might + * have changed to allow the changes to be propagated to stacked + * VLAN devices. + */ +void netdev_change_features(struct net_device *dev) +{ + __netdev_update_features(dev); + netdev_features_change(dev); +} +EXPORT_SYMBOL(netdev_change_features); + /** * netif_stacked_transfer_operstate - transfer operstate * @rootdev: the root or lower level device to transfer state from -- cgit From bdc220da3209d50b8c295490dec94845c88670a2 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 9 May 2011 17:42:46 +0000 Subject: netdevice.h: Align struct net_device members Save a bit of space. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- include/linux/netdevice.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 1d9696a9ee4d..a134d809125b 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1020,9 +1020,6 @@ struct net_device { * part of the usual set specified in Space.c. */ - unsigned char if_port; /* Selectable AUI, TP,..*/ - unsigned char dma; /* DMA channel */ - unsigned long state; struct list_head dev_list; @@ -1146,13 +1143,16 @@ struct net_device { const struct header_ops *header_ops; unsigned int flags; /* interface flags (a la BSD) */ + unsigned int priv_flags; /* Like 'flags' but invisible to userspace. */ unsigned short gflags; - unsigned int priv_flags; /* Like 'flags' but invisible to userspace. */ unsigned short padded; /* How much padding added by alloc_netdev() */ unsigned char operstate; /* RFC2863 operstate */ unsigned char link_mode; /* mapping policy to operstate */ + unsigned char if_port; /* Selectable AUI, TP,..*/ + unsigned char dma; /* DMA channel */ + unsigned int mtu; /* interface MTU value */ unsigned short type; /* interface hardware type */ unsigned short hard_header_len; /* hardware hdr length */ -- cgit From 29dd54b72ba8c5ad0dd6dd33584449b5953f700b Mon Sep 17 00:00:00 2001 From: Anirban Chakraborty Date: Thu, 12 May 2011 12:48:32 +0000 Subject: ethtool: Added support for FW dump Added code to take FW dump via ethtool. Dump level can be controlled via setting the dump flag. A get function is provided to query the current setting of the dump flag. Dump data is obtained from the driver via a separate get function. Changes from v3: Fixed buffer length issue in ethtool_get_dump_data function. Updated kernel doc for ethtool_dump struct and get_dump_flag function. Changes from v2: Provided separate commands for get flag and data. Check for minimum of the two buffer length obtained via ethtool and driver and use that for dump buffer Pass up the driver return error codes up to the caller. Added kernel doc comments. Signed-off-by: Anirban Chakraborty Reviewed-by: Ben Hutchings Signed-off-by: David S. Miller --- include/linux/ethtool.h | 31 +++++++++++++++++ net/core/ethtool.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index bd0b50b85f06..c6a850ab2ec5 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -601,6 +601,26 @@ struct ethtool_flash { char data[ETHTOOL_FLASH_MAX_FILENAME]; }; +/** + * struct ethtool_dump - used for retrieving, setting device dump + * @cmd: Command number - %ETHTOOL_GET_DUMP_FLAG, %ETHTOOL_GET_DUMP_DATA, or + * %ETHTOOL_SET_DUMP + * @version: FW version of the dump, filled in by driver + * @flag: driver dependent flag for dump setting, filled in by driver during + * get and filled in by ethtool for set operation + * @len: length of dump data, used as the length of the user buffer on entry to + * %ETHTOOL_GET_DUMP_DATA and this is returned as dump length by driver + * for %ETHTOOL_GET_DUMP_FLAG command + * @data: data collected for get dump data operation + */ +struct ethtool_dump { + __u32 cmd; + __u32 version; + __u32 flag; + __u32 len; + __u8 data[0]; +}; + /* for returning and changing feature sets */ /** @@ -853,6 +873,10 @@ bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported); * @get_channels: Get number of channels. * @set_channels: Set number of channels. Returns a negative error code or * zero. + * @get_dump_flag: Get dump flag indicating current dump length, version, + * and flag of the device. + * @get_dump_data: Get dump data. + * @set_dump: Set dump specific flags to the device. * * All operations are optional (i.e. the function pointer may be set * to %NULL) and callers must take this into account. Callers must @@ -927,6 +951,10 @@ struct ethtool_ops { const struct ethtool_rxfh_indir *); void (*get_channels)(struct net_device *, struct ethtool_channels *); int (*set_channels)(struct net_device *, struct ethtool_channels *); + int (*get_dump_flag)(struct net_device *, struct ethtool_dump *); + int (*get_dump_data)(struct net_device *, + struct ethtool_dump *, void *); + int (*set_dump)(struct net_device *, struct ethtool_dump *); }; #endif /* __KERNEL__ */ @@ -998,6 +1026,9 @@ struct ethtool_ops { #define ETHTOOL_SFEATURES 0x0000003b /* Change device offload settings */ #define ETHTOOL_GCHANNELS 0x0000003c /* Get no of channels */ #define ETHTOOL_SCHANNELS 0x0000003d /* Set no of channels */ +#define ETHTOOL_SET_DUMP 0x0000003e /* Set dump settings */ +#define ETHTOOL_GET_DUMP_FLAG 0x0000003f /* Get dump settings */ +#define ETHTOOL_GET_DUMP_DATA 0x00000040 /* Get dump data */ /* compatibility with older code */ #define SPARC_ETH_GSET ETHTOOL_GSET diff --git a/net/core/ethtool.c b/net/core/ethtool.c index b8c2b10f397a..b8c2bcfee6af 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -1823,6 +1823,87 @@ static noinline_for_stack int ethtool_flash_device(struct net_device *dev, return dev->ethtool_ops->flash_device(dev, &efl); } +static int ethtool_set_dump(struct net_device *dev, + void __user *useraddr) +{ + struct ethtool_dump dump; + + if (!dev->ethtool_ops->set_dump) + return -EOPNOTSUPP; + + if (copy_from_user(&dump, useraddr, sizeof(dump))) + return -EFAULT; + + return dev->ethtool_ops->set_dump(dev, &dump); +} + +static int ethtool_get_dump_flag(struct net_device *dev, + void __user *useraddr) +{ + int ret; + struct ethtool_dump dump; + const struct ethtool_ops *ops = dev->ethtool_ops; + + if (!dev->ethtool_ops->get_dump_flag) + return -EOPNOTSUPP; + + if (copy_from_user(&dump, useraddr, sizeof(dump))) + return -EFAULT; + + ret = ops->get_dump_flag(dev, &dump); + if (ret) + return ret; + + if (copy_to_user(useraddr, &dump, sizeof(dump))) + return -EFAULT; + return 0; +} + +static int ethtool_get_dump_data(struct net_device *dev, + void __user *useraddr) +{ + int ret; + __u32 len; + struct ethtool_dump dump, tmp; + const struct ethtool_ops *ops = dev->ethtool_ops; + void *data = NULL; + + if (!dev->ethtool_ops->get_dump_data || + !dev->ethtool_ops->get_dump_flag) + return -EOPNOTSUPP; + + if (copy_from_user(&dump, useraddr, sizeof(dump))) + return -EFAULT; + + memset(&tmp, 0, sizeof(tmp)); + tmp.cmd = ETHTOOL_GET_DUMP_FLAG; + ret = ops->get_dump_flag(dev, &tmp); + if (ret) + return ret; + + len = (tmp.len > dump.len) ? dump.len : tmp.len; + if (!len) + return -EFAULT; + + data = vzalloc(tmp.len); + if (!data) + return -ENOMEM; + ret = ops->get_dump_data(dev, &dump, data); + if (ret) + goto out; + + if (copy_to_user(useraddr, &dump, sizeof(dump))) { + ret = -EFAULT; + goto out; + } + useraddr += offsetof(struct ethtool_dump, data); + if (copy_to_user(useraddr, data, len)) + ret = -EFAULT; +out: + vfree(data); + return ret; +} + /* The main entry point in this file. Called from net/core/dev.c */ int dev_ethtool(struct net *net, struct ifreq *ifr) @@ -2039,6 +2120,15 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) case ETHTOOL_SCHANNELS: rc = ethtool_set_channels(dev, useraddr); break; + case ETHTOOL_SET_DUMP: + rc = ethtool_set_dump(dev, useraddr); + break; + case ETHTOOL_GET_DUMP_FLAG: + rc = ethtool_get_dump_flag(dev, useraddr); + break; + case ETHTOOL_GET_DUMP_DATA: + rc = ethtool_get_dump_data(dev, useraddr); + break; default: rc = -EOPNOTSUPP; } -- cgit From 47a150edc2ae734c0f4bf50aa19499e23b9a46f8 Mon Sep 17 00:00:00 2001 From: "Serge E. Hallyn" Date: Fri, 13 May 2011 04:27:54 +0100 Subject: Cache user_ns in struct cred If !CONFIG_USERNS, have current_user_ns() defined to (&init_user_ns). Get rid of _current_user_ns. This requires nsown_capable() to be defined in capability.c rather than as static inline in capability.h, so do that. Request_key needs init_user_ns defined at current_user_ns if !CONFIG_USERNS, so forward-declare that in cred.h if !CONFIG_USERNS at current_user_ns() define. Compile-tested with and without CONFIG_USERNS. Signed-off-by: Serge E. Hallyn [ This makes a huge performance difference for acl_permission_check(), up to 30%. And that is one of the hottest kernel functions for loads that are pathname-lookup heavy. ] Signed-off-by: Linus Torvalds --- include/linux/capability.h | 13 +------------ include/linux/cred.h | 10 ++++++++-- kernel/capability.c | 12 ++++++++++++ kernel/cred.c | 12 ++++++------ 4 files changed, 27 insertions(+), 20 deletions(-) (limited to 'include/linux') diff --git a/include/linux/capability.h b/include/linux/capability.h index 16ee8b49a200..d4675af963fa 100644 --- a/include/linux/capability.h +++ b/include/linux/capability.h @@ -546,18 +546,7 @@ extern bool has_capability_noaudit(struct task_struct *t, int cap); extern bool capable(int cap); extern bool ns_capable(struct user_namespace *ns, int cap); extern bool task_ns_capable(struct task_struct *t, int cap); - -/** - * nsown_capable - Check superior capability to one's own user_ns - * @cap: The capability in question - * - * Return true if the current task has the given superior capability - * targeted at its own user namespace. - */ -static inline bool nsown_capable(int cap) -{ - return ns_capable(current_user_ns(), cap); -} +extern bool nsown_capable(int cap); /* audit system wants to get cap info from files as well */ extern int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data *cpu_caps); diff --git a/include/linux/cred.h b/include/linux/cred.h index 9aeeb0ba2003..be16b61283cc 100644 --- a/include/linux/cred.h +++ b/include/linux/cred.h @@ -146,6 +146,7 @@ struct cred { void *security; /* subjective LSM security */ #endif struct user_struct *user; /* real user ID subscription */ + struct user_namespace *user_ns; /* cached user->user_ns */ struct group_info *group_info; /* supplementary groups for euid/fsgid */ struct rcu_head rcu; /* RCU deletion hook */ }; @@ -354,10 +355,15 @@ static inline void put_cred(const struct cred *_cred) #define current_fsgid() (current_cred_xxx(fsgid)) #define current_cap() (current_cred_xxx(cap_effective)) #define current_user() (current_cred_xxx(user)) -#define _current_user_ns() (current_cred_xxx(user)->user_ns) #define current_security() (current_cred_xxx(security)) -extern struct user_namespace *current_user_ns(void); +#ifdef CONFIG_USER_NS +#define current_user_ns() (current_cred_xxx(user_ns)) +#else +extern struct user_namespace init_user_ns; +#define current_user_ns() (&init_user_ns) +#endif + #define current_uid_gid(_uid, _gid) \ do { \ diff --git a/kernel/capability.c b/kernel/capability.c index bf0c734d0c12..32a80e08ff4b 100644 --- a/kernel/capability.c +++ b/kernel/capability.c @@ -399,3 +399,15 @@ bool task_ns_capable(struct task_struct *t, int cap) return ns_capable(task_cred_xxx(t, user)->user_ns, cap); } EXPORT_SYMBOL(task_ns_capable); + +/** + * nsown_capable - Check superior capability to one's own user_ns + * @cap: The capability in question + * + * Return true if the current task has the given superior capability + * targeted at its own user namespace. + */ +bool nsown_capable(int cap) +{ + return ns_capable(current_user_ns(), cap); +} diff --git a/kernel/cred.c b/kernel/cred.c index 5557b55048df..8093c16b84b1 100644 --- a/kernel/cred.c +++ b/kernel/cred.c @@ -54,6 +54,7 @@ struct cred init_cred = { .cap_effective = CAP_INIT_EFF_SET, .cap_bset = CAP_INIT_BSET, .user = INIT_USER, + .user_ns = &init_user_ns, .group_info = &init_groups, #ifdef CONFIG_KEYS .tgcred = &init_tgcred, @@ -410,6 +411,11 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags) goto error_put; } + /* cache user_ns in cred. Doesn't need a refcount because it will + * stay pinned by cred->user + */ + new->user_ns = new->user->user_ns; + #ifdef CONFIG_KEYS /* new threads get their own thread keyrings if their parent already * had one */ @@ -741,12 +747,6 @@ int set_create_files_as(struct cred *new, struct inode *inode) } EXPORT_SYMBOL(set_create_files_as); -struct user_namespace *current_user_ns(void) -{ - return _current_user_ns(); -} -EXPORT_SYMBOL(current_user_ns); - #ifdef CONFIG_DEBUG_CREDENTIALS bool creds_are_invalid(const struct cred *cred) -- cgit From 82a3242e11d9e63c8195be46c954efaefee35e22 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 12 May 2011 16:01:02 -0700 Subject: sysfs: remove "last sysfs file:" line from the oops messages On some arches (x86, sh, arm, unicore, powerpc) the oops message would print out the last sysfs file accessed. This was very useful in finding a number of sysfs and driver core bugs in the 2.5 and early 2.6 development days, but it has been a number of years since this file has actually helped in debugging anything that couldn't also be trivially determined from the stack traceback. So it's time to delete the line. This is good as we need all the space we can get for oops messages at times on consoles. Acked-by: Phil Carmody Acked-by: Ingo Molnar Cc: Andrew Morton Cc: Thomas Gleixner Signed-off-by: Greg Kroah-Hartman --- arch/arm/kernel/traps.c | 1 - arch/powerpc/kernel/traps.c | 1 - arch/sh/kernel/traps_32.c | 1 - arch/unicore32/kernel/traps.c | 1 - arch/x86/kernel/dumpstack.c | 1 - fs/sysfs/file.c | 12 ------------ include/linux/sysfs.h | 5 ----- 7 files changed, 22 deletions(-) (limited to 'include/linux') diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 3b54ad19d489..d52eec268b47 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -234,7 +234,6 @@ static int __die(const char *str, int err, struct thread_info *thread, struct pt printk(KERN_EMERG "Internal error: %s: %x [#%d]" S_PREEMPT S_SMP "\n", str, err, ++die_counter); - sysfs_printk_last_file(); /* trap and error numbers are mostly meaningless on ARM */ ret = notify_die(DIE_OOPS, str, regs, err, tsk->thread.trap_no, SIGSEGV); diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 5ddb801bc154..d782cd71c07c 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -143,7 +143,6 @@ int die(const char *str, struct pt_regs *regs, long err) #endif printk("%s\n", ppc_md.name ? ppc_md.name : ""); - sysfs_printk_last_file(); if (notify_die(DIE_OOPS, str, regs, err, 255, SIGSEGV) == NOTIFY_STOP) return 1; diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c index 3484c2f65aba..b51a17104b5f 100644 --- a/arch/sh/kernel/traps_32.c +++ b/arch/sh/kernel/traps_32.c @@ -87,7 +87,6 @@ void die(const char * str, struct pt_regs * regs, long err) bust_spinlocks(1); printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); - sysfs_printk_last_file(); print_modules(); show_regs(regs); diff --git a/arch/unicore32/kernel/traps.c b/arch/unicore32/kernel/traps.c index 254e36fa9513..b9a26465e728 100644 --- a/arch/unicore32/kernel/traps.c +++ b/arch/unicore32/kernel/traps.c @@ -192,7 +192,6 @@ static int __die(const char *str, int err, struct thread_info *thread, printk(KERN_EMERG "Internal error: %s: %x [#%d]\n", str, err, ++die_counter); - sysfs_printk_last_file(); /* trap and error numbers are mostly meaningless on UniCore */ ret = notify_die(DIE_OOPS, str, regs, err, tsk->thread.trap_no, \ diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c index e2a3f0606da4..f72e7193acc5 100644 --- a/arch/x86/kernel/dumpstack.c +++ b/arch/x86/kernel/dumpstack.c @@ -279,7 +279,6 @@ int __kprobes __die(const char *str, struct pt_regs *regs, long err) printk("DEBUG_PAGEALLOC"); #endif printk("\n"); - sysfs_printk_last_file(); if (notify_die(DIE_OOPS, str, regs, err, current->thread.trap_no, SIGSEGV) == NOTIFY_STOP) return 1; diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index da3fefe91a8f..1ad8c93c1b85 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c @@ -24,13 +24,6 @@ #include "sysfs.h" -/* used in crash dumps to help with debugging */ -static char last_sysfs_file[PATH_MAX]; -void sysfs_printk_last_file(void) -{ - printk(KERN_EMERG "last sysfs file: %s\n", last_sysfs_file); -} - /* * There's one sysfs_buffer for each open file and one * sysfs_open_dirent for each sysfs_dirent with one or more open @@ -337,11 +330,6 @@ static int sysfs_open_file(struct inode *inode, struct file *file) struct sysfs_buffer *buffer; const struct sysfs_ops *ops; int error = -EACCES; - char *p; - - p = d_path(&file->f_path, last_sysfs_file, sizeof(last_sysfs_file)); - if (!IS_ERR(p)) - memmove(last_sysfs_file, p, strlen(p) + 1); /* need attr_sd for attr and ops, its parent for kobj */ if (!sysfs_get_active(attr_sd)) diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index 30b881555fa5..c3acda60eee0 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -176,7 +176,6 @@ struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd, const unsigned char *name); struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd); void sysfs_put(struct sysfs_dirent *sd); -void sysfs_printk_last_file(void); /* Called to clear a ns tag when it is no longer valid */ void sysfs_exit_ns(enum kobj_ns_type type, const void *tag); @@ -348,10 +347,6 @@ static inline int __must_check sysfs_init(void) return 0; } -static inline void sysfs_printk_last_file(void) -{ -} - #endif /* CONFIG_SYSFS */ #endif /* _SYSFS_H_ */ -- cgit From 0b61d2acb1ea48d8eba798ed92759b7f1b0f4209 Mon Sep 17 00:00:00 2001 From: J Freyensee Date: Fri, 6 May 2011 16:56:49 -0700 Subject: Intel PTI implementaiton of MIPI 1149.7. The PTI (Parallel Trace Interface) driver directs trace data routed from various parts in the system out through an Intel Penwell PTI port and out of the mobile device for analysis with a debugging tool (Lauterbach or Fido). Though n_tracesink and n_tracerouter line discipline drivers are used to extract modem tracing data to the PTI driver and other parts of an Intel mobile solution, the PTI driver can be used independent of n_tracesink and n_tracerouter. You should select this driver if the target kernel is meant for an Intel Atom (non-netbook) mobile device containing a MIPI P1149.7 standard implementation. Signed-off-by: J Freyensee Signed-off-by: Greg Kroah-Hartman --- drivers/misc/Kconfig | 13 + drivers/misc/Makefile | 1 + drivers/misc/pti.c | 980 ++++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/pti.h | 42 +++ 4 files changed, 1036 insertions(+) create mode 100644 drivers/misc/pti.c create mode 100644 include/linux/pti.h (limited to 'include/linux') diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 915c31ef84cd..ec33d939548c 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -144,6 +144,19 @@ config PHANTOM If you choose to build module, its name will be phantom. If unsure, say N here. +config INTEL_MID_PTI + tristate "Parallel Trace Interface for MIPI P1149.7 cJTAG standard" + default n + help + The PTI (Parallel Trace Interface) driver directs + trace data routed from various parts in the system out + through an Intel Penwell PTI port and out of the mobile + device for analysis with a debugging tool (Lauterbach or Fido). + + You should select this driver if the target kernel is meant for + an Intel Atom (non-netbook) mobile device containing a MIPI + P1149.7 standard implementation. + config SGI_IOC4 tristate "SGI IOC4 Base IO support" depends on PCI diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index f5468602961f..662aa3c71d05 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_IBM_ASM) += ibmasm/ obj-$(CONFIG_AD525X_DPOT) += ad525x_dpot.o obj-$(CONFIG_AD525X_DPOT_I2C) += ad525x_dpot-i2c.o obj-$(CONFIG_AD525X_DPOT_SPI) += ad525x_dpot-spi.o +0bj-$(CONFIG_INTEL_MID_PTI) += pti.o obj-$(CONFIG_ATMEL_PWM) += atmel_pwm.o obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o diff --git a/drivers/misc/pti.c b/drivers/misc/pti.c new file mode 100644 index 000000000000..bb6f9255c17c --- /dev/null +++ b/drivers/misc/pti.c @@ -0,0 +1,980 @@ +/* + * pti.c - PTI driver for cJTAG data extration + * + * Copyright (C) Intel 2010 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * The PTI (Parallel Trace Interface) driver directs trace data routed from + * various parts in the system out through the Intel Penwell PTI port and + * out of the mobile device for analysis with a debugging tool + * (Lauterbach, Fido). This is part of a solution for the MIPI P1149.7, + * compact JTAG, standard. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVERNAME "pti" +#define PCINAME "pciPTI" +#define TTYNAME "ttyPTI" +#define CHARNAME "pti" +#define PTITTY_MINOR_START 0 +#define PTITTY_MINOR_NUM 2 +#define MAX_APP_IDS 16 /* 128 channel ids / u8 bit size */ +#define MAX_OS_IDS 16 /* 128 channel ids / u8 bit size */ +#define MAX_MODEM_IDS 16 /* 128 channel ids / u8 bit size */ +#define MODEM_BASE_ID 71 /* modem master ID address */ +#define CONTROL_ID 72 /* control master ID address */ +#define CONSOLE_ID 73 /* console master ID address */ +#define OS_BASE_ID 74 /* base OS master ID address */ +#define APP_BASE_ID 80 /* base App master ID address */ +#define CONTROL_FRAME_LEN 32 /* PTI control frame maximum size */ +#define USER_COPY_SIZE 8192 /* 8Kb buffer for user space copy */ +#define APERTURE_14 0x3800000 /* offset to first OS write addr */ +#define APERTURE_LEN 0x400000 /* address length */ + +struct pti_tty { + struct pti_masterchannel *mc; +}; + +struct pti_dev { + struct tty_port port; + unsigned long pti_addr; + unsigned long aperture_base; + void __iomem *pti_ioaddr; + u8 ia_app[MAX_APP_IDS]; + u8 ia_os[MAX_OS_IDS]; + u8 ia_modem[MAX_MODEM_IDS]; +}; + +/* + * This protects access to ia_app, ia_os, and ia_modem, + * which keeps track of channels allocated in + * an aperture write id. + */ +static DEFINE_MUTEX(alloclock); + +static struct pci_device_id pci_ids[] __devinitconst = { + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x82B)}, + {0} +}; + +static struct tty_driver *pti_tty_driver; +static struct pti_dev *drv_data; + +static unsigned int pti_console_channel; +static unsigned int pti_control_channel; + +/** + * pti_write_to_aperture()- The private write function to PTI HW. + * + * @mc: The 'aperture'. It's part of a write address that holds + * a master and channel ID. + * @buf: Data being written to the HW that will ultimately be seen + * in a debugging tool (Fido, Lauterbach). + * @len: Size of buffer. + * + * Since each aperture is specified by a unique + * master/channel ID, no two processes will be writing + * to the same aperture at the same time so no lock is required. The + * PTI-Output agent will send these out in the order that they arrived, and + * thus, it will intermix these messages. The debug tool can then later + * regroup the appropriate message segments together reconstituting each + * message. + */ +static void pti_write_to_aperture(struct pti_masterchannel *mc, + u8 *buf, + int len) +{ + int dwordcnt; + int final; + int i; + u32 ptiword; + u32 __iomem *aperture; + u8 *p = buf; + + /* + * calculate the aperture offset from the base using the master and + * channel id's. + */ + aperture = drv_data->pti_ioaddr + (mc->master << 15) + + (mc->channel << 8); + + dwordcnt = len >> 2; + final = len - (dwordcnt << 2); /* final = trailing bytes */ + if (final == 0 && dwordcnt != 0) { /* always need a final dword */ + final += 4; + dwordcnt--; + } + + for (i = 0; i < dwordcnt; i++) { + ptiword = be32_to_cpu(*(u32 *)p); + p += 4; + iowrite32(ptiword, aperture); + } + + aperture += PTI_LASTDWORD_DTS; /* adding DTS signals that is EOM */ + + ptiword = 0; + for (i = 0; i < final; i++) + ptiword |= *p++ << (24-(8*i)); + + iowrite32(ptiword, aperture); + return; +} + +/** + * pti_control_frame_built_and_sent()- control frame build and send function. + * + * @mc: The master / channel structure on which the function + * built a control frame. + * + * To be able to post process the PTI contents on host side, a control frame + * is added before sending any PTI content. So the host side knows on + * each PTI frame the name of the thread using a dedicated master / channel. + * The thread name is retrieved from the 'current' global variable. + * This function builds this frame and sends it to a master ID CONTROL_ID. + * The overhead is only 32 bytes since the driver only writes to HW + * in 32 byte chunks. + */ + +static void pti_control_frame_built_and_sent(struct pti_masterchannel *mc) +{ + struct pti_masterchannel mccontrol = {.master = CONTROL_ID, + .channel = 0}; + const char *control_format = "%3d %3d %s"; + u8 control_frame[CONTROL_FRAME_LEN]; + + /* + * Since we access the comm member in current's task_struct, + * we only need to be as large as what 'comm' in that + * structure is. + */ + char comm[TASK_COMM_LEN]; + + if (!in_interrupt()) + get_task_comm(comm, current); + else + strncpy(comm, "Interrupt", TASK_COMM_LEN); + + /* Absolutely ensure our buffer is zero terminated. */ + comm[TASK_COMM_LEN-1] = 0; + + mccontrol.channel = pti_control_channel; + pti_control_channel = (pti_control_channel + 1) & 0x7f; + + snprintf(control_frame, CONTROL_FRAME_LEN, control_format, mc->master, + mc->channel, comm); + pti_write_to_aperture(&mccontrol, control_frame, strlen(control_frame)); +} + +/** + * pti_write_full_frame_to_aperture()- high level function to + * write to PTI. + * + * @mc: The 'aperture'. It's part of a write address that holds + * a master and channel ID. + * @buf: Data being written to the HW that will ultimately be seen + * in a debugging tool (Fido, Lauterbach). + * @len: Size of buffer. + * + * All threads sending data (either console, user space application, ...) + * are calling the high level function to write to PTI meaning that it is + * possible to add a control frame before sending the content. + */ +static void pti_write_full_frame_to_aperture(struct pti_masterchannel *mc, + const unsigned char *buf, + int len) +{ + pti_control_frame_built_and_sent(mc); + pti_write_to_aperture(mc, (u8 *)buf, len); +} + +/** + * get_id()- Allocate a master and channel ID. + * + * @id_array: an array of bits representing what channel + * id's are allocated for writing. + * @max_ids: The max amount of available write IDs to use. + * @base_id: The starting SW channel ID, based on the Intel + * PTI arch. + * + * Returns: + * pti_masterchannel struct with master, channel ID address + * 0 for error + * + * Each bit in the arrays ia_app and ia_os correspond to a master and + * channel id. The bit is one if the id is taken and 0 if free. For + * every master there are 128 channel id's. + */ +static struct pti_masterchannel *get_id(u8 *id_array, int max_ids, int base_id) +{ + struct pti_masterchannel *mc; + int i, j, mask; + + mc = kmalloc(sizeof(struct pti_masterchannel), GFP_KERNEL); + if (mc == NULL) + return NULL; + + /* look for a byte with a free bit */ + for (i = 0; i < max_ids; i++) + if (id_array[i] != 0xff) + break; + if (i == max_ids) { + kfree(mc); + return NULL; + } + /* find the bit in the 128 possible channel opportunities */ + mask = 0x80; + for (j = 0; j < 8; j++) { + if ((id_array[i] & mask) == 0) + break; + mask >>= 1; + } + + /* grab it */ + id_array[i] |= mask; + mc->master = base_id; + mc->channel = ((i & 0xf)<<3) + j; + /* write new master Id / channel Id allocation to channel control */ + pti_control_frame_built_and_sent(mc); + return mc; +} + +/* + * The following three functions: + * pti_request_mastercahannel(), mipi_release_masterchannel() + * and pti_writedata() are an API for other kernel drivers to + * access PTI. + */ + +/** + * pti_request_masterchannel()- Kernel API function used to allocate + * a master, channel ID address + * to write to PTI HW. + * + * @type: 0- request Application master, channel aperture ID write address. + * 1- request OS master, channel aperture ID write + * address. + * 2- request Modem master, channel aperture ID + * write address. + * Other values, error. + * + * Returns: + * pti_masterchannel struct + * 0 for error + */ +struct pti_masterchannel *pti_request_masterchannel(u8 type) +{ + struct pti_masterchannel *mc; + + mutex_lock(&alloclock); + + switch (type) { + + case 0: + mc = get_id(drv_data->ia_app, MAX_APP_IDS, APP_BASE_ID); + break; + + case 1: + mc = get_id(drv_data->ia_os, MAX_OS_IDS, OS_BASE_ID); + break; + + case 2: + mc = get_id(drv_data->ia_modem, MAX_MODEM_IDS, MODEM_BASE_ID); + break; + default: + mc = NULL; + } + + mutex_unlock(&alloclock); + return mc; +} +EXPORT_SYMBOL_GPL(pti_request_masterchannel); + +/** + * pti_release_masterchannel()- Kernel API function used to release + * a master, channel ID address + * used to write to PTI HW. + * + * @mc: master, channel apeture ID address to be released. + */ +void pti_release_masterchannel(struct pti_masterchannel *mc) +{ + u8 master, channel, i; + + mutex_lock(&alloclock); + + if (mc) { + master = mc->master; + channel = mc->channel; + + if (master == APP_BASE_ID) { + i = channel >> 3; + drv_data->ia_app[i] &= ~(0x80>>(channel & 0x7)); + } else if (master == OS_BASE_ID) { + i = channel >> 3; + drv_data->ia_os[i] &= ~(0x80>>(channel & 0x7)); + } else { + i = channel >> 3; + drv_data->ia_modem[i] &= ~(0x80>>(channel & 0x7)); + } + + kfree(mc); + } + + mutex_unlock(&alloclock); +} +EXPORT_SYMBOL_GPL(pti_release_masterchannel); + +/** + * pti_writedata()- Kernel API function used to write trace + * debugging data to PTI HW. + * + * @mc: Master, channel aperture ID address to write to. + * Null value will return with no write occurring. + * @buf: Trace debuging data to write to the PTI HW. + * Null value will return with no write occurring. + * @count: Size of buf. Value of 0 or a negative number will + * return with no write occuring. + */ +void pti_writedata(struct pti_masterchannel *mc, u8 *buf, int count) +{ + /* + * since this function is exported, this is treated like an + * API function, thus, all parameters should + * be checked for validity. + */ + if ((mc != NULL) && (buf != NULL) && (count > 0)) + pti_write_to_aperture(mc, buf, count); + return; +} +EXPORT_SYMBOL_GPL(pti_writedata); + +/** + * pti_pci_remove()- Driver exit method to remove PTI from + * PCI bus. + * @pdev: variable containing pci info of PTI. + */ +static void __devexit pti_pci_remove(struct pci_dev *pdev) +{ + struct pti_dev *drv_data; + + drv_data = pci_get_drvdata(pdev); + if (drv_data != NULL) { + pci_iounmap(pdev, drv_data->pti_ioaddr); + pci_set_drvdata(pdev, NULL); + kfree(drv_data); + pci_release_region(pdev, 1); + pci_disable_device(pdev); + } +} + +/* + * for the tty_driver_*() basic function descriptions, see tty_driver.h. + * Specific header comments made for PTI-related specifics. + */ + +/** + * pti_tty_driver_open()- Open an Application master, channel aperture + * ID to the PTI device via tty device. + * + * @tty: tty interface. + * @filp: filp interface pased to tty_port_open() call. + * + * Returns: + * int, 0 for success + * otherwise, fail value + * + * The main purpose of using the tty device interface is for + * each tty port to have a unique PTI write aperture. In an + * example use case, ttyPTI0 gets syslogd and an APP aperture + * ID and ttyPTI1 is where the n_tracesink ldisc hooks to route + * modem messages into PTI. Modem trace data does not have to + * go to ttyPTI1, but ttyPTI0 and ttyPTI1 do need to be distinct + * master IDs. These messages go through the PTI HW and out of + * the handheld platform and to the Fido/Lauterbach device. + */ +static int pti_tty_driver_open(struct tty_struct *tty, struct file *filp) +{ + /* + * we actually want to allocate a new channel per open, per + * system arch. HW gives more than plenty channels for a single + * system task to have its own channel to write trace data. This + * also removes a locking requirement for the actual write + * procedure. + */ + return tty_port_open(&drv_data->port, tty, filp); +} + +/** + * pti_tty_driver_close()- close tty device and release Application + * master, channel aperture ID to the PTI device via tty device. + * + * @tty: tty interface. + * @filp: filp interface pased to tty_port_close() call. + * + * The main purpose of using the tty device interface is to route + * syslog daemon messages to the PTI HW and out of the handheld platform + * and to the Fido/Lauterbach device. + */ +static void pti_tty_driver_close(struct tty_struct *tty, struct file *filp) +{ + tty_port_close(&drv_data->port, tty, filp); +} + +/** + * pti_tty_intstall()- Used to set up specific master-channels + * to tty ports for organizational purposes when + * tracing viewed from debuging tools. + * + * @driver: tty driver information. + * @tty: tty struct containing pti information. + * + * Returns: + * 0 for success + * otherwise, error + */ +static int pti_tty_install(struct tty_driver *driver, struct tty_struct *tty) +{ + int idx = tty->index; + struct pti_tty *pti_tty_data; + int ret = tty_init_termios(tty); + + if (ret == 0) { + tty_driver_kref_get(driver); + tty->count++; + driver->ttys[idx] = tty; + + pti_tty_data = kmalloc(sizeof(struct pti_tty), GFP_KERNEL); + if (pti_tty_data == NULL) + return -ENOMEM; + + if (idx == PTITTY_MINOR_START) + pti_tty_data->mc = pti_request_masterchannel(0); + else + pti_tty_data->mc = pti_request_masterchannel(2); + + if (pti_tty_data->mc == NULL) + return -ENXIO; + tty->driver_data = pti_tty_data; + } + + return ret; +} + +/** + * pti_tty_cleanup()- Used to de-allocate master-channel resources + * tied to tty's of this driver. + * + * @tty: tty struct containing pti information. + */ +static void pti_tty_cleanup(struct tty_struct *tty) +{ + struct pti_tty *pti_tty_data = tty->driver_data; + if (pti_tty_data == NULL) + return; + pti_release_masterchannel(pti_tty_data->mc); + kfree(tty->driver_data); + tty->driver_data = NULL; +} + +/** + * pti_tty_driver_write()- Write trace debugging data through the char + * interface to the PTI HW. Part of the misc device implementation. + * + * @filp: Contains private data which is used to obtain + * master, channel write ID. + * @data: trace data to be written. + * @len: # of byte to write. + * + * Returns: + * int, # of bytes written + * otherwise, error + */ +static int pti_tty_driver_write(struct tty_struct *tty, + const unsigned char *buf, int len) +{ + struct pti_tty *pti_tty_data = tty->driver_data; + if ((pti_tty_data != NULL) && (pti_tty_data->mc != NULL)) { + pti_write_to_aperture(pti_tty_data->mc, (u8 *)buf, len); + return len; + } + /* + * we can't write to the pti hardware if the private driver_data + * and the mc address is not there. + */ + else + return -EFAULT; +} + +/** + * pti_tty_write_room()- Always returns 2048. + * + * @tty: contains tty info of the pti driver. + */ +static int pti_tty_write_room(struct tty_struct *tty) +{ + return 2048; +} + +/** + * pti_char_open()- Open an Application master, channel aperture + * ID to the PTI device. Part of the misc device implementation. + * + * @inode: not used. + * @filp: Output- will have a masterchannel struct set containing + * the allocated application PTI aperture write address. + * + * Returns: + * int, 0 for success + * otherwise, a fail value + */ +static int pti_char_open(struct inode *inode, struct file *filp) +{ + struct pti_masterchannel *mc; + + /* + * We really do want to fail immediately if + * pti_request_masterchannel() fails, + * before assigning the value to filp->private_data. + * Slightly easier to debug if this driver needs debugging. + */ + mc = pti_request_masterchannel(0); + if (mc == NULL) + return -ENOMEM; + filp->private_data = mc; + return 0; +} + +/** + * pti_char_release()- Close a char channel to the PTI device. Part + * of the misc device implementation. + * + * @inode: Not used in this implementaiton. + * @filp: Contains private_data that contains the master, channel + * ID to be released by the PTI device. + * + * Returns: + * always 0 + */ +static int pti_char_release(struct inode *inode, struct file *filp) +{ + pti_release_masterchannel(filp->private_data); + kfree(filp->private_data); + return 0; +} + +/** + * pti_char_write()- Write trace debugging data through the char + * interface to the PTI HW. Part of the misc device implementation. + * + * @filp: Contains private data which is used to obtain + * master, channel write ID. + * @data: trace data to be written. + * @len: # of byte to write. + * @ppose: Not used in this function implementation. + * + * Returns: + * int, # of bytes written + * otherwise, error value + * + * Notes: From side discussions with Alan Cox and experimenting + * with PTI debug HW like Nokia's Fido box and Lauterbach + * devices, 8192 byte write buffer used by USER_COPY_SIZE was + * deemed an appropriate size for this type of usage with + * debugging HW. + */ +static ssize_t pti_char_write(struct file *filp, const char __user *data, + size_t len, loff_t *ppose) +{ + struct pti_masterchannel *mc; + void *kbuf; + const char __user *tmp; + size_t size = USER_COPY_SIZE; + size_t n = 0; + + tmp = data; + mc = filp->private_data; + + kbuf = kmalloc(size, GFP_KERNEL); + if (kbuf == NULL) { + pr_err("%s(%d): buf allocation failed\n", + __func__, __LINE__); + return -ENOMEM; + } + + do { + if (len - n > USER_COPY_SIZE) + size = USER_COPY_SIZE; + else + size = len - n; + + if (copy_from_user(kbuf, tmp, size)) { + kfree(kbuf); + return n ? n : -EFAULT; + } + + pti_write_to_aperture(mc, kbuf, size); + n += size; + tmp += size; + + } while (len > n); + + kfree(kbuf); + return len; +} + +static const struct tty_operations pti_tty_driver_ops = { + .open = pti_tty_driver_open, + .close = pti_tty_driver_close, + .write = pti_tty_driver_write, + .write_room = pti_tty_write_room, + .install = pti_tty_install, + .cleanup = pti_tty_cleanup +}; + +static const struct file_operations pti_char_driver_ops = { + .owner = THIS_MODULE, + .write = pti_char_write, + .open = pti_char_open, + .release = pti_char_release, +}; + +static struct miscdevice pti_char_driver = { + .minor = MISC_DYNAMIC_MINOR, + .name = CHARNAME, + .fops = &pti_char_driver_ops +}; + +/** + * pti_console_write()- Write to the console that has been acquired. + * + * @c: Not used in this implementaiton. + * @buf: Data to be written. + * @len: Length of buf. + */ +static void pti_console_write(struct console *c, const char *buf, unsigned len) +{ + static struct pti_masterchannel mc = {.master = CONSOLE_ID, + .channel = 0}; + + mc.channel = pti_console_channel; + pti_console_channel = (pti_console_channel + 1) & 0x7f; + + pti_write_full_frame_to_aperture(&mc, buf, len); +} + +/** + * pti_console_device()- Return the driver tty structure and set the + * associated index implementation. + * + * @c: Console device of the driver. + * @index: index associated with c. + * + * Returns: + * always value of pti_tty_driver structure when this function + * is called. + */ +static struct tty_driver *pti_console_device(struct console *c, int *index) +{ + *index = c->index; + return pti_tty_driver; +} + +/** + * pti_console_setup()- Initialize console variables used by the driver. + * + * @c: Not used. + * @opts: Not used. + * + * Returns: + * always 0. + */ +static int pti_console_setup(struct console *c, char *opts) +{ + pti_console_channel = 0; + pti_control_channel = 0; + return 0; +} + +/* + * pti_console struct, used to capture OS printk()'s and shift + * out to the PTI device for debugging. This cannot be + * enabled upon boot because of the possibility of eating + * any serial console printk's (race condition discovered). + * The console should be enabled upon when the tty port is + * used for the first time. Since the primary purpose for + * the tty port is to hook up syslog to it, the tty port + * will be open for a really long time. + */ +static struct console pti_console = { + .name = TTYNAME, + .write = pti_console_write, + .device = pti_console_device, + .setup = pti_console_setup, + .flags = CON_PRINTBUFFER, + .index = 0, +}; + +/** + * pti_port_activate()- Used to start/initialize any items upon + * first opening of tty_port(). + * + * @port- The tty port number of the PTI device. + * @tty- The tty struct associated with this device. + * + * Returns: + * always returns 0 + * + * Notes: The primary purpose of the PTI tty port 0 is to hook + * the syslog daemon to it; thus this port will be open for a + * very long time. + */ +static int pti_port_activate(struct tty_port *port, struct tty_struct *tty) +{ + if (port->tty->index == PTITTY_MINOR_START) + console_start(&pti_console); + return 0; +} + +/** + * pti_port_shutdown()- Used to stop/shutdown any items upon the + * last tty port close. + * + * @port- The tty port number of the PTI device. + * + * Notes: The primary purpose of the PTI tty port 0 is to hook + * the syslog daemon to it; thus this port will be open for a + * very long time. + */ +static void pti_port_shutdown(struct tty_port *port) +{ + if (port->tty->index == PTITTY_MINOR_START) + console_stop(&pti_console); +} + +static const struct tty_port_operations tty_port_ops = { + .activate = pti_port_activate, + .shutdown = pti_port_shutdown, +}; + +/* + * Note the _probe() call sets everything up and ties the char and tty + * to successfully detecting the PTI device on the pci bus. + */ + +/** + * pti_pci_probe()- Used to detect pti on the pci bus and set + * things up in the driver. + * + * @pdev- pci_dev struct values for pti. + * @ent- pci_device_id struct for pti driver. + * + * Returns: + * 0 for success + * otherwise, error + */ +static int __devinit pti_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + int retval = -EINVAL; + int pci_bar = 1; + + dev_dbg(&pdev->dev, "%s %s(%d): PTI PCI ID %04x:%04x\n", __FILE__, + __func__, __LINE__, pdev->vendor, pdev->device); + + retval = misc_register(&pti_char_driver); + if (retval) { + pr_err("%s(%d): CHAR registration failed of pti driver\n", + __func__, __LINE__); + pr_err("%s(%d): Error value returned: %d\n", + __func__, __LINE__, retval); + return retval; + } + + retval = pci_enable_device(pdev); + if (retval != 0) { + dev_err(&pdev->dev, + "%s: pci_enable_device() returned error %d\n", + __func__, retval); + return retval; + } + + drv_data = kzalloc(sizeof(*drv_data), GFP_KERNEL); + + if (drv_data == NULL) { + retval = -ENOMEM; + dev_err(&pdev->dev, + "%s(%d): kmalloc() returned NULL memory.\n", + __func__, __LINE__); + return retval; + } + drv_data->pti_addr = pci_resource_start(pdev, pci_bar); + + retval = pci_request_region(pdev, pci_bar, dev_name(&pdev->dev)); + if (retval != 0) { + dev_err(&pdev->dev, + "%s(%d): pci_request_region() returned error %d\n", + __func__, __LINE__, retval); + kfree(drv_data); + return retval; + } + drv_data->aperture_base = drv_data->pti_addr+APERTURE_14; + drv_data->pti_ioaddr = + ioremap_nocache((u32)drv_data->aperture_base, + APERTURE_LEN); + if (!drv_data->pti_ioaddr) { + pci_release_region(pdev, pci_bar); + retval = -ENOMEM; + kfree(drv_data); + return retval; + } + + pci_set_drvdata(pdev, drv_data); + + tty_port_init(&drv_data->port); + drv_data->port.ops = &tty_port_ops; + + tty_register_device(pti_tty_driver, 0, &pdev->dev); + tty_register_device(pti_tty_driver, 1, &pdev->dev); + + register_console(&pti_console); + + return retval; +} + +static struct pci_driver pti_pci_driver = { + .name = PCINAME, + .id_table = pci_ids, + .probe = pti_pci_probe, + .remove = pti_pci_remove, +}; + +/** + * + * pti_init()- Overall entry/init call to the pti driver. + * It starts the registration process with the kernel. + * + * Returns: + * int __init, 0 for success + * otherwise value is an error + * + */ +static int __init pti_init(void) +{ + int retval = -EINVAL; + + /* First register module as tty device */ + + pti_tty_driver = alloc_tty_driver(1); + if (pti_tty_driver == NULL) { + pr_err("%s(%d): Memory allocation failed for ptiTTY driver\n", + __func__, __LINE__); + return -ENOMEM; + } + + pti_tty_driver->owner = THIS_MODULE; + pti_tty_driver->magic = TTY_DRIVER_MAGIC; + pti_tty_driver->driver_name = DRIVERNAME; + pti_tty_driver->name = TTYNAME; + pti_tty_driver->major = 0; + pti_tty_driver->minor_start = PTITTY_MINOR_START; + pti_tty_driver->minor_num = PTITTY_MINOR_NUM; + pti_tty_driver->num = PTITTY_MINOR_NUM; + pti_tty_driver->type = TTY_DRIVER_TYPE_SYSTEM; + pti_tty_driver->subtype = SYSTEM_TYPE_SYSCONS; + pti_tty_driver->flags = TTY_DRIVER_REAL_RAW | + TTY_DRIVER_DYNAMIC_DEV; + pti_tty_driver->init_termios = tty_std_termios; + + tty_set_operations(pti_tty_driver, &pti_tty_driver_ops); + + retval = tty_register_driver(pti_tty_driver); + if (retval) { + pr_err("%s(%d): TTY registration failed of pti driver\n", + __func__, __LINE__); + pr_err("%s(%d): Error value returned: %d\n", + __func__, __LINE__, retval); + + pti_tty_driver = NULL; + return retval; + } + + retval = pci_register_driver(&pti_pci_driver); + + if (retval) { + pr_err("%s(%d): PCI registration failed of pti driver\n", + __func__, __LINE__); + pr_err("%s(%d): Error value returned: %d\n", + __func__, __LINE__, retval); + + tty_unregister_driver(pti_tty_driver); + pr_err("%s(%d): Unregistering TTY part of pti driver\n", + __func__, __LINE__); + pti_tty_driver = NULL; + return retval; + } + + return retval; +} + +/** + * pti_exit()- Unregisters this module as a tty and pci driver. + */ +static void __exit pti_exit(void) +{ + int retval; + + tty_unregister_device(pti_tty_driver, 0); + tty_unregister_device(pti_tty_driver, 1); + + retval = tty_unregister_driver(pti_tty_driver); + if (retval) { + pr_err("%s(%d): TTY unregistration failed of pti driver\n", + __func__, __LINE__); + pr_err("%s(%d): Error value returned: %d\n", + __func__, __LINE__, retval); + } + + pci_unregister_driver(&pti_pci_driver); + + retval = misc_deregister(&pti_char_driver); + if (retval) { + pr_err("%s(%d): CHAR unregistration failed of pti driver\n", + __func__, __LINE__); + pr_err("%s(%d): Error value returned: %d\n", + __func__, __LINE__, retval); + } + + unregister_console(&pti_console); + return; +} + +module_init(pti_init); +module_exit(pti_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Ken Mills, Jay Freyensee"); +MODULE_DESCRIPTION("PTI Driver"); + diff --git a/include/linux/pti.h b/include/linux/pti.h new file mode 100644 index 000000000000..81af667bb2d5 --- /dev/null +++ b/include/linux/pti.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) Intel 2011 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * The PTI (Parallel Trace Interface) driver directs trace data routed from + * various parts in the system out through the Intel Penwell PTI port and + * out of the mobile device for analysis with a debugging tool + * (Lauterbach, Fido). This is part of a solution for the MIPI P1149.7, + * compact JTAG, standard. + * + * This header file will allow other parts of the OS to use the + * interface to write out it's contents for debugging a mobile system. + */ + +#ifndef PTI_H_ +#define PTI_H_ + +/* offset for last dword of any PTI message. Part of MIPI P1149.7 */ +#define PTI_LASTDWORD_DTS 0x30 + +/* basic structure used as a write address to the PTI HW */ +struct pti_masterchannel { + u8 master; + u8 channel; +}; + +/* the following functions are defined in misc/pti.c */ +void pti_writedata(struct pti_masterchannel *mc, u8 *buf, int count); +struct pti_masterchannel *pti_request_masterchannel(u8 type); +void pti_release_masterchannel(struct pti_masterchannel *mc); + +#endif /*PTI_H_*/ -- cgit From ee4f6b4b89665b92ead67deaa2e5d2ffa1af2b5f Mon Sep 17 00:00:00 2001 From: J Freyensee Date: Fri, 6 May 2011 16:56:50 -0700 Subject: n_tracerouter and n_tracesink ldisc additions. The n_tracerouter and n_tracesink line discpline drivers use the Linux tty line discpline framework to route trace data coming from a tty port (say UART for example) to the trace sink line discipline driver and to another tty port(say USB). Those these two line discipline drivers can be used together, independently from pti.c, they are part of the original implementation solution of the MIPI P1149.7, compact JTAG, PTI solution for Intel mobile platforms starting with the Medfield platform. Signed-off-by: J Freyensee Signed-off-by: Greg Kroah-Hartman --- drivers/tty/Kconfig | 31 ++++++ drivers/tty/Makefile | 2 + drivers/tty/n_tracerouter.c | 243 ++++++++++++++++++++++++++++++++++++++++++++ drivers/tty/n_tracesink.c | 238 +++++++++++++++++++++++++++++++++++++++++++ drivers/tty/n_tracesink.h | 36 +++++++ include/linux/tty.h | 2 + 6 files changed, 552 insertions(+) create mode 100644 drivers/tty/n_tracerouter.c create mode 100644 drivers/tty/n_tracesink.c create mode 100644 drivers/tty/n_tracesink.h (limited to 'include/linux') diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig index 3fd7199301b6..bd7cc0527999 100644 --- a/drivers/tty/Kconfig +++ b/drivers/tty/Kconfig @@ -319,3 +319,34 @@ config N_GSM This line discipline provides support for the GSM MUX protocol and presents the mux as a set of 61 individual tty devices. +config TRACE_ROUTER + tristate "Trace data router for MIPI P1149.7 cJTAG standard" + depends on TRACE_SINK + default n + help + The trace router uses the Linux tty line discipline framework to + route trace data coming from a tty port (say UART for example) to + the trace sink line discipline driver and to another tty port (say + USB). This is part of a solution for the MIPI P1149.7, compact JTAG, + standard, which is for debugging mobile devices. The PTI driver in + drivers/misc/pti.c defines the majority of this MIPI solution. + + You should select this driver if the target kernel is meant for + a mobile device containing a modem. Then you will need to select + "Trace data sink for MIPI P1149.7 cJTAG standard" line discipline + driver. + +config TRACE_SINK + tristate "Trace data sink for MIPI P1149.7 cJTAG standard" + default n + help + The trace sink uses the Linux line discipline framework to receive + trace data coming from the trace router line discipline driver + to a user-defined tty port target, like USB. + This is to provide a way to extract modem trace data on + devices that do not have a PTI HW module, or just need modem + trace data to come out of a different HW output port. + This is part of a solution for the P1149.7, compact JTAG, standard. + + If you select this option, you need to select + "Trace data router for MIPI P1149.7 cJTAG standard". diff --git a/drivers/tty/Makefile b/drivers/tty/Makefile index 690522fcb338..ea89b0bd15fe 100644 --- a/drivers/tty/Makefile +++ b/drivers/tty/Makefile @@ -6,6 +6,8 @@ obj-$(CONFIG_AUDIT) += tty_audit.o obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o obj-$(CONFIG_N_HDLC) += n_hdlc.o obj-$(CONFIG_N_GSM) += n_gsm.o +obj-$(CONFIG_TRACE_ROUTER) += n_tracerouter.o +obj-$(CONFIG_TRACE_SINK) += n_tracesink.o obj-$(CONFIG_R3964) += n_r3964.o obj-y += vt/ diff --git a/drivers/tty/n_tracerouter.c b/drivers/tty/n_tracerouter.c new file mode 100644 index 000000000000..1f063d3aa32f --- /dev/null +++ b/drivers/tty/n_tracerouter.c @@ -0,0 +1,243 @@ +/* + * n_tracerouter.c - Trace data router through tty space + * + * Copyright (C) Intel 2011 + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This trace router uses the Linux line discipline framework to route + * trace data coming from a HW Modem to a PTI (Parallel Trace Module) port. + * The solution is not specific to a HW modem and this line disciple can + * be used to route any stream of data in kernel space. + * This is part of a solution for the P1149.7, compact JTAG, standard. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "n_tracesink.h" + +/* + * Other ldisc drivers use 65536 which basically means, + * 'I can always accept 64k' and flow control is off. + * This number is deemed appropriate for this driver. + */ +#define RECEIVE_ROOM 65536 +#define DRIVERNAME "n_tracerouter" + +/* + * struct to hold private configuration data for this ldisc. + * opencalled is used to hold if this ldisc has been opened. + * kref_tty holds the tty reference the ldisc sits on top of. + */ +struct tracerouter_data { + u8 opencalled; + struct tty_struct *kref_tty; +}; +static struct tracerouter_data *tr_data; + +/* lock for when tty reference is being used */ +static DEFINE_MUTEX(routelock); + +/** + * n_tracerouter_open() - Called when a tty is opened by a SW entity. + * @tty: terminal device to the ldisc. + * + * Return: + * 0 for success. + * + * Caveats: This should only be opened one time per SW entity. + */ +static int n_tracerouter_open(struct tty_struct *tty) +{ + int retval = -EEXIST; + + mutex_lock(&routelock); + if (tr_data->opencalled == 0) { + + tr_data->kref_tty = tty_kref_get(tty); + if (tr_data->kref_tty == NULL) { + retval = -EFAULT; + } else { + tr_data->opencalled = 1; + tty->disc_data = tr_data; + tty->receive_room = RECEIVE_ROOM; + tty_driver_flush_buffer(tty); + retval = 0; + } + } + mutex_unlock(&routelock); + return retval; +} + +/** + * n_tracerouter_close() - close connection + * @tty: terminal device to the ldisc. + * + * Called when a software entity wants to close a connection. + */ +static void n_tracerouter_close(struct tty_struct *tty) +{ + struct tracerouter_data *tptr = tty->disc_data; + + mutex_lock(&routelock); + WARN_ON(tptr->kref_tty != tr_data->kref_tty); + tty_driver_flush_buffer(tty); + tty_kref_put(tr_data->kref_tty); + tr_data->kref_tty = NULL; + tr_data->opencalled = 0; + tty->disc_data = NULL; + mutex_unlock(&routelock); +} + +/** + * n_tracerouter_read() - read request from user space + * @tty: terminal device passed into the ldisc. + * @file: pointer to open file object. + * @buf: pointer to the data buffer that gets eventually returned. + * @nr: number of bytes of the data buffer that is returned. + * + * function that allows read() functionality in userspace. By default if this + * is not implemented it returns -EIO. This module is functioning like a + * router via n_tracerouter_receivebuf(), and there is no real requirement + * to implement this function. However, an error return value other than + * -EIO should be used just to show that there was an intent not to have + * this function implemented. Return value based on read() man pages. + * + * Return: + * -EINVAL + */ +static ssize_t n_tracerouter_read(struct tty_struct *tty, struct file *file, + unsigned char __user *buf, size_t nr) { + return -EINVAL; +} + +/** + * n_tracerouter_write() - Function that allows write() in userspace. + * @tty: terminal device passed into the ldisc. + * @file: pointer to open file object. + * @buf: pointer to the data buffer that gets eventually returned. + * @nr: number of bytes of the data buffer that is returned. + * + * By default if this is not implemented, it returns -EIO. + * This should not be implemented, ever, because + * 1. this driver is functioning like a router via + * n_tracerouter_receivebuf() + * 2. No writes to HW will ever go through this line discpline driver. + * However, an error return value other than -EIO should be used + * just to show that there was an intent not to have this function + * implemented. Return value based on write() man pages. + * + * Return: + * -EINVAL + */ +static ssize_t n_tracerouter_write(struct tty_struct *tty, struct file *file, + const unsigned char *buf, size_t nr) { + return -EINVAL; +} + +/** + * n_tracerouter_receivebuf() - Routing function for driver. + * @tty: terminal device passed into the ldisc. It's assumed + * tty will never be NULL. + * @cp: buffer, block of characters to be eventually read by + * someone, somewhere (user read() call or some kernel function). + * @fp: flag buffer. + * @count: number of characters (aka, bytes) in cp. + * + * This function takes the input buffer, cp, and passes it to + * an external API function for processing. + */ +static void n_tracerouter_receivebuf(struct tty_struct *tty, + const unsigned char *cp, + char *fp, int count) +{ + mutex_lock(&routelock); + n_tracesink_datadrain((u8 *) cp, count); + mutex_unlock(&routelock); +} + +/* + * Flush buffer is not impelemented as the ldisc has no internal buffering + * so the tty_driver_flush_buffer() is sufficient for this driver's needs. + */ + +static struct tty_ldisc_ops tty_ptirouter_ldisc = { + .owner = THIS_MODULE, + .magic = TTY_LDISC_MAGIC, + .name = DRIVERNAME, + .open = n_tracerouter_open, + .close = n_tracerouter_close, + .read = n_tracerouter_read, + .write = n_tracerouter_write, + .receive_buf = n_tracerouter_receivebuf +}; + +/** + * n_tracerouter_init - module initialisation + * + * Registers this module as a line discipline driver. + * + * Return: + * 0 for success, any other value error. + */ +static int __init n_tracerouter_init(void) +{ + int retval; + + tr_data = kzalloc(sizeof(struct tracerouter_data), GFP_KERNEL); + if (tr_data == NULL) + return -ENOMEM; + + + /* Note N_TRACEROUTER is defined in linux/tty.h */ + retval = tty_register_ldisc(N_TRACEROUTER, &tty_ptirouter_ldisc); + if (retval < 0) { + pr_err("%s: Registration failed: %d\n", __func__, retval); + kfree(tr_data); + } + return retval; +} + +/** + * n_tracerouter_exit - module unload + * + * Removes this module as a line discipline driver. + */ +static void __exit n_tracerouter_exit(void) +{ + int retval = tty_unregister_ldisc(N_TRACEROUTER); + + if (retval < 0) + pr_err("%s: Unregistration failed: %d\n", __func__, retval); + else + kfree(tr_data); +} + +module_init(n_tracerouter_init); +module_exit(n_tracerouter_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Jay Freyensee"); +MODULE_ALIAS_LDISC(N_TRACEROUTER); +MODULE_DESCRIPTION("Trace router ldisc driver"); diff --git a/drivers/tty/n_tracesink.c b/drivers/tty/n_tracesink.c new file mode 100644 index 000000000000..ddce58b973d2 --- /dev/null +++ b/drivers/tty/n_tracesink.c @@ -0,0 +1,238 @@ +/* + * n_tracesink.c - Trace data router and sink path through tty space. + * + * Copyright (C) Intel 2011 + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * The trace sink uses the Linux line discipline framework to receive + * trace data coming from the PTI source line discipline driver + * to a user-desired tty port, like USB. + * This is to provide a way to extract modem trace data on + * devices that do not have a PTI HW module, or just need modem + * trace data to come out of a different HW output port. + * This is part of a solution for the P1149.7, compact JTAG, standard. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "n_tracesink.h" + +/* + * Other ldisc drivers use 65536 which basically means, + * 'I can always accept 64k' and flow control is off. + * This number is deemed appropriate for this driver. + */ +#define RECEIVE_ROOM 65536 +#define DRIVERNAME "n_tracesink" + +/* + * there is a quirk with this ldisc is he can write data + * to a tty from anyone calling his kernel API, which + * meets customer requirements in the drivers/misc/pti.c + * project. So he needs to know when he can and cannot write when + * the API is called. In theory, the API can be called + * after an init() but before a successful open() which + * would crash the system if tty is not checked. + */ +static struct tty_struct *this_tty; +static DEFINE_MUTEX(writelock); + +/** + * n_tracesink_open() - Called when a tty is opened by a SW entity. + * @tty: terminal device to the ldisc. + * + * Return: + * 0 for success, + * -EFAULT = couldn't get a tty kref n_tracesink will sit + * on top of + * -EEXIST = open() called successfully once and it cannot + * be called again. + * + * Caveats: open() should only be successful the first time a + * SW entity calls it. + */ +static int n_tracesink_open(struct tty_struct *tty) +{ + int retval = -EEXIST; + + mutex_lock(&writelock); + if (this_tty == NULL) { + this_tty = tty_kref_get(tty); + if (this_tty == NULL) { + retval = -EFAULT; + } else { + tty->disc_data = this_tty; + tty_driver_flush_buffer(tty); + retval = 0; + } + } + mutex_unlock(&writelock); + + return retval; +} + +/** + * n_tracesink_close() - close connection + * @tty: terminal device to the ldisc. + * + * Called when a software entity wants to close a connection. + */ +static void n_tracesink_close(struct tty_struct *tty) +{ + mutex_lock(&writelock); + tty_driver_flush_buffer(tty); + tty_kref_put(this_tty); + this_tty = NULL; + tty->disc_data = NULL; + mutex_unlock(&writelock); +} + +/** + * n_tracesink_read() - read request from user space + * @tty: terminal device passed into the ldisc. + * @file: pointer to open file object. + * @buf: pointer to the data buffer that gets eventually returned. + * @nr: number of bytes of the data buffer that is returned. + * + * function that allows read() functionality in userspace. By default if this + * is not implemented it returns -EIO. This module is functioning like a + * router via n_tracesink_receivebuf(), and there is no real requirement + * to implement this function. However, an error return value other than + * -EIO should be used just to show that there was an intent not to have + * this function implemented. Return value based on read() man pages. + * + * Return: + * -EINVAL + */ +static ssize_t n_tracesink_read(struct tty_struct *tty, struct file *file, + unsigned char __user *buf, size_t nr) { + return -EINVAL; +} + +/** + * n_tracesink_write() - Function that allows write() in userspace. + * @tty: terminal device passed into the ldisc. + * @file: pointer to open file object. + * @buf: pointer to the data buffer that gets eventually returned. + * @nr: number of bytes of the data buffer that is returned. + * + * By default if this is not implemented, it returns -EIO. + * This should not be implemented, ever, because + * 1. this driver is functioning like a router via + * n_tracesink_receivebuf() + * 2. No writes to HW will ever go through this line discpline driver. + * However, an error return value other than -EIO should be used + * just to show that there was an intent not to have this function + * implemented. Return value based on write() man pages. + * + * Return: + * -EINVAL + */ +static ssize_t n_tracesink_write(struct tty_struct *tty, struct file *file, + const unsigned char *buf, size_t nr) { + return -EINVAL; +} + +/** + * n_tracesink_datadrain() - Kernel API function used to route + * trace debugging data to user-defined + * port like USB. + * + * @buf: Trace debuging data buffer to write to tty target + * port. Null value will return with no write occurring. + * @count: Size of buf. Value of 0 or a negative number will + * return with no write occuring. + * + * Caveat: If this line discipline does not set the tty it sits + * on top of via an open() call, this API function will not + * call the tty's write() call because it will have no pointer + * to call the write(). + */ +void n_tracesink_datadrain(u8 *buf, int count) +{ + mutex_lock(&writelock); + + if ((buf != NULL) && (count > 0) && (this_tty != NULL)) + this_tty->ops->write(this_tty, buf, count); + + mutex_unlock(&writelock); +} +EXPORT_SYMBOL_GPL(n_tracesink_datadrain); + +/* + * Flush buffer is not impelemented as the ldisc has no internal buffering + * so the tty_driver_flush_buffer() is sufficient for this driver's needs. + */ + +/* + * tty_ldisc function operations for this driver. + */ +static struct tty_ldisc_ops tty_n_tracesink = { + .owner = THIS_MODULE, + .magic = TTY_LDISC_MAGIC, + .name = DRIVERNAME, + .open = n_tracesink_open, + .close = n_tracesink_close, + .read = n_tracesink_read, + .write = n_tracesink_write +}; + +/** + * n_tracesink_init- module initialisation + * + * Registers this module as a line discipline driver. + * + * Return: + * 0 for success, any other value error. + */ +static int __init n_tracesink_init(void) +{ + /* Note N_TRACESINK is defined in linux/tty.h */ + int retval = tty_register_ldisc(N_TRACESINK, &tty_n_tracesink); + + if (retval < 0) + pr_err("%s: Registration failed: %d\n", __func__, retval); + + return retval; +} + +/** + * n_tracesink_exit - module unload + * + * Removes this module as a line discipline driver. + */ +static void __exit n_tracesink_exit(void) +{ + int retval = tty_unregister_ldisc(N_TRACESINK); + + if (retval < 0) + pr_err("%s: Unregistration failed: %d\n", __func__, retval); +} + +module_init(n_tracesink_init); +module_exit(n_tracesink_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Jay Freyensee"); +MODULE_ALIAS_LDISC(N_TRACESINK); +MODULE_DESCRIPTION("Trace sink ldisc driver"); diff --git a/drivers/tty/n_tracesink.h b/drivers/tty/n_tracesink.h new file mode 100644 index 000000000000..a68bb44f1ef5 --- /dev/null +++ b/drivers/tty/n_tracesink.h @@ -0,0 +1,36 @@ +/* + * n_tracesink.h - Kernel driver API to route trace data in kernel space. + * + * Copyright (C) Intel 2011 + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * The PTI (Parallel Trace Interface) driver directs trace data routed from + * various parts in the system out through the Intel Penwell PTI port and + * out of the mobile device for analysis with a debugging tool + * (Lauterbach, Fido). This is part of a solution for the MIPI P1149.7, + * compact JTAG, standard. + * + * This header file is used by n_tracerouter to be able to send the + * data of it's tty port to the tty port this module sits. This + * mechanism can also be used independent of the PTI module. + * + */ + +#ifndef N_TRACESINK_H_ +#define N_TRACESINK_H_ + +void n_tracesink_datadrain(u8 *buf, int count); + +#endif diff --git a/include/linux/tty.h b/include/linux/tty.h index 4db4ca79f895..d6f05292e456 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -50,6 +50,8 @@ #define N_CAIF 20 /* CAIF protocol for talking to modems */ #define N_GSM0710 21 /* GSM 0710 Mux */ #define N_TI_WL 22 /* for TI's WL BT, FM, GPS combo chips */ +#define N_TRACESINK 23 /* Trace data routing for MIPI P1149.7 */ +#define N_TRACEROUTER 24 /* Trace data routing for MIPI P1149.7 */ /* * This character is the same as _POSIX_VDISABLE: it cannot be used as -- cgit From 8c414ff3f4dcdde228c6a668385218290d73a265 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 8 May 2011 18:50:20 +0100 Subject: clocksource: convert footbridge to generic i8253 clocksource Convert the footbridge isa-timer code to use generic i8253 clocksource. Acked-by: John Stultz Acked-by: Thomas Gleixner Signed-off-by: Russell King --- arch/arm/include/asm/i8253.h | 15 ++++++++++++ arch/arm/mach-footbridge/Kconfig | 2 ++ arch/arm/mach-footbridge/isa-timer.c | 45 ++++-------------------------------- include/linux/clocksource.h | 2 ++ 4 files changed, 23 insertions(+), 41 deletions(-) create mode 100644 arch/arm/include/asm/i8253.h (limited to 'include/linux') diff --git a/arch/arm/include/asm/i8253.h b/arch/arm/include/asm/i8253.h new file mode 100644 index 000000000000..70656b69d5ce --- /dev/null +++ b/arch/arm/include/asm/i8253.h @@ -0,0 +1,15 @@ +#ifndef __ASMARM_I8253_H +#define __ASMARM_I8253_H + +/* i8253A PIT registers */ +#define PIT_MODE 0x43 +#define PIT_CH0 0x40 + +#define PIT_LATCH ((PIT_TICK_RATE + HZ / 2) / HZ) + +extern raw_spinlock_t i8253_lock; + +#define outb_pit outb_p +#define inb_pit inb_p + +#endif diff --git a/arch/arm/mach-footbridge/Kconfig b/arch/arm/mach-footbridge/Kconfig index bdd257921cfb..46adca068f2c 100644 --- a/arch/arm/mach-footbridge/Kconfig +++ b/arch/arm/mach-footbridge/Kconfig @@ -4,6 +4,7 @@ menu "Footbridge Implementations" config ARCH_CATS bool "CATS" + select CLKSRC_I8253 select FOOTBRIDGE_HOST select ISA select ISA_DMA @@ -59,6 +60,7 @@ config ARCH_EBSA285_HOST config ARCH_NETWINDER bool "NetWinder" + select CLKSRC_I8253 select FOOTBRIDGE_HOST select ISA select ISA_DMA diff --git a/arch/arm/mach-footbridge/isa-timer.c b/arch/arm/mach-footbridge/isa-timer.c index 441c6ce0d555..7020f1a3feca 100644 --- a/arch/arm/mach-footbridge/isa-timer.c +++ b/arch/arm/mach-footbridge/isa-timer.c @@ -10,53 +10,16 @@ #include #include #include +#include #include #include - +#include #include #include "common.h" -#define PIT_MODE 0x43 -#define PIT_CH0 0x40 - -#define PIT_LATCH ((PIT_TICK_RATE + HZ / 2) / HZ) - -static cycle_t pit_read(struct clocksource *cs) -{ - unsigned long flags; - static int old_count; - static u32 old_jifs; - int count; - u32 jifs; - - raw_local_irq_save(flags); - - jifs = jiffies; - outb_p(0x00, PIT_MODE); /* latch the count */ - count = inb_p(PIT_CH0); /* read the latched count */ - count |= inb_p(PIT_CH0) << 8; - - if (count > old_count && jifs == old_jifs) - count = old_count; - - old_count = count; - old_jifs = jifs; - - raw_local_irq_restore(flags); - - count = (PIT_LATCH - 1) - count; - - return (cycle_t)(jifs * PIT_LATCH) + count; -} - -static struct clocksource pit_cs = { - .name = "pit", - .rating = 110, - .read = pit_read, - .mask = CLOCKSOURCE_MASK(32), -}; +DEFINE_RAW_SPINLOCK(i8253_lock); static void pit_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) @@ -121,7 +84,7 @@ static void __init isa_timer_init(void) pit_ce.max_delta_ns = clockevent_delta2ns(0x7fff, &pit_ce); pit_ce.min_delta_ns = clockevent_delta2ns(0x000f, &pit_ce); - clocksource_register_hz(&pit_cs, PIT_TICK_RATE); + clocksource_i8253_init(); setup_irq(pit_ce.irq, &pit_timer_irq); clockevents_register_device(&pit_ce); diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h index c37b21ad5a3b..f13469b3df86 100644 --- a/include/linux/clocksource.h +++ b/include/linux/clocksource.h @@ -341,4 +341,6 @@ static inline void update_vsyscall_tz(void) extern void timekeeping_notify(struct clocksource *clock); +extern int clocksource_i8253_init(void); + #endif /* _LINUX_CLOCKSOURCE_H */ -- cgit From 9281b16caac1276817b77033c5b8a1f5ca30102c Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Sun, 24 Apr 2011 14:30:14 -0500 Subject: pata_cm64x: fix boot crash on parisc The old IDE cmd64x checks the status of the CNTRL register to see if the ports are enabled before probing them. pata_cmd64x doesn't do this, which causes a HPMC on parisc when it tries to poke at the secondary port because apparently the BAR isn't wired up (and a non-responding piece of memory causes a HPMC). Fix this by porting the CNTRL register port detection logic from IDE cmd64x. In addition, following converns from Alan Cox, add a check to see if a mobility electronics bridge is the immediate parent and forgo the check if it is (prevents problems on hotplug controllers). Signed-off-by: James Bottomley Signed-off-by: Jeff Garzik --- drivers/ata/pata_cmd64x.c | 42 ++++++++++++++++++++++++++++++++++++++---- include/linux/pci_ids.h | 2 ++ 2 files changed, 40 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c index 905ff76d3cbb..7bafc16cf5e0 100644 --- a/drivers/ata/pata_cmd64x.c +++ b/drivers/ata/pata_cmd64x.c @@ -41,6 +41,9 @@ enum { CFR = 0x50, CFR_INTR_CH0 = 0x04, + CNTRL = 0x51, + CNTRL_CH0 = 0x04, + CNTRL_CH1 = 0x08, CMDTIM = 0x52, ARTTIM0 = 0x53, DRWTIM0 = 0x54, @@ -328,9 +331,19 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .port_ops = &cmd648_port_ops } }; - const struct ata_port_info *ppi[] = { &cmd_info[id->driver_data], NULL }; - u8 mrdmode; + const struct ata_port_info *ppi[] = { + &cmd_info[id->driver_data], + &cmd_info[id->driver_data], + NULL + }; + u8 mrdmode, reg; int rc; + struct pci_dev *bridge = pdev->bus->self; + /* mobility split bridges don't report enabled ports correctly */ + int port_ok = !(bridge && bridge->vendor == + PCI_VENDOR_ID_MOBILITY_ELECTRONICS); + /* all (with exceptions below) apart from 643 have CNTRL_CH0 bit */ + int cntrl_ch0_ok = (id->driver_data != 0); rc = pcim_enable_device(pdev); if (rc) @@ -341,11 +354,18 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) if (pdev->device == PCI_DEVICE_ID_CMD_646) { /* Does UDMA work ? */ - if (pdev->revision > 4) + if (pdev->revision > 4) { ppi[0] = &cmd_info[2]; + ppi[1] = &cmd_info[2]; + } /* Early rev with other problems ? */ - else if (pdev->revision == 1) + else if (pdev->revision == 1) { ppi[0] = &cmd_info[3]; + ppi[1] = &cmd_info[3]; + } + /* revs 1,2 have no CNTRL_CH0 */ + if (pdev->revision < 3) + cntrl_ch0_ok = 0; } pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64); @@ -354,6 +374,20 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) mrdmode |= 0x02; /* Memory read line enable */ pci_write_config_byte(pdev, MRDMODE, mrdmode); + /* check for enabled ports */ + pci_read_config_byte(pdev, CNTRL, ®); + if (!port_ok) + dev_printk(KERN_NOTICE, &pdev->dev, "Mobility Bridge detected, ignoring CNTRL port enable/disable\n"); + if (port_ok && cntrl_ch0_ok && !(reg & CNTRL_CH0)) { + dev_printk(KERN_NOTICE, &pdev->dev, "Primary port is disabled\n"); + ppi[0] = &ata_dummy_port_info; + + } + if (port_ok && !(reg & CNTRL_CH1)) { + dev_printk(KERN_NOTICE, &pdev->dev, "Secondary port is disabled\n"); + ppi[1] = &ata_dummy_port_info; + } + /* Force PIO 0 here.. */ /* PPC specific fixup copied from old driver */ diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 8abe8d78c4bf..8652a4fa3fe2 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -608,6 +608,8 @@ #define PCI_DEVICE_ID_MATROX_G550 0x2527 #define PCI_DEVICE_ID_MATROX_VIA 0x4536 +#define PCI_VENDOR_ID_MOBILITY_ELECTRONICS 0x14f2 + #define PCI_VENDOR_ID_CT 0x102c #define PCI_DEVICE_ID_CT_69000 0x00c0 #define PCI_DEVICE_ID_CT_65545 0x00d8 -- cgit From e1e8fb6a1ff3f9487e03a4cbf85b81d1316068ce Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Fri, 15 Apr 2011 03:02:49 +0000 Subject: fs: remove FS_COW_FL FS_COW_FL and FS_NOCOW_FL were newly introduced to control per file COW in btrfs, but FS_NOCOW_FL is sufficient. The fact is we don't have corresponding BTRFS_INODE_COW flag. COW is default, and FS_NOCOW_FL can be used to switch off COW for a single file. If we mount btrfs with nodatacow, a newly created file will be set with the FS_NOCOW_FL flag. So to turn on COW for it, we can just clear the FS_NOCOW_FL flag. Signed-off-by: Li Zefan Signed-off-by: Chris Mason --- fs/btrfs/ioctl.c | 15 ++++++--------- include/linux/fs.h | 1 - 2 files changed, 6 insertions(+), 10 deletions(-) (limited to 'include/linux') diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index f580a3a5d2fc..3240dd90da42 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -144,16 +144,13 @@ static int check_flags(unsigned int flags) if (flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | \ FS_NOATIME_FL | FS_NODUMP_FL | \ FS_SYNC_FL | FS_DIRSYNC_FL | \ - FS_NOCOMP_FL | FS_COMPR_FL | \ - FS_NOCOW_FL | FS_COW_FL)) + FS_NOCOMP_FL | FS_COMPR_FL | + FS_NOCOW_FL)) return -EOPNOTSUPP; if ((flags & FS_NOCOMP_FL) && (flags & FS_COMPR_FL)) return -EINVAL; - if ((flags & FS_NOCOW_FL) && (flags & FS_COW_FL)) - return -EINVAL; - return 0; } @@ -218,6 +215,10 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg) ip->flags |= BTRFS_INODE_DIRSYNC; else ip->flags &= ~BTRFS_INODE_DIRSYNC; + if (flags & FS_NOCOW_FL) + ip->flags |= BTRFS_INODE_NODATACOW; + else + ip->flags &= ~BTRFS_INODE_NODATACOW; /* * The COMPRESS flag can only be changed by users, while the NOCOMPRESS @@ -231,10 +232,6 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg) ip->flags |= BTRFS_INODE_COMPRESS; ip->flags &= ~BTRFS_INODE_NOCOMPRESS; } - if (flags & FS_NOCOW_FL) - ip->flags |= BTRFS_INODE_NODATACOW; - else if (flags & FS_COW_FL) - ip->flags &= ~BTRFS_INODE_NODATACOW; trans = btrfs_join_transaction(root, 1); BUG_ON(IS_ERR(trans)); diff --git a/include/linux/fs.h b/include/linux/fs.h index de9dd8119b71..56a41412903d 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -365,7 +365,6 @@ struct inodes_stat_t { #define FS_EXTENT_FL 0x00080000 /* Extents */ #define FS_DIRECTIO_FL 0x00100000 /* Use direct i/o */ #define FS_NOCOW_FL 0x00800000 /* Do not cow file */ -#define FS_COW_FL 0x02000000 /* Cow file */ #define FS_RESERVED_FL 0x80000000 /* reserved for ext2 lib */ #define FS_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */ -- cgit From 4c3b512c6b054e8c0bf14b1d61b20d4569de0a21 Mon Sep 17 00:00:00 2001 From: Dave Martin Date: Mon, 18 Apr 2011 14:48:22 +0100 Subject: ARM: 6882/1: ELF: Define new core note type for VFP registers The VFP registers are not currently included in coredumps, and there's no existing note type where they can sensibly be included, so this patch defines a dedicated note type for them. Signed-off-by: Dave Martin Acked-by: Will Deacon Signed-off-by: Russell King --- include/linux/elf.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/elf.h b/include/linux/elf.h index 4d608014753a..110821cb6ea5 100644 --- a/include/linux/elf.h +++ b/include/linux/elf.h @@ -395,6 +395,7 @@ typedef struct elf64_shdr { #define NT_S390_CTRS 0x304 /* s390 control registers */ #define NT_S390_PREFIX 0x305 /* s390 prefix register */ #define NT_S390_LAST_BREAK 0x306 /* s390 breaking event address */ +#define NT_ARM_VFP 0x400 /* ARM VFP/NEON registers */ /* Note header in a PT_NOTE section */ -- cgit From 86f315bbb2374f1f077500ad131dd9b71856e697 Mon Sep 17 00:00:00 2001 From: Chris Ball Date: Mon, 16 May 2011 11:32:26 -0400 Subject: Revert "mmc: fix a race between card-detect rescan and clock-gate work instances" This reverts commit 26fc8775b51484d8c0a671198639c6d5ae60533e, which has been reported to cause boot/resume-time crashes for some users: https://bbs.archlinux.org/viewtopic.php?id=118751. Signed-off-by: Chris Ball Cc: --- drivers/mmc/core/host.c | 9 +++++---- include/linux/mmc/host.h | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 2b200c1cfbba..461e6a17fb90 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c @@ -94,7 +94,7 @@ static void mmc_host_clk_gate_delayed(struct mmc_host *host) spin_unlock_irqrestore(&host->clk_lock, flags); return; } - mmc_claim_host(host); + mutex_lock(&host->clk_gate_mutex); spin_lock_irqsave(&host->clk_lock, flags); if (!host->clk_requests) { spin_unlock_irqrestore(&host->clk_lock, flags); @@ -104,7 +104,7 @@ static void mmc_host_clk_gate_delayed(struct mmc_host *host) pr_debug("%s: gated MCI clock\n", mmc_hostname(host)); } spin_unlock_irqrestore(&host->clk_lock, flags); - mmc_release_host(host); + mutex_unlock(&host->clk_gate_mutex); } /* @@ -130,7 +130,7 @@ void mmc_host_clk_ungate(struct mmc_host *host) { unsigned long flags; - mmc_claim_host(host); + mutex_lock(&host->clk_gate_mutex); spin_lock_irqsave(&host->clk_lock, flags); if (host->clk_gated) { spin_unlock_irqrestore(&host->clk_lock, flags); @@ -140,7 +140,7 @@ void mmc_host_clk_ungate(struct mmc_host *host) } host->clk_requests++; spin_unlock_irqrestore(&host->clk_lock, flags); - mmc_release_host(host); + mutex_unlock(&host->clk_gate_mutex); } /** @@ -215,6 +215,7 @@ static inline void mmc_host_clk_init(struct mmc_host *host) host->clk_gated = false; INIT_WORK(&host->clk_gate_work, mmc_host_clk_gate_work); spin_lock_init(&host->clk_lock); + mutex_init(&host->clk_gate_mutex); } /** diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index eb792cb6d745..bcb793ec7374 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -183,6 +183,7 @@ struct mmc_host { struct work_struct clk_gate_work; /* delayed clock gate */ unsigned int clk_old; /* old clock value cache */ spinlock_t clk_lock; /* lock for clk fields */ + struct mutex clk_gate_mutex; /* mutex for clock gating */ #endif /* host specific block data */ -- cgit From 8d38d74b648513dd8ed8bd2b67d899208ef4e09e Mon Sep 17 00:00:00 2001 From: Chen Gong Date: Mon, 16 May 2011 10:58:57 -0700 Subject: pstore: fix one type of return value in pstore the return type of function _read_ in pstore is size_t, but in the callback function of _read_, the logic doesn't consider it too much, which means if negative value (assuming error here) is returned, it will be converted to positive because of type casting. ssize_t is enough for this function. Signed-off-by: Chen Gong Signed-off-by: Tony Luck --- drivers/acpi/apei/erst.c | 4 ++-- fs/pstore/platform.c | 4 ++-- include/linux/pstore.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c index d6cb0ff6988e..d5a89d067f98 100644 --- a/drivers/acpi/apei/erst.c +++ b/drivers/acpi/apei/erst.c @@ -929,7 +929,7 @@ static int erst_check_table(struct acpi_table_erst *erst_tab) return 0; } -static size_t erst_reader(u64 *id, enum pstore_type_id *type, +static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, struct timespec *time); static u64 erst_writer(enum pstore_type_id type, size_t size); @@ -957,7 +957,7 @@ struct cper_pstore_record { char data[]; } __packed; -static size_t erst_reader(u64 *id, enum pstore_type_id *type, +static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, struct timespec *time) { int rc; diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c index f835a25625ff..912403c2a93d 100644 --- a/fs/pstore/platform.c +++ b/fs/pstore/platform.c @@ -152,7 +152,7 @@ EXPORT_SYMBOL_GPL(pstore_register); void pstore_get_records(void) { struct pstore_info *psi = psinfo; - size_t size; + ssize_t size; u64 id; enum pstore_type_id type; struct timespec time; @@ -163,7 +163,7 @@ void pstore_get_records(void) mutex_lock(&psinfo->buf_mutex); while ((size = psi->read(&id, &type, &time)) > 0) { - if (pstore_mkfile(type, psi->name, id, psi->buf, size, + if (pstore_mkfile(type, psi->name, id, psi->buf, (size_t)size, time, psi->erase)) failed++; } diff --git a/include/linux/pstore.h b/include/linux/pstore.h index 41977737bb7d..14ce2f5d08af 100644 --- a/include/linux/pstore.h +++ b/include/linux/pstore.h @@ -35,7 +35,7 @@ struct pstore_info { struct mutex buf_mutex; /* serialize access to 'buf' */ char *buf; size_t bufsize; - size_t (*read)(u64 *id, enum pstore_type_id *type, + ssize_t (*read)(u64 *id, enum pstore_type_id *type, struct timespec *time); u64 (*write)(enum pstore_type_id type, size_t size); int (*erase)(u64 id); -- cgit From 06cf91b4b4aafa50ee0a94c81d2c6922a18af242 Mon Sep 17 00:00:00 2001 From: Chen Gong Date: Mon, 16 May 2011 11:00:27 -0700 Subject: pstore: fix pstore filesystem mount/remount issue Currently after mount/remount operation on pstore filesystem, the content on pstore will be lost. It is because current ERST implementation doesn't support multi-user usage, which moves internal pointer to the end after accessing it. Adding multi-user support for pstore usage. Signed-off-by: Chen Gong Signed-off-by: Tony Luck --- drivers/acpi/apei/erst.c | 48 +++++++++++++++++++++++++++++++++++------------- fs/pstore/platform.c | 8 +++++++- include/linux/pstore.h | 2 ++ 3 files changed, 44 insertions(+), 14 deletions(-) (limited to 'include/linux') diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c index d5a89d067f98..ddb68c4f8d3e 100644 --- a/drivers/acpi/apei/erst.c +++ b/drivers/acpi/apei/erst.c @@ -929,6 +929,8 @@ static int erst_check_table(struct acpi_table_erst *erst_tab) return 0; } +static int erst_open_pstore(struct pstore_info *psi); +static int erst_close_pstore(struct pstore_info *psi); static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, struct timespec *time); static u64 erst_writer(enum pstore_type_id type, size_t size); @@ -936,6 +938,8 @@ static u64 erst_writer(enum pstore_type_id type, size_t size); static struct pstore_info erst_info = { .owner = THIS_MODULE, .name = "erst", + .open = erst_open_pstore, + .close = erst_close_pstore, .read = erst_reader, .write = erst_writer, .erase = erst_clear @@ -957,12 +961,32 @@ struct cper_pstore_record { char data[]; } __packed; +static int reader_pos; + +static int erst_open_pstore(struct pstore_info *psi) +{ + int rc; + + if (erst_disable) + return -ENODEV; + + rc = erst_get_record_id_begin(&reader_pos); + + return rc; +} + +static int erst_close_pstore(struct pstore_info *psi) +{ + erst_get_record_id_end(); + + return 0; +} + static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, struct timespec *time) { int rc; - ssize_t len; - unsigned long flags; + ssize_t len = 0; u64 record_id; struct cper_pstore_record *rcd = (struct cper_pstore_record *) (erst_info.buf - sizeof(*rcd)); @@ -970,24 +994,21 @@ static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, if (erst_disable) return -ENODEV; - raw_spin_lock_irqsave(&erst_lock, flags); skip: - rc = __erst_get_next_record_id(&record_id); - if (rc) { - raw_spin_unlock_irqrestore(&erst_lock, flags); - return rc; - } + rc = erst_get_record_id_next(&reader_pos, &record_id); + if (rc) + goto out; + /* no more record */ if (record_id == APEI_ERST_INVALID_RECORD_ID) { - raw_spin_unlock_irqrestore(&erst_lock, flags); - return 0; + rc = -1; + goto out; } - len = __erst_read(record_id, &rcd->hdr, sizeof(*rcd) + + len = erst_read(record_id, &rcd->hdr, sizeof(*rcd) + erst_erange.size); if (uuid_le_cmp(rcd->hdr.creator_id, CPER_CREATOR_PSTORE) != 0) goto skip; - raw_spin_unlock_irqrestore(&erst_lock, flags); *id = record_id; if (uuid_le_cmp(rcd->sec_hdr.section_type, @@ -1005,7 +1026,8 @@ skip: time->tv_sec = 0; time->tv_nsec = 0; - return len - sizeof(*rcd); +out: + return (rc < 0) ? rc : (len - sizeof(*rcd)); } static u64 erst_writer(enum pstore_type_id type, size_t size) diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c index 912403c2a93d..f2c3ff20ea68 100644 --- a/fs/pstore/platform.c +++ b/fs/pstore/platform.c @@ -156,17 +156,23 @@ void pstore_get_records(void) u64 id; enum pstore_type_id type; struct timespec time; - int failed = 0; + int failed = 0, rc; if (!psi) return; mutex_lock(&psinfo->buf_mutex); + rc = psi->open(psi); + if (rc) + goto out; + while ((size = psi->read(&id, &type, &time)) > 0) { if (pstore_mkfile(type, psi->name, id, psi->buf, (size_t)size, time, psi->erase)) failed++; } + psi->close(psi); +out: mutex_unlock(&psinfo->buf_mutex); if (failed) diff --git a/include/linux/pstore.h b/include/linux/pstore.h index 14ce2f5d08af..2455ef2683f0 100644 --- a/include/linux/pstore.h +++ b/include/linux/pstore.h @@ -35,6 +35,8 @@ struct pstore_info { struct mutex buf_mutex; /* serialize access to 'buf' */ char *buf; size_t bufsize; + int (*open)(struct pstore_info *psi); + int (*close)(struct pstore_info *psi); ssize_t (*read)(u64 *id, enum pstore_type_id *type, struct timespec *time); u64 (*write)(enum pstore_type_id type, size_t size); -- cgit From 7527a782e187d1214a5b3dc2897ce441033bb4ef Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 13 May 2011 10:58:57 +0200 Subject: cfg80211: advertise possible interface combinations Add the ability to advertise interface combinations in nl80211. This allows the driver to indicate what the combinations are that it supports. "Combinations" of just a single interface are implicit, as previously. Note that cfg80211 will enforce that the restrictions are met, but not for all drivers yet (once all drivers are updated, we can remove the flag and enforce for all). When no combinations are actually supported, an empty list will be exported so that userspace can know if the kernel exported this info or not (although it isn't clear to me what tools using the info should do if the kernel didn't export it). Since some interface types are purely virtual/software and don't fit the restrictions, those are exposed in a new list of pure SW types, not subject to restrictions. This mainly exists to handle AP-VLAN and monitor interfaces in mac80211. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/linux/nl80211.h | 122 +++++++++++++++++++++++++++++++++++++++++++++++- include/net/cfg80211.h | 88 ++++++++++++++++++++++++++++++++++ net/mac80211/main.c | 16 +++++-- net/wireless/core.c | 69 +++++++++++++++++++++++++++ net/wireless/core.h | 11 +++++ net/wireless/nl80211.c | 105 +++++++++++++++++++++++++++++++++++------ net/wireless/util.c | 80 +++++++++++++++++++++++++++++++ 7 files changed, 472 insertions(+), 19 deletions(-) (limited to 'include/linux') diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 281a2bb6a6ec..0ea497cb607c 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -76,6 +76,39 @@ * below. */ +/** + * DOC: Virtual interface / concurrency capabilities + * + * Some devices are able to operate with virtual MACs, they can have + * more than one virtual interface. The capability handling for this + * is a bit complex though, as there may be a number of restrictions + * on the types of concurrency that are supported. + * + * To start with, each device supports the interface types listed in + * the %NL80211_ATTR_SUPPORTED_IFTYPES attribute, but by listing the + * types there no concurrency is implied. + * + * Once concurrency is desired, more attributes must be observed: + * To start with, since some interface types are purely managed in + * software, like the AP-VLAN type in mac80211 for example, there's + * an additional list of these, they can be added at any time and + * are only restricted by some semantic restrictions (e.g. AP-VLAN + * cannot be added without a corresponding AP interface). This list + * is exported in the %NL80211_ATTR_SOFTWARE_IFTYPES attribute. + * + * Further, the list of supported combinations is exported. This is + * in the %NL80211_ATTR_INTERFACE_COMBINATIONS attribute. Basically, + * it exports a list of "groups", and at any point in time the + * interfaces that are currently active must fall into any one of + * the advertised groups. Within each group, there are restrictions + * on the number of interfaces of different types that are supported + * and also the number of different channels, along with potentially + * some other restrictions. See &enum nl80211_if_combination_attrs. + * + * All together, these attributes define the concurrency of virtual + * interfaces that a given device supports. + */ + /** * enum nl80211_commands - supported nl80211 commands * @@ -954,6 +987,14 @@ enum nl80211_commands { * @NL80211_ATTR_SCHED_SCAN_INTERVAL: Interval between scheduled scan * cycles, in msecs. * + * @NL80211_ATTR_INTERFACE_COMBINATIONS: Nested attribute listing the supported + * interface combinations. In each nested item, it contains attributes + * defined in &enum nl80211_if_combination_attrs. + * @NL80211_ATTR_SOFTWARE_IFTYPES: Nested attribute (just like + * %NL80211_ATTR_SUPPORTED_IFTYPES) containing the interface types that + * are managed in software: interfaces of these types aren't subject to + * any restrictions in their number or combinations. + * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use */ @@ -1149,6 +1190,9 @@ enum nl80211_attrs { NL80211_ATTR_SCHED_SCAN_INTERVAL, + NL80211_ATTR_INTERFACE_COMBINATIONS, + NL80211_ATTR_SOFTWARE_IFTYPES, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, @@ -1201,7 +1245,9 @@ enum nl80211_attrs { * @NL80211_IFTYPE_ADHOC: independent BSS member * @NL80211_IFTYPE_STATION: managed BSS member * @NL80211_IFTYPE_AP: access point - * @NL80211_IFTYPE_AP_VLAN: VLAN interface for access points + * @NL80211_IFTYPE_AP_VLAN: VLAN interface for access points; VLAN interfaces + * are a bit special in that they must always be tied to a pre-existing + * AP type interface. * @NL80211_IFTYPE_WDS: wireless distribution interface * @NL80211_IFTYPE_MONITOR: monitor interface receiving all frames * @NL80211_IFTYPE_MESH_POINT: mesh point @@ -2206,4 +2252,78 @@ enum nl80211_wowlan_triggers { MAX_NL80211_WOWLAN_TRIG = NUM_NL80211_WOWLAN_TRIG - 1 }; +/** + * enum nl80211_iface_limit_attrs - limit attributes + * @NL80211_IFACE_LIMIT_UNSPEC: (reserved) + * @NL80211_IFACE_LIMIT_MAX: maximum number of interfaces that + * can be chosen from this set of interface types (u32) + * @NL80211_IFACE_LIMIT_TYPES: nested attribute containing a + * flag attribute for each interface type in this set + * @NUM_NL80211_IFACE_LIMIT: number of attributes + * @MAX_NL80211_IFACE_LIMIT: highest attribute number + */ +enum nl80211_iface_limit_attrs { + NL80211_IFACE_LIMIT_UNSPEC, + NL80211_IFACE_LIMIT_MAX, + NL80211_IFACE_LIMIT_TYPES, + + /* keep last */ + NUM_NL80211_IFACE_LIMIT, + MAX_NL80211_IFACE_LIMIT = NUM_NL80211_IFACE_LIMIT - 1 +}; + +/** + * enum nl80211_if_combination_attrs -- interface combination attributes + * + * @NL80211_IFACE_COMB_UNSPEC: (reserved) + * @NL80211_IFACE_COMB_LIMITS: Nested attributes containing the limits + * for given interface types, see &enum nl80211_iface_limit_attrs. + * @NL80211_IFACE_COMB_MAXNUM: u32 attribute giving the total number of + * interfaces that can be created in this group. This number doesn't + * apply to interfaces purely managed in software, which are listed + * in a separate attribute %NL80211_ATTR_INTERFACES_SOFTWARE. + * @NL80211_IFACE_COMB_STA_AP_BI_MATCH: flag attribute specifying that + * beacon intervals within this group must be all the same even for + * infrastructure and AP/GO combinations, i.e. the GO(s) must adopt + * the infrastructure network's beacon interval. + * @NL80211_IFACE_COMB_NUM_CHANNELS: u32 attribute specifying how many + * different channels may be used within this group. + * @NUM_NL80211_IFACE_COMB: number of attributes + * @MAX_NL80211_IFACE_COMB: highest attribute number + * + * Examples: + * limits = [ #{STA} <= 1, #{AP} <= 1 ], matching BI, channels = 1, max = 2 + * => allows an AP and a STA that must match BIs + * + * numbers = [ #{AP, P2P-GO} <= 8 ], channels = 1, max = 8 + * => allows 8 of AP/GO + * + * numbers = [ #{STA} <= 2 ], channels = 2, max = 2 + * => allows two STAs on different channels + * + * numbers = [ #{STA} <= 1, #{P2P-client,P2P-GO} <= 3 ], max = 4 + * => allows a STA plus three P2P interfaces + * + * The list of these four possiblities could completely be contained + * within the %NL80211_ATTR_INTERFACE_COMBINATIONS attribute to indicate + * that any of these groups must match. + * + * "Combinations" of just a single interface will not be listed here, + * a single interface of any valid interface type is assumed to always + * be possible by itself. This means that implicitly, for each valid + * interface type, the following group always exists: + * numbers = [ #{} <= 1 ], channels = 1, max = 1 + */ +enum nl80211_if_combination_attrs { + NL80211_IFACE_COMB_UNSPEC, + NL80211_IFACE_COMB_LIMITS, + NL80211_IFACE_COMB_MAXNUM, + NL80211_IFACE_COMB_STA_AP_BI_MATCH, + NL80211_IFACE_COMB_NUM_CHANNELS, + + /* keep last */ + NUM_NL80211_IFACE_COMB, + MAX_NL80211_IFACE_COMB = NUM_NL80211_IFACE_COMB - 1 +}; + #endif /* __LINUX_NL80211_H */ diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index e1f1b41f7b13..04afcfb9eaf4 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1547,6 +1547,10 @@ struct cfg80211_ops { * hints read the documenation for regulatory_hint_found_beacon() * @WIPHY_FLAG_NETNS_OK: if not set, do not allow changing the netns of this * wiphy at all + * @WIPHY_FLAG_ENFORCE_COMBINATIONS: Set this flag to enforce interface + * combinations for this device. This flag is used for backward + * compatibility only until all drivers advertise combinations and + * they will always be enforced. * @WIPHY_FLAG_PS_ON_BY_DEFAULT: if set to true, powersave will be enabled * by default -- this flag will be set depending on the kernel's default * on wiphy_new(), but can be changed by the driver if it has a good @@ -1574,6 +1578,81 @@ enum wiphy_flags { WIPHY_FLAG_IBSS_RSN = BIT(8), WIPHY_FLAG_MESH_AUTH = BIT(10), WIPHY_FLAG_SUPPORTS_SCHED_SCAN = BIT(11), + WIPHY_FLAG_ENFORCE_COMBINATIONS = BIT(12), +}; + +/** + * struct ieee80211_iface_limit - limit on certain interface types + * @max: maximum number of interfaces of these types + * @types: interface types (bits) + */ +struct ieee80211_iface_limit { + u16 max; + u16 types; +}; + +/** + * struct ieee80211_iface_combination - possible interface combination + * @limits: limits for the given interface types + * @n_limits: number of limitations + * @num_different_channels: can use up to this many different channels + * @max_interfaces: maximum number of interfaces in total allowed in this + * group + * @beacon_int_infra_match: In this combination, the beacon intervals + * between infrastructure and AP types must match. This is required + * only in special cases. + * + * These examples can be expressed as follows: + * + * Allow #STA <= 1, #AP <= 1, matching BI, channels = 1, 2 total: + * + * struct ieee80211_iface_limit limits1[] = { + * { .max = 1, .types = BIT(NL80211_IFTYPE_STATION), }, + * { .max = 1, .types = BIT(NL80211_IFTYPE_AP}, }, + * }; + * struct ieee80211_iface_combination combination1 = { + * .limits = limits1, + * .n_limits = ARRAY_SIZE(limits1), + * .max_interfaces = 2, + * .beacon_int_infra_match = true, + * }; + * + * + * Allow #{AP, P2P-GO} <= 8, channels = 1, 8 total: + * + * struct ieee80211_iface_limit limits2[] = { + * { .max = 8, .types = BIT(NL80211_IFTYPE_AP) | + * BIT(NL80211_IFTYPE_P2P_GO), }, + * }; + * struct ieee80211_iface_combination combination2 = { + * .limits = limits2, + * .n_limits = ARRAY_SIZE(limits2), + * .max_interfaces = 8, + * .num_different_channels = 1, + * }; + * + * + * Allow #STA <= 1, #{P2P-client,P2P-GO} <= 3 on two channels, 4 total. + * This allows for an infrastructure connection and three P2P connections. + * + * struct ieee80211_iface_limit limits3[] = { + * { .max = 1, .types = BIT(NL80211_IFTYPE_STATION), }, + * { .max = 3, .types = BIT(NL80211_IFTYPE_P2P_GO) | + * BIT(NL80211_IFTYPE_P2P_CLIENT), }, + * }; + * struct ieee80211_iface_combination combination3 = { + * .limits = limits3, + * .n_limits = ARRAY_SIZE(limits3), + * .max_interfaces = 4, + * .num_different_channels = 2, + * }; + */ +struct ieee80211_iface_combination { + const struct ieee80211_iface_limit *limits; + u32 num_different_channels; + u16 max_interfaces; + u8 n_limits; + bool beacon_int_infra_match; }; struct mac_address { @@ -1653,6 +1732,11 @@ struct wiphy_wowlan_support { * @priv: driver private data (sized according to wiphy_new() parameter) * @interface_modes: bitmask of interfaces types valid for this wiphy, * must be set by driver + * @iface_combinations: Valid interface combinations array, should not + * list single interface types. + * @n_iface_combinations: number of entries in @iface_combinations array. + * @software_iftypes: bitmask of software interface types, these are not + * subject to any restrictions since they are purely managed in SW. * @flags: wiphy flags, see &enum wiphy_flags * @bss_priv_size: each BSS struct has private data allocated with it, * this variable determines its size @@ -1697,6 +1781,10 @@ struct wiphy { const struct ieee80211_txrx_stypes *mgmt_stypes; + const struct ieee80211_iface_combination *iface_combinations; + int n_iface_combinations; + u16 software_iftypes; + u16 n_addresses; /* Supported interface modes, OR together BIT(NL80211_IFTYPE_...) */ diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 7f89011fa22d..79a2281678bf 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -685,7 +685,7 @@ EXPORT_SYMBOL(ieee80211_alloc_hw); int ieee80211_register_hw(struct ieee80211_hw *hw) { struct ieee80211_local *local = hw_to_local(hw); - int result; + int result, i; enum ieee80211_band band; int channels, max_bitrates; bool supp_ht; @@ -743,11 +743,19 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) return -ENOMEM; /* if low-level driver supports AP, we also support VLAN */ - if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) - local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN); + if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) { + hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN); + hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_AP_VLAN); + } /* mac80211 always supports monitor */ - local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR); + hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR); + hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR); + + /* mac80211 doesn't support more than 1 channel */ + for (i = 0; i < hw->wiphy->n_iface_combinations; i++) + if (hw->wiphy->iface_combinations[i].num_different_channels > 1) + return -EINVAL; #ifndef CONFIG_MAC80211_MESH /* mesh depends on Kconfig, but drivers should set it if they want */ diff --git a/net/wireless/core.c b/net/wireless/core.c index 18b002f16860..c22ef3492ee6 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -416,6 +416,67 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) } EXPORT_SYMBOL(wiphy_new); +static int wiphy_verify_combinations(struct wiphy *wiphy) +{ + const struct ieee80211_iface_combination *c; + int i, j; + + /* If we have combinations enforce them */ + if (wiphy->n_iface_combinations) + wiphy->flags |= WIPHY_FLAG_ENFORCE_COMBINATIONS; + + for (i = 0; i < wiphy->n_iface_combinations; i++) { + u32 cnt = 0; + u16 all_iftypes = 0; + + c = &wiphy->iface_combinations[i]; + + /* Combinations with just one interface aren't real */ + if (WARN_ON(c->max_interfaces < 2)) + return -EINVAL; + + /* Need at least one channel */ + if (WARN_ON(!c->num_different_channels)) + return -EINVAL; + + if (WARN_ON(!c->n_limits)) + return -EINVAL; + + for (j = 0; j < c->n_limits; j++) { + u16 types = c->limits[j].types; + + /* + * interface types shouldn't overlap, this is + * used in cfg80211_can_change_interface() + */ + if (WARN_ON(types & all_iftypes)) + return -EINVAL; + all_iftypes |= types; + + if (WARN_ON(!c->limits[j].max)) + return -EINVAL; + + /* Shouldn't list software iftypes in combinations! */ + if (WARN_ON(wiphy->software_iftypes & types)) + return -EINVAL; + + cnt += c->limits[j].max; + /* + * Don't advertise an unsupported type + * in a combination. + */ + if (WARN_ON((wiphy->interface_modes & types) != types)) + return -EINVAL; + } + + /* You can't even choose that many! */ + if (WARN_ON(cnt < c->max_interfaces)) + return -EINVAL; + } + + return 0; +} + int wiphy_register(struct wiphy *wiphy) { struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); @@ -444,6 +505,10 @@ int wiphy_register(struct wiphy *wiphy) if (WARN_ON(ifmodes != wiphy->interface_modes)) wiphy->interface_modes = ifmodes; + res = wiphy_verify_combinations(wiphy); + if (res) + return res; + /* sanity check supported bands/channels */ for (band = 0; band < IEEE80211_NUM_BANDS; band++) { sband = wiphy->bands[band]; @@ -698,6 +763,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb, struct net_device *dev = ndev; struct wireless_dev *wdev = dev->ieee80211_ptr; struct cfg80211_registered_device *rdev; + int ret; if (!wdev) return NOTIFY_DONE; @@ -893,6 +959,9 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb, return notifier_from_errno(-EOPNOTSUPP); if (rfkill_blocked(rdev->rfkill)) return notifier_from_errno(-ERFKILL); + ret = cfg80211_can_add_interface(rdev, wdev->iftype); + if (ret) + return notifier_from_errno(ret); break; } diff --git a/net/wireless/core.h b/net/wireless/core.h index d4b8f4c0bbbb..bf0fb40e3c8b 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -422,6 +422,17 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, u32 *flags, struct vif_params *params); void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev); +int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev, + struct wireless_dev *wdev, + enum nl80211_iftype iftype); + +static inline int +cfg80211_can_add_interface(struct cfg80211_registered_device *rdev, + enum nl80211_iftype iftype) +{ + return cfg80211_can_change_interface(rdev, NULL, iftype); +} + struct ieee80211_channel * rdev_freq_to_chan(struct cfg80211_registered_device *rdev, int freq, enum nl80211_channel_type channel_type); diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 9ef8e287d61b..beac296b1fde 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -564,6 +564,88 @@ static int nl80211_key_allowed(struct wireless_dev *wdev) return 0; } +static int nl80211_put_iftypes(struct sk_buff *msg, u32 attr, u16 ifmodes) +{ + struct nlattr *nl_modes = nla_nest_start(msg, attr); + int i; + + if (!nl_modes) + goto nla_put_failure; + + i = 0; + while (ifmodes) { + if (ifmodes & 1) + NLA_PUT_FLAG(msg, i); + ifmodes >>= 1; + i++; + } + + nla_nest_end(msg, nl_modes); + return 0; + +nla_put_failure: + return -ENOBUFS; +} + +static int nl80211_put_iface_combinations(struct wiphy *wiphy, + struct sk_buff *msg) +{ + struct nlattr *nl_combis; + int i, j; + + nl_combis = nla_nest_start(msg, + NL80211_ATTR_INTERFACE_COMBINATIONS); + if (!nl_combis) + goto nla_put_failure; + + for (i = 0; i < wiphy->n_iface_combinations; i++) { + const struct ieee80211_iface_combination *c; + struct nlattr *nl_combi, *nl_limits; + + c = &wiphy->iface_combinations[i]; + + nl_combi = nla_nest_start(msg, i + 1); + if (!nl_combi) + goto nla_put_failure; + + nl_limits = nla_nest_start(msg, NL80211_IFACE_COMB_LIMITS); + if (!nl_limits) + goto nla_put_failure; + + for (j = 0; j < c->n_limits; j++) { + struct nlattr *nl_limit; + + nl_limit = nla_nest_start(msg, j + 1); + if (!nl_limit) + goto nla_put_failure; + NLA_PUT_U32(msg, NL80211_IFACE_LIMIT_MAX, + c->limits[j].max); + if (nl80211_put_iftypes(msg, NL80211_IFACE_LIMIT_TYPES, + c->limits[j].types)) + goto nla_put_failure; + nla_nest_end(msg, nl_limit); + } + + nla_nest_end(msg, nl_limits); + + if (c->beacon_int_infra_match) + NLA_PUT_FLAG(msg, + NL80211_IFACE_COMB_STA_AP_BI_MATCH); + NLA_PUT_U32(msg, NL80211_IFACE_COMB_NUM_CHANNELS, + c->num_different_channels); + NLA_PUT_U32(msg, NL80211_IFACE_COMB_MAXNUM, + c->max_interfaces); + + nla_nest_end(msg, nl_combi); + } + + nla_nest_end(msg, nl_combis); + + return 0; +nla_put_failure: + return -ENOBUFS; +} + static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, struct cfg80211_registered_device *dev) { @@ -571,13 +653,11 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, struct nlattr *nl_bands, *nl_band; struct nlattr *nl_freqs, *nl_freq; struct nlattr *nl_rates, *nl_rate; - struct nlattr *nl_modes; struct nlattr *nl_cmds; enum ieee80211_band band; struct ieee80211_channel *chan; struct ieee80211_rate *rate; int i; - u16 ifmodes = dev->wiphy.interface_modes; const struct ieee80211_txrx_stypes *mgmt_stypes = dev->wiphy.mgmt_stypes; @@ -637,20 +717,10 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, } } - nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES); - if (!nl_modes) + if (nl80211_put_iftypes(msg, NL80211_ATTR_SUPPORTED_IFTYPES, + dev->wiphy.interface_modes)) goto nla_put_failure; - i = 0; - while (ifmodes) { - if (ifmodes & 1) - NLA_PUT_FLAG(msg, i); - ifmodes >>= 1; - i++; - } - - nla_nest_end(msg, nl_modes); - nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS); if (!nl_bands) goto nla_put_failure; @@ -865,6 +935,13 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, nla_nest_end(msg, nl_wowlan); } + if (nl80211_put_iftypes(msg, NL80211_ATTR_SOFTWARE_IFTYPES, + dev->wiphy.software_iftypes)) + goto nla_put_failure; + + if (nl80211_put_iface_combinations(&dev->wiphy, msg)) + goto nla_put_failure; + return genlmsg_end(msg, hdr); nla_put_failure: diff --git a/net/wireless/util.c b/net/wireless/util.c index 414c9f604df6..95e4e254da0a 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -803,6 +803,11 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, return -EBUSY; if (ntype != otype) { + err = cfg80211_can_change_interface(rdev, dev->ieee80211_ptr, + ntype); + if (err) + return err; + dev->ieee80211_ptr->use_4addr = false; dev->ieee80211_ptr->mesh_id_up_len = 0; @@ -921,3 +926,78 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, return res; } + +int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev, + struct wireless_dev *wdev, + enum nl80211_iftype iftype) +{ + struct wireless_dev *wdev_iter; + int num[NUM_NL80211_IFTYPES]; + int total = 1; + int i, j; + + ASSERT_RTNL(); + + /* Always allow software iftypes */ + if (rdev->wiphy.software_iftypes & BIT(iftype)) + return 0; + + /* + * Drivers will gradually all set this flag, until all + * have it we only enforce for those that set it. + */ + if (!(rdev->wiphy.flags & WIPHY_FLAG_ENFORCE_COMBINATIONS)) + return 0; + + memset(num, 0, sizeof(num)); + + num[iftype] = 1; + + mutex_lock(&rdev->devlist_mtx); + list_for_each_entry(wdev_iter, &rdev->netdev_list, list) { + if (wdev_iter == wdev) + continue; + if (!netif_running(wdev_iter->netdev)) + continue; + + if (rdev->wiphy.software_iftypes & BIT(wdev_iter->iftype)) + continue; + + num[wdev_iter->iftype]++; + total++; + } + mutex_unlock(&rdev->devlist_mtx); + + for (i = 0; i < rdev->wiphy.n_iface_combinations; i++) { + const struct ieee80211_iface_combination *c; + struct ieee80211_iface_limit *limits; + + c = &rdev->wiphy.iface_combinations[i]; + + limits = kmemdup(c->limits, sizeof(limits[0]) * c->n_limits, + GFP_KERNEL); + if (!limits) + return -ENOMEM; + if (total > c->max_interfaces) + goto cont; + + for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) { + if (rdev->wiphy.software_iftypes & BIT(iftype)) + continue; + for (j = 0; j < c->n_limits; j++) { + if (!(limits[j].types & iftype)) + continue; + if (limits[j].max < num[iftype]) + goto cont; + limits[j].max -= num[iftype]; + } + } + /* yay, it fits */ + kfree(limits); + return 0; + cont: + kfree(limits); + } + + return -EBUSY; +} -- cgit From 57cf8043a64b56a10b9f194572548a3dfb62e596 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Fri, 13 May 2011 10:45:43 -0700 Subject: nl80211: Move peer link state definition to nl80211 These definitions need to be exposed now that we can set the peer link states via NL80211_ATTR_STA_PLINK_STATE. They were already being (opaquely) reported by NL80211_STA_INFO_PLINK_STATE. Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- include/linux/nl80211.h | 41 +++++++++++++++++++++++++-- include/net/cfg80211.h | 27 ------------------ net/mac80211/cfg.c | 6 ++-- net/mac80211/mesh_plink.c | 72 +++++++++++++++++++++++------------------------ net/mac80211/rx.c | 2 +- net/mac80211/sta_info.c | 2 +- net/mac80211/sta_info.h | 6 ++-- net/wireless/nl80211.c | 2 +- 8 files changed, 83 insertions(+), 75 deletions(-) (limited to 'include/linux') diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 0ea497cb607c..fc3a94821b1e 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -973,9 +973,10 @@ enum nl80211_commands { * @NL80211_ATTR_SUPPORT_MESH_AUTH: Currently, this means the underlying driver * allows auth frames in a mesh to be passed to userspace for processing via * the @NL80211_MESH_SETUP_USERSPACE_AUTH flag. - * @NL80211_ATTR_STA_PLINK_STATE: The state of a mesh peer link. Used when - * userspace is driving the peer link management state machine. - * @NL80211_MESH_SETUP_USERSPACE_AMPE must be enabled. + * @NL80211_ATTR_STA_PLINK_STATE: The state of a mesh peer link as + * defined in &enum nl80211_plink_state. Used when userspace is + * driving the peer link management state machine. + * @NL80211_MESH_SETUP_USERSPACE_AMPE must be enabled. * * @NL80211_ATTR_WOWLAN_SUPPORTED: indicates, as part of the wiphy capabilities, * the supported WoWLAN triggers @@ -1396,6 +1397,7 @@ enum nl80211_sta_bss_param { * @NL80211_STA_INFO_LLID: the station's mesh LLID * @NL80211_STA_INFO_PLID: the station's mesh PLID * @NL80211_STA_INFO_PLINK_STATE: peer link state for the station + * (see %enum nl80211_plink_state) * @NL80211_STA_INFO_RX_BITRATE: last unicast data frame rx rate, nested * attribute, like NL80211_STA_INFO_TX_BITRATE. * @NL80211_STA_INFO_BSS_PARAM: current station's view of BSS, nested attribute @@ -2326,4 +2328,37 @@ enum nl80211_if_combination_attrs { MAX_NL80211_IFACE_COMB = NUM_NL80211_IFACE_COMB - 1 }; + +/** + * enum nl80211_plink_state - state of a mesh peer link finite state machine + * + * @NL80211_PLINK_LISTEN: initial state, considered the implicit + * state of non existant mesh peer links + * @NL80211_PLINK_OPN_SNT: mesh plink open frame has been sent to + * this mesh peer + * @NL80211_PLINK_OPN_RCVD: mesh plink open frame has been received + * from this mesh peer + * @NL80211_PLINK_CNF_RCVD: mesh plink confirm frame has been + * received from this mesh peer + * @NL80211_PLINK_ESTAB: mesh peer link is established + * @NL80211_PLINK_HOLDING: mesh peer link is being closed or cancelled + * @NL80211_PLINK_BLOCKED: all frames transmitted from this mesh + * plink are discarded + * @NUM_NL80211_PLINK_STATES: number of peer link states + * @MAX_NL80211_PLINK_STATES: highest numerical value of plink states + */ +enum nl80211_plink_state { + NL80211_PLINK_LISTEN, + NL80211_PLINK_OPN_SNT, + NL80211_PLINK_OPN_RCVD, + NL80211_PLINK_CNF_RCVD, + NL80211_PLINK_ESTAB, + NL80211_PLINK_HOLDING, + NL80211_PLINK_BLOCKED, + + /* keep last */ + NUM_NL80211_PLINK_STATES, + MAX_NL80211_PLINK_STATES = NUM_NL80211_PLINK_STATES - 1 +}; + #endif /* __LINUX_NL80211_H */ diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 04afcfb9eaf4..0a2d795d35de 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -371,33 +371,6 @@ enum plink_actions { PLINK_ACTION_BLOCK, }; -/** - * enum plink_states - state of a mesh peer link finite state machine - * - * @PLINK_LISTEN: initial state, considered the implicit state of non - * existant mesh peer links - * @PLINK_OPN_SNT: mesh plink open frame has been sent to this mesh - * peer @PLINK_OPN_RCVD: mesh plink open frame has been received from - * this mesh peer - * @PLINK_CNF_RCVD: mesh plink confirm frame has been received from - * this mesh peer - * @PLINK_ESTAB: mesh peer link is established - * @PLINK_HOLDING: mesh peer link is being closed or cancelled - * @PLINK_BLOCKED: all frames transmitted from this mesh plink are - * discarded - * @PLINK_INVALID: reserved - */ -enum plink_state { - PLINK_LISTEN, - PLINK_OPN_SNT, - PLINK_OPN_RCVD, - PLINK_CNF_RCVD, - PLINK_ESTAB, - PLINK_HOLDING, - PLINK_BLOCKED, - PLINK_INVALID, -}; - /** * struct station_parameters - station parameters * diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 6ecd5862735d..be70c70d3f5b 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -730,9 +730,9 @@ static void sta_apply_parameters(struct ieee80211_local *local, #ifdef CONFIG_MAC80211_MESH if (sdata->u.mesh.security & IEEE80211_MESH_SEC_SECURED) switch (params->plink_state) { - case PLINK_LISTEN: - case PLINK_ESTAB: - case PLINK_BLOCKED: + case NL80211_PLINK_LISTEN: + case NL80211_PLINK_ESTAB: + case NL80211_PLINK_BLOCKED: sta->plink_state = params->plink_state; break; default: diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 2c37bee3095a..f4adc0917888 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -83,7 +83,7 @@ void mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata) */ static inline void mesh_plink_fsm_restart(struct sta_info *sta) { - sta->plink_state = PLINK_LISTEN; + sta->plink_state = NL80211_PLINK_LISTEN; sta->llid = sta->plid = sta->reason = 0; sta->plink_retries = 0; } @@ -126,11 +126,11 @@ static bool __mesh_plink_deactivate(struct sta_info *sta) struct ieee80211_sub_if_data *sdata = sta->sdata; bool deactivated = false; - if (sta->plink_state == PLINK_ESTAB) { + if (sta->plink_state == NL80211_PLINK_ESTAB) { mesh_plink_dec_estab_count(sdata); deactivated = true; } - sta->plink_state = PLINK_BLOCKED; + sta->plink_state = NL80211_PLINK_BLOCKED; mesh_path_flush_by_nexthop(sta); return deactivated; @@ -268,7 +268,7 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates, sta->last_rx = jiffies; sta->sta.supp_rates[local->hw.conf.channel->band] = rates; if (mesh_peer_accepts_plinks(elems) && - sta->plink_state == PLINK_LISTEN && + sta->plink_state == NL80211_PLINK_LISTEN && sdata->u.mesh.accepting_plinks && sdata->u.mesh.mshcfg.auto_open_plinks) mesh_plink_open(sta); @@ -308,8 +308,8 @@ static void mesh_plink_timer(unsigned long data) sdata = sta->sdata; switch (sta->plink_state) { - case PLINK_OPN_RCVD: - case PLINK_OPN_SNT: + case NL80211_PLINK_OPN_RCVD: + case NL80211_PLINK_OPN_SNT: /* retry timer */ if (sta->plink_retries < dot11MeshMaxRetries(sdata)) { u32 rand; @@ -328,17 +328,17 @@ static void mesh_plink_timer(unsigned long data) } reason = cpu_to_le16(MESH_MAX_RETRIES); /* fall through on else */ - case PLINK_CNF_RCVD: + case NL80211_PLINK_CNF_RCVD: /* confirm timer */ if (!reason) reason = cpu_to_le16(MESH_CONFIRM_TIMEOUT); - sta->plink_state = PLINK_HOLDING; + sta->plink_state = NL80211_PLINK_HOLDING; mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); spin_unlock_bh(&sta->lock); mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid, plid, reason); break; - case PLINK_HOLDING: + case NL80211_PLINK_HOLDING: /* holding timer */ del_timer(&sta->plink_timer); mesh_plink_fsm_restart(sta); @@ -386,11 +386,11 @@ int mesh_plink_open(struct sta_info *sta) spin_lock_bh(&sta->lock); get_random_bytes(&llid, 2); sta->llid = llid; - if (sta->plink_state != PLINK_LISTEN) { + if (sta->plink_state != NL80211_PLINK_LISTEN) { spin_unlock_bh(&sta->lock); return -EBUSY; } - sta->plink_state = PLINK_OPN_SNT; + sta->plink_state = NL80211_PLINK_OPN_SNT; mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); spin_unlock_bh(&sta->lock); mpl_dbg("Mesh plink: starting establishment with %pM\n", @@ -407,7 +407,7 @@ void mesh_plink_block(struct sta_info *sta) spin_lock_bh(&sta->lock); deactivated = __mesh_plink_deactivate(sta); - sta->plink_state = PLINK_BLOCKED; + sta->plink_state = NL80211_PLINK_BLOCKED; spin_unlock_bh(&sta->lock); if (deactivated) @@ -430,13 +430,13 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m __le16 plid, llid, reason; #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG static const char *mplstates[] = { - [PLINK_LISTEN] = "LISTEN", - [PLINK_OPN_SNT] = "OPN-SNT", - [PLINK_OPN_RCVD] = "OPN-RCVD", - [PLINK_CNF_RCVD] = "CNF_RCVD", - [PLINK_ESTAB] = "ESTAB", - [PLINK_HOLDING] = "HOLDING", - [PLINK_BLOCKED] = "BLOCKED" + [NL80211_PLINK_LISTEN] = "LISTEN", + [NL80211_PLINK_OPN_SNT] = "OPN-SNT", + [NL80211_PLINK_OPN_RCVD] = "OPN-RCVD", + [NL80211_PLINK_CNF_RCVD] = "CNF_RCVD", + [NL80211_PLINK_ESTAB] = "ESTAB", + [NL80211_PLINK_HOLDING] = "HOLDING", + [NL80211_PLINK_BLOCKED] = "BLOCKED" }; #endif @@ -502,7 +502,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m return; } - if (sta && sta->plink_state == PLINK_BLOCKED) { + if (sta && sta->plink_state == NL80211_PLINK_BLOCKED) { rcu_read_unlock(); return; } @@ -572,7 +572,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m event = CNF_ACPT; break; case PLINK_CLOSE: - if (sta->plink_state == PLINK_ESTAB) + if (sta->plink_state == NL80211_PLINK_ESTAB) /* Do not check for llid or plid. This does not * follow the standard but since multiple plinks * per sta are not supported, it is necessary in @@ -607,14 +607,14 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m reason = 0; switch (sta->plink_state) { /* spin_unlock as soon as state is updated at each case */ - case PLINK_LISTEN: + case NL80211_PLINK_LISTEN: switch (event) { case CLS_ACPT: mesh_plink_fsm_restart(sta); spin_unlock_bh(&sta->lock); break; case OPN_ACPT: - sta->plink_state = PLINK_OPN_RCVD; + sta->plink_state = NL80211_PLINK_OPN_RCVD; sta->plid = plid; get_random_bytes(&llid, 2); sta->llid = llid; @@ -631,7 +631,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m } break; - case PLINK_OPN_SNT: + case NL80211_PLINK_OPN_SNT: switch (event) { case OPN_RJCT: case CNF_RJCT: @@ -640,7 +640,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m if (!reason) reason = cpu_to_le16(MESH_CLOSE_RCVD); sta->reason = reason; - sta->plink_state = PLINK_HOLDING; + sta->plink_state = NL80211_PLINK_HOLDING; if (!mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata))) sta->ignore_plink_timer = true; @@ -652,7 +652,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m break; case OPN_ACPT: /* retry timer is left untouched */ - sta->plink_state = PLINK_OPN_RCVD; + sta->plink_state = NL80211_PLINK_OPN_RCVD; sta->plid = plid; llid = sta->llid; spin_unlock_bh(&sta->lock); @@ -660,7 +660,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m plid, 0); break; case CNF_ACPT: - sta->plink_state = PLINK_CNF_RCVD; + sta->plink_state = NL80211_PLINK_CNF_RCVD; if (!mod_plink_timer(sta, dot11MeshConfirmTimeout(sdata))) sta->ignore_plink_timer = true; @@ -673,7 +673,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m } break; - case PLINK_OPN_RCVD: + case NL80211_PLINK_OPN_RCVD: switch (event) { case OPN_RJCT: case CNF_RJCT: @@ -682,7 +682,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m if (!reason) reason = cpu_to_le16(MESH_CLOSE_RCVD); sta->reason = reason; - sta->plink_state = PLINK_HOLDING; + sta->plink_state = NL80211_PLINK_HOLDING; if (!mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata))) sta->ignore_plink_timer = true; @@ -700,7 +700,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m break; case CNF_ACPT: del_timer(&sta->plink_timer); - sta->plink_state = PLINK_ESTAB; + sta->plink_state = NL80211_PLINK_ESTAB; spin_unlock_bh(&sta->lock); mesh_plink_inc_estab_count(sdata); ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); @@ -713,7 +713,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m } break; - case PLINK_CNF_RCVD: + case NL80211_PLINK_CNF_RCVD: switch (event) { case OPN_RJCT: case CNF_RJCT: @@ -722,7 +722,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m if (!reason) reason = cpu_to_le16(MESH_CLOSE_RCVD); sta->reason = reason; - sta->plink_state = PLINK_HOLDING; + sta->plink_state = NL80211_PLINK_HOLDING; if (!mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata))) sta->ignore_plink_timer = true; @@ -734,7 +734,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m break; case OPN_ACPT: del_timer(&sta->plink_timer); - sta->plink_state = PLINK_ESTAB; + sta->plink_state = NL80211_PLINK_ESTAB; spin_unlock_bh(&sta->lock); mesh_plink_inc_estab_count(sdata); ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); @@ -749,13 +749,13 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m } break; - case PLINK_ESTAB: + case NL80211_PLINK_ESTAB: switch (event) { case CLS_ACPT: reason = cpu_to_le16(MESH_CLOSE_RCVD); sta->reason = reason; deactivated = __mesh_plink_deactivate(sta); - sta->plink_state = PLINK_HOLDING; + sta->plink_state = NL80211_PLINK_HOLDING; llid = sta->llid; mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); spin_unlock_bh(&sta->lock); @@ -775,7 +775,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m break; } break; - case PLINK_HOLDING: + case NL80211_PLINK_HOLDING: switch (event) { case CLS_ACPT: if (del_timer(&sta->plink_timer)) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 1b9413fb3839..3a9515cb7ce1 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -490,7 +490,7 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) * establisment frame, beacon or probe, drop the frame. */ - if (!rx->sta || sta_plink_state(rx->sta) != PLINK_ESTAB) { + if (!rx->sta || sta_plink_state(rx->sta) != NL80211_PLINK_ESTAB) { struct ieee80211_mgmt *mgmt; if (!ieee80211_is_mgmt(hdr->frame_control)) diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 82ab6b4643fc..4a15f9603562 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -277,7 +277,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ #ifdef CONFIG_MAC80211_MESH - sta->plink_state = PLINK_LISTEN; + sta->plink_state = NL80211_PLINK_LISTEN; init_timer(&sta->plink_timer); #endif diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index d6b566076f05..c6ae8718bd57 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -318,7 +318,7 @@ struct sta_info { u8 plink_retries; bool ignore_plink_timer; bool plink_timer_was_running; - enum plink_state plink_state; + enum nl80211_plink_state plink_state; u32 plink_timeout; struct timer_list plink_timer; #endif @@ -336,12 +336,12 @@ struct sta_info { struct ieee80211_sta sta; }; -static inline enum plink_state sta_plink_state(struct sta_info *sta) +static inline enum nl80211_plink_state sta_plink_state(struct sta_info *sta) { #ifdef CONFIG_MAC80211_MESH return sta->plink_state; #endif - return PLINK_LISTEN; + return NL80211_PLINK_LISTEN; } static inline void set_sta_flags(struct sta_info *sta, const u32 flags) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index beac296b1fde..2222ce08ee91 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -2335,7 +2335,7 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) memset(¶ms, 0, sizeof(params)); params.listen_interval = -1; - params.plink_state = PLINK_INVALID; + params.plink_state = -1; if (info->attrs[NL80211_ATTR_STA_AID]) return -EINVAL; -- cgit From 2064af917b3ba7589070064ca4ed12cecd99a63c Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Fri, 29 Apr 2011 00:37:26 +0200 Subject: PM: Revert "driver core: platform_bus: allow runtime override of dev_pm_ops" The platform_bus_set_pm_ops() operation is deprecated in favor of the new device power domain infrastructre implemented in commit 7538e3db6e015e890825fbd9f8659952896ddd5b (PM: add support for device power domains) Signed-off-by: Kevin Hilman Signed-off-by: Rafael J. Wysocki --- drivers/base/platform.c | 35 ----------------------------------- include/linux/platform_device.h | 3 --- 2 files changed, 38 deletions(-) (limited to 'include/linux') diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 079c18a5e471..48425f183029 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -916,41 +916,6 @@ struct bus_type platform_bus_type = { }; EXPORT_SYMBOL_GPL(platform_bus_type); -/** - * platform_bus_get_pm_ops() - return pointer to busses dev_pm_ops - * - * This function can be used by platform code to get the current - * set of dev_pm_ops functions used by the platform_bus_type. - */ -const struct dev_pm_ops * __init platform_bus_get_pm_ops(void) -{ - return platform_bus_type.pm; -} - -/** - * platform_bus_set_pm_ops() - update dev_pm_ops for the platform_bus_type - * - * @pm: pointer to new dev_pm_ops struct to be used for platform_bus_type - * - * Platform code can override the dev_pm_ops methods of - * platform_bus_type by using this function. It is expected that - * platform code will first do a platform_bus_get_pm_ops(), then - * kmemdup it, then customize selected methods and pass a pointer to - * the new struct dev_pm_ops to this function. - * - * Since platform-specific code is customizing methods for *all* - * devices (not just platform-specific devices) it is expected that - * any custom overrides of these functions will keep existing behavior - * and simply extend it. For example, any customization of the - * runtime PM methods should continue to call the pm_generic_* - * functions as the default ones do in addition to the - * platform-specific behavior. - */ -void __init platform_bus_set_pm_ops(const struct dev_pm_ops *pm) -{ - platform_bus_type.pm = pm; -} - int __init platform_bus_init(void) { int error; diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index e0093e061b08..ede1a80e3358 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h @@ -150,9 +150,6 @@ extern struct platform_device *platform_create_bundle(struct platform_driver *dr struct resource *res, unsigned int n_res, const void *data, size_t size); -extern const struct dev_pm_ops * platform_bus_get_pm_ops(void); -extern void platform_bus_set_pm_ops(const struct dev_pm_ops *pm); - /* early platform driver interface */ struct early_platform_driver { const char *class_str; -- cgit From f0201738b61b1adcf6b2c4719c5c415745014c1c Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 12 Apr 2011 19:06:39 -0400 Subject: ftrace: Avoid recording mcount on .init sections directly The init and exit sections should not be traced and adding a call to mcount to them is a waste of text and instruction cache. Have the macro section attributes include notrace to ignore these functions for tracing from the build. Link: http://lkml.kernel.org/r/20110421023738.953028219@goodmis.org Signed-off-by: Steven Rostedt --- include/linux/init.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/init.h b/include/linux/init.h index 577671c55153..9146f39cdddf 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -79,29 +79,29 @@ #define __exitused __used #endif -#define __exit __section(.exit.text) __exitused __cold +#define __exit __section(.exit.text) __exitused __cold notrace /* Used for HOTPLUG */ -#define __devinit __section(.devinit.text) __cold +#define __devinit __section(.devinit.text) __cold notrace #define __devinitdata __section(.devinit.data) #define __devinitconst __section(.devinit.rodata) -#define __devexit __section(.devexit.text) __exitused __cold +#define __devexit __section(.devexit.text) __exitused __cold notrace #define __devexitdata __section(.devexit.data) #define __devexitconst __section(.devexit.rodata) /* Used for HOTPLUG_CPU */ -#define __cpuinit __section(.cpuinit.text) __cold +#define __cpuinit __section(.cpuinit.text) __cold notrace #define __cpuinitdata __section(.cpuinit.data) #define __cpuinitconst __section(.cpuinit.rodata) -#define __cpuexit __section(.cpuexit.text) __exitused __cold +#define __cpuexit __section(.cpuexit.text) __exitused __cold notrace #define __cpuexitdata __section(.cpuexit.data) #define __cpuexitconst __section(.cpuexit.rodata) /* Used for MEMORY_HOTPLUG */ -#define __meminit __section(.meminit.text) __cold +#define __meminit __section(.meminit.text) __cold notrace #define __meminitdata __section(.meminit.data) #define __meminitconst __section(.meminit.rodata) -#define __memexit __section(.memexit.text) __exitused __cold +#define __memexit __section(.memexit.text) __exitused __cold notrace #define __memexitdata __section(.memexit.data) #define __memexitconst __section(.memexit.rodata) -- cgit From 3532cb0ca2774b05e3c660f536ba3d1b38061fc9 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Mon, 16 May 2011 23:17:34 -0700 Subject: Input: ad714x - allow platform code to specify irqflags Add option to specify irqflags in platfrom data. Also update copyright notice. Signed-off-by: Michael Hennerich Tested-by: Jean-Francois Dagenais Signed-off-by: Dmitry Torokhov --- drivers/input/misc/ad714x.c | 4 +++- include/linux/input/ad714x.h | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/drivers/input/misc/ad714x.c b/drivers/input/misc/ad714x.c index 0f2db45f730c..5f683ec2999e 100644 --- a/drivers/input/misc/ad714x.c +++ b/drivers/input/misc/ad714x.c @@ -1257,7 +1257,9 @@ struct ad714x_chip *ad714x_probe(struct device *dev, u16 bus_type, int irq, } error = request_threaded_irq(ad714x->irq, NULL, ad714x_interrupt_thread, - IRQF_TRIGGER_FALLING, "ad714x_captouch", ad714x); + plat_data->irqflags ? + plat_data->irqflags : IRQF_TRIGGER_FALLING, + "ad714x_captouch", ad714x); if (error) { dev_err(dev, "can't allocate irq %d\n", ad714x->irq); goto err_unreg_dev; diff --git a/include/linux/input/ad714x.h b/include/linux/input/ad714x.h index 0cbe5e81482e..d388d857bf14 100644 --- a/include/linux/input/ad714x.h +++ b/include/linux/input/ad714x.h @@ -6,7 +6,7 @@ * The platform_data for the device's "struct device" holds this * information. * - * Copyright 2009 Analog Devices Inc. + * Copyright 2009-2011 Analog Devices Inc. * * Licensed under the GPL-2 or later. */ @@ -58,6 +58,7 @@ struct ad714x_platform_data { struct ad714x_button_plat *button; unsigned short stage_cfg_reg[STAGE_NUM][STAGE_CFGREG_NUM]; unsigned short sys_cfg_reg[SYS_CFGREG_NUM]; + unsigned long irqflags; }; #endif -- cgit From 84005eb5ea2939d448047fcf6924b3b9b6ed974d Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 17 May 2011 09:31:01 -0700 Subject: Input: tsc2007 - add max_rt parameter to platform data Finger touch events or very quick stylus events on low-quality panels can cause the tsc2007 to read bogus values. Looking at oscilloscope snapshots, this seems to be caused by the touch event disappearing during the measurements. These bogus values result in misclicks, where the X and Y values deviate from the real position. Most of these misclicks can be filtered out by setting a low enough threshold for the maximum resistance (which is loosely the inverse of the pressure) allowed to consider a set of values valid. Since this behaviour is largely dependent on the type and quality of the panel, this commit introduces the max_rt parameter. The default value is kept at MAX_12BIT. Signed-off-by: Thierry Reding Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/tsc2007.c | 4 +++- include/linux/i2c/tsc2007.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c index df4ae354969d..8c48a91a6783 100644 --- a/drivers/input/touchscreen/tsc2007.c +++ b/drivers/input/touchscreen/tsc2007.c @@ -75,6 +75,7 @@ struct tsc2007 { u16 model; u16 x_plate_ohms; + u16 max_rt; bool pendown; int irq; @@ -185,7 +186,7 @@ static void tsc2007_work(struct work_struct *work) tsc2007_read_values(ts, &tc); rt = tsc2007_calculate_pressure(ts, &tc); - if (rt > MAX_12BIT) { + if (rt > ts->max_rt) { /* * Sample found inconsistent by debouncing or pressure is * beyond the maximum. Don't report it to user space, @@ -294,6 +295,7 @@ static int __devinit tsc2007_probe(struct i2c_client *client, ts->model = pdata->model; ts->x_plate_ohms = pdata->x_plate_ohms; + ts->max_rt = pdata->max_rt ? : MAX_12BIT; ts->get_pendown_state = pdata->get_pendown_state; ts->clear_penirq = pdata->clear_penirq; diff --git a/include/linux/i2c/tsc2007.h b/include/linux/i2c/tsc2007.h index c6361fbb7bf9..d95f11347314 100644 --- a/include/linux/i2c/tsc2007.h +++ b/include/linux/i2c/tsc2007.h @@ -6,6 +6,7 @@ struct tsc2007_platform_data { u16 model; /* 2007. */ u16 x_plate_ohms; + u16 max_rt; /* max. resistance above which samples are ignored */ int (*get_pendown_state)(void); void (*clear_penirq)(void); /* If needed, clear 2nd level -- cgit From 2d137c7ed25f9754f52495af570897ad993e4fe7 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 17 May 2011 09:31:33 -0700 Subject: Input: tsc2007 - add poll_delay parameter to platform data Depending on the quality of the touch panel, the time for the X-, X+, Y- and Y+ inputs to settle may vary. The poll_delay parameter can be used to override the default of 1 millisecond. Cc: Dmitry Torokhov Cc: Kwangwoo Lee Signed-off-by: Thierry Reding Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/tsc2007.c | 5 +++-- include/linux/i2c/tsc2007.h | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c index 8c48a91a6783..faa82ddb014b 100644 --- a/drivers/input/touchscreen/tsc2007.c +++ b/drivers/input/touchscreen/tsc2007.c @@ -27,7 +27,6 @@ #include #include -#define TS_POLL_DELAY 1 /* ms delay between samples */ #define TS_POLL_PERIOD 1 /* ms delay between samples */ #define TSC2007_MEASURE_TEMP0 (0x0 << 4) @@ -76,6 +75,7 @@ struct tsc2007 { u16 model; u16 x_plate_ohms; u16 max_rt; + unsigned long poll_delay; bool pendown; int irq; @@ -242,7 +242,7 @@ static irqreturn_t tsc2007_irq(int irq, void *handle) if (!ts->get_pendown_state || likely(ts->get_pendown_state())) { disable_irq_nosync(ts->irq); schedule_delayed_work(&ts->work, - msecs_to_jiffies(TS_POLL_DELAY)); + msecs_to_jiffies(ts->poll_delay)); } if (ts->clear_penirq) @@ -296,6 +296,7 @@ static int __devinit tsc2007_probe(struct i2c_client *client, ts->model = pdata->model; ts->x_plate_ohms = pdata->x_plate_ohms; ts->max_rt = pdata->max_rt ? : MAX_12BIT; + ts->poll_delay = pdata->poll_delay ? : 1; ts->get_pendown_state = pdata->get_pendown_state; ts->clear_penirq = pdata->clear_penirq; diff --git a/include/linux/i2c/tsc2007.h b/include/linux/i2c/tsc2007.h index d95f11347314..342b130a0a98 100644 --- a/include/linux/i2c/tsc2007.h +++ b/include/linux/i2c/tsc2007.h @@ -7,6 +7,8 @@ struct tsc2007_platform_data { u16 model; /* 2007. */ u16 x_plate_ohms; u16 max_rt; /* max. resistance above which samples are ignored */ + unsigned long poll_delay; /* delay (in ms) after pen-down event + before polling starts */ int (*get_pendown_state)(void); void (*clear_penirq)(void); /* If needed, clear 2nd level -- cgit From 1af38eac8cdb70dbad3086b4f1bf7296eb1b09b1 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 17 May 2011 09:32:02 -0700 Subject: Input: tsc2007 - add poll_period parameter to platform data This new parameter allows the polling frequency to be configured while keeping the default of once every millisecond. Signed-off-by: Thierry Reding Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/tsc2007.c | 6 +++--- include/linux/i2c/tsc2007.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c index faa82ddb014b..87c40c79f71e 100644 --- a/drivers/input/touchscreen/tsc2007.c +++ b/drivers/input/touchscreen/tsc2007.c @@ -27,8 +27,6 @@ #include #include -#define TS_POLL_PERIOD 1 /* ms delay between samples */ - #define TSC2007_MEASURE_TEMP0 (0x0 << 4) #define TSC2007_MEASURE_AUX (0x2 << 4) #define TSC2007_MEASURE_TEMP1 (0x4 << 4) @@ -76,6 +74,7 @@ struct tsc2007 { u16 x_plate_ohms; u16 max_rt; unsigned long poll_delay; + unsigned long poll_period; bool pendown; int irq; @@ -230,7 +229,7 @@ static void tsc2007_work(struct work_struct *work) out: if (ts->pendown || debounced) schedule_delayed_work(&ts->work, - msecs_to_jiffies(TS_POLL_PERIOD)); + msecs_to_jiffies(ts->poll_period)); else enable_irq(ts->irq); } @@ -297,6 +296,7 @@ static int __devinit tsc2007_probe(struct i2c_client *client, ts->x_plate_ohms = pdata->x_plate_ohms; ts->max_rt = pdata->max_rt ? : MAX_12BIT; ts->poll_delay = pdata->poll_delay ? : 1; + ts->poll_period = pdata->poll_period ? : 1; ts->get_pendown_state = pdata->get_pendown_state; ts->clear_penirq = pdata->clear_penirq; diff --git a/include/linux/i2c/tsc2007.h b/include/linux/i2c/tsc2007.h index 342b130a0a98..a51dac081aca 100644 --- a/include/linux/i2c/tsc2007.h +++ b/include/linux/i2c/tsc2007.h @@ -9,6 +9,7 @@ struct tsc2007_platform_data { u16 max_rt; /* max. resistance above which samples are ignored */ unsigned long poll_delay; /* delay (in ms) after pen-down event before polling starts */ + unsigned long poll_period; /* time (in ms) between samples */ int (*get_pendown_state)(void); void (*clear_penirq)(void); /* If needed, clear 2nd level -- cgit From 891e376b1e864519bf7e49fa741f473078318530 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 17 May 2011 09:32:29 -0700 Subject: Input: tsc2007 - add X, Y and Z fuzz factors to platform data These new platform-specific values can be used to set the fuzz parameter passed to the input_set_abs_params() function for the ABS_X, ABS_Y and ABS_PRESSURE axes. Signed-off-by: Thierry Reding Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/tsc2007.c | 7 ++++--- include/linux/i2c/tsc2007.h | 3 +++ 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c index 87c40c79f71e..fadc11545b1e 100644 --- a/drivers/input/touchscreen/tsc2007.c +++ b/drivers/input/touchscreen/tsc2007.c @@ -310,9 +310,10 @@ static int __devinit tsc2007_probe(struct i2c_client *client, input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); - input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, 0, 0); - input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, 0, 0); - input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT, 0, 0); + input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, pdata->fuzzx, 0); + input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, pdata->fuzzy, 0); + input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT, + pdata->fuzzz, 0); if (pdata->init_platform_hw) pdata->init_platform_hw(); diff --git a/include/linux/i2c/tsc2007.h b/include/linux/i2c/tsc2007.h index a51dac081aca..591427a63b06 100644 --- a/include/linux/i2c/tsc2007.h +++ b/include/linux/i2c/tsc2007.h @@ -10,6 +10,9 @@ struct tsc2007_platform_data { unsigned long poll_delay; /* delay (in ms) after pen-down event before polling starts */ unsigned long poll_period; /* time (in ms) between samples */ + int fuzzx; /* fuzz factor for X, Y and pressure axes */ + int fuzzy; + int fuzzz; int (*get_pendown_state)(void); void (*clear_penirq)(void); /* If needed, clear 2nd level -- cgit From a144c6a6c924aa1da04dd77fb84b89927354fdff Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 6 May 2011 20:09:42 +0200 Subject: PM: Print a warning if firmware is requested when tasks are frozen Some drivers erroneously use request_firmware() from their ->resume() (or ->thaw(), or ->restore()) callbacks, which is not going to work unless the firmware has been built in. This causes system resume to stall until the firmware-loading timeout expires, which makes users think that the resume has failed and reboot their machines unnecessarily. For this reason, make _request_firmware() print a warning and return immediately with error code if it has been called when tasks are frozen and it's impossible to start any new usermode helpers. Signed-off-by: Rafael J. Wysocki Acked-by: Greg Kroah-Hartman Reviewed-by: Valdis Kletnieks --- drivers/base/firmware_class.c | 5 +++++ include/linux/kmod.h | 5 +++++ kernel/kmod.c | 9 +++++++++ 3 files changed, 19 insertions(+) (limited to 'include/linux') diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 8c798ef7f13f..bbb03e6f7255 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -521,6 +521,11 @@ static int _request_firmware(const struct firmware **firmware_p, if (!firmware_p) return -EINVAL; + if (WARN_ON(usermodehelper_is_disabled())) { + dev_err(device, "firmware: %s will not be loaded\n", name); + return -EBUSY; + } + *firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL); if (!firmware) { dev_err(device, "%s: kmalloc(struct firmware) failed\n", diff --git a/include/linux/kmod.h b/include/linux/kmod.h index 6efd7a78de6a..7f3dbcb78116 100644 --- a/include/linux/kmod.h +++ b/include/linux/kmod.h @@ -111,7 +111,12 @@ call_usermodehelper(char *path, char **argv, char **envp, enum umh_wait wait) extern void usermodehelper_init(void); +#ifdef CONFIG_PM_SLEEP extern int usermodehelper_disable(void); extern void usermodehelper_enable(void); +extern bool usermodehelper_is_disabled(void); +#else +static inline bool usermodehelper_is_disabled(void) { return false; } +#endif #endif /* __LINUX_KMOD_H__ */ diff --git a/kernel/kmod.c b/kernel/kmod.c index 9cd0591c96a2..9ab513bd0c3c 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c @@ -301,6 +301,15 @@ void usermodehelper_enable(void) usermodehelper_disabled = 0; } +/** + * usermodehelper_is_disabled - check if new helpers are allowed to be started + */ +bool usermodehelper_is_disabled(void) +{ + return usermodehelper_disabled; +} +EXPORT_SYMBOL_GPL(usermodehelper_is_disabled); + static void helper_lock(void) { atomic_inc(&running_helpers); -- cgit From 13d53f8775c6a00b070a3eef6833795412eb7fcd Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 10 May 2011 21:27:34 +0200 Subject: kmod: always provide usermodehelper_disable() We need to prevent kernel-forked processes during system poweroff. Such processes try to access the filesystem whose disks we are trying to shutdown at the same time. This causes delays and exceptions in the storage drivers. A follow-up patch will add these calls and need usermodehelper_disable() also on systems without suspend support. Signed-off-by: Kay Sievers Signed-off-by: Rafael J. Wysocki --- include/linux/kmod.h | 4 ---- kernel/kmod.c | 7 ------- 2 files changed, 11 deletions(-) (limited to 'include/linux') diff --git a/include/linux/kmod.h b/include/linux/kmod.h index 7f3dbcb78116..310231823852 100644 --- a/include/linux/kmod.h +++ b/include/linux/kmod.h @@ -111,12 +111,8 @@ call_usermodehelper(char *path, char **argv, char **envp, enum umh_wait wait) extern void usermodehelper_init(void); -#ifdef CONFIG_PM_SLEEP extern int usermodehelper_disable(void); extern void usermodehelper_enable(void); extern bool usermodehelper_is_disabled(void); -#else -static inline bool usermodehelper_is_disabled(void) { return false; } -#endif #endif /* __LINUX_KMOD_H__ */ diff --git a/kernel/kmod.c b/kernel/kmod.c index 9ab513bd0c3c..5ae0ff38425f 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c @@ -245,7 +245,6 @@ static void __call_usermodehelper(struct work_struct *work) } } -#ifdef CONFIG_PM_SLEEP /* * If set, call_usermodehelper_exec() will exit immediately returning -EBUSY * (used for preventing user land processes from being created after the user @@ -321,12 +320,6 @@ static void helper_unlock(void) if (atomic_dec_and_test(&running_helpers)) wake_up(&running_helpers_waitq); } -#else /* CONFIG_PM_SLEEP */ -#define usermodehelper_disabled 0 - -static inline void helper_lock(void) {} -static inline void helper_unlock(void) {} -#endif /* CONFIG_PM_SLEEP */ /** * call_usermodehelper_setup - prepare to call a usermode helper -- cgit From 91e7c75ba93c48a82670d630b9daac92ff70095d Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 17 May 2011 23:26:00 +0200 Subject: PM: Allow drivers to allocate memory from .prepare() callbacks safely If device drivers allocate substantial amounts of memory (above 1 MB) in their hibernate .freeze() callbacks (or in their legacy suspend callbcks during hibernation), the subsequent creation of hibernate image may fail due to the lack of memory. This is the case, because the drivers' .freeze() callbacks are executed after the hibernate memory preallocation has been carried out and the preallocated amount of memory may be too small to cover the new driver allocations. Unfortunately, the drivers' .prepare() callbacks also are executed after the hibernate memory preallocation has completed, so they are not suitable for allocating additional memory either. Thus the only way a driver can safely allocate memory during hibernation is to use a hibernate/suspend notifier. However, the notifiers are called before the freezing of user space and the drivers wanting to use them for allocating additional memory may not know how much memory needs to be allocated at that point. To let device drivers overcome this difficulty rework the hibernation sequence so that the memory preallocation is carried out after the drivers' .prepare() callbacks have been executed, so that the .prepare() callbacks can be used for allocating additional memory to be used by the drivers' .freeze() callbacks. Update documentation to match the new behavior of the code. Signed-off-by: Rafael J. Wysocki --- Documentation/power/devices.txt | 14 +++++++---- Documentation/power/notifiers.txt | 51 ++++++++++++++++++--------------------- drivers/base/power/main.c | 18 +++++++++----- include/linux/pm.h | 4 +++ kernel/power/hibernate.c | 17 ++++++++++--- 5 files changed, 61 insertions(+), 43 deletions(-) (limited to 'include/linux') diff --git a/Documentation/power/devices.txt b/Documentation/power/devices.txt index 1971bcf48a60..88880839ece4 100644 --- a/Documentation/power/devices.txt +++ b/Documentation/power/devices.txt @@ -279,11 +279,15 @@ When the system goes into the standby or memory sleep state, the phases are: time.) Unlike the other suspend-related phases, during the prepare phase the device tree is traversed top-down. - The prepare phase uses only a bus callback. After the callback method - returns, no new children may be registered below the device. The method - may also prepare the device or driver in some way for the upcoming - system power transition, but it should not put the device into a - low-power state. + In addition to that, if device drivers need to allocate additional + memory to be able to hadle device suspend correctly, that should be + done in the prepare phase. + + After the prepare callback method returns, no new children may be + registered below the device. The method may also prepare the device or + driver in some way for the upcoming system power transition (for + example, by allocating additional memory required for this purpose), but + it should not put the device into a low-power state. 2. The suspend methods should quiesce the device to stop it from performing I/O. They also may save the device registers and put it into the diff --git a/Documentation/power/notifiers.txt b/Documentation/power/notifiers.txt index cf980709122a..c2a4a346c0d9 100644 --- a/Documentation/power/notifiers.txt +++ b/Documentation/power/notifiers.txt @@ -1,46 +1,41 @@ Suspend notifiers - (C) 2007 Rafael J. Wysocki , GPL - -There are some operations that device drivers may want to carry out in their -.suspend() routines, but shouldn't, because they can cause the hibernation or -suspend to fail. For example, a driver may want to allocate a substantial amount -of memory (like 50 MB) in .suspend(), but that shouldn't be done after the -swsusp's memory shrinker has run. - -Also, there may be some operations, that subsystems want to carry out before a -hibernation/suspend or after a restore/resume, requiring the system to be fully -functional, so the drivers' .suspend() and .resume() routines are not suitable -for this purpose. For example, device drivers may want to upload firmware to -their devices after a restore from a hibernation image, but they cannot do it by -calling request_firmware() from their .resume() routines (user land processes -are frozen at this point). The solution may be to load the firmware into -memory before processes are frozen and upload it from there in the .resume() -routine. Of course, a hibernation notifier may be used for this purpose. - -The subsystems that have such needs can register suspend notifiers that will be -called upon the following events by the suspend core: + (C) 2007-2011 Rafael J. Wysocki , GPL + +There are some operations that subsystems or drivers may want to carry out +before hibernation/suspend or after restore/resume, but they require the system +to be fully functional, so the drivers' and subsystems' .suspend() and .resume() +or even .prepare() and .complete() callbacks are not suitable for this purpose. +For example, device drivers may want to upload firmware to their devices after +resume/restore, but they cannot do it by calling request_firmware() from their +.resume() or .complete() routines (user land processes are frozen at these +points). The solution may be to load the firmware into memory before processes +are frozen and upload it from there in the .resume() routine. +A suspend/hibernation notifier may be used for this purpose. + +The subsystems or drivers having such needs can register suspend notifiers that +will be called upon the following events by the PM core: PM_HIBERNATION_PREPARE The system is going to hibernate or suspend, tasks will be frozen immediately. PM_POST_HIBERNATION The system memory state has been restored from a - hibernation image or an error occurred during the - hibernation. Device drivers' .resume() callbacks have + hibernation image or an error occurred during + hibernation. Device drivers' restore callbacks have been executed and tasks have been thawed. PM_RESTORE_PREPARE The system is going to restore a hibernation image. - If all goes well the restored kernel will issue a + If all goes well, the restored kernel will issue a PM_POST_HIBERNATION notification. -PM_POST_RESTORE An error occurred during the hibernation restore. - Device drivers' .resume() callbacks have been executed +PM_POST_RESTORE An error occurred during restore from hibernation. + Device drivers' restore callbacks have been executed and tasks have been thawed. -PM_SUSPEND_PREPARE The system is preparing for a suspend. +PM_SUSPEND_PREPARE The system is preparing for suspend. PM_POST_SUSPEND The system has just resumed or an error occurred during - the suspend. Device drivers' .resume() callbacks have - been executed and tasks have been thawed. + suspend. Device drivers' resume callbacks have been + executed and tasks have been thawed. It is generally assumed that whatever the notifiers do for PM_HIBERNATION_PREPARE, should be undone for PM_POST_HIBERNATION. Analogously, diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 3b354560f306..aa6320207745 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -579,11 +579,13 @@ static bool is_async(struct device *dev) * Execute the appropriate "resume" callback for all devices whose status * indicates that they are suspended. */ -static void dpm_resume(pm_message_t state) +void dpm_resume(pm_message_t state) { struct device *dev; ktime_t starttime = ktime_get(); + might_sleep(); + mutex_lock(&dpm_list_mtx); pm_transition = state; async_error = 0; @@ -656,10 +658,12 @@ static void device_complete(struct device *dev, pm_message_t state) * Execute the ->complete() callbacks for all devices whose PM status is not * DPM_ON (this allows new devices to be registered). */ -static void dpm_complete(pm_message_t state) +void dpm_complete(pm_message_t state) { struct list_head list; + might_sleep(); + INIT_LIST_HEAD(&list); mutex_lock(&dpm_list_mtx); while (!list_empty(&dpm_prepared_list)) { @@ -688,7 +692,6 @@ static void dpm_complete(pm_message_t state) */ void dpm_resume_end(pm_message_t state) { - might_sleep(); dpm_resume(state); dpm_complete(state); } @@ -912,11 +915,13 @@ static int device_suspend(struct device *dev) * dpm_suspend - Execute "suspend" callbacks for all non-sysdev devices. * @state: PM transition of the system being carried out. */ -static int dpm_suspend(pm_message_t state) +int dpm_suspend(pm_message_t state) { ktime_t starttime = ktime_get(); int error = 0; + might_sleep(); + mutex_lock(&dpm_list_mtx); pm_transition = state; async_error = 0; @@ -1003,10 +1008,12 @@ static int device_prepare(struct device *dev, pm_message_t state) * * Execute the ->prepare() callback(s) for all devices. */ -static int dpm_prepare(pm_message_t state) +int dpm_prepare(pm_message_t state) { int error = 0; + might_sleep(); + mutex_lock(&dpm_list_mtx); while (!list_empty(&dpm_list)) { struct device *dev = to_device(dpm_list.next); @@ -1055,7 +1062,6 @@ int dpm_suspend_start(pm_message_t state) { int error; - might_sleep(); error = dpm_prepare(state); if (!error) error = dpm_suspend(state); diff --git a/include/linux/pm.h b/include/linux/pm.h index 3cc3e7e589f0..dce7c7148771 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -533,10 +533,14 @@ struct dev_power_domain { extern void device_pm_lock(void); extern void dpm_resume_noirq(pm_message_t state); extern void dpm_resume_end(pm_message_t state); +extern void dpm_resume(pm_message_t state); +extern void dpm_complete(pm_message_t state); extern void device_pm_unlock(void); extern int dpm_suspend_noirq(pm_message_t state); extern int dpm_suspend_start(pm_message_t state); +extern int dpm_suspend(pm_message_t state); +extern int dpm_prepare(pm_message_t state); extern void __suspend_report_result(const char *function, void *fn, int ret); diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index 95a2ac40f48c..f9bec56d8825 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c @@ -327,20 +327,25 @@ static int create_image(int platform_mode) int hibernation_snapshot(int platform_mode) { + pm_message_t msg = PMSG_RECOVER; int error; error = platform_begin(platform_mode); if (error) goto Close; + error = dpm_prepare(PMSG_FREEZE); + if (error) + goto Complete_devices; + /* Preallocate image memory before shutting down devices. */ error = hibernate_preallocate_memory(); if (error) - goto Close; + goto Complete_devices; suspend_console(); pm_restrict_gfp_mask(); - error = dpm_suspend_start(PMSG_FREEZE); + error = dpm_suspend(PMSG_FREEZE); if (error) goto Recover_platform; @@ -358,13 +363,17 @@ int hibernation_snapshot(int platform_mode) if (error || !in_suspend) swsusp_free(); - dpm_resume_end(in_suspend ? - (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE); + msg = in_suspend ? (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE; + dpm_resume(msg); if (error || !in_suspend) pm_restore_gfp_mask(); resume_console(); + + Complete_devices: + dpm_complete(msg); + Close: platform_end(platform_mode); return error; -- cgit From 6538df80194e305f1b78cafb556f4bb442f808b3 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 17 May 2011 23:26:21 +0200 Subject: PM: Introduce generic prepare and complete callbacks for subsystems Introduce generic .prepare() and .complete() power management callbacks, currently missing, that can be used by subsystems and power domains and export them. Provide NULL definitions of all the generic system sleep callbacks for CONFIG_PM_SLEEP unset. Signed-off-by: Rafael J. Wysocki --- drivers/base/power/generic_ops.c | 39 +++++++++++++++++++++++++++++++++++++++ include/linux/pm.h | 26 +++++++++++++++++++------- 2 files changed, 58 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/drivers/base/power/generic_ops.c b/drivers/base/power/generic_ops.c index 42f97f925629..cb3bb368681c 100644 --- a/drivers/base/power/generic_ops.c +++ b/drivers/base/power/generic_ops.c @@ -73,6 +73,23 @@ EXPORT_SYMBOL_GPL(pm_generic_runtime_resume); #endif /* CONFIG_PM_RUNTIME */ #ifdef CONFIG_PM_SLEEP +/** + * pm_generic_prepare - Generic routine preparing a device for power transition. + * @dev: Device to prepare. + * + * Prepare a device for a system-wide power transition. + */ +int pm_generic_prepare(struct device *dev) +{ + struct device_driver *drv = dev->driver; + int ret = 0; + + if (drv && drv->pm && drv->pm->prepare) + ret = drv->pm->prepare(dev); + + return ret; +} + /** * __pm_generic_call - Generic suspend/freeze/poweroff/thaw subsystem callback. * @dev: Device to handle. @@ -213,16 +230,38 @@ int pm_generic_restore(struct device *dev) return __pm_generic_resume(dev, PM_EVENT_RESTORE); } EXPORT_SYMBOL_GPL(pm_generic_restore); + +/** + * pm_generic_complete - Generic routine competing a device power transition. + * @dev: Device to handle. + * + * Complete a device power transition during a system-wide power transition. + */ +void pm_generic_complete(struct device *dev) +{ + struct device_driver *drv = dev->driver; + + if (drv && drv->pm && drv->pm->complete) + drv->pm->complete(dev); + + /* + * Let runtime PM try to suspend devices that haven't been in use before + * going into the system-wide sleep state we're resuming from. + */ + pm_runtime_idle(dev); +} #endif /* CONFIG_PM_SLEEP */ struct dev_pm_ops generic_subsys_pm_ops = { #ifdef CONFIG_PM_SLEEP + .prepare = pm_generic_prepare, .suspend = pm_generic_suspend, .resume = pm_generic_resume, .freeze = pm_generic_freeze, .thaw = pm_generic_thaw, .poweroff = pm_generic_poweroff, .restore = pm_generic_restore, + .complete = pm_generic_complete, #endif #ifdef CONFIG_PM_RUNTIME .runtime_suspend = pm_generic_runtime_suspend, diff --git a/include/linux/pm.h b/include/linux/pm.h index dce7c7148771..3160648ccdda 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -550,6 +550,16 @@ extern void __suspend_report_result(const char *function, void *fn, int ret); } while (0) extern int device_pm_wait_for_dev(struct device *sub, struct device *dev); + +extern int pm_generic_prepare(struct device *dev); +extern int pm_generic_suspend(struct device *dev); +extern int pm_generic_resume(struct device *dev); +extern int pm_generic_freeze(struct device *dev); +extern int pm_generic_thaw(struct device *dev); +extern int pm_generic_restore(struct device *dev); +extern int pm_generic_poweroff(struct device *dev); +extern void pm_generic_complete(struct device *dev); + #else /* !CONFIG_PM_SLEEP */ #define device_pm_lock() do {} while (0) @@ -566,6 +576,15 @@ static inline int device_pm_wait_for_dev(struct device *a, struct device *b) { return 0; } + +#define pm_generic_prepare NULL +#define pm_generic_suspend NULL +#define pm_generic_resume NULL +#define pm_generic_freeze NULL +#define pm_generic_thaw NULL +#define pm_generic_restore NULL +#define pm_generic_poweroff NULL +#define pm_generic_complete NULL #endif /* !CONFIG_PM_SLEEP */ /* How to reorder dpm_list after device_move() */ @@ -576,11 +595,4 @@ enum dpm_order { DPM_ORDER_DEV_LAST, }; -extern int pm_generic_suspend(struct device *dev); -extern int pm_generic_resume(struct device *dev); -extern int pm_generic_freeze(struct device *dev); -extern int pm_generic_thaw(struct device *dev); -extern int pm_generic_restore(struct device *dev); -extern int pm_generic_poweroff(struct device *dev); - #endif /* _LINUX_PM_H */ -- cgit From a934a00a69e940b126b9bdbf83e630ef5fe43523 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Wed, 18 May 2011 10:37:35 +0200 Subject: block: Fix discard topology stacking and reporting In some cases we would end up stacking discard_zeroes_data incorrectly. Fix this by enabling the feature by default for stacking drivers and clearing it for low-level drivers. Incorporating a device that does not support dzd will then cause the feature to be disabled in the stacking driver. Also ensure that the maximum discard value does not overflow when exported in sysfs and return 0 in the alignment and dzd fields for devices that don't support discard. Reported-by: Lukas Czerner Signed-off-by: Martin K. Petersen Acked-by: Mike Snitzer Cc: stable@kernel.org Signed-off-by: Jens Axboe --- block/blk-settings.c | 3 ++- block/blk-sysfs.c | 3 ++- include/linux/blkdev.h | 7 +++++-- 3 files changed, 9 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/block/blk-settings.c b/block/blk-settings.c index cd3c428e194f..fa1eb0449a05 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c @@ -120,7 +120,7 @@ void blk_set_default_limits(struct queue_limits *lim) lim->discard_granularity = 0; lim->discard_alignment = 0; lim->discard_misaligned = 0; - lim->discard_zeroes_data = -1; + lim->discard_zeroes_data = 1; lim->logical_block_size = lim->physical_block_size = lim->io_min = 512; lim->bounce_pfn = (unsigned long)(BLK_BOUNCE_ANY >> PAGE_SHIFT); lim->alignment_offset = 0; @@ -166,6 +166,7 @@ void blk_queue_make_request(struct request_queue *q, make_request_fn *mfn) blk_set_default_limits(&q->limits); blk_queue_max_hw_sectors(q, BLK_SAFE_MAX_SECTORS); + q->limits.discard_zeroes_data = 0; /* * by default assume old behaviour and bounce for any highmem page diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index 6d735122bc59..53bd0c77bfda 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c @@ -152,7 +152,8 @@ static ssize_t queue_discard_granularity_show(struct request_queue *q, char *pag static ssize_t queue_discard_max_show(struct request_queue *q, char *page) { - return queue_var_show(q->limits.max_discard_sectors << 9, page); + return sprintf(page, "%llu\n", + (unsigned long long)q->limits.max_discard_sectors << 9); } static ssize_t queue_discard_zeroes_data_show(struct request_queue *q, char *page) diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 9f921bf4bf8c..520d8618ed76 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -257,7 +257,7 @@ struct queue_limits { unsigned char misaligned; unsigned char discard_misaligned; unsigned char cluster; - signed char discard_zeroes_data; + unsigned char discard_zeroes_data; }; struct request_queue @@ -1069,13 +1069,16 @@ static inline int queue_limit_discard_alignment(struct queue_limits *lim, sector { unsigned int alignment = (sector << 9) & (lim->discard_granularity - 1); + if (!lim->max_discard_sectors) + return 0; + return (lim->discard_granularity + lim->discard_alignment - alignment) & (lim->discard_granularity - 1); } static inline unsigned int queue_discard_zeroes_data(struct request_queue *q) { - if (q->limits.discard_zeroes_data == 1) + if (q->limits.max_discard_sectors && q->limits.discard_zeroes_data == 1) return 1; return 0; -- cgit From f12a20fc9bfba4218ecbc4e40c8e08dc2a85dc99 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 17 May 2011 15:44:12 -0700 Subject: procfs: add stub for proc_mkdir_mode() Provide a stub for proc_mkdir_mode() when CONFIG_PROC_FS is not enabled, just like the stub for proc_mkdir(). Fixes this linux-next build error: drivers/net/wireless/airo.c:4504: error: implicit declaration of function 'proc_mkdir_mode' Signed-off-by: Randy Dunlap Cc: Stephen Rothwell Cc: Alexey Dobriyan Cc: "John W. Linville" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/proc_fs.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index 838c1149251a..eaf4350c0f90 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -208,6 +208,8 @@ static inline struct proc_dir_entry *proc_symlink(const char *name, struct proc_dir_entry *parent,const char *dest) {return NULL;} static inline struct proc_dir_entry *proc_mkdir(const char *name, struct proc_dir_entry *parent) {return NULL;} +static inline struct proc_dir_entry *proc_mkdir_mode(const char *name, + mode_t mode, struct proc_dir_entry *parent) { return NULL; } static inline struct proc_dir_entry *create_proc_read_entry(const char *name, mode_t mode, struct proc_dir_entry *base, -- cgit From fe12bc2c996d3e492b2920e32ac79f7bbae3e15d Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 18 May 2011 12:48:00 +0200 Subject: genirq: Uninline and sanity check generic_handle_irq() generic_handle_irq() is missing a NULL pointer check for the result of irq_to_desc. This was a not a big problem, but we want to expose it to drivers, so we better have sanity checks in place. Add a return value as well, which indicates that the irq number was valid and the handler was invoked. Based on the pure code move from Jonathan Cameron. Signed-off-by: Thomas Gleixner Cc: Jonathan Cameron --- include/linux/irqdesc.h | 5 +---- kernel/irq/irqdesc.c | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h index c70b1aa4b93a..2d921b35212c 100644 --- a/include/linux/irqdesc.h +++ b/include/linux/irqdesc.h @@ -111,10 +111,7 @@ static inline void generic_handle_irq_desc(unsigned int irq, struct irq_desc *de desc->handle_irq(irq, desc); } -static inline void generic_handle_irq(unsigned int irq) -{ - generic_handle_irq_desc(irq, irq_to_desc(irq)); -} +int generic_handle_irq(unsigned int irq); /* Test to see if a driver has successfully requested an irq */ static inline int irq_has_action(unsigned int irq) diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c index e07b975fdc5a..9f65b0225d6a 100644 --- a/kernel/irq/irqdesc.c +++ b/kernel/irq/irqdesc.c @@ -290,6 +290,21 @@ static int irq_expand_nr_irqs(unsigned int nr) #endif /* !CONFIG_SPARSE_IRQ */ +/** + * generic_handle_irq - Invoke the handler for a particular irq + * @irq: The irq number to handle + * + */ +int generic_handle_irq(unsigned int irq) +{ + struct irq_desc *desc = irq_to_desc(irq); + + if (!desc) + return -EINVAL; + generic_handle_irq_desc(irq, desc); + return 0; +} + /* Dynamic interrupt handling */ /** -- cgit From b2b07e4fdbc51383cfc0ba5618c2ddf5c9d038f2 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Wed, 18 May 2011 15:08:03 +0200 Subject: signal: trivial, fix the "timespec declared inside parameter list" warning Fix the compile warning, do_sigtimedwait(struct timespec *) in signal.h needs the forward declaration of timespec. Reported-and-acked-by: Mike Frysinger Signed-off-by: Oleg Nesterov --- include/linux/signal.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/signal.h b/include/linux/signal.h index 7e2526374fd7..a44e7f062238 100644 --- a/include/linux/signal.h +++ b/include/linux/signal.h @@ -234,6 +234,9 @@ static inline int valid_signal(unsigned long sig) return sig <= _NSIG ? 1 : 0; } +struct timespec; +struct pt_regs; + extern int next_signal(struct sigpending *pending, sigset_t *mask); extern int do_send_sig_info(int sig, struct siginfo *info, struct task_struct *p, bool group); @@ -248,7 +251,6 @@ extern int sigprocmask(int, sigset_t *, sigset_t *); extern void set_current_blocked(const sigset_t *); extern int show_unhandled_signals; -struct pt_regs; extern int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, struct pt_regs *regs, void *cookie); extern void exit_signals(struct task_struct *tsk); -- cgit From 01294d82622d6d9d64bde8e4530c7e2c6dbb6ee6 Mon Sep 17 00:00:00 2001 From: Milton Miller Date: Wed, 18 May 2011 10:27:39 -0500 Subject: of: fix race when matching drivers If two drivers are probing devices at the same time, both will write their match table result to the dev->of_match cache at the same time. Only write the result if the device matches. In a thread titled "SBus devices sometimes detected, sometimes not", Meelis reported his SBus hme was not detected about 50% of the time. From the debug suggested by Grant it was obvious another driver matched some devices between the call to match the hme and the hme discovery failling. Reported-by: Meelis Roos Signed-off-by: Milton Miller [grant.likely: modified to only call of_match_device() once] Signed-off-by: Grant Likely --- include/linux/of_device.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/of_device.h b/include/linux/of_device.h index 8bfe6c1d4365..b33d68814a73 100644 --- a/include/linux/of_device.h +++ b/include/linux/of_device.h @@ -21,8 +21,12 @@ extern void of_device_make_bus_id(struct device *dev); static inline int of_driver_match_device(struct device *dev, const struct device_driver *drv) { - dev->of_match = of_match_device(drv->of_match_table, dev); - return dev->of_match != NULL; + const struct of_device_id *match; + + match = of_match_device(drv->of_match_table, dev); + if (match) + dev->of_match = match; + return match != NULL; } extern struct platform_device *of_dev_get(struct platform_device *dev); -- cgit From b1608d69cb804e414d0887140ba08a9398e4e638 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Wed, 18 May 2011 11:19:24 -0600 Subject: drivercore: revert addition of of_match to struct device Commit b826291c, "drivercore/dt: add a match table pointer to struct device" added an of_match pointer to struct device to cache the of_match_table entry discovered at driver match time. This was unsafe because matching is not an atomic operation with probing a driver. If two or more drivers are attempted to be matched to a driver at the same time, then the cached matching entry pointer could get overwritten. This patch reverts the of_match cache pointer and reworks all users to call of_match_device() directly instead. Signed-off-by: Grant Likely --- arch/powerpc/platforms/83xx/suspend.c | 7 +++++-- arch/powerpc/sysdev/fsl_msi.c | 7 +++++-- arch/sparc/kernel/pci_sabre.c | 5 ++++- arch/sparc/kernel/pci_schizo.c | 8 ++++++-- drivers/atm/fore200e.c | 7 +++++-- drivers/char/hw_random/n2-drv.c | 7 +++++-- drivers/char/ipmi/ipmi_si_intf.c | 7 +++++-- drivers/char/xilinx_hwicap/xilinx_hwicap.c | 14 +++++++++----- drivers/edac/ppc4xx_edac.c | 2 +- drivers/i2c/busses/i2c-mpc.c | 9 ++++++--- drivers/mmc/host/sdhci-of-core.c | 7 +++++-- drivers/mtd/maps/physmap_of.c | 7 +++++-- drivers/net/can/mscan/mpc5xxx_can.c | 7 +++++-- drivers/net/fs_enet/fs_enet-main.c | 9 ++++++--- drivers/net/fs_enet/mii-fec.c | 7 +++++-- drivers/net/sunhme.c | 7 +++++-- drivers/scsi/qlogicpti.c | 7 +++++-- drivers/tty/serial/of_serial.c | 7 +++++-- drivers/usb/gadget/fsl_qe_udc.c | 7 +++++-- drivers/watchdog/mpc8xxx_wdt.c | 7 +++++-- include/linux/device.h | 1 - include/linux/of_device.h | 12 ++++++------ 22 files changed, 108 insertions(+), 50 deletions(-) (limited to 'include/linux') diff --git a/arch/powerpc/platforms/83xx/suspend.c b/arch/powerpc/platforms/83xx/suspend.c index 188272934cfb..104faa8aa23c 100644 --- a/arch/powerpc/platforms/83xx/suspend.c +++ b/arch/powerpc/platforms/83xx/suspend.c @@ -318,17 +318,20 @@ static const struct platform_suspend_ops mpc83xx_suspend_ops = { .end = mpc83xx_suspend_end, }; +static struct of_device_id pmc_match[]; static int pmc_probe(struct platform_device *ofdev) { + const struct of_device_id *match; struct device_node *np = ofdev->dev.of_node; struct resource res; struct pmc_type *type; int ret = 0; - if (!ofdev->dev.of_match) + match = of_match_device(pmc_match, &ofdev->dev); + if (!match) return -EINVAL; - type = ofdev->dev.of_match->data; + type = match->data; if (!of_device_is_available(np)) return -ENODEV; diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index d5679dc1e20f..01cd2f089512 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c @@ -304,8 +304,10 @@ static int __devinit fsl_msi_setup_hwirq(struct fsl_msi *msi, return 0; } +static const struct of_device_id fsl_of_msi_ids[]; static int __devinit fsl_of_msi_probe(struct platform_device *dev) { + const struct of_device_id *match; struct fsl_msi *msi; struct resource res; int err, i, j, irq_index, count; @@ -316,9 +318,10 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev) u32 offset; static const u32 all_avail[] = { 0, NR_MSI_IRQS }; - if (!dev->dev.of_match) + match = of_match_device(fsl_of_msi_ids, &dev->dev); + if (!match) return -EINVAL; - features = dev->dev.of_match->data; + features = match->data; printk(KERN_DEBUG "Setting up Freescale MSI support\n"); diff --git a/arch/sparc/kernel/pci_sabre.c b/arch/sparc/kernel/pci_sabre.c index 948068a083fc..d1840dbdaa2f 100644 --- a/arch/sparc/kernel/pci_sabre.c +++ b/arch/sparc/kernel/pci_sabre.c @@ -452,8 +452,10 @@ static void __devinit sabre_pbm_init(struct pci_pbm_info *pbm, sabre_scan_bus(pbm, &op->dev); } +static const struct of_device_id sabre_match[]; static int __devinit sabre_probe(struct platform_device *op) { + const struct of_device_id *match; const struct linux_prom64_registers *pr_regs; struct device_node *dp = op->dev.of_node; struct pci_pbm_info *pbm; @@ -463,7 +465,8 @@ static int __devinit sabre_probe(struct platform_device *op) const u32 *vdma; u64 clear_irq; - hummingbird_p = op->dev.of_match && (op->dev.of_match->data != NULL); + match = of_match_device(sabre_match, &op->dev); + hummingbird_p = match && (match->data != NULL); if (!hummingbird_p) { struct device_node *cpu_dp; diff --git a/arch/sparc/kernel/pci_schizo.c b/arch/sparc/kernel/pci_schizo.c index fecfcb2063c8..283fbc329a43 100644 --- a/arch/sparc/kernel/pci_schizo.c +++ b/arch/sparc/kernel/pci_schizo.c @@ -1458,11 +1458,15 @@ out_err: return err; } +static const struct of_device_id schizo_match[]; static int __devinit schizo_probe(struct platform_device *op) { - if (!op->dev.of_match) + const struct of_device_id *match; + + match = of_match_device(schizo_match, &op->dev); + if (!match) return -EINVAL; - return __schizo_init(op, (unsigned long) op->dev.of_match->data); + return __schizo_init(op, (unsigned long)match->data); } /* The ordering of this table is very important. Some Tomatillo diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c index bdd2719f3f68..bc9e702186dd 100644 --- a/drivers/atm/fore200e.c +++ b/drivers/atm/fore200e.c @@ -2643,16 +2643,19 @@ fore200e_init(struct fore200e* fore200e, struct device *parent) } #ifdef CONFIG_SBUS +static const struct of_device_id fore200e_sba_match[]; static int __devinit fore200e_sba_probe(struct platform_device *op) { + const struct of_device_id *match; const struct fore200e_bus *bus; struct fore200e *fore200e; static int index = 0; int err; - if (!op->dev.of_match) + match = of_match_device(fore200e_sba_match, &op->dev); + if (!match) return -EINVAL; - bus = op->dev.of_match->data; + bus = match->data; fore200e = kzalloc(sizeof(struct fore200e), GFP_KERNEL); if (!fore200e) diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c index 43ac61978d8b..ac6739e085e3 100644 --- a/drivers/char/hw_random/n2-drv.c +++ b/drivers/char/hw_random/n2-drv.c @@ -619,15 +619,18 @@ static void __devinit n2rng_driver_version(void) pr_info("%s", version); } +static const struct of_device_id n2rng_match[]; static int __devinit n2rng_probe(struct platform_device *op) { + const struct of_device_id *match; int victoria_falls; int err = -ENOMEM; struct n2rng *np; - if (!op->dev.of_match) + match = of_match_device(n2rng_match, &op->dev); + if (!match) return -EINVAL; - victoria_falls = (op->dev.of_match->data != NULL); + victoria_falls = (match->data != NULL); n2rng_driver_version(); np = kzalloc(sizeof(*np), GFP_KERNEL); diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index cc6c9b2546a3..64c6b8530615 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -2554,9 +2554,11 @@ static struct pci_driver ipmi_pci_driver = { }; #endif /* CONFIG_PCI */ +static struct of_device_id ipmi_match[]; static int __devinit ipmi_probe(struct platform_device *dev) { #ifdef CONFIG_OF + const struct of_device_id *match; struct smi_info *info; struct resource resource; const __be32 *regsize, *regspacing, *regshift; @@ -2566,7 +2568,8 @@ static int __devinit ipmi_probe(struct platform_device *dev) dev_info(&dev->dev, "probing via device tree\n"); - if (!dev->dev.of_match) + match = of_match_device(ipmi_match, &dev->dev); + if (!match) return -EINVAL; ret = of_address_to_resource(np, 0, &resource); @@ -2601,7 +2604,7 @@ static int __devinit ipmi_probe(struct platform_device *dev) return -ENOMEM; } - info->si_type = (enum si_type) dev->dev.of_match->data; + info->si_type = (enum si_type) match->data; info->addr_source = SI_DEVICETREE; info->irq_setup = std_irq_setup; diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c index d6412c16385f..39ccdeada791 100644 --- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c +++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c @@ -715,13 +715,13 @@ static int __devexit hwicap_remove(struct device *dev) } #ifdef CONFIG_OF -static int __devinit hwicap_of_probe(struct platform_device *op) +static int __devinit hwicap_of_probe(struct platform_device *op, + const struct hwicap_driver_config *config) { struct resource res; const unsigned int *id; const char *family; int rc; - const struct hwicap_driver_config *config = op->dev.of_match->data; const struct config_registers *regs; @@ -751,20 +751,24 @@ static int __devinit hwicap_of_probe(struct platform_device *op) regs); } #else -static inline int hwicap_of_probe(struct platform_device *op) +static inline int hwicap_of_probe(struct platform_device *op, + const struct hwicap_driver_config *config) { return -EINVAL; } #endif /* CONFIG_OF */ +static const struct of_device_id __devinitconst hwicap_of_match[]; static int __devinit hwicap_drv_probe(struct platform_device *pdev) { + const struct of_device_id *match; struct resource *res; const struct config_registers *regs; const char *family; - if (pdev->dev.of_match) - return hwicap_of_probe(pdev); + match = of_match_device(hwicap_of_match, &pdev->dev); + if (match) + return hwicap_of_probe(pdev, match->data); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) diff --git a/drivers/edac/ppc4xx_edac.c b/drivers/edac/ppc4xx_edac.c index c1f0045ceb8e..af8e7b1aa290 100644 --- a/drivers/edac/ppc4xx_edac.c +++ b/drivers/edac/ppc4xx_edac.c @@ -1019,7 +1019,7 @@ ppc4xx_edac_mc_init(struct mem_ctl_info *mci, struct ppc4xx_edac_pdata *pdata = NULL; const struct device_node *np = op->dev.of_node; - if (op->dev.of_match == NULL) + if (of_match_device(ppc4xx_edac_match, &op->dev) == NULL) return -EINVAL; /* Initial driver pointers and private data */ diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index 75b984c519ac..107397a606b4 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -560,15 +560,18 @@ static struct i2c_adapter mpc_ops = { .timeout = HZ, }; +static const struct of_device_id mpc_i2c_of_match[]; static int __devinit fsl_i2c_probe(struct platform_device *op) { + const struct of_device_id *match; struct mpc_i2c *i2c; const u32 *prop; u32 clock = MPC_I2C_CLOCK_LEGACY; int result = 0; int plen; - if (!op->dev.of_match) + match = of_match_device(mpc_i2c_of_match, &op->dev); + if (!match) return -EINVAL; i2c = kzalloc(sizeof(*i2c), GFP_KERNEL); @@ -605,8 +608,8 @@ static int __devinit fsl_i2c_probe(struct platform_device *op) clock = *prop; } - if (op->dev.of_match->data) { - struct mpc_i2c_data *data = op->dev.of_match->data; + if (match->data) { + struct mpc_i2c_data *data = match->data; data->setup(op->dev.of_node, i2c, clock, data->prescaler); } else { /* Backwards compatibility */ diff --git a/drivers/mmc/host/sdhci-of-core.c b/drivers/mmc/host/sdhci-of-core.c index f9b611fc773e..60e4186a4345 100644 --- a/drivers/mmc/host/sdhci-of-core.c +++ b/drivers/mmc/host/sdhci-of-core.c @@ -124,8 +124,10 @@ static bool __devinit sdhci_of_wp_inverted(struct device_node *np) #endif } +static const struct of_device_id sdhci_of_match[]; static int __devinit sdhci_of_probe(struct platform_device *ofdev) { + const struct of_device_id *match; struct device_node *np = ofdev->dev.of_node; struct sdhci_of_data *sdhci_of_data; struct sdhci_host *host; @@ -134,9 +136,10 @@ static int __devinit sdhci_of_probe(struct platform_device *ofdev) int size; int ret; - if (!ofdev->dev.of_match) + match = of_match_device(sdhci_of_match, &ofdev->dev); + if (!match) return -EINVAL; - sdhci_of_data = ofdev->dev.of_match->data; + sdhci_of_data = match->data; if (!of_device_is_available(np)) return -ENODEV; diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c index bd483f0c57e1..c1d33464aee8 100644 --- a/drivers/mtd/maps/physmap_of.c +++ b/drivers/mtd/maps/physmap_of.c @@ -214,11 +214,13 @@ static void __devinit of_free_probes(const char **probes) } #endif +static struct of_device_id of_flash_match[]; static int __devinit of_flash_probe(struct platform_device *dev) { #ifdef CONFIG_MTD_PARTITIONS const char **part_probe_types; #endif + const struct of_device_id *match; struct device_node *dp = dev->dev.of_node; struct resource res; struct of_flash *info; @@ -232,9 +234,10 @@ static int __devinit of_flash_probe(struct platform_device *dev) struct mtd_info **mtd_list = NULL; resource_size_t res_size; - if (!dev->dev.of_match) + match = of_match_device(of_flash_match, &dev->dev); + if (!match) return -EINVAL; - probe_type = dev->dev.of_match->data; + probe_type = match->data; reg_tuple_size = (of_n_addr_cells(dp) + of_n_size_cells(dp)) * sizeof(u32); diff --git a/drivers/net/can/mscan/mpc5xxx_can.c b/drivers/net/can/mscan/mpc5xxx_can.c index bd1d811c204f..5fedc3375562 100644 --- a/drivers/net/can/mscan/mpc5xxx_can.c +++ b/drivers/net/can/mscan/mpc5xxx_can.c @@ -247,8 +247,10 @@ static u32 __devinit mpc512x_can_get_clock(struct platform_device *ofdev, } #endif /* CONFIG_PPC_MPC512x */ +static struct of_device_id mpc5xxx_can_table[]; static int __devinit mpc5xxx_can_probe(struct platform_device *ofdev) { + const struct of_device_id *match; struct mpc5xxx_can_data *data; struct device_node *np = ofdev->dev.of_node; struct net_device *dev; @@ -258,9 +260,10 @@ static int __devinit mpc5xxx_can_probe(struct platform_device *ofdev) int irq, mscan_clksrc = 0; int err = -ENOMEM; - if (!ofdev->dev.of_match) + match = of_match_device(mpc5xxx_can_table, &ofdev->dev); + if (!match) return -EINVAL; - data = (struct mpc5xxx_can_data *)ofdev->dev.of_match->data; + data = match->data; base = of_iomap(np, 0); if (!base) { diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index 24cb953900dd..5131e61c358c 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c @@ -998,8 +998,10 @@ static const struct net_device_ops fs_enet_netdev_ops = { #endif }; +static struct of_device_id fs_enet_match[]; static int __devinit fs_enet_probe(struct platform_device *ofdev) { + const struct of_device_id *match; struct net_device *ndev; struct fs_enet_private *fep; struct fs_platform_info *fpi; @@ -1007,14 +1009,15 @@ static int __devinit fs_enet_probe(struct platform_device *ofdev) const u8 *mac_addr; int privsize, len, ret = -ENODEV; - if (!ofdev->dev.of_match) + match = of_match_device(fs_enet_match, &ofdev->dev); + if (!match) return -EINVAL; fpi = kzalloc(sizeof(*fpi), GFP_KERNEL); if (!fpi) return -ENOMEM; - if (!IS_FEC(ofdev->dev.of_match)) { + if (!IS_FEC(match)) { data = of_get_property(ofdev->dev.of_node, "fsl,cpm-command", &len); if (!data || len != 4) goto out_free_fpi; @@ -1049,7 +1052,7 @@ static int __devinit fs_enet_probe(struct platform_device *ofdev) fep->dev = &ofdev->dev; fep->ndev = ndev; fep->fpi = fpi; - fep->ops = ofdev->dev.of_match->data; + fep->ops = match->data; ret = fep->ops->setup_data(ndev); if (ret) diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c index 7e840d373ab3..6a2e150e75bb 100644 --- a/drivers/net/fs_enet/mii-fec.c +++ b/drivers/net/fs_enet/mii-fec.c @@ -101,17 +101,20 @@ static int fs_enet_fec_mii_reset(struct mii_bus *bus) return 0; } +static struct of_device_id fs_enet_mdio_fec_match[]; static int __devinit fs_enet_mdio_probe(struct platform_device *ofdev) { + const struct of_device_id *match; struct resource res; struct mii_bus *new_bus; struct fec_info *fec; int (*get_bus_freq)(struct device_node *); int ret = -ENOMEM, clock, speed; - if (!ofdev->dev.of_match) + match = of_match_device(fs_enet_mdio_fec_match, &ofdev->dev); + if (!match) return -EINVAL; - get_bus_freq = ofdev->dev.of_match->data; + get_bus_freq = match->data; new_bus = mdiobus_alloc(); if (!new_bus) diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index eb4f59fb01e9..bff2f7999ff0 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c @@ -3237,15 +3237,18 @@ static void happy_meal_pci_exit(void) #endif #ifdef CONFIG_SBUS +static const struct of_device_id hme_sbus_match[]; static int __devinit hme_sbus_probe(struct platform_device *op) { + const struct of_device_id *match; struct device_node *dp = op->dev.of_node; const char *model = of_get_property(dp, "model", NULL); int is_qfe; - if (!op->dev.of_match) + match = of_match_device(hme_sbus_match, &op->dev); + if (!match) return -EINVAL; - is_qfe = (op->dev.of_match->data != NULL); + is_qfe = (match->data != NULL); if (!is_qfe && model && !strcmp(model, "SUNW,sbus-qfe")) is_qfe = 1; diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c index e2d45c91b8e8..9689d41c7888 100644 --- a/drivers/scsi/qlogicpti.c +++ b/drivers/scsi/qlogicpti.c @@ -1292,8 +1292,10 @@ static struct scsi_host_template qpti_template = { .use_clustering = ENABLE_CLUSTERING, }; +static const struct of_device_id qpti_match[]; static int __devinit qpti_sbus_probe(struct platform_device *op) { + const struct of_device_id *match; struct scsi_host_template *tpnt; struct device_node *dp = op->dev.of_node; struct Scsi_Host *host; @@ -1301,9 +1303,10 @@ static int __devinit qpti_sbus_probe(struct platform_device *op) static int nqptis; const char *fcode; - if (!op->dev.of_match) + match = of_match_device(qpti_match, &op->dev); + if (!match) return -EINVAL; - tpnt = op->dev.of_match->data; + tpnt = match->data; /* Sometimes Antares cards come up not completely * setup, and we get a report of a zero IRQ. diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c index 0e8eec516df4..c911b2419abb 100644 --- a/drivers/tty/serial/of_serial.c +++ b/drivers/tty/serial/of_serial.c @@ -80,14 +80,17 @@ static int __devinit of_platform_serial_setup(struct platform_device *ofdev, /* * Try to register a serial port */ +static struct of_device_id of_platform_serial_table[]; static int __devinit of_platform_serial_probe(struct platform_device *ofdev) { + const struct of_device_id *match; struct of_serial_info *info; struct uart_port port; int port_type; int ret; - if (!ofdev->dev.of_match) + match = of_match_device(of_platform_serial_table, &ofdev->dev); + if (!match) return -EINVAL; if (of_find_property(ofdev->dev.of_node, "used-by-rtas", NULL)) @@ -97,7 +100,7 @@ static int __devinit of_platform_serial_probe(struct platform_device *ofdev) if (info == NULL) return -ENOMEM; - port_type = (unsigned long)ofdev->dev.of_match->data; + port_type = (unsigned long)match->data; ret = of_platform_serial_setup(ofdev, port_type, &port); if (ret) goto out; diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index 36613b37c504..3a68e09309f7 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/fsl_qe_udc.c @@ -2539,15 +2539,18 @@ static void qe_udc_release(struct device *dev) } /* Driver probe functions */ +static const struct of_device_id qe_udc_match[]; static int __devinit qe_udc_probe(struct platform_device *ofdev) { + const struct of_device_id *match; struct device_node *np = ofdev->dev.of_node; struct qe_ep *ep; unsigned int ret = 0; unsigned int i; const void *prop; - if (!ofdev->dev.of_match) + match = of_match_device(qe_udc_match, &ofdev->dev); + if (!match) return -EINVAL; prop = of_get_property(np, "mode", NULL); @@ -2561,7 +2564,7 @@ static int __devinit qe_udc_probe(struct platform_device *ofdev) return -ENOMEM; } - udc_controller->soc_type = (unsigned long)ofdev->dev.of_match->data; + udc_controller->soc_type = (unsigned long)match->data; udc_controller->usb_regs = of_iomap(np, 0); if (!udc_controller->usb_regs) { ret = -ENOMEM; diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c index 528bceb220fd..eed5436ffb51 100644 --- a/drivers/watchdog/mpc8xxx_wdt.c +++ b/drivers/watchdog/mpc8xxx_wdt.c @@ -185,17 +185,20 @@ static struct miscdevice mpc8xxx_wdt_miscdev = { .fops = &mpc8xxx_wdt_fops, }; +static const struct of_device_id mpc8xxx_wdt_match[]; static int __devinit mpc8xxx_wdt_probe(struct platform_device *ofdev) { int ret; + const struct of_device_id *match; struct device_node *np = ofdev->dev.of_node; struct mpc8xxx_wdt_type *wdt_type; u32 freq = fsl_get_sys_freq(); bool enabled; - if (!ofdev->dev.of_match) + match = of_match_device(mpc8xxx_wdt_match, &ofdev->dev); + if (!match) return -EINVAL; - wdt_type = ofdev->dev.of_match->data; + wdt_type = match->data; if (!freq || freq == -1) return -EINVAL; diff --git a/include/linux/device.h b/include/linux/device.h index ab8dfc095709..d08399db6e2c 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -442,7 +442,6 @@ struct device { struct dev_archdata archdata; struct device_node *of_node; /* associated device tree node */ - const struct of_device_id *of_match; /* matching of_device_id from driver */ dev_t devt; /* dev_t, creates the sysfs "dev" */ diff --git a/include/linux/of_device.h b/include/linux/of_device.h index b33d68814a73..ae5638480ef2 100644 --- a/include/linux/of_device.h +++ b/include/linux/of_device.h @@ -21,12 +21,7 @@ extern void of_device_make_bus_id(struct device *dev); static inline int of_driver_match_device(struct device *dev, const struct device_driver *drv) { - const struct of_device_id *match; - - match = of_match_device(drv->of_match_table, dev); - if (match) - dev->of_match = match; - return match != NULL; + return of_match_device(drv->of_match_table, dev) != NULL; } extern struct platform_device *of_dev_get(struct platform_device *dev); @@ -62,6 +57,11 @@ static inline int of_device_uevent(struct device *dev, static inline void of_device_node_put(struct device *dev) { } +static inline const struct of_device_id *of_match_device( + const struct of_device_id *matches, const struct device *dev) +{ + return NULL; +} #endif /* CONFIG_OF_DEVICE */ #endif /* _LINUX_OF_DEVICE_H */ -- cgit From b448c4e3ae6d20108dba1d7833f2c0d3dbad87ce Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 29 Apr 2011 15:12:32 -0400 Subject: ftrace: Replace FTRACE_FL_NOTRACE flag with a hash of ignored functions To prepare for the accounting system that will allow multiple users of the function tracer, having the FTRACE_FL_NOTRACE as a flag in the dyn_trace record does not make sense. All ftrace_ops will soon have a hash of functions they should trace and not trace. By making a global hash of functions not to trace makes this easier for the transition. Signed-off-by: Steven Rostedt --- include/linux/ftrace.h | 1 - kernel/trace/ftrace.c | 176 +++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 150 insertions(+), 27 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 32047449b309..fe0a90a09243 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -149,7 +149,6 @@ enum { FTRACE_FL_FREE = (1 << 0), FTRACE_FL_FILTER = (1 << 1), FTRACE_FL_ENABLED = (1 << 2), - FTRACE_FL_NOTRACE = (1 << 3), }; struct dyn_ftrace { diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index d3406346ced6..04c002a491fb 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -57,6 +57,7 @@ /* hash bits for specific function selection */ #define FTRACE_HASH_BITS 7 #define FTRACE_FUNC_HASHSIZE (1 << FTRACE_HASH_BITS) +#define FTRACE_HASH_MAX_BITS 10 /* ftrace_enabled is a method to turn ftrace on or off */ int ftrace_enabled __read_mostly; @@ -865,6 +866,22 @@ enum { FTRACE_START_FUNC_RET = (1 << 3), FTRACE_STOP_FUNC_RET = (1 << 4), }; +struct ftrace_func_entry { + struct hlist_node hlist; + unsigned long ip; +}; + +struct ftrace_hash { + unsigned long size_bits; + struct hlist_head *buckets; + unsigned long count; +}; + +static struct hlist_head notrace_buckets[1 << FTRACE_HASH_MAX_BITS]; +static struct ftrace_hash notrace_hash = { + .size_bits = FTRACE_HASH_MAX_BITS, + .buckets = notrace_buckets, +}; static int ftrace_filtered; @@ -889,6 +906,79 @@ static struct ftrace_page *ftrace_pages; static struct dyn_ftrace *ftrace_free_records; +static struct ftrace_func_entry * +ftrace_lookup_ip(struct ftrace_hash *hash, unsigned long ip) +{ + unsigned long key; + struct ftrace_func_entry *entry; + struct hlist_head *hhd; + struct hlist_node *n; + + if (!hash->count) + return NULL; + + if (hash->size_bits > 0) + key = hash_long(ip, hash->size_bits); + else + key = 0; + + hhd = &hash->buckets[key]; + + hlist_for_each_entry_rcu(entry, n, hhd, hlist) { + if (entry->ip == ip) + return entry; + } + return NULL; +} + +static int add_hash_entry(struct ftrace_hash *hash, unsigned long ip) +{ + struct ftrace_func_entry *entry; + struct hlist_head *hhd; + unsigned long key; + + entry = kmalloc(sizeof(*entry), GFP_KERNEL); + if (!entry) + return -ENOMEM; + + if (hash->size_bits) + key = hash_long(ip, hash->size_bits); + else + key = 0; + + entry->ip = ip; + hhd = &hash->buckets[key]; + hlist_add_head(&entry->hlist, hhd); + hash->count++; + + return 0; +} + +static void +remove_hash_entry(struct ftrace_hash *hash, + struct ftrace_func_entry *entry) +{ + hlist_del(&entry->hlist); + kfree(entry); + hash->count--; +} + +static void ftrace_hash_clear(struct ftrace_hash *hash) +{ + struct hlist_head *hhd; + struct hlist_node *tp, *tn; + struct ftrace_func_entry *entry; + int size = 1 << hash->size_bits; + int i; + + for (i = 0; i < size; i++) { + hhd = &hash->buckets[i]; + hlist_for_each_entry_safe(entry, tp, tn, hhd, hlist) + remove_hash_entry(hash, entry); + } + FTRACE_WARN_ON(hash->count); +} + /* * This is a double for. Do not use 'break' to break out of the loop, * you must use a goto. @@ -1032,7 +1122,7 @@ __ftrace_replace_code(struct dyn_ftrace *rec, int enable) * If we want to enable it and filtering is on, enable it only if * it's filtered */ - if (enable && !(rec->flags & FTRACE_FL_NOTRACE)) { + if (enable && !ftrace_lookup_ip(¬race_hash, rec->ip)) { if (!ftrace_filtered || (rec->flags & FTRACE_FL_FILTER)) flag = FTRACE_FL_ENABLED; } @@ -1465,7 +1555,7 @@ t_next(struct seq_file *m, void *v, loff_t *pos) !(rec->flags & FTRACE_FL_FILTER)) || ((iter->flags & FTRACE_ITER_NOTRACE) && - !(rec->flags & FTRACE_FL_NOTRACE))) { + !ftrace_lookup_ip(¬race_hash, rec->ip))) { rec = NULL; goto retry; } @@ -1609,14 +1699,15 @@ static void ftrace_filter_reset(int enable) { struct ftrace_page *pg; struct dyn_ftrace *rec; - unsigned long type = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE; mutex_lock(&ftrace_lock); - if (enable) + if (enable) { ftrace_filtered = 0; - do_for_each_ftrace_rec(pg, rec) { - rec->flags &= ~type; - } while_for_each_ftrace_rec(); + do_for_each_ftrace_rec(pg, rec) { + rec->flags &= ~FTRACE_FL_FILTER; + } while_for_each_ftrace_rec(); + } else + ftrace_hash_clear(¬race_hash); mutex_unlock(&ftrace_lock); } @@ -1716,13 +1807,36 @@ static int ftrace_match(char *str, char *regex, int len, int type) return matched; } -static void -update_record(struct dyn_ftrace *rec, unsigned long flag, int not) +static int +update_record(struct dyn_ftrace *rec, int enable, int not) { - if (not) - rec->flags &= ~flag; - else - rec->flags |= flag; + struct ftrace_func_entry *entry; + struct ftrace_hash *hash = ¬race_hash; + int ret = 0; + + if (enable) { + if (not) + rec->flags &= ~FTRACE_FL_FILTER; + else + rec->flags |= FTRACE_FL_FILTER; + } else { + if (not) { + /* Do nothing if it doesn't exist */ + entry = ftrace_lookup_ip(hash, rec->ip); + if (!entry) + return 0; + + remove_hash_entry(hash, entry); + } else { + /* Do nothing if it exists */ + entry = ftrace_lookup_ip(hash, rec->ip); + if (entry) + return 0; + + ret = add_hash_entry(hash, rec->ip); + } + } + return ret; } static int @@ -1754,16 +1868,14 @@ static int match_records(char *buff, int len, char *mod, int enable, int not) struct dyn_ftrace *rec; int type = MATCH_FULL; char *search = buff; - unsigned long flag; int found = 0; + int ret; if (len) { type = filter_parse_regex(buff, len, &search, ¬); search_len = strlen(search); } - flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE; - mutex_lock(&ftrace_lock); if (unlikely(ftrace_disabled)) @@ -1772,7 +1884,11 @@ static int match_records(char *buff, int len, char *mod, int enable, int not) do_for_each_ftrace_rec(pg, rec) { if (ftrace_match_record(rec, mod, search, search_len, type)) { - update_record(rec, flag, not); + ret = update_record(rec, enable, not); + if (ret < 0) { + found = ret; + goto out_unlock; + } found = 1; } /* @@ -1821,6 +1937,7 @@ static int ftrace_mod_callback(char *func, char *cmd, char *param, int enable) { char *mod; + int ret = -EINVAL; /* * cmd == 'mod' because we only registered this func @@ -1832,15 +1949,19 @@ ftrace_mod_callback(char *func, char *cmd, char *param, int enable) /* we must have a module name */ if (!param) - return -EINVAL; + return ret; mod = strsep(¶m, ":"); if (!strlen(mod)) - return -EINVAL; + return ret; - if (ftrace_match_module_records(func, mod, enable)) - return 0; - return -EINVAL; + ret = ftrace_match_module_records(func, mod, enable); + if (!ret) + ret = -EINVAL; + if (ret < 0) + return ret; + + return 0; } static struct ftrace_func_command ftrace_mod_cmd = { @@ -2132,14 +2253,17 @@ static int ftrace_process_regex(char *buff, int len, int enable) { char *func, *command, *next = buff; struct ftrace_func_command *p; - int ret = -EINVAL; + int ret; func = strsep(&next, ":"); if (!next) { - if (ftrace_match_records(func, len, enable)) - return 0; - return ret; + ret = ftrace_match_records(func, len, enable); + if (!ret) + ret = -EINVAL; + if (ret < 0) + return ret; + return 0; } /* command found */ -- cgit From 1cf41dd79993389b012e4542ab502ce36ae7343f Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 29 Apr 2011 20:59:51 -0400 Subject: ftrace: Use hash instead for FTRACE_FL_FILTER When multiple users are allowed to have their own set of functions to trace, having the FTRACE_FL_FILTER flag will not be enough to handle the accounting of those users. Each user will need their own set of functions. Replace the FTRACE_FL_FILTER with a filter_hash instead. This is temporary until the rest of the function filtering accounting gets in. Signed-off-by: Steven Rostedt --- include/linux/ftrace.h | 3 +- kernel/trace/ftrace.c | 151 ++++++++++++++++++++++--------------------------- 2 files changed, 70 insertions(+), 84 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index fe0a90a09243..52fc5d4e6edd 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -147,8 +147,7 @@ extern int ftrace_text_reserved(void *start, void *end); enum { FTRACE_FL_FREE = (1 << 0), - FTRACE_FL_FILTER = (1 << 1), - FTRACE_FL_ENABLED = (1 << 2), + FTRACE_FL_ENABLED = (1 << 1), }; struct dyn_ftrace { diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 04c002a491fb..222eca4c3022 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -883,7 +883,11 @@ static struct ftrace_hash notrace_hash = { .buckets = notrace_buckets, }; -static int ftrace_filtered; +static struct hlist_head filter_buckets[1 << FTRACE_HASH_MAX_BITS]; +static struct ftrace_hash filter_hash = { + .size_bits = FTRACE_HASH_MAX_BITS, + .buckets = filter_buckets, +}; static struct dyn_ftrace *ftrace_new_addrs; @@ -1123,7 +1127,7 @@ __ftrace_replace_code(struct dyn_ftrace *rec, int enable) * it's filtered */ if (enable && !ftrace_lookup_ip(¬race_hash, rec->ip)) { - if (!ftrace_filtered || (rec->flags & FTRACE_FL_FILTER)) + if (!filter_hash.count || ftrace_lookup_ip(&filter_hash, rec->ip)) flag = FTRACE_FL_ENABLED; } @@ -1430,6 +1434,7 @@ struct ftrace_iterator { struct dyn_ftrace *func; struct ftrace_func_probe *probe; struct trace_parser parser; + struct ftrace_hash *hash; int hidx; int idx; unsigned flags; @@ -1552,7 +1557,7 @@ t_next(struct seq_file *m, void *v, loff_t *pos) if ((rec->flags & FTRACE_FL_FREE) || ((iter->flags & FTRACE_ITER_FILTER) && - !(rec->flags & FTRACE_FL_FILTER)) || + !(ftrace_lookup_ip(&filter_hash, rec->ip))) || ((iter->flags & FTRACE_ITER_NOTRACE) && !ftrace_lookup_ip(¬race_hash, rec->ip))) { @@ -1598,7 +1603,7 @@ static void *t_start(struct seq_file *m, loff_t *pos) * off, we can short cut and just print out that all * functions are enabled. */ - if (iter->flags & FTRACE_ITER_FILTER && !ftrace_filtered) { + if (iter->flags & FTRACE_ITER_FILTER && !filter_hash.count) { if (*pos > 0) return t_hash_start(m, pos); iter->flags |= FTRACE_ITER_PRINTALL; @@ -1695,24 +1700,16 @@ ftrace_avail_open(struct inode *inode, struct file *file) return ret; } -static void ftrace_filter_reset(int enable) +static void ftrace_filter_reset(struct ftrace_hash *hash) { - struct ftrace_page *pg; - struct dyn_ftrace *rec; - mutex_lock(&ftrace_lock); - if (enable) { - ftrace_filtered = 0; - do_for_each_ftrace_rec(pg, rec) { - rec->flags &= ~FTRACE_FL_FILTER; - } while_for_each_ftrace_rec(); - } else - ftrace_hash_clear(¬race_hash); + ftrace_hash_clear(hash); mutex_unlock(&ftrace_lock); } static int -ftrace_regex_open(struct inode *inode, struct file *file, int enable) +ftrace_regex_open(struct ftrace_hash *hash, int flag, + struct inode *inode, struct file *file) { struct ftrace_iterator *iter; int ret = 0; @@ -1729,15 +1726,16 @@ ftrace_regex_open(struct inode *inode, struct file *file, int enable) return -ENOMEM; } + iter->hash = hash; + mutex_lock(&ftrace_regex_lock); if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) - ftrace_filter_reset(enable); + ftrace_filter_reset(hash); if (file->f_mode & FMODE_READ) { iter->pg = ftrace_pages_start; - iter->flags = enable ? FTRACE_ITER_FILTER : - FTRACE_ITER_NOTRACE; + iter->flags = flag; ret = seq_open(file, &show_ftrace_seq_ops); if (!ret) { @@ -1757,13 +1755,15 @@ ftrace_regex_open(struct inode *inode, struct file *file, int enable) static int ftrace_filter_open(struct inode *inode, struct file *file) { - return ftrace_regex_open(inode, file, 1); + return ftrace_regex_open(&filter_hash, FTRACE_ITER_FILTER, + inode, file); } static int ftrace_notrace_open(struct inode *inode, struct file *file) { - return ftrace_regex_open(inode, file, 0); + return ftrace_regex_open(¬race_hash, FTRACE_ITER_NOTRACE, + inode, file); } static loff_t @@ -1808,33 +1808,24 @@ static int ftrace_match(char *str, char *regex, int len, int type) } static int -update_record(struct dyn_ftrace *rec, int enable, int not) +enter_record(struct ftrace_hash *hash, struct dyn_ftrace *rec, int not) { struct ftrace_func_entry *entry; - struct ftrace_hash *hash = ¬race_hash; int ret = 0; - if (enable) { - if (not) - rec->flags &= ~FTRACE_FL_FILTER; - else - rec->flags |= FTRACE_FL_FILTER; - } else { - if (not) { - /* Do nothing if it doesn't exist */ - entry = ftrace_lookup_ip(hash, rec->ip); - if (!entry) - return 0; + entry = ftrace_lookup_ip(hash, rec->ip); + if (not) { + /* Do nothing if it doesn't exist */ + if (!entry) + return 0; - remove_hash_entry(hash, entry); - } else { - /* Do nothing if it exists */ - entry = ftrace_lookup_ip(hash, rec->ip); - if (entry) - return 0; + remove_hash_entry(hash, entry); + } else { + /* Do nothing if it exists */ + if (entry) + return 0; - ret = add_hash_entry(hash, rec->ip); - } + ret = add_hash_entry(hash, rec->ip); } return ret; } @@ -1861,7 +1852,9 @@ ftrace_match_record(struct dyn_ftrace *rec, char *mod, return ftrace_match(str, regex, len, type); } -static int match_records(char *buff, int len, char *mod, int enable, int not) +static int +match_records(struct ftrace_hash *hash, char *buff, + int len, char *mod, int not) { unsigned search_len = 0; struct ftrace_page *pg; @@ -1884,20 +1877,13 @@ static int match_records(char *buff, int len, char *mod, int enable, int not) do_for_each_ftrace_rec(pg, rec) { if (ftrace_match_record(rec, mod, search, search_len, type)) { - ret = update_record(rec, enable, not); + ret = enter_record(hash, rec, not); if (ret < 0) { found = ret; goto out_unlock; } found = 1; } - /* - * Only enable filtering if we have a function that - * is filtered on. - */ - if (enable && (rec->flags & FTRACE_FL_FILTER)) - ftrace_filtered = 1; - } while_for_each_ftrace_rec(); out_unlock: mutex_unlock(&ftrace_lock); @@ -1906,12 +1892,13 @@ static int match_records(char *buff, int len, char *mod, int enable, int not) } static int -ftrace_match_records(char *buff, int len, int enable) +ftrace_match_records(struct ftrace_hash *hash, char *buff, int len) { - return match_records(buff, len, NULL, enable, 0); + return match_records(hash, buff, len, NULL, 0); } -static int ftrace_match_module_records(char *buff, char *mod, int enable) +static int +ftrace_match_module_records(struct ftrace_hash *hash, char *buff, char *mod) { int not = 0; @@ -1925,7 +1912,7 @@ static int ftrace_match_module_records(char *buff, char *mod, int enable) not = 1; } - return match_records(buff, strlen(buff), mod, enable, not); + return match_records(hash, buff, strlen(buff), mod, not); } /* @@ -1936,6 +1923,7 @@ static int ftrace_match_module_records(char *buff, char *mod, int enable) static int ftrace_mod_callback(char *func, char *cmd, char *param, int enable) { + struct ftrace_hash *hash; char *mod; int ret = -EINVAL; @@ -1955,7 +1943,12 @@ ftrace_mod_callback(char *func, char *cmd, char *param, int enable) if (!strlen(mod)) return ret; - ret = ftrace_match_module_records(func, mod, enable); + if (enable) + hash = &filter_hash; + else + hash = ¬race_hash; + + ret = ftrace_match_module_records(hash, func, mod); if (!ret) ret = -EINVAL; if (ret < 0) @@ -2253,12 +2246,18 @@ static int ftrace_process_regex(char *buff, int len, int enable) { char *func, *command, *next = buff; struct ftrace_func_command *p; + struct ftrace_hash *hash; int ret; + if (enable) + hash = &filter_hash; + else + hash = ¬race_hash; + func = strsep(&next, ":"); if (!next) { - ret = ftrace_match_records(func, len, enable); + ret = ftrace_match_records(hash, func, len); if (!ret) ret = -EINVAL; if (ret < 0) @@ -2340,16 +2339,16 @@ ftrace_notrace_write(struct file *file, const char __user *ubuf, } static void -ftrace_set_regex(unsigned char *buf, int len, int reset, int enable) +ftrace_set_regex(struct ftrace_hash *hash, unsigned char *buf, int len, int reset) { if (unlikely(ftrace_disabled)) return; mutex_lock(&ftrace_regex_lock); if (reset) - ftrace_filter_reset(enable); + ftrace_filter_reset(hash); if (buf) - ftrace_match_records(buf, len, enable); + ftrace_match_records(hash, buf, len); mutex_unlock(&ftrace_regex_lock); } @@ -2364,7 +2363,7 @@ ftrace_set_regex(unsigned char *buf, int len, int reset, int enable) */ void ftrace_set_filter(unsigned char *buf, int len, int reset) { - ftrace_set_regex(buf, len, reset, 1); + ftrace_set_regex(&filter_hash, buf, len, reset); } /** @@ -2379,7 +2378,7 @@ void ftrace_set_filter(unsigned char *buf, int len, int reset) */ void ftrace_set_notrace(unsigned char *buf, int len, int reset) { - ftrace_set_regex(buf, len, reset, 0); + ftrace_set_regex(¬race_hash, buf, len, reset); } /* @@ -2431,22 +2430,22 @@ static void __init set_ftrace_early_graph(char *buf) } #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ -static void __init set_ftrace_early_filter(char *buf, int enable) +static void __init set_ftrace_early_filter(struct ftrace_hash *hash, char *buf) { char *func; while (buf) { func = strsep(&buf, ","); - ftrace_set_regex(func, strlen(func), 0, enable); + ftrace_set_regex(hash, func, strlen(func), 0); } } static void __init set_ftrace_early_filters(void) { if (ftrace_filter_buf[0]) - set_ftrace_early_filter(ftrace_filter_buf, 1); + set_ftrace_early_filter(&filter_hash, ftrace_filter_buf); if (ftrace_notrace_buf[0]) - set_ftrace_early_filter(ftrace_notrace_buf, 0); + set_ftrace_early_filter(¬race_hash, ftrace_notrace_buf); #ifdef CONFIG_FUNCTION_GRAPH_TRACER if (ftrace_graph_buf[0]) set_ftrace_early_graph(ftrace_graph_buf); @@ -2454,7 +2453,7 @@ static void __init set_ftrace_early_filters(void) } static int -ftrace_regex_release(struct inode *inode, struct file *file, int enable) +ftrace_regex_release(struct inode *inode, struct file *file) { struct seq_file *m = (struct seq_file *)file->private_data; struct ftrace_iterator *iter; @@ -2471,7 +2470,7 @@ ftrace_regex_release(struct inode *inode, struct file *file, int enable) parser = &iter->parser; if (trace_parser_loaded(parser)) { parser->buffer[parser->idx] = 0; - ftrace_match_records(parser->buffer, parser->idx, enable); + ftrace_match_records(iter->hash, parser->buffer, parser->idx); } trace_parser_put(parser); @@ -2488,18 +2487,6 @@ ftrace_regex_release(struct inode *inode, struct file *file, int enable) return 0; } -static int -ftrace_filter_release(struct inode *inode, struct file *file) -{ - return ftrace_regex_release(inode, file, 1); -} - -static int -ftrace_notrace_release(struct inode *inode, struct file *file) -{ - return ftrace_regex_release(inode, file, 0); -} - static const struct file_operations ftrace_avail_fops = { .open = ftrace_avail_open, .read = seq_read, @@ -2512,7 +2499,7 @@ static const struct file_operations ftrace_filter_fops = { .read = seq_read, .write = ftrace_filter_write, .llseek = ftrace_regex_lseek, - .release = ftrace_filter_release, + .release = ftrace_regex_release, }; static const struct file_operations ftrace_notrace_fops = { @@ -2520,7 +2507,7 @@ static const struct file_operations ftrace_notrace_fops = { .read = seq_read, .write = ftrace_notrace_write, .llseek = ftrace_regex_lseek, - .release = ftrace_notrace_release, + .release = ftrace_regex_release, }; #ifdef CONFIG_FUNCTION_GRAPH_TRACER -- cgit From f45948e898e7bc76a73a468796d2ce80dd040058 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 2 May 2011 12:29:25 -0400 Subject: ftrace: Create a global_ops to hold the filter and notrace hashes Combine the filter and notrace hashes to be accessed by a single entity, the global_ops. The global_ops is a ftrace_ops structure that is passed to different functions that can read or modify the filtering of the function tracer. The ftrace_ops structure was modified to hold a filter and notrace hashes so that later patches may allow each ftrace_ops to have its own set of rules to what functions may be filtered. Signed-off-by: Steven Rostedt --- include/linux/ftrace.h | 10 ++++++-- kernel/trace/ftrace.c | 65 +++++++++++++++++++++++++++++++++++--------------- 2 files changed, 54 insertions(+), 21 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 52fc5d4e6edd..6658a51390fe 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -29,9 +29,15 @@ ftrace_enable_sysctl(struct ctl_table *table, int write, typedef void (*ftrace_func_t)(unsigned long ip, unsigned long parent_ip); +struct ftrace_hash; + struct ftrace_ops { - ftrace_func_t func; - struct ftrace_ops *next; + ftrace_func_t func; + struct ftrace_ops *next; +#ifdef CONFIG_DYNAMIC_FTRACE + struct ftrace_hash *notrace_hash; + struct ftrace_hash *filter_hash; +#endif }; extern int function_trace_stop; diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 222eca4c3022..a517a6c40645 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -889,6 +889,12 @@ static struct ftrace_hash filter_hash = { .buckets = filter_buckets, }; +struct ftrace_ops global_ops = { + .func = ftrace_stub, + .notrace_hash = ¬race_hash, + .filter_hash = &filter_hash, +}; + static struct dyn_ftrace *ftrace_new_addrs; static DEFINE_MUTEX(ftrace_regex_lock); @@ -1112,6 +1118,7 @@ int ftrace_text_reserved(void *start, void *end) static int __ftrace_replace_code(struct dyn_ftrace *rec, int enable) { + struct ftrace_ops *ops = &global_ops; unsigned long ftrace_addr; unsigned long flag = 0UL; @@ -1126,8 +1133,9 @@ __ftrace_replace_code(struct dyn_ftrace *rec, int enable) * If we want to enable it and filtering is on, enable it only if * it's filtered */ - if (enable && !ftrace_lookup_ip(¬race_hash, rec->ip)) { - if (!filter_hash.count || ftrace_lookup_ip(&filter_hash, rec->ip)) + if (enable && !ftrace_lookup_ip(ops->notrace_hash, rec->ip)) { + if (!ops->filter_hash->count || + ftrace_lookup_ip(ops->filter_hash, rec->ip)) flag = FTRACE_FL_ENABLED; } @@ -1531,6 +1539,7 @@ static void * t_next(struct seq_file *m, void *v, loff_t *pos) { struct ftrace_iterator *iter = m->private; + struct ftrace_ops *ops = &global_ops; struct dyn_ftrace *rec = NULL; if (unlikely(ftrace_disabled)) @@ -1557,10 +1566,10 @@ t_next(struct seq_file *m, void *v, loff_t *pos) if ((rec->flags & FTRACE_FL_FREE) || ((iter->flags & FTRACE_ITER_FILTER) && - !(ftrace_lookup_ip(&filter_hash, rec->ip))) || + !(ftrace_lookup_ip(ops->filter_hash, rec->ip))) || ((iter->flags & FTRACE_ITER_NOTRACE) && - !ftrace_lookup_ip(¬race_hash, rec->ip))) { + !ftrace_lookup_ip(ops->notrace_hash, rec->ip))) { rec = NULL; goto retry; } @@ -1584,6 +1593,7 @@ static void reset_iter_read(struct ftrace_iterator *iter) static void *t_start(struct seq_file *m, loff_t *pos) { struct ftrace_iterator *iter = m->private; + struct ftrace_ops *ops = &global_ops; void *p = NULL; loff_t l; @@ -1603,7 +1613,7 @@ static void *t_start(struct seq_file *m, loff_t *pos) * off, we can short cut and just print out that all * functions are enabled. */ - if (iter->flags & FTRACE_ITER_FILTER && !filter_hash.count) { + if (iter->flags & FTRACE_ITER_FILTER && !ops->filter_hash->count) { if (*pos > 0) return t_hash_start(m, pos); iter->flags |= FTRACE_ITER_PRINTALL; @@ -1708,10 +1718,11 @@ static void ftrace_filter_reset(struct ftrace_hash *hash) } static int -ftrace_regex_open(struct ftrace_hash *hash, int flag, +ftrace_regex_open(struct ftrace_ops *ops, int flag, struct inode *inode, struct file *file) { struct ftrace_iterator *iter; + struct ftrace_hash *hash; int ret = 0; if (unlikely(ftrace_disabled)) @@ -1726,6 +1737,11 @@ ftrace_regex_open(struct ftrace_hash *hash, int flag, return -ENOMEM; } + if (flag & FTRACE_ITER_NOTRACE) + hash = ops->notrace_hash; + else + hash = ops->filter_hash; + iter->hash = hash; mutex_lock(&ftrace_regex_lock); @@ -1755,14 +1771,14 @@ ftrace_regex_open(struct ftrace_hash *hash, int flag, static int ftrace_filter_open(struct inode *inode, struct file *file) { - return ftrace_regex_open(&filter_hash, FTRACE_ITER_FILTER, + return ftrace_regex_open(&global_ops, FTRACE_ITER_FILTER, inode, file); } static int ftrace_notrace_open(struct inode *inode, struct file *file) { - return ftrace_regex_open(¬race_hash, FTRACE_ITER_NOTRACE, + return ftrace_regex_open(&global_ops, FTRACE_ITER_NOTRACE, inode, file); } @@ -1923,6 +1939,7 @@ ftrace_match_module_records(struct ftrace_hash *hash, char *buff, char *mod) static int ftrace_mod_callback(char *func, char *cmd, char *param, int enable) { + struct ftrace_ops *ops = &global_ops; struct ftrace_hash *hash; char *mod; int ret = -EINVAL; @@ -1944,9 +1961,9 @@ ftrace_mod_callback(char *func, char *cmd, char *param, int enable) return ret; if (enable) - hash = &filter_hash; + hash = ops->filter_hash; else - hash = ¬race_hash; + hash = ops->notrace_hash; ret = ftrace_match_module_records(hash, func, mod); if (!ret) @@ -2245,14 +2262,15 @@ int unregister_ftrace_command(struct ftrace_func_command *cmd) static int ftrace_process_regex(char *buff, int len, int enable) { char *func, *command, *next = buff; + struct ftrace_ops *ops = &global_ops; struct ftrace_func_command *p; struct ftrace_hash *hash; int ret; if (enable) - hash = &filter_hash; + hash = ops->filter_hash; else - hash = ¬race_hash; + hash = ops->notrace_hash; func = strsep(&next, ":"); @@ -2339,11 +2357,19 @@ ftrace_notrace_write(struct file *file, const char __user *ubuf, } static void -ftrace_set_regex(struct ftrace_hash *hash, unsigned char *buf, int len, int reset) +ftrace_set_regex(struct ftrace_ops *ops, unsigned char *buf, int len, + int reset, int enable) { + struct ftrace_hash *hash; + if (unlikely(ftrace_disabled)) return; + if (enable) + hash = ops->filter_hash; + else + hash = ops->notrace_hash; + mutex_lock(&ftrace_regex_lock); if (reset) ftrace_filter_reset(hash); @@ -2363,7 +2389,7 @@ ftrace_set_regex(struct ftrace_hash *hash, unsigned char *buf, int len, int rese */ void ftrace_set_filter(unsigned char *buf, int len, int reset) { - ftrace_set_regex(&filter_hash, buf, len, reset); + ftrace_set_regex(&global_ops, buf, len, reset, 1); } /** @@ -2378,7 +2404,7 @@ void ftrace_set_filter(unsigned char *buf, int len, int reset) */ void ftrace_set_notrace(unsigned char *buf, int len, int reset) { - ftrace_set_regex(¬race_hash, buf, len, reset); + ftrace_set_regex(&global_ops, buf, len, reset, 0); } /* @@ -2430,22 +2456,23 @@ static void __init set_ftrace_early_graph(char *buf) } #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ -static void __init set_ftrace_early_filter(struct ftrace_hash *hash, char *buf) +static void __init +set_ftrace_early_filter(struct ftrace_ops *ops, char *buf, int enable) { char *func; while (buf) { func = strsep(&buf, ","); - ftrace_set_regex(hash, func, strlen(func), 0); + ftrace_set_regex(ops, func, strlen(func), 0, enable); } } static void __init set_ftrace_early_filters(void) { if (ftrace_filter_buf[0]) - set_ftrace_early_filter(&filter_hash, ftrace_filter_buf); + set_ftrace_early_filter(&global_ops, ftrace_filter_buf, 1); if (ftrace_notrace_buf[0]) - set_ftrace_early_filter(¬race_hash, ftrace_notrace_buf); + set_ftrace_early_filter(&global_ops, ftrace_notrace_buf, 0); #ifdef CONFIG_FUNCTION_GRAPH_TRACER if (ftrace_graph_buf[0]) set_ftrace_early_graph(ftrace_graph_buf); -- cgit From ed926f9b35cda0988234c356e16a7cb30f4e5338 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 3 May 2011 13:25:24 -0400 Subject: ftrace: Use counters to enable functions to trace Every function has its own record that stores the instruction pointer and flags for the function to be traced. There are only two flags: enabled and free. The enabled flag states that tracing for the function has been enabled (actively traced), and the free flag states that the record no longer points to a function and can be used by new functions (loaded modules). These flags are now moved to the MSB of the flags (actually just the top 32bits). The rest of the bits (30 bits) are now used as a ref counter. Everytime a tracer register functions to trace, those functions will have its counter incremented. When tracing is enabled, to determine if a function should be traced, the counter is examined, and if it is non-zero it is set to trace. When a ftrace_ops is registered to trace functions, its hashes are examined. If the ftrace_ops filter_hash count is zero, then all functions are set to be traced, otherwise only the functions in the hash are to be traced. The exception to this is if a function is also in the ftrace_ops notrace_hash. Then that function's counter is not incremented for this ftrace_ops. Signed-off-by: Steven Rostedt --- include/linux/ftrace.h | 8 ++- kernel/trace/ftrace.c | 158 ++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 148 insertions(+), 18 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 6658a51390fe..ab1c46e70bb6 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -37,6 +37,7 @@ struct ftrace_ops { #ifdef CONFIG_DYNAMIC_FTRACE struct ftrace_hash *notrace_hash; struct ftrace_hash *filter_hash; + unsigned long flags; #endif }; @@ -152,10 +153,13 @@ extern void unregister_ftrace_function_probe_all(char *glob); extern int ftrace_text_reserved(void *start, void *end); enum { - FTRACE_FL_FREE = (1 << 0), - FTRACE_FL_ENABLED = (1 << 1), + FTRACE_FL_ENABLED = (1 << 30), + FTRACE_FL_FREE = (1 << 31), }; +#define FTRACE_FL_MASK (0x3UL << 30) +#define FTRACE_REF_MAX ((1 << 30) - 1) + struct dyn_ftrace { union { unsigned long ip; /* address of mcount call-site */ diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 46f08264980b..5dd332cc5aa8 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -890,6 +890,10 @@ static const struct ftrace_hash empty_hash = { }; #define EMPTY_HASH ((struct ftrace_hash *)&empty_hash) +enum { + FTRACE_OPS_FL_ENABLED = 1, +}; + struct ftrace_ops global_ops = { .func = ftrace_stub, .notrace_hash = EMPTY_HASH, @@ -1161,6 +1165,105 @@ ftrace_hash_move(struct ftrace_hash **dst, struct ftrace_hash *src) } \ } +static void __ftrace_hash_rec_update(struct ftrace_ops *ops, + int filter_hash, + bool inc) +{ + struct ftrace_hash *hash; + struct ftrace_hash *other_hash; + struct ftrace_page *pg; + struct dyn_ftrace *rec; + int count = 0; + int all = 0; + + /* Only update if the ops has been registered */ + if (!(ops->flags & FTRACE_OPS_FL_ENABLED)) + return; + + /* + * In the filter_hash case: + * If the count is zero, we update all records. + * Otherwise we just update the items in the hash. + * + * In the notrace_hash case: + * We enable the update in the hash. + * As disabling notrace means enabling the tracing, + * and enabling notrace means disabling, the inc variable + * gets inversed. + */ + if (filter_hash) { + hash = ops->filter_hash; + other_hash = ops->notrace_hash; + if (!hash->count) + all = 1; + } else { + inc = !inc; + hash = ops->notrace_hash; + other_hash = ops->filter_hash; + /* + * If the notrace hash has no items, + * then there's nothing to do. + */ + if (!hash->count) + return; + } + + do_for_each_ftrace_rec(pg, rec) { + int in_other_hash = 0; + int in_hash = 0; + int match = 0; + + if (all) { + /* + * Only the filter_hash affects all records. + * Update if the record is not in the notrace hash. + */ + if (!ftrace_lookup_ip(other_hash, rec->ip)) + match = 1; + } else { + in_hash = !!ftrace_lookup_ip(hash, rec->ip); + in_other_hash = !!ftrace_lookup_ip(other_hash, rec->ip); + + /* + * + */ + if (filter_hash && in_hash && !in_other_hash) + match = 1; + else if (!filter_hash && in_hash && + (in_other_hash || !other_hash->count)) + match = 1; + } + if (!match) + continue; + + if (inc) { + rec->flags++; + if (FTRACE_WARN_ON((rec->flags & ~FTRACE_FL_MASK) == FTRACE_REF_MAX)) + return; + } else { + if (FTRACE_WARN_ON((rec->flags & ~FTRACE_FL_MASK) == 0)) + return; + rec->flags--; + } + count++; + /* Shortcut, if we handled all records, we are done. */ + if (!all && count == hash->count) + return; + } while_for_each_ftrace_rec(); +} + +static void ftrace_hash_rec_disable(struct ftrace_ops *ops, + int filter_hash) +{ + __ftrace_hash_rec_update(ops, filter_hash, 0); +} + +static void ftrace_hash_rec_enable(struct ftrace_ops *ops, + int filter_hash) +{ + __ftrace_hash_rec_update(ops, filter_hash, 1); +} + static void ftrace_free_rec(struct dyn_ftrace *rec) { rec->freelist = ftrace_free_records; @@ -1276,26 +1379,24 @@ int ftrace_text_reserved(void *start, void *end) static int __ftrace_replace_code(struct dyn_ftrace *rec, int enable) { - struct ftrace_ops *ops = &global_ops; unsigned long ftrace_addr; unsigned long flag = 0UL; ftrace_addr = (unsigned long)FTRACE_ADDR; /* - * If this record is not to be traced or we want to disable it, - * then disable it. + * If we are enabling tracing: * - * If we want to enable it and filtering is off, then enable it. + * If the record has a ref count, then we need to enable it + * because someone is using it. * - * If we want to enable it and filtering is on, enable it only if - * it's filtered + * Otherwise we make sure its disabled. + * + * If we are disabling tracing, then disable all records that + * are enabled. */ - if (enable && !ftrace_lookup_ip(ops->notrace_hash, rec->ip)) { - if (!ops->filter_hash->count || - ftrace_lookup_ip(ops->filter_hash, rec->ip)) - flag = FTRACE_FL_ENABLED; - } + if (enable && (rec->flags & ~FTRACE_FL_MASK)) + flag = FTRACE_FL_ENABLED; /* If the state of this record hasn't changed, then do nothing */ if ((rec->flags & FTRACE_FL_ENABLED) == flag) @@ -1423,17 +1524,25 @@ static void ftrace_startup_enable(int command) static void ftrace_startup(int command) { + struct ftrace_ops *ops = &global_ops; + if (unlikely(ftrace_disabled)) return; ftrace_start_up++; command |= FTRACE_ENABLE_CALLS; + ops->flags |= FTRACE_OPS_FL_ENABLED; + if (ftrace_start_up == 1) + ftrace_hash_rec_enable(ops, 1); + ftrace_startup_enable(command); } static void ftrace_shutdown(int command) { + struct ftrace_ops *ops = &global_ops; + if (unlikely(ftrace_disabled)) return; @@ -1446,7 +1555,12 @@ static void ftrace_shutdown(int command) WARN_ON_ONCE(ftrace_start_up < 0); if (!ftrace_start_up) + ftrace_hash_rec_disable(ops, 1); + + if (!ftrace_start_up) { command |= FTRACE_DISABLE_CALLS; + ops->flags &= ~FTRACE_OPS_FL_ENABLED; + } if (saved_ftrace_func != ftrace_trace_function) { saved_ftrace_func = ftrace_trace_function; @@ -2668,6 +2782,7 @@ ftrace_regex_release(struct inode *inode, struct file *file) struct ftrace_iterator *iter; struct ftrace_hash **orig_hash; struct trace_parser *parser; + int filter_hash; int ret; mutex_lock(&ftrace_regex_lock); @@ -2687,15 +2802,26 @@ ftrace_regex_release(struct inode *inode, struct file *file) trace_parser_put(parser); if (file->f_mode & FMODE_WRITE) { - if (iter->flags & FTRACE_ITER_NOTRACE) - orig_hash = &iter->ops->notrace_hash; - else + filter_hash = !!(iter->flags & FTRACE_ITER_FILTER); + + if (filter_hash) orig_hash = &iter->ops->filter_hash; + else + orig_hash = &iter->ops->notrace_hash; mutex_lock(&ftrace_lock); + /* + * Remove the current set, update the hash and add + * them back. + */ + ftrace_hash_rec_disable(iter->ops, filter_hash); ret = ftrace_hash_move(orig_hash, iter->hash); - if (!ret && ftrace_start_up && ftrace_enabled) - ftrace_run_update_code(FTRACE_ENABLE_CALLS); + if (!ret) { + ftrace_hash_rec_enable(iter->ops, filter_hash); + if (iter->ops->flags & FTRACE_OPS_FL_ENABLED + && ftrace_enabled) + ftrace_run_update_code(FTRACE_ENABLE_CALLS); + } mutex_unlock(&ftrace_lock); } free_ftrace_hash(iter->hash); -- cgit From b848914ce39589d89ee0078a6d1ef452b464729e Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 4 May 2011 09:27:52 -0400 Subject: ftrace: Implement separate user function filtering ftrace_ops that are registered to trace functions can now be agnostic to each other in respect to what functions they trace. Each ops has their own hash of the functions they want to trace and a hash to what they do not want to trace. A empty hash for the functions they want to trace denotes all functions should be traced that are not in the notrace hash. Cc: Paul E. McKenney Signed-off-by: Steven Rostedt --- include/linux/ftrace.h | 7 +- kernel/trace/ftrace.c | 193 ++++++++++++++++++++++++++++++-------- kernel/trace/trace_functions.c | 2 + kernel/trace/trace_irqsoff.c | 1 + kernel/trace/trace_sched_wakeup.c | 1 + kernel/trace/trace_stack.c | 1 + 6 files changed, 166 insertions(+), 39 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index ab1c46e70bb6..4609c0ece79a 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -31,13 +31,18 @@ typedef void (*ftrace_func_t)(unsigned long ip, unsigned long parent_ip); struct ftrace_hash; +enum { + FTRACE_OPS_FL_ENABLED = 1 << 0, + FTRACE_OPS_FL_GLOBAL = 1 << 1, +}; + struct ftrace_ops { ftrace_func_t func; struct ftrace_ops *next; + unsigned long flags; #ifdef CONFIG_DYNAMIC_FTRACE struct ftrace_hash *notrace_hash; struct ftrace_hash *filter_hash; - unsigned long flags; #endif }; diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 92b6fdf49ae5..6c7e1df39b57 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -87,24 +87,29 @@ static struct ftrace_ops ftrace_list_end __read_mostly = .func = ftrace_stub, }; -static struct ftrace_ops *ftrace_list __read_mostly = &ftrace_list_end; +static struct ftrace_ops *ftrace_global_list __read_mostly = &ftrace_list_end; +static struct ftrace_ops *ftrace_ops_list __read_mostly = &ftrace_list_end; ftrace_func_t ftrace_trace_function __read_mostly = ftrace_stub; ftrace_func_t __ftrace_trace_function __read_mostly = ftrace_stub; ftrace_func_t ftrace_pid_function __read_mostly = ftrace_stub; static struct ftrace_ops global_ops; +static void +ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip); + /* - * Traverse the ftrace_list, invoking all entries. The reason that we + * Traverse the ftrace_global_list, invoking all entries. The reason that we * can use rcu_dereference_raw() is that elements removed from this list * are simply leaked, so there is no need to interact with a grace-period * mechanism. The rcu_dereference_raw() calls are needed to handle - * concurrent insertions into the ftrace_list. + * concurrent insertions into the ftrace_global_list. * * Silly Alpha and silly pointer-speculation compiler optimizations! */ -static void ftrace_list_func(unsigned long ip, unsigned long parent_ip) +static void ftrace_global_list_func(unsigned long ip, + unsigned long parent_ip) { - struct ftrace_ops *op = rcu_dereference_raw(ftrace_list); /*see above*/ + struct ftrace_ops *op = rcu_dereference_raw(ftrace_global_list); /*see above*/ while (op != &ftrace_list_end) { op->func(ip, parent_ip); @@ -163,11 +168,11 @@ static void update_global_ops(void) * function directly. Otherwise, we need to iterate over the * registered callers. */ - if (ftrace_list == &ftrace_list_end || - ftrace_list->next == &ftrace_list_end) - func = ftrace_list->func; + if (ftrace_global_list == &ftrace_list_end || + ftrace_global_list->next == &ftrace_list_end) + func = ftrace_global_list->func; else - func = ftrace_list_func; + func = ftrace_global_list_func; /* If we filter on pids, update to use the pid function */ if (!list_empty(&ftrace_pids)) { @@ -184,7 +189,11 @@ static void update_ftrace_function(void) update_global_ops(); - func = global_ops.func; + if (ftrace_ops_list == &ftrace_list_end || + ftrace_ops_list->next == &ftrace_list_end) + func = ftrace_ops_list->func; + else + func = ftrace_ops_list_func; #ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST ftrace_trace_function = func; @@ -198,10 +207,10 @@ static void add_ftrace_ops(struct ftrace_ops **list, struct ftrace_ops *ops) { ops->next = *list; /* - * We are entering ops into the ftrace_list but another + * We are entering ops into the list but another * CPU might be walking that list. We need to make sure * the ops->next pointer is valid before another CPU sees - * the ops pointer included into the ftrace_list. + * the ops pointer included into the list. */ rcu_assign_pointer(*list, ops); } @@ -238,7 +247,18 @@ static int __register_ftrace_function(struct ftrace_ops *ops) if (FTRACE_WARN_ON(ops == &global_ops)) return -EINVAL; - add_ftrace_ops(&ftrace_list, ops); + if (WARN_ON(ops->flags & FTRACE_OPS_FL_ENABLED)) + return -EBUSY; + + if (ops->flags & FTRACE_OPS_FL_GLOBAL) { + int first = ftrace_global_list == &ftrace_list_end; + add_ftrace_ops(&ftrace_global_list, ops); + ops->flags |= FTRACE_OPS_FL_ENABLED; + if (first) + add_ftrace_ops(&ftrace_ops_list, &global_ops); + } else + add_ftrace_ops(&ftrace_ops_list, ops); + if (ftrace_enabled) update_ftrace_function(); @@ -252,12 +272,24 @@ static int __unregister_ftrace_function(struct ftrace_ops *ops) if (ftrace_disabled) return -ENODEV; + if (WARN_ON(!(ops->flags & FTRACE_OPS_FL_ENABLED))) + return -EBUSY; + if (FTRACE_WARN_ON(ops == &global_ops)) return -EINVAL; - ret = remove_ftrace_ops(&ftrace_list, ops); + if (ops->flags & FTRACE_OPS_FL_GLOBAL) { + ret = remove_ftrace_ops(&ftrace_global_list, ops); + if (!ret && ftrace_global_list == &ftrace_list_end) + ret = remove_ftrace_ops(&ftrace_ops_list, &global_ops); + if (!ret) + ops->flags &= ~FTRACE_OPS_FL_ENABLED; + } else + ret = remove_ftrace_ops(&ftrace_ops_list, ops); + if (ret < 0) return ret; + if (ftrace_enabled) update_ftrace_function(); @@ -928,10 +960,6 @@ static const struct ftrace_hash empty_hash = { }; #define EMPTY_HASH ((struct ftrace_hash *)&empty_hash) -enum { - FTRACE_OPS_FL_ENABLED = 1, -}; - static struct ftrace_ops global_ops = { .func = ftrace_stub, .notrace_hash = EMPTY_HASH, @@ -1189,6 +1217,40 @@ ftrace_hash_move(struct ftrace_hash **dst, struct ftrace_hash *src) return 0; } +/* + * Test the hashes for this ops to see if we want to call + * the ops->func or not. + * + * It's a match if the ip is in the ops->filter_hash or + * the filter_hash does not exist or is empty, + * AND + * the ip is not in the ops->notrace_hash. + */ +static int +ftrace_ops_test(struct ftrace_ops *ops, unsigned long ip) +{ + struct ftrace_hash *filter_hash; + struct ftrace_hash *notrace_hash; + int ret; + + /* The hashes are freed with call_rcu_sched() */ + preempt_disable_notrace(); + + filter_hash = rcu_dereference_raw(ops->filter_hash); + notrace_hash = rcu_dereference_raw(ops->notrace_hash); + + if ((!filter_hash || !filter_hash->count || + ftrace_lookup_ip(filter_hash, ip)) && + (!notrace_hash || !notrace_hash->count || + !ftrace_lookup_ip(notrace_hash, ip))) + ret = 1; + else + ret = 0; + preempt_enable_notrace(); + + return ret; +} + /* * This is a double for. Do not use 'break' to break out of the loop, * you must use a goto. @@ -1232,7 +1294,7 @@ static void __ftrace_hash_rec_update(struct ftrace_ops *ops, if (filter_hash) { hash = ops->filter_hash; other_hash = ops->notrace_hash; - if (!hash->count) + if (!hash || !hash->count) all = 1; } else { inc = !inc; @@ -1242,7 +1304,7 @@ static void __ftrace_hash_rec_update(struct ftrace_ops *ops, * If the notrace hash has no items, * then there's nothing to do. */ - if (!hash->count) + if (hash && !hash->count) return; } @@ -1256,11 +1318,11 @@ static void __ftrace_hash_rec_update(struct ftrace_ops *ops, * Only the filter_hash affects all records. * Update if the record is not in the notrace hash. */ - if (!ftrace_lookup_ip(other_hash, rec->ip)) + if (!other_hash || !ftrace_lookup_ip(other_hash, rec->ip)) match = 1; } else { - in_hash = !!ftrace_lookup_ip(hash, rec->ip); - in_other_hash = !!ftrace_lookup_ip(other_hash, rec->ip); + in_hash = hash && !!ftrace_lookup_ip(hash, rec->ip); + in_other_hash = other_hash && !!ftrace_lookup_ip(other_hash, rec->ip); /* * @@ -1546,6 +1608,7 @@ static void ftrace_run_update_code(int command) static ftrace_func_t saved_ftrace_func; static int ftrace_start_up; +static int global_start_up; static void ftrace_startup_enable(int command) { @@ -1562,14 +1625,25 @@ static void ftrace_startup_enable(int command) static void ftrace_startup(struct ftrace_ops *ops, int command) { + bool hash_enable = true; + if (unlikely(ftrace_disabled)) return; ftrace_start_up++; command |= FTRACE_ENABLE_CALLS; + /* ops marked global share the filter hashes */ + if (ops->flags & FTRACE_OPS_FL_GLOBAL) { + ops = &global_ops; + /* Don't update hash if global is already set */ + if (global_start_up) + hash_enable = false; + global_start_up++; + } + ops->flags |= FTRACE_OPS_FL_ENABLED; - if (ftrace_start_up == 1) + if (hash_enable) ftrace_hash_rec_enable(ops, 1); ftrace_startup_enable(command); @@ -1577,6 +1651,8 @@ static void ftrace_startup(struct ftrace_ops *ops, int command) static void ftrace_shutdown(struct ftrace_ops *ops, int command) { + bool hash_disable = true; + if (unlikely(ftrace_disabled)) return; @@ -1588,13 +1664,25 @@ static void ftrace_shutdown(struct ftrace_ops *ops, int command) */ WARN_ON_ONCE(ftrace_start_up < 0); - if (!ftrace_start_up) + if (ops->flags & FTRACE_OPS_FL_GLOBAL) { + ops = &global_ops; + global_start_up--; + WARN_ON_ONCE(global_start_up < 0); + /* Don't update hash if global still has users */ + if (global_start_up) { + WARN_ON_ONCE(!ftrace_start_up); + hash_disable = false; + } + } + + if (hash_disable) ftrace_hash_rec_disable(ops, 1); - if (!ftrace_start_up) { - command |= FTRACE_DISABLE_CALLS; + if (ops != &global_ops || !global_start_up) ops->flags &= ~FTRACE_OPS_FL_ENABLED; - } + + if (!ftrace_start_up) + command |= FTRACE_DISABLE_CALLS; if (saved_ftrace_func != ftrace_trace_function) { saved_ftrace_func = ftrace_trace_function; @@ -2381,6 +2469,7 @@ static int ftrace_probe_registered; static void __enable_ftrace_function_probe(void) { + int ret; int i; if (ftrace_probe_registered) @@ -2395,13 +2484,16 @@ static void __enable_ftrace_function_probe(void) if (i == FTRACE_FUNC_HASHSIZE) return; - __register_ftrace_function(&trace_probe_ops); - ftrace_startup(&global_ops, 0); + ret = __register_ftrace_function(&trace_probe_ops); + if (!ret) + ftrace_startup(&trace_probe_ops, 0); + ftrace_probe_registered = 1; } static void __disable_ftrace_function_probe(void) { + int ret; int i; if (!ftrace_probe_registered) @@ -2414,8 +2506,10 @@ static void __disable_ftrace_function_probe(void) } /* no more funcs left */ - __unregister_ftrace_function(&trace_probe_ops); - ftrace_shutdown(&global_ops, 0); + ret = __unregister_ftrace_function(&trace_probe_ops); + if (!ret) + ftrace_shutdown(&trace_probe_ops, 0); + ftrace_probe_registered = 0; } @@ -3319,8 +3413,28 @@ static inline void ftrace_startup_enable(int command) { } # define ftrace_shutdown(ops, command) do { } while (0) # define ftrace_startup_sysctl() do { } while (0) # define ftrace_shutdown_sysctl() do { } while (0) + +static inline int +ftrace_ops_test(struct ftrace_ops *ops, unsigned long ip) +{ + return 1; +} + #endif /* CONFIG_DYNAMIC_FTRACE */ +static void +ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip) +{ + /* see comment above ftrace_global_list_func */ + struct ftrace_ops *op = rcu_dereference_raw(ftrace_ops_list); + + while (op != &ftrace_list_end) { + if (ftrace_ops_test(op, ip)) + op->func(ip, parent_ip); + op = rcu_dereference_raw(op->next); + }; +} + static void clear_ftrace_swapper(void) { struct task_struct *p; @@ -3621,7 +3735,9 @@ int register_ftrace_function(struct ftrace_ops *ops) goto out_unlock; ret = __register_ftrace_function(ops); - ftrace_startup(&global_ops, 0); + if (!ret) + ftrace_startup(ops, 0); + out_unlock: mutex_unlock(&ftrace_lock); @@ -3640,7 +3756,8 @@ int unregister_ftrace_function(struct ftrace_ops *ops) mutex_lock(&ftrace_lock); ret = __unregister_ftrace_function(ops); - ftrace_shutdown(&global_ops, 0); + if (!ret) + ftrace_shutdown(ops, 0); mutex_unlock(&ftrace_lock); return ret; @@ -3670,11 +3787,11 @@ ftrace_enable_sysctl(struct ctl_table *table, int write, ftrace_startup_sysctl(); /* we are starting ftrace again */ - if (ftrace_list != &ftrace_list_end) { - if (ftrace_list->next == &ftrace_list_end) - ftrace_trace_function = ftrace_list->func; + if (ftrace_ops_list != &ftrace_list_end) { + if (ftrace_ops_list->next == &ftrace_list_end) + ftrace_trace_function = ftrace_ops_list->func; else - ftrace_trace_function = ftrace_list_func; + ftrace_trace_function = ftrace_ops_list_func; } } else { diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c index 16aee4d44e8f..8d0e1cc4e974 100644 --- a/kernel/trace/trace_functions.c +++ b/kernel/trace/trace_functions.c @@ -149,11 +149,13 @@ function_stack_trace_call(unsigned long ip, unsigned long parent_ip) static struct ftrace_ops trace_ops __read_mostly = { .func = function_trace_call, + .flags = FTRACE_OPS_FL_GLOBAL, }; static struct ftrace_ops trace_stack_ops __read_mostly = { .func = function_stack_trace_call, + .flags = FTRACE_OPS_FL_GLOBAL, }; /* Our two options */ diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c index a4969b47afc1..c77424be284d 100644 --- a/kernel/trace/trace_irqsoff.c +++ b/kernel/trace/trace_irqsoff.c @@ -153,6 +153,7 @@ irqsoff_tracer_call(unsigned long ip, unsigned long parent_ip) static struct ftrace_ops trace_ops __read_mostly = { .func = irqsoff_tracer_call, + .flags = FTRACE_OPS_FL_GLOBAL, }; #endif /* CONFIG_FUNCTION_TRACER */ diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c index 7319559ed59f..f029dd4fd2ca 100644 --- a/kernel/trace/trace_sched_wakeup.c +++ b/kernel/trace/trace_sched_wakeup.c @@ -129,6 +129,7 @@ wakeup_tracer_call(unsigned long ip, unsigned long parent_ip) static struct ftrace_ops trace_ops __read_mostly = { .func = wakeup_tracer_call, + .flags = FTRACE_OPS_FL_GLOBAL, }; #endif /* CONFIG_FUNCTION_TRACER */ diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c index 4c5dead0c239..b0b53b8e4c25 100644 --- a/kernel/trace/trace_stack.c +++ b/kernel/trace/trace_stack.c @@ -133,6 +133,7 @@ stack_trace_call(unsigned long ip, unsigned long parent_ip) static struct ftrace_ops trace_ops __read_mostly = { .func = stack_trace_call, + .flags = FTRACE_OPS_FL_GLOBAL, }; static ssize_t -- cgit From cdbe61bfe70440939e457fb4a8d0995eaaed17de Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 5 May 2011 21:14:55 -0400 Subject: ftrace: Allow dynamically allocated function tracers Now that functions may be selected individually, it only makes sense that we should allow dynamically allocated trace structures to be traced. This will allow perf to allocate a ftrace_ops structure at runtime and use it to pick and choose which functions that structure will trace. Note, a dynamically allocated ftrace_ops will always be called indirectly instead of being called directly from the mcount in entry.S. This is because there's no safe way to prevent mcount from being preempted before calling the function, unless we modify every entry.S to do so (not likely). Thus, dynamically allocated functions will now be called by the ftrace_ops_list_func() that loops through the ops that are allocated if there are more than one op allocated at a time. This loop is protected with a preempt_disable. To determine if an ftrace_ops structure is allocated or not, a new util function was added to the kernel/extable.c called core_kernel_data(), which returns 1 if the address is between _sdata and _edata. Cc: Paul E. McKenney Signed-off-by: Steven Rostedt --- include/linux/ftrace.h | 1 + include/linux/kernel.h | 1 + kernel/extable.c | 8 ++++++++ kernel/trace/ftrace.c | 37 ++++++++++++++++++++++++++++++------- 4 files changed, 40 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 4609c0ece79a..caba694a62b6 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -34,6 +34,7 @@ struct ftrace_hash; enum { FTRACE_OPS_FL_ENABLED = 1 << 0, FTRACE_OPS_FL_GLOBAL = 1 << 1, + FTRACE_OPS_FL_DYNAMIC = 1 << 2, }; struct ftrace_ops { diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 00cec4dc0ae2..f37ba716ef8b 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -283,6 +283,7 @@ extern char *get_options(const char *str, int nints, int *ints); extern unsigned long long memparse(const char *ptr, char **retptr); extern int core_kernel_text(unsigned long addr); +extern int core_kernel_data(unsigned long addr); extern int __kernel_text_address(unsigned long addr); extern int kernel_text_address(unsigned long addr); extern int func_ptr_is_kernel_text(void *ptr); diff --git a/kernel/extable.c b/kernel/extable.c index 7f8f263f8524..c2d625fcda77 100644 --- a/kernel/extable.c +++ b/kernel/extable.c @@ -72,6 +72,14 @@ int core_kernel_text(unsigned long addr) return 0; } +int core_kernel_data(unsigned long addr) +{ + if (addr >= (unsigned long)_sdata && + addr < (unsigned long)_edata) + return 1; + return 0; +} + int __kernel_text_address(unsigned long addr) { if (core_kernel_text(addr)) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 6c7e1df39b57..5b3ee04e39d9 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -189,8 +189,14 @@ static void update_ftrace_function(void) update_global_ops(); + /* + * If we are at the end of the list and this ops is + * not dynamic, then have the mcount trampoline call + * the function directly + */ if (ftrace_ops_list == &ftrace_list_end || - ftrace_ops_list->next == &ftrace_list_end) + (ftrace_ops_list->next == &ftrace_list_end && + !(ftrace_ops_list->flags & FTRACE_OPS_FL_DYNAMIC))) func = ftrace_ops_list->func; else func = ftrace_ops_list_func; @@ -250,6 +256,9 @@ static int __register_ftrace_function(struct ftrace_ops *ops) if (WARN_ON(ops->flags & FTRACE_OPS_FL_ENABLED)) return -EBUSY; + if (!core_kernel_data((unsigned long)ops)) + ops->flags |= FTRACE_OPS_FL_DYNAMIC; + if (ops->flags & FTRACE_OPS_FL_GLOBAL) { int first = ftrace_global_list == &ftrace_list_end; add_ftrace_ops(&ftrace_global_list, ops); @@ -293,6 +302,13 @@ static int __unregister_ftrace_function(struct ftrace_ops *ops) if (ftrace_enabled) update_ftrace_function(); + /* + * Dynamic ops may be freed, we must make sure that all + * callers are done before leaving this function. + */ + if (ops->flags & FTRACE_OPS_FL_DYNAMIC) + synchronize_sched(); + return 0; } @@ -1225,6 +1241,9 @@ ftrace_hash_move(struct ftrace_hash **dst, struct ftrace_hash *src) * the filter_hash does not exist or is empty, * AND * the ip is not in the ops->notrace_hash. + * + * This needs to be called with preemption disabled as + * the hashes are freed with call_rcu_sched(). */ static int ftrace_ops_test(struct ftrace_ops *ops, unsigned long ip) @@ -1233,9 +1252,6 @@ ftrace_ops_test(struct ftrace_ops *ops, unsigned long ip) struct ftrace_hash *notrace_hash; int ret; - /* The hashes are freed with call_rcu_sched() */ - preempt_disable_notrace(); - filter_hash = rcu_dereference_raw(ops->filter_hash); notrace_hash = rcu_dereference_raw(ops->notrace_hash); @@ -1246,7 +1262,6 @@ ftrace_ops_test(struct ftrace_ops *ops, unsigned long ip) ret = 1; else ret = 0; - preempt_enable_notrace(); return ret; } @@ -3425,14 +3440,20 @@ ftrace_ops_test(struct ftrace_ops *ops, unsigned long ip) static void ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip) { - /* see comment above ftrace_global_list_func */ - struct ftrace_ops *op = rcu_dereference_raw(ftrace_ops_list); + struct ftrace_ops *op; + /* + * Some of the ops may be dynamically allocated, + * they must be freed after a synchronize_sched(). + */ + preempt_disable_notrace(); + op = rcu_dereference_raw(ftrace_ops_list); while (op != &ftrace_list_end) { if (ftrace_ops_test(op, ip)) op->func(ip, parent_ip); op = rcu_dereference_raw(op->next); }; + preempt_enable_notrace(); } static void clear_ftrace_swapper(void) @@ -3743,6 +3764,7 @@ int register_ftrace_function(struct ftrace_ops *ops) mutex_unlock(&ftrace_lock); return ret; } +EXPORT_SYMBOL_GPL(register_ftrace_function); /** * unregister_ftrace_function - unregister a function for profiling. @@ -3762,6 +3784,7 @@ int unregister_ftrace_function(struct ftrace_ops *ops) return ret; } +EXPORT_SYMBOL_GPL(unregister_ftrace_function); int ftrace_enable_sysctl(struct ctl_table *table, int write, -- cgit From 936e074b286ae779f134312178dbab139ee7ea52 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 5 May 2011 22:54:01 -0400 Subject: ftrace: Modify ftrace_set_filter/notrace to take ops Since users of the function tracer can now pick and choose which functions they want to trace agnostically from other users of the function tracer, we need to pass the ops struct to the ftrace_set_filter() functions. The functions ftrace_set_global_filter() and ftrace_set_global_notrace() is added to keep the old filter functions which are used to modify the generic function tracers. Signed-off-by: Steven Rostedt --- include/linux/ftrace.h | 7 ++++++- kernel/trace/ftrace.c | 46 +++++++++++++++++++++++++++++++++++++++++-- kernel/trace/trace_selftest.c | 4 ++-- 3 files changed, 52 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index caba694a62b6..9d88e1cb5dbb 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -179,7 +179,12 @@ struct dyn_ftrace { }; int ftrace_force_update(void); -void ftrace_set_filter(unsigned char *buf, int len, int reset); +void ftrace_set_filter(struct ftrace_ops *ops, unsigned char *buf, + int len, int reset); +void ftrace_set_notrace(struct ftrace_ops *ops, unsigned char *buf, + int len, int reset); +void ftrace_set_global_filter(unsigned char *buf, int len, int reset); +void ftrace_set_global_notrace(unsigned char *buf, int len, int reset); int register_ftrace_command(struct ftrace_func_command *cmd); int unregister_ftrace_command(struct ftrace_func_command *cmd); diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 5b3ee04e39d9..d017c2c82c44 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -2826,6 +2826,10 @@ ftrace_set_regex(struct ftrace_ops *ops, unsigned char *buf, int len, struct ftrace_hash *hash; int ret; + /* All global ops uses the global ops filters */ + if (ops->flags & FTRACE_OPS_FL_GLOBAL) + ops = &global_ops; + if (unlikely(ftrace_disabled)) return -ENODEV; @@ -2856,6 +2860,41 @@ ftrace_set_regex(struct ftrace_ops *ops, unsigned char *buf, int len, /** * ftrace_set_filter - set a function to filter on in ftrace + * @ops - the ops to set the filter with + * @buf - the string that holds the function filter text. + * @len - the length of the string. + * @reset - non zero to reset all filters before applying this filter. + * + * Filters denote which functions should be enabled when tracing is enabled. + * If @buf is NULL and reset is set, all functions will be enabled for tracing. + */ +void ftrace_set_filter(struct ftrace_ops *ops, unsigned char *buf, + int len, int reset) +{ + ftrace_set_regex(ops, buf, len, reset, 1); +} +EXPORT_SYMBOL_GPL(ftrace_set_filter); + +/** + * ftrace_set_notrace - set a function to not trace in ftrace + * @ops - the ops to set the notrace filter with + * @buf - the string that holds the function notrace text. + * @len - the length of the string. + * @reset - non zero to reset all filters before applying this filter. + * + * Notrace Filters denote which functions should not be enabled when tracing + * is enabled. If @buf is NULL and reset is set, all functions will be enabled + * for tracing. + */ +void ftrace_set_notrace(struct ftrace_ops *ops, unsigned char *buf, + int len, int reset) +{ + ftrace_set_regex(ops, buf, len, reset, 0); +} +EXPORT_SYMBOL_GPL(ftrace_set_notrace); +/** + * ftrace_set_filter - set a function to filter on in ftrace + * @ops - the ops to set the filter with * @buf - the string that holds the function filter text. * @len - the length of the string. * @reset - non zero to reset all filters before applying this filter. @@ -2863,13 +2902,15 @@ ftrace_set_regex(struct ftrace_ops *ops, unsigned char *buf, int len, * Filters denote which functions should be enabled when tracing is enabled. * If @buf is NULL and reset is set, all functions will be enabled for tracing. */ -void ftrace_set_filter(unsigned char *buf, int len, int reset) +void ftrace_set_global_filter(unsigned char *buf, int len, int reset) { ftrace_set_regex(&global_ops, buf, len, reset, 1); } +EXPORT_SYMBOL_GPL(ftrace_set_global_filter); /** * ftrace_set_notrace - set a function to not trace in ftrace + * @ops - the ops to set the notrace filter with * @buf - the string that holds the function notrace text. * @len - the length of the string. * @reset - non zero to reset all filters before applying this filter. @@ -2878,10 +2919,11 @@ void ftrace_set_filter(unsigned char *buf, int len, int reset) * is enabled. If @buf is NULL and reset is set, all functions will be enabled * for tracing. */ -void ftrace_set_notrace(unsigned char *buf, int len, int reset) +void ftrace_set_global_notrace(unsigned char *buf, int len, int reset) { ftrace_set_regex(&global_ops, buf, len, reset, 0); } +EXPORT_SYMBOL_GPL(ftrace_set_global_notrace); /* * command line interface to allow users to set filters on boot up. diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index 659732eba07c..0fa2db305b7c 100644 --- a/kernel/trace/trace_selftest.c +++ b/kernel/trace/trace_selftest.c @@ -131,7 +131,7 @@ int trace_selftest_startup_dynamic_tracing(struct tracer *trace, func_name = "*" __stringify(DYN_FTRACE_TEST_NAME); /* filter only on our function */ - ftrace_set_filter(func_name, strlen(func_name), 1); + ftrace_set_global_filter(func_name, strlen(func_name), 1); /* enable tracing */ ret = tracer_init(trace, tr); @@ -181,7 +181,7 @@ int trace_selftest_startup_dynamic_tracing(struct tracer *trace, tracer_enabled = save_tracer_enabled; /* Enable tracing on all functions again */ - ftrace_set_filter(NULL, 0, 1); + ftrace_set_global_filter(NULL, 0, 1); return ret; } -- cgit From b4bc842802db3314f9a657094da0450a903ea619 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 7 Feb 2011 16:02:25 -0800 Subject: module: deal with alignment issues in built-in module versions On m68k natural alignment is 2-byte boundary but we are trying to align structures in __modver section on sizeof(void *) boundary. This causes trouble when we try to access elements in this section in array-like fashion when create "version" attributes for built-in modules. Moreover, as DaveM said, we can't reliably put structures into independent objects, put them into a special section, and then expect array access over them (via the section boundaries) after linking the objects together to just "work" due to variable alignment choices in different situations. The only solution that seems to work reliably is to make an array of plain pointers to the objects in question and put those pointers in the special section. Reported-by: Geert Uytterhoeven Signed-off-by: Dmitry Torokhov Signed-off-by: Rusty Russell --- include/linux/module.h | 10 +++++----- kernel/params.c | 9 ++++++--- 2 files changed, 11 insertions(+), 8 deletions(-) (limited to 'include/linux') diff --git a/include/linux/module.h b/include/linux/module.h index 5de42043dff0..4cfebc211695 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -174,10 +174,7 @@ extern struct module __this_module; #define MODULE_VERSION(_version) \ extern ssize_t __modver_version_show(struct module_attribute *, \ struct module *, char *); \ - static struct module_version_attribute __modver_version_attr \ - __used \ - __attribute__ ((__section__ ("__modver"),aligned(sizeof(void *)))) \ - = { \ + static struct module_version_attribute ___modver_attr = { \ .mattr = { \ .attr = { \ .name = "version", \ @@ -187,7 +184,10 @@ extern struct module __this_module; }, \ .module_name = KBUILD_MODNAME, \ .version = _version, \ - } + }; \ + static const struct module_version_attribute \ + __used __attribute__ ((__section__ ("__modver"))) \ + * __moduleparam_const __modver_attr = &___modver_attr #endif /* Optional firmware file (or files) needed by the module diff --git a/kernel/params.c b/kernel/params.c index 7ab388a48a2e..28c5d5c83f6b 100644 --- a/kernel/params.c +++ b/kernel/params.c @@ -821,15 +821,18 @@ ssize_t __modver_version_show(struct module_attribute *mattr, return sprintf(buf, "%s\n", vattr->version); } -extern struct module_version_attribute __start___modver[], __stop___modver[]; +extern const struct module_version_attribute *__start___modver[]; +extern const struct module_version_attribute *__stop___modver[]; static void __init version_sysfs_builtin(void) { - const struct module_version_attribute *vattr; + const struct module_version_attribute **p; struct module_kobject *mk; int err; - for (vattr = __start___modver; vattr < __stop___modver; vattr++) { + for (p = __start___modver; p < __stop___modver; p++) { + const struct module_version_attribute *vattr = *p; + mk = locate_module_kobject(vattr->module_name); if (mk) { err = sysfs_create_file(&mk->kobj, &vattr->mattr.attr); -- cgit From 9b73a5840c7d5f77e5766626716df13787cb258c Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 7 Feb 2011 16:02:27 -0800 Subject: module: do not hide __modver_version_show declaration behind ifdef Doing so prevents the following warning from sparse: CHECK kernel/params.c kernel/params.c:817:9: warning: symbol '__modver_version_show' was not declared. Should it be static? since kernel/params.c is never compiled with MODULE being set. Signed-off-by: Dmitry Torokhov Signed-off-by: Rusty Russell --- include/linux/module.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/module.h b/include/linux/module.h index 4cfebc211695..23996ad147e7 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -64,6 +64,9 @@ struct module_version_attribute { const char *version; } __attribute__ ((__aligned__(sizeof(void *)))); +extern ssize_t __modver_version_show(struct module_attribute *, + struct module *, char *); + struct module_kobject { struct kobject kobj; @@ -172,8 +175,6 @@ extern struct module __this_module; #define MODULE_VERSION(_version) MODULE_INFO(version, _version) #else #define MODULE_VERSION(_version) \ - extern ssize_t __modver_version_show(struct module_attribute *, \ - struct module *, char *); \ static struct module_version_attribute ___modver_attr = { \ .mattr = { \ .attr = { \ -- cgit From a288bd651f4180c224cfddf837a0416157a36661 Mon Sep 17 00:00:00 2001 From: Richard Kennedy Date: Thu, 19 May 2011 16:55:25 -0600 Subject: module: remove 64 bit alignment padding from struct module with CONFIG_TRACE* Reorder struct module to remove 24 bytes of alignment padding on 64 bit builds when the CONFIG_TRACE options are selected. This allows the structure to fit into one fewer cache lines, and its size drops from 592 to 568 on x86_64. Signed-off-by: Richard Kennedy Signed-off-by: Rusty Russell --- include/linux/module.h | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/module.h b/include/linux/module.h index 23996ad147e7..65cc6cc73ca8 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -368,34 +368,35 @@ struct module struct module_notes_attrs *notes_attrs; #endif + /* The command line arguments (may be mangled). People like + keeping pointers to this stuff */ + char *args; + #ifdef CONFIG_SMP /* Per-cpu data. */ void __percpu *percpu; unsigned int percpu_size; #endif - /* The command line arguments (may be mangled). People like - keeping pointers to this stuff */ - char *args; #ifdef CONFIG_TRACEPOINTS - struct tracepoint * const *tracepoints_ptrs; unsigned int num_tracepoints; + struct tracepoint * const *tracepoints_ptrs; #endif #ifdef HAVE_JUMP_LABEL struct jump_entry *jump_entries; unsigned int num_jump_entries; #endif #ifdef CONFIG_TRACING - const char **trace_bprintk_fmt_start; unsigned int num_trace_bprintk_fmt; + const char **trace_bprintk_fmt_start; #endif #ifdef CONFIG_EVENT_TRACING struct ftrace_event_call **trace_events; unsigned int num_trace_events; #endif #ifdef CONFIG_FTRACE_MCOUNT_RECORD - unsigned long *ftrace_callsites; unsigned int num_ftrace_callsites; + unsigned long *ftrace_callsites; #endif #ifdef CONFIG_MODULE_UNLOAD -- cgit From c5be0b2eb1ca05e0cd747f9c0ba552c6ee8827a0 Mon Sep 17 00:00:00 2001 From: Richard Kennedy Date: Thu, 19 May 2011 16:55:25 -0600 Subject: module: reorder kparam_array to remove alignment padding on 64 bit builds Reorder structure kparam_array to remove 8 bytes of alignment padding on 64 bit builds, dropping its size from 40 to 32 bytes. Also update the macro module_param_array_named to initialise the structure using its member names to allow it to be changed without touching all its call sites. 'git grep' finds module_param_array in 1037 places so this patch will save a small amount of data space across many modules. Signed-off-by: Richard Kennedy Signed-off-by: Rusty Russell --- include/linux/moduleparam.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h index 07b41951e3fa..ddaae98c53f9 100644 --- a/include/linux/moduleparam.h +++ b/include/linux/moduleparam.h @@ -67,9 +67,9 @@ struct kparam_string { struct kparam_array { unsigned int max; + unsigned int elemsize; unsigned int *num; const struct kernel_param_ops *ops; - unsigned int elemsize; void *elem; }; @@ -371,8 +371,9 @@ extern int param_get_invbool(char *buffer, const struct kernel_param *kp); */ #define module_param_array_named(name, array, type, nump, perm) \ static const struct kparam_array __param_arr_##name \ - = { ARRAY_SIZE(array), nump, ¶m_ops_##type, \ - sizeof(array[0]), array }; \ + = { .max = ARRAY_SIZE(array), .num = nump, \ + .ops = ¶m_ops_##type, \ + .elemsize = sizeof(array[0]), .elem = array }; \ __module_param_call(MODULE_PARAM_PREFIX, name, \ ¶m_array_ops, \ .arr = &__param_arr_##name, \ -- cgit From de4d8d53465483168d6a627d409ee2d09d8e3308 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 19 Apr 2011 21:49:58 +0200 Subject: module: each_symbol_section instead of each_symbol Instead of having a callback function for each symbol in the kernel, have a callback for each array of symbols. This eases the logic when we move to sorted symbols and binary search. Signed-off-by: Rusty Russell Signed-off-by: Alessio Igor Bogani --- include/linux/module.h | 5 +++-- kernel/module.c | 42 +++++++++++++++++++++++++++--------------- 2 files changed, 30 insertions(+), 17 deletions(-) (limited to 'include/linux') diff --git a/include/linux/module.h b/include/linux/module.h index 65cc6cc73ca8..49f4ad0ddec2 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -477,8 +477,9 @@ const struct kernel_symbol *find_symbol(const char *name, bool warn); /* Walk the exported symbol table */ -bool each_symbol(bool (*fn)(const struct symsearch *arr, struct module *owner, - unsigned int symnum, void *data), void *data); +bool each_symbol_section(bool (*fn)(const struct symsearch *arr, + struct module *owner, + void *data), void *data); /* Returns 0 and fills in value, defined and namebuf, or -ERANGE if symnum out of range. */ diff --git a/kernel/module.c b/kernel/module.c index 0e6f97f43c88..e8aa462301e7 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -240,23 +240,24 @@ static bool each_symbol_in_section(const struct symsearch *arr, struct module *owner, bool (*fn)(const struct symsearch *syms, struct module *owner, - unsigned int symnum, void *data), + void *data), void *data) { - unsigned int i, j; + unsigned int j; for (j = 0; j < arrsize; j++) { - for (i = 0; i < arr[j].stop - arr[j].start; i++) - if (fn(&arr[j], owner, i, data)) - return true; + if (fn(&arr[j], owner, data)) + return true; } return false; } /* Returns true as soon as fn returns true, otherwise false. */ -bool each_symbol(bool (*fn)(const struct symsearch *arr, struct module *owner, - unsigned int symnum, void *data), void *data) +bool each_symbol_section(bool (*fn)(const struct symsearch *arr, + struct module *owner, + void *data), + void *data) { struct module *mod; static const struct symsearch arr[] = { @@ -309,7 +310,7 @@ bool each_symbol(bool (*fn)(const struct symsearch *arr, struct module *owner, } return false; } -EXPORT_SYMBOL_GPL(each_symbol); +EXPORT_SYMBOL_GPL(each_symbol_section); struct find_symbol_arg { /* Input */ @@ -323,15 +324,12 @@ struct find_symbol_arg { const struct kernel_symbol *sym; }; -static bool find_symbol_in_section(const struct symsearch *syms, - struct module *owner, - unsigned int symnum, void *data) +static bool check_symbol(const struct symsearch *syms, + struct module *owner, + unsigned int symnum, void *data) { struct find_symbol_arg *fsa = data; - if (strcmp(syms->start[symnum].name, fsa->name) != 0) - return false; - if (!fsa->gplok) { if (syms->licence == GPL_ONLY) return false; @@ -365,6 +363,20 @@ static bool find_symbol_in_section(const struct symsearch *syms, return true; } +static bool find_symbol_in_section(const struct symsearch *syms, + struct module *owner, + void *data) +{ + struct find_symbol_arg *fsa = data; + unsigned int i; + + for (i = 0; i < syms->stop - syms->start; i++) { + if (strcmp(syms->start[i].name, fsa->name) == 0) + return check_symbol(syms, owner, i, data); + } + return false; +} + /* Find a symbol and return it, along with, (optional) crc and * (optional) module which owns it. Needs preempt disabled or module_mutex. */ const struct kernel_symbol *find_symbol(const char *name, @@ -379,7 +391,7 @@ const struct kernel_symbol *find_symbol(const char *name, fsa.gplok = gplok; fsa.warn = warn; - if (each_symbol(find_symbol_in_section, &fsa)) { + if (each_symbol_section(find_symbol_in_section, &fsa)) { if (owner) *owner = fsa.owner; if (crc) -- cgit From f02e8a6596b7dc9b2171f7ff5654039ef0950cdc Mon Sep 17 00:00:00 2001 From: Alessio Igor Bogani Date: Thu, 14 Apr 2011 14:59:39 +0200 Subject: module: Sort exported symbols This patch places every exported symbol in its own section (i.e. "___ksymtab+printk"). Thus the linker will use its SORT() directive to sort and finally merge all symbol in the right and final section (i.e. "__ksymtab"). The symbol prefixed archs use an underscore as prefix for symbols. To avoid collision we use a different character to create the temporary section names. This work was supported by a hardware donation from the CE Linux Forum. Signed-off-by: Alessio Igor Bogani Signed-off-by: Rusty Russell (folded in '+' fixup) Tested-by: Dirk Behme --- include/asm-generic/vmlinux.lds.h | 20 ++++++++++---------- include/linux/module.h | 4 ++-- scripts/module-common.lds | 11 +++++++++++ 3 files changed, 23 insertions(+), 12 deletions(-) (limited to 'include/linux') diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index bd297a20ab98..b27445e00b6c 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -274,70 +274,70 @@ /* Kernel symbol table: Normal symbols */ \ __ksymtab : AT(ADDR(__ksymtab) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__start___ksymtab) = .; \ - *(__ksymtab) \ + *(SORT(___ksymtab+*)) \ VMLINUX_SYMBOL(__stop___ksymtab) = .; \ } \ \ /* Kernel symbol table: GPL-only symbols */ \ __ksymtab_gpl : AT(ADDR(__ksymtab_gpl) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__start___ksymtab_gpl) = .; \ - *(__ksymtab_gpl) \ + *(SORT(___ksymtab_gpl+*)) \ VMLINUX_SYMBOL(__stop___ksymtab_gpl) = .; \ } \ \ /* Kernel symbol table: Normal unused symbols */ \ __ksymtab_unused : AT(ADDR(__ksymtab_unused) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__start___ksymtab_unused) = .; \ - *(__ksymtab_unused) \ + *(SORT(___ksymtab_unused+*)) \ VMLINUX_SYMBOL(__stop___ksymtab_unused) = .; \ } \ \ /* Kernel symbol table: GPL-only unused symbols */ \ __ksymtab_unused_gpl : AT(ADDR(__ksymtab_unused_gpl) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__start___ksymtab_unused_gpl) = .; \ - *(__ksymtab_unused_gpl) \ + *(SORT(___ksymtab_unused_gpl+*)) \ VMLINUX_SYMBOL(__stop___ksymtab_unused_gpl) = .; \ } \ \ /* Kernel symbol table: GPL-future-only symbols */ \ __ksymtab_gpl_future : AT(ADDR(__ksymtab_gpl_future) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__start___ksymtab_gpl_future) = .; \ - *(__ksymtab_gpl_future) \ + *(SORT(___ksymtab_gpl_future+*)) \ VMLINUX_SYMBOL(__stop___ksymtab_gpl_future) = .; \ } \ \ /* Kernel symbol table: Normal symbols */ \ __kcrctab : AT(ADDR(__kcrctab) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__start___kcrctab) = .; \ - *(__kcrctab) \ + *(SORT(___kcrctab+*)) \ VMLINUX_SYMBOL(__stop___kcrctab) = .; \ } \ \ /* Kernel symbol table: GPL-only symbols */ \ __kcrctab_gpl : AT(ADDR(__kcrctab_gpl) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__start___kcrctab_gpl) = .; \ - *(__kcrctab_gpl) \ + *(SORT(___kcrctab_gpl+*)) \ VMLINUX_SYMBOL(__stop___kcrctab_gpl) = .; \ } \ \ /* Kernel symbol table: Normal unused symbols */ \ __kcrctab_unused : AT(ADDR(__kcrctab_unused) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__start___kcrctab_unused) = .; \ - *(__kcrctab_unused) \ + *(SORT(___kcrctab_unused+*)) \ VMLINUX_SYMBOL(__stop___kcrctab_unused) = .; \ } \ \ /* Kernel symbol table: GPL-only unused symbols */ \ __kcrctab_unused_gpl : AT(ADDR(__kcrctab_unused_gpl) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__start___kcrctab_unused_gpl) = .; \ - *(__kcrctab_unused_gpl) \ + *(SORT(___kcrctab_unused_gpl+*)) \ VMLINUX_SYMBOL(__stop___kcrctab_unused_gpl) = .; \ } \ \ /* Kernel symbol table: GPL-future-only symbols */ \ __kcrctab_gpl_future : AT(ADDR(__kcrctab_gpl_future) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__start___kcrctab_gpl_future) = .; \ - *(__kcrctab_gpl_future) \ + *(SORT(___kcrctab_gpl_future+*)) \ VMLINUX_SYMBOL(__stop___kcrctab_gpl_future) = .; \ } \ \ diff --git a/include/linux/module.h b/include/linux/module.h index 49f4ad0ddec2..d9ca2d5dc6d0 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -224,7 +224,7 @@ struct module_use { extern void *__crc_##sym __attribute__((weak)); \ static const unsigned long __kcrctab_##sym \ __used \ - __attribute__((section("__kcrctab" sec), unused)) \ + __attribute__((section("___kcrctab" sec "+" #sym), unused)) \ = (unsigned long) &__crc_##sym; #else #define __CRC_SYMBOL(sym, sec) @@ -239,7 +239,7 @@ struct module_use { = MODULE_SYMBOL_PREFIX #sym; \ static const struct kernel_symbol __ksymtab_##sym \ __used \ - __attribute__((section("__ksymtab" sec), unused)) \ + __attribute__((section("___ksymtab" sec "+" #sym), unused)) \ = { (unsigned long)&sym, __kstrtab_##sym } #define EXPORT_SYMBOL(sym) \ diff --git a/scripts/module-common.lds b/scripts/module-common.lds index 47a1f9ae0ede..0865b3e752be 100644 --- a/scripts/module-common.lds +++ b/scripts/module-common.lds @@ -5,4 +5,15 @@ */ SECTIONS { /DISCARD/ : { *(.discard) } + + __ksymtab : { *(SORT(___ksymtab+*)) } + __ksymtab_gpl : { *(SORT(___ksymtab_gpl+*)) } + __ksymtab_unused : { *(SORT(___ksymtab_unused+*)) } + __ksymtab_unused_gpl : { *(SORT(___ksymtab_unused_gpl+*)) } + __ksymtab_gpl_future : { *(SORT(___ksymtab_gpl_future+*)) } + __kcrctab : { *(SORT(___kcrctab+*)) } + __kcrctab_gpl : { *(SORT(___kcrctab_gpl+*)) } + __kcrctab_unused : { *(SORT(___kcrctab_unused+*)) } + __kcrctab_unused_gpl : { *(SORT(___kcrctab_unused_gpl+*)) } + __kcrctab_gpl_future : { *(SORT(___kcrctab_gpl_future+*)) } } -- cgit From 1a94dc35bc5c166d89913dc01a49d27a3c21a455 Mon Sep 17 00:00:00 2001 From: Tim Abbott Date: Thu, 14 Apr 2011 20:00:19 +0200 Subject: lib: Add generic binary search function to the kernel. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There a large number hand-coded binary searches in the kernel (run "git grep search | grep binary" to find many of them). Since in my experience, hand-coding binary searches can be error-prone, it seems worth cleaning this up by providing a generic binary search function. This generic binary search implementation comes from Ksplice. It has the same basic API as the C library bsearch() function. Ksplice uses it in half a dozen places with 4 different comparison functions, and I think our code is substantially cleaner because of this. Signed-off-by: Tim Abbott Extra-bikeshedding-by: Alan Jenkins Extra-bikeshedding-by: André Goddard Rosa Extra-bikeshedding-by: Rusty Russell Signed-off-by: Rusty Russell Signed-off-by: Alessio Igor Bogani Signed-off-by: Rusty Russell --- include/linux/bsearch.h | 9 +++++++++ lib/Makefile | 3 ++- lib/bsearch.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 include/linux/bsearch.h create mode 100644 lib/bsearch.c (limited to 'include/linux') diff --git a/include/linux/bsearch.h b/include/linux/bsearch.h new file mode 100644 index 000000000000..90b1aa867224 --- /dev/null +++ b/include/linux/bsearch.h @@ -0,0 +1,9 @@ +#ifndef _LINUX_BSEARCH_H +#define _LINUX_BSEARCH_H + +#include + +void *bsearch(const void *key, const void *base, size_t num, size_t size, + int (*cmp)(const void *key, const void *elt)); + +#endif /* _LINUX_BSEARCH_H */ diff --git a/lib/Makefile b/lib/Makefile index ef0f28571156..4b49a249064b 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -21,7 +21,8 @@ lib-y += kobject.o kref.o klist.o obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \ bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \ - string_helpers.o gcd.o lcm.o list_sort.o uuid.o flex_array.o + string_helpers.o gcd.o lcm.o list_sort.o uuid.o flex_array.o \ + bsearch.o obj-y += kstrtox.o obj-$(CONFIG_TEST_KSTRTOX) += test-kstrtox.o diff --git a/lib/bsearch.c b/lib/bsearch.c new file mode 100644 index 000000000000..5b54758e2afb --- /dev/null +++ b/lib/bsearch.c @@ -0,0 +1,53 @@ +/* + * A generic implementation of binary search for the Linux kernel + * + * Copyright (C) 2008-2009 Ksplice, Inc. + * Author: Tim Abbott + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2. + */ + +#include +#include + +/* + * bsearch - binary search an array of elements + * @key: pointer to item being searched for + * @base: pointer to first element to search + * @num: number of elements + * @size: size of each element + * @cmp: pointer to comparison function + * + * This function does a binary search on the given array. The + * contents of the array should already be in ascending sorted order + * under the provided comparison function. + * + * Note that the key need not have the same type as the elements in + * the array, e.g. key could be a string and the comparison function + * could compare the string with the struct's name field. However, if + * the key and elements in the array are of the same type, you can use + * the same comparison function for both sort() and bsearch(). + */ +void *bsearch(const void *key, const void *base, size_t num, size_t size, + int (*cmp)(const void *key, const void *elt)) +{ + size_t start = 0, end = num; + int result; + + while (start < end) { + size_t mid = start + (end - start) / 2; + + result = cmp(key, base + mid * size); + if (result < 0) + end = mid; + else if (result > 0) + start = mid + 1; + else + return (void *)base + mid * size; + } + + return NULL; +} +EXPORT_SYMBOL(bsearch); -- cgit From d0f1fed29e6e73d9d17f4c91a5896a4ce3938d45 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Tue, 19 Apr 2011 12:43:45 +0100 Subject: Add a strtobool function matching semantics of existing in kernel equivalents This is a rename of the usr_strtobool proposal, which was a renamed, relocated and fixed version of previous kstrtobool RFC Signed-off-by: Jonathan Cameron Signed-off-by: Rusty Russell --- include/linux/string.h | 1 + lib/string.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) (limited to 'include/linux') diff --git a/include/linux/string.h b/include/linux/string.h index a716ee2a8adb..a176db2f2c85 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -123,6 +123,7 @@ extern char **argv_split(gfp_t gfp, const char *str, int *argcp); extern void argv_free(char **argv); extern bool sysfs_streq(const char *s1, const char *s2); +extern int strtobool(const char *s, bool *res); #ifdef CONFIG_BINARY_PRINTF int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args); diff --git a/lib/string.c b/lib/string.c index f71bead1be3e..01fad9b203e1 100644 --- a/lib/string.c +++ b/lib/string.c @@ -535,6 +535,35 @@ bool sysfs_streq(const char *s1, const char *s2) } EXPORT_SYMBOL(sysfs_streq); +/** + * strtobool - convert common user inputs into boolean values + * @s: input string + * @res: result + * + * This routine returns 0 iff the first character is one of 'Yy1Nn0'. + * Otherwise it will return -EINVAL. Value pointed to by res is + * updated upon finding a match. + */ +int strtobool(const char *s, bool *res) +{ + switch (s[0]) { + case 'y': + case 'Y': + case '1': + *res = true; + break; + case 'n': + case 'N': + case '0': + *res = false; + break; + default: + return -EINVAL; + } + return 0; +} +EXPORT_SYMBOL(strtobool); + #ifndef __HAVE_ARCH_MEMSET /** * memset - Fill a region of memory with the given value -- cgit From 9d2e173644bb5c42ff1b280fbdda3f195a7cf1f7 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Thu, 19 May 2011 00:59:32 -0700 Subject: Input: ADP5589 - new driver for I2C Keypad Decoder and I/O Expander From http://www.analog.com/ADP5589: The ADP5589 is an I/O port expander and keypad matrix decoder designed for QWERTY type phones that require a large keypad matrix and expanded I/O lines. Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/Kconfig | 10 + drivers/input/keyboard/Makefile | 1 + drivers/input/keyboard/adp5589-keys.c | 771 ++++++++++++++++++++++++++++++++++ include/linux/input/adp5589.h | 213 ++++++++++ 4 files changed, 995 insertions(+) create mode 100644 drivers/input/keyboard/adp5589-keys.c create mode 100644 include/linux/input/adp5589.h (limited to 'include/linux') diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index dec090ac7d31..69badb4e06aa 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -32,6 +32,16 @@ config KEYBOARD_ADP5588 To compile this driver as a module, choose M here: the module will be called adp5588-keys. +config KEYBOARD_ADP5589 + tristate "ADP5589 I2C QWERTY Keypad and IO Expander" + depends on I2C + help + Say Y here if you want to use a ADP5589 attached to your + system I2C bus. + + To compile this driver as a module, choose M here: the + module will be called adp5589-keys. + config KEYBOARD_AMIGA tristate "Amiga keyboard" depends on AMIGA diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index b45361009f2e..c49cf8e04cd7 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_KEYBOARD_ADP5520) += adp5520-keys.o obj-$(CONFIG_KEYBOARD_ADP5588) += adp5588-keys.o +obj-$(CONFIG_KEYBOARD_ADP5589) += adp5589-keys.o obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o obj-$(CONFIG_KEYBOARD_ATARI) += atakbd.o obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o diff --git a/drivers/input/keyboard/adp5589-keys.c b/drivers/input/keyboard/adp5589-keys.c new file mode 100644 index 000000000000..631598663aab --- /dev/null +++ b/drivers/input/keyboard/adp5589-keys.c @@ -0,0 +1,771 @@ +/* + * Description: keypad driver for ADP5589 + * I2C QWERTY Keypad and IO Expander + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * Copyright (C) 2010-2011 Analog Devices Inc. + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* GENERAL_CFG Register */ +#define OSC_EN (1 << 7) +#define CORE_CLK(x) (((x) & 0x3) << 5) +#define LCK_TRK_LOGIC (1 << 4) +#define LCK_TRK_GPI (1 << 3) +#define INT_CFG (1 << 1) +#define RST_CFG (1 << 0) + +/* INT_EN Register */ +#define LOGIC2_IEN (1 << 5) +#define LOGIC1_IEN (1 << 4) +#define LOCK_IEN (1 << 3) +#define OVRFLOW_IEN (1 << 2) +#define GPI_IEN (1 << 1) +#define EVENT_IEN (1 << 0) + +/* Interrupt Status Register */ +#define LOGIC2_INT (1 << 5) +#define LOGIC1_INT (1 << 4) +#define LOCK_INT (1 << 3) +#define OVRFLOW_INT (1 << 2) +#define GPI_INT (1 << 1) +#define EVENT_INT (1 << 0) + +/* STATUS Register */ + +#define LOGIC2_STAT (1 << 7) +#define LOGIC1_STAT (1 << 6) +#define LOCK_STAT (1 << 5) +#define KEC 0xF + +/* PIN_CONFIG_D Register */ +#define C4_EXTEND_CFG (1 << 6) /* RESET2 */ +#define R4_EXTEND_CFG (1 << 5) /* RESET1 */ + +/* LOCK_CFG */ +#define LOCK_EN (1 << 0) + +#define PTIME_MASK 0x3 +#define LTIME_MASK 0x3 + +/* Key Event Register xy */ +#define KEY_EV_PRESSED (1 << 7) +#define KEY_EV_MASK (0x7F) + +#define KEYP_MAX_EVENT 16 + +#define MAXGPIO 19 +#define ADP_BANK(offs) ((offs) >> 3) +#define ADP_BIT(offs) (1u << ((offs) & 0x7)) + +struct adp5589_kpad { + struct i2c_client *client; + struct input_dev *input; + unsigned short keycode[ADP5589_KEYMAPSIZE]; + const struct adp5589_gpi_map *gpimap; + unsigned short gpimapsize; + unsigned extend_cfg; +#ifdef CONFIG_GPIOLIB + unsigned char gpiomap[MAXGPIO]; + bool export_gpio; + struct gpio_chip gc; + struct mutex gpio_lock; /* Protect cached dir, dat_out */ + u8 dat_out[3]; + u8 dir[3]; +#endif +}; + +static int adp5589_read(struct i2c_client *client, u8 reg) +{ + int ret = i2c_smbus_read_byte_data(client, reg); + + if (ret < 0) + dev_err(&client->dev, "Read Error\n"); + + return ret; +} + +static int adp5589_write(struct i2c_client *client, u8 reg, u8 val) +{ + return i2c_smbus_write_byte_data(client, reg, val); +} + +#ifdef CONFIG_GPIOLIB +static int adp5589_gpio_get_value(struct gpio_chip *chip, unsigned off) +{ + struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc); + unsigned int bank = ADP_BANK(kpad->gpiomap[off]); + unsigned int bit = ADP_BIT(kpad->gpiomap[off]); + + return !!(adp5589_read(kpad->client, ADP5589_GPI_STATUS_A + bank) & + bit); +} + +static void adp5589_gpio_set_value(struct gpio_chip *chip, + unsigned off, int val) +{ + struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc); + unsigned int bank = ADP_BANK(kpad->gpiomap[off]); + unsigned int bit = ADP_BIT(kpad->gpiomap[off]); + + mutex_lock(&kpad->gpio_lock); + + if (val) + kpad->dat_out[bank] |= bit; + else + kpad->dat_out[bank] &= ~bit; + + adp5589_write(kpad->client, ADP5589_GPO_DATA_OUT_A + bank, + kpad->dat_out[bank]); + + mutex_unlock(&kpad->gpio_lock); +} + +static int adp5589_gpio_direction_input(struct gpio_chip *chip, unsigned off) +{ + struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc); + unsigned int bank = ADP_BANK(kpad->gpiomap[off]); + unsigned int bit = ADP_BIT(kpad->gpiomap[off]); + int ret; + + mutex_lock(&kpad->gpio_lock); + + kpad->dir[bank] &= ~bit; + ret = adp5589_write(kpad->client, ADP5589_GPIO_DIRECTION_A + bank, + kpad->dir[bank]); + + mutex_unlock(&kpad->gpio_lock); + + return ret; +} + +static int adp5589_gpio_direction_output(struct gpio_chip *chip, + unsigned off, int val) +{ + struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc); + unsigned int bank = ADP_BANK(kpad->gpiomap[off]); + unsigned int bit = ADP_BIT(kpad->gpiomap[off]); + int ret; + + mutex_lock(&kpad->gpio_lock); + + kpad->dir[bank] |= bit; + + if (val) + kpad->dat_out[bank] |= bit; + else + kpad->dat_out[bank] &= ~bit; + + ret = adp5589_write(kpad->client, ADP5589_GPO_DATA_OUT_A + bank, + kpad->dat_out[bank]); + ret |= adp5589_write(kpad->client, ADP5589_GPIO_DIRECTION_A + bank, + kpad->dir[bank]); + + mutex_unlock(&kpad->gpio_lock); + + return ret; +} + +static int __devinit adp5589_build_gpiomap(struct adp5589_kpad *kpad, + const struct adp5589_kpad_platform_data *pdata) +{ + bool pin_used[MAXGPIO]; + int n_unused = 0; + int i; + + memset(pin_used, false, sizeof(pin_used)); + + for (i = 0; i < MAXGPIO; i++) + if (pdata->keypad_en_mask & (1 << i)) + pin_used[i] = true; + + for (i = 0; i < kpad->gpimapsize; i++) + pin_used[kpad->gpimap[i].pin - ADP5589_GPI_PIN_BASE] = true; + + if (kpad->extend_cfg & R4_EXTEND_CFG) + pin_used[4] = true; + + if (kpad->extend_cfg & C4_EXTEND_CFG) + pin_used[12] = true; + + for (i = 0; i < MAXGPIO; i++) + if (!pin_used[i]) + kpad->gpiomap[n_unused++] = i; + + return n_unused; +} + +static int __devinit adp5589_gpio_add(struct adp5589_kpad *kpad) +{ + struct device *dev = &kpad->client->dev; + const struct adp5589_kpad_platform_data *pdata = dev->platform_data; + const struct adp5589_gpio_platform_data *gpio_data = pdata->gpio_data; + int i, error; + + if (!gpio_data) + return 0; + + kpad->gc.ngpio = adp5589_build_gpiomap(kpad, pdata); + if (kpad->gc.ngpio == 0) { + dev_info(dev, "No unused gpios left to export\n"); + return 0; + } + + kpad->export_gpio = true; + + kpad->gc.direction_input = adp5589_gpio_direction_input; + kpad->gc.direction_output = adp5589_gpio_direction_output; + kpad->gc.get = adp5589_gpio_get_value; + kpad->gc.set = adp5589_gpio_set_value; + kpad->gc.can_sleep = 1; + + kpad->gc.base = gpio_data->gpio_start; + kpad->gc.label = kpad->client->name; + kpad->gc.owner = THIS_MODULE; + + mutex_init(&kpad->gpio_lock); + + error = gpiochip_add(&kpad->gc); + if (error) { + dev_err(dev, "gpiochip_add failed, err: %d\n", error); + return error; + } + + for (i = 0; i <= ADP_BANK(MAXGPIO); i++) { + kpad->dat_out[i] = adp5589_read(kpad->client, + ADP5589_GPO_DATA_OUT_A + i); + kpad->dir[i] = adp5589_read(kpad->client, + ADP5589_GPIO_DIRECTION_A + i); + } + + if (gpio_data->setup) { + error = gpio_data->setup(kpad->client, + kpad->gc.base, kpad->gc.ngpio, + gpio_data->context); + if (error) + dev_warn(dev, "setup failed, %d\n", error); + } + + return 0; +} + +static void __devexit adp5589_gpio_remove(struct adp5589_kpad *kpad) +{ + struct device *dev = &kpad->client->dev; + const struct adp5589_kpad_platform_data *pdata = dev->platform_data; + const struct adp5589_gpio_platform_data *gpio_data = pdata->gpio_data; + int error; + + if (!kpad->export_gpio) + return; + + if (gpio_data->teardown) { + error = gpio_data->teardown(kpad->client, + kpad->gc.base, kpad->gc.ngpio, + gpio_data->context); + if (error) + dev_warn(dev, "teardown failed %d\n", error); + } + + error = gpiochip_remove(&kpad->gc); + if (error) + dev_warn(dev, "gpiochip_remove failed %d\n", error); +} +#else +static inline int adp5589_gpio_add(struct adp5589_kpad *kpad) +{ + return 0; +} + +static inline void adp5589_gpio_remove(struct adp5589_kpad *kpad) +{ +} +#endif + +static void adp5589_report_switches(struct adp5589_kpad *kpad, + int key, int key_val) +{ + int i; + + for (i = 0; i < kpad->gpimapsize; i++) { + if (key_val == kpad->gpimap[i].pin) { + input_report_switch(kpad->input, + kpad->gpimap[i].sw_evt, + key & KEY_EV_PRESSED); + break; + } + } +} + +static void adp5589_report_events(struct adp5589_kpad *kpad, int ev_cnt) +{ + int i; + + for (i = 0; i < ev_cnt; i++) { + int key = adp5589_read(kpad->client, ADP5589_FIFO_1 + i); + int key_val = key & KEY_EV_MASK; + + if (key_val >= ADP5589_GPI_PIN_BASE && + key_val <= ADP5589_GPI_PIN_END) { + adp5589_report_switches(kpad, key, key_val); + } else { + input_report_key(kpad->input, + kpad->keycode[key_val - 1], + key & KEY_EV_PRESSED); + } + } +} + +static irqreturn_t adp5589_irq(int irq, void *handle) +{ + struct adp5589_kpad *kpad = handle; + struct i2c_client *client = kpad->client; + int status, ev_cnt; + + status = adp5589_read(client, ADP5589_INT_STATUS); + + if (status & OVRFLOW_INT) /* Unlikely and should never happen */ + dev_err(&client->dev, "Event Overflow Error\n"); + + if (status & EVENT_INT) { + ev_cnt = adp5589_read(client, ADP5589_STATUS) & KEC; + if (ev_cnt) { + adp5589_report_events(kpad, ev_cnt); + input_sync(kpad->input); + } + } + + adp5589_write(client, ADP5589_INT_STATUS, status); /* Status is W1C */ + + return IRQ_HANDLED; +} + +static int __devinit adp5589_get_evcode(struct adp5589_kpad *kpad, unsigned short key) +{ + int i; + + for (i = 0; i < ADP5589_KEYMAPSIZE; i++) + if (key == kpad->keycode[i]) + return (i + 1) | KEY_EV_PRESSED; + + dev_err(&kpad->client->dev, "RESET/UNLOCK key not in keycode map\n"); + + return -EINVAL; +} + +static int __devinit adp5589_setup(struct adp5589_kpad *kpad) +{ + struct i2c_client *client = kpad->client; + const struct adp5589_kpad_platform_data *pdata = + client->dev.platform_data; + int i, ret; + unsigned char evt_mode1 = 0, evt_mode2 = 0, evt_mode3 = 0; + unsigned char pull_mask = 0; + + ret = adp5589_write(client, ADP5589_PIN_CONFIG_A, + pdata->keypad_en_mask & 0xFF); + ret |= adp5589_write(client, ADP5589_PIN_CONFIG_B, + (pdata->keypad_en_mask >> 8) & 0xFF); + ret |= adp5589_write(client, ADP5589_PIN_CONFIG_C, + (pdata->keypad_en_mask >> 16) & 0xFF); + + if (pdata->en_keylock) { + ret |= adp5589_write(client, ADP5589_UNLOCK1, + pdata->unlock_key1); + ret |= adp5589_write(client, ADP5589_UNLOCK2, + pdata->unlock_key2); + ret |= adp5589_write(client, ADP5589_UNLOCK_TIMERS, + pdata->unlock_timer & LTIME_MASK); + ret |= adp5589_write(client, ADP5589_LOCK_CFG, LOCK_EN); + } + + for (i = 0; i < KEYP_MAX_EVENT; i++) + ret |= adp5589_read(client, ADP5589_FIFO_1 + i); + + for (i = 0; i < pdata->gpimapsize; i++) { + unsigned short pin = pdata->gpimap[i].pin; + + if (pin <= ADP5589_GPI_PIN_ROW_END) { + evt_mode1 |= (1 << (pin - ADP5589_GPI_PIN_ROW_BASE)); + } else { + evt_mode2 |= + ((1 << (pin - ADP5589_GPI_PIN_COL_BASE)) & 0xFF); + evt_mode3 |= + ((1 << (pin - ADP5589_GPI_PIN_COL_BASE)) >> 8); + } + } + + if (pdata->gpimapsize) { + ret |= adp5589_write(client, ADP5589_GPI_EVENT_EN_A, evt_mode1); + ret |= adp5589_write(client, ADP5589_GPI_EVENT_EN_B, evt_mode2); + ret |= adp5589_write(client, ADP5589_GPI_EVENT_EN_C, evt_mode3); + } + + if (pdata->pull_dis_mask & pdata->pullup_en_100k & + pdata->pullup_en_300k & pdata->pulldown_en_300k) + dev_warn(&client->dev, "Conflicting pull resistor config\n"); + + for (i = 0; i < MAXGPIO; i++) { + unsigned val = 0; + + if (pdata->pullup_en_300k & (1 << i)) + val = 0; + else if (pdata->pulldown_en_300k & (1 << i)) + val = 1; + else if (pdata->pullup_en_100k & (1 << i)) + val = 2; + else if (pdata->pull_dis_mask & (1 << i)) + val = 3; + + pull_mask |= val << (2 * (i & 0x3)); + + if ((i & 0x3) == 0x3 || i == MAXGPIO - 1) { + ret |= adp5589_write(client, + ADP5589_RPULL_CONFIG_A + (i >> 2), + pull_mask); + pull_mask = 0; + } + } + + if (pdata->reset1_key_1 && pdata->reset1_key_2 && pdata->reset1_key_3) { + ret |= adp5589_write(client, ADP5589_RESET1_EVENT_A, + adp5589_get_evcode(kpad, + pdata->reset1_key_1)); + ret |= adp5589_write(client, ADP5589_RESET1_EVENT_B, + adp5589_get_evcode(kpad, + pdata->reset1_key_2)); + ret |= adp5589_write(client, ADP5589_RESET1_EVENT_C, + adp5589_get_evcode(kpad, + pdata->reset1_key_3)); + kpad->extend_cfg |= R4_EXTEND_CFG; + } + + if (pdata->reset2_key_1 && pdata->reset2_key_2) { + ret |= adp5589_write(client, ADP5589_RESET2_EVENT_A, + adp5589_get_evcode(kpad, + pdata->reset2_key_1)); + ret |= adp5589_write(client, ADP5589_RESET2_EVENT_B, + adp5589_get_evcode(kpad, + pdata->reset2_key_2)); + kpad->extend_cfg |= C4_EXTEND_CFG; + } + + if (kpad->extend_cfg) { + ret |= adp5589_write(client, ADP5589_RESET_CFG, + pdata->reset_cfg); + ret |= adp5589_write(client, ADP5589_PIN_CONFIG_D, + kpad->extend_cfg); + } + + for (i = 0; i <= ADP_BANK(MAXGPIO); i++) + ret |= adp5589_write(client, ADP5589_DEBOUNCE_DIS_A + i, + pdata->debounce_dis_mask >> (i * 8)); + + ret |= adp5589_write(client, ADP5589_POLL_PTIME_CFG, + pdata->scan_cycle_time & PTIME_MASK); + ret |= adp5589_write(client, ADP5589_INT_STATUS, LOGIC2_INT | + LOGIC1_INT | OVRFLOW_INT | LOCK_INT | + GPI_INT | EVENT_INT); /* Status is W1C */ + + ret |= adp5589_write(client, ADP5589_GENERAL_CFG, + INT_CFG | OSC_EN | CORE_CLK(3)); + ret |= adp5589_write(client, ADP5589_INT_EN, + OVRFLOW_IEN | GPI_IEN | EVENT_IEN); + + if (ret < 0) { + dev_err(&client->dev, "Write Error\n"); + return ret; + } + + return 0; +} + +static void __devinit adp5589_report_switch_state(struct adp5589_kpad *kpad) +{ + int gpi_stat1 = adp5589_read(kpad->client, ADP5589_GPI_STATUS_A); + int gpi_stat2 = adp5589_read(kpad->client, ADP5589_GPI_STATUS_B); + int gpi_stat3 = adp5589_read(kpad->client, ADP5589_GPI_STATUS_C); + int gpi_stat_tmp, pin_loc; + int i; + + for (i = 0; i < kpad->gpimapsize; i++) { + unsigned short pin = kpad->gpimap[i].pin; + + if (pin <= ADP5589_GPI_PIN_ROW_END) { + gpi_stat_tmp = gpi_stat1; + pin_loc = pin - ADP5589_GPI_PIN_ROW_BASE; + } else if ((pin - ADP5589_GPI_PIN_COL_BASE) < 8) { + gpi_stat_tmp = gpi_stat2; + pin_loc = pin - ADP5589_GPI_PIN_COL_BASE; + } else { + gpi_stat_tmp = gpi_stat3; + pin_loc = pin - ADP5589_GPI_PIN_COL_BASE - 8; + } + + if (gpi_stat_tmp < 0) { + dev_err(&kpad->client->dev, + "Can't read GPIO_DAT_STAT switch" + " %d default to OFF\n", pin); + gpi_stat_tmp = 0; + } + + input_report_switch(kpad->input, + kpad->gpimap[i].sw_evt, + !(gpi_stat_tmp & (1 << pin_loc))); + } + + input_sync(kpad->input); +} + +static int __devinit adp5589_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct adp5589_kpad *kpad; + const struct adp5589_kpad_platform_data *pdata; + struct input_dev *input; + unsigned int revid; + int ret, i; + int error; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_err(&client->dev, "SMBUS Byte Data not Supported\n"); + return -EIO; + } + + pdata = client->dev.platform_data; + if (!pdata) { + dev_err(&client->dev, "no platform data?\n"); + return -EINVAL; + } + + if (!((pdata->keypad_en_mask & 0xFF) && + (pdata->keypad_en_mask >> 8)) || !pdata->keymap) { + dev_err(&client->dev, "no rows, cols or keymap from pdata\n"); + return -EINVAL; + } + + if (pdata->keymapsize != ADP5589_KEYMAPSIZE) { + dev_err(&client->dev, "invalid keymapsize\n"); + return -EINVAL; + } + + if (!pdata->gpimap && pdata->gpimapsize) { + dev_err(&client->dev, "invalid gpimap from pdata\n"); + return -EINVAL; + } + + if (pdata->gpimapsize > ADP5589_GPIMAPSIZE_MAX) { + dev_err(&client->dev, "invalid gpimapsize\n"); + return -EINVAL; + } + + for (i = 0; i < pdata->gpimapsize; i++) { + unsigned short pin = pdata->gpimap[i].pin; + + if (pin < ADP5589_GPI_PIN_BASE || pin > ADP5589_GPI_PIN_END) { + dev_err(&client->dev, "invalid gpi pin data\n"); + return -EINVAL; + } + + if ((1 << (pin - ADP5589_GPI_PIN_ROW_BASE)) & + pdata->keypad_en_mask) { + dev_err(&client->dev, "invalid gpi row/col data\n"); + return -EINVAL; + } + } + + if (!client->irq) { + dev_err(&client->dev, "no IRQ?\n"); + return -EINVAL; + } + + kpad = kzalloc(sizeof(*kpad), GFP_KERNEL); + input = input_allocate_device(); + if (!kpad || !input) { + error = -ENOMEM; + goto err_free_mem; + } + + kpad->client = client; + kpad->input = input; + + ret = adp5589_read(client, ADP5589_ID); + if (ret < 0) { + error = ret; + goto err_free_mem; + } + + revid = (u8) ret & ADP5589_DEVICE_ID_MASK; + + input->name = client->name; + input->phys = "adp5589-keys/input0"; + input->dev.parent = &client->dev; + + input_set_drvdata(input, kpad); + + input->id.bustype = BUS_I2C; + input->id.vendor = 0x0001; + input->id.product = 0x0001; + input->id.version = revid; + + input->keycodesize = sizeof(kpad->keycode[0]); + input->keycodemax = pdata->keymapsize; + input->keycode = kpad->keycode; + + memcpy(kpad->keycode, pdata->keymap, + pdata->keymapsize * input->keycodesize); + + kpad->gpimap = pdata->gpimap; + kpad->gpimapsize = pdata->gpimapsize; + + /* setup input device */ + __set_bit(EV_KEY, input->evbit); + + if (pdata->repeat) + __set_bit(EV_REP, input->evbit); + + for (i = 0; i < input->keycodemax; i++) + __set_bit(kpad->keycode[i] & KEY_MAX, input->keybit); + __clear_bit(KEY_RESERVED, input->keybit); + + if (kpad->gpimapsize) + __set_bit(EV_SW, input->evbit); + for (i = 0; i < kpad->gpimapsize; i++) + __set_bit(kpad->gpimap[i].sw_evt, input->swbit); + + error = input_register_device(input); + if (error) { + dev_err(&client->dev, "unable to register input device\n"); + goto err_free_mem; + } + + error = request_threaded_irq(client->irq, NULL, adp5589_irq, + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + client->dev.driver->name, kpad); + if (error) { + dev_err(&client->dev, "irq %d busy?\n", client->irq); + goto err_unreg_dev; + } + + error = adp5589_setup(kpad); + if (error) + goto err_free_irq; + + if (kpad->gpimapsize) + adp5589_report_switch_state(kpad); + + error = adp5589_gpio_add(kpad); + if (error) + goto err_free_irq; + + device_init_wakeup(&client->dev, 1); + i2c_set_clientdata(client, kpad); + + dev_info(&client->dev, "Rev.%d keypad, irq %d\n", revid, client->irq); + return 0; + +err_free_irq: + free_irq(client->irq, kpad); +err_unreg_dev: + input_unregister_device(input); + input = NULL; +err_free_mem: + input_free_device(input); + kfree(kpad); + + return error; +} + +static int __devexit adp5589_remove(struct i2c_client *client) +{ + struct adp5589_kpad *kpad = i2c_get_clientdata(client); + + adp5589_write(client, ADP5589_GENERAL_CFG, 0); + free_irq(client->irq, kpad); + input_unregister_device(kpad->input); + adp5589_gpio_remove(kpad); + kfree(kpad); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int adp5589_suspend(struct device *dev) +{ + struct adp5589_kpad *kpad = dev_get_drvdata(dev); + struct i2c_client *client = kpad->client; + + disable_irq(client->irq); + + if (device_may_wakeup(&client->dev)) + enable_irq_wake(client->irq); + + return 0; +} + +static int adp5589_resume(struct device *dev) +{ + struct adp5589_kpad *kpad = dev_get_drvdata(dev); + struct i2c_client *client = kpad->client; + + if (device_may_wakeup(&client->dev)) + disable_irq_wake(client->irq); + + enable_irq(client->irq); + + return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(adp5589_dev_pm_ops, adp5589_suspend, adp5589_resume); + +static const struct i2c_device_id adp5589_id[] = { + {"adp5589-keys", 0}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, adp5589_id); + +static struct i2c_driver adp5589_driver = { + .driver = { + .name = KBUILD_MODNAME, + .owner = THIS_MODULE, + .pm = &adp5589_dev_pm_ops, + }, + .probe = adp5589_probe, + .remove = __devexit_p(adp5589_remove), + .id_table = adp5589_id, +}; + +static int __init adp5589_init(void) +{ + return i2c_add_driver(&adp5589_driver); +} +module_init(adp5589_init); + +static void __exit adp5589_exit(void) +{ + i2c_del_driver(&adp5589_driver); +} +module_exit(adp5589_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("ADP5589 Keypad driver"); diff --git a/include/linux/input/adp5589.h b/include/linux/input/adp5589.h new file mode 100644 index 000000000000..ef792ecfaabf --- /dev/null +++ b/include/linux/input/adp5589.h @@ -0,0 +1,213 @@ +/* + * Analog Devices ADP5589 I/O Expander and QWERTY Keypad Controller + * + * Copyright 2010-2011 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#ifndef _ADP5589_H +#define _ADP5589_H + +#define ADP5589_ID 0x00 +#define ADP5589_INT_STATUS 0x01 +#define ADP5589_STATUS 0x02 +#define ADP5589_FIFO_1 0x03 +#define ADP5589_FIFO_2 0x04 +#define ADP5589_FIFO_3 0x05 +#define ADP5589_FIFO_4 0x06 +#define ADP5589_FIFO_5 0x07 +#define ADP5589_FIFO_6 0x08 +#define ADP5589_FIFO_7 0x09 +#define ADP5589_FIFO_8 0x0A +#define ADP5589_FIFO_9 0x0B +#define ADP5589_FIFO_10 0x0C +#define ADP5589_FIFO_11 0x0D +#define ADP5589_FIFO_12 0x0E +#define ADP5589_FIFO_13 0x0F +#define ADP5589_FIFO_14 0x10 +#define ADP5589_FIFO_15 0x11 +#define ADP5589_FIFO_16 0x12 +#define ADP5589_GPI_INT_STAT_A 0x13 +#define ADP5589_GPI_INT_STAT_B 0x14 +#define ADP5589_GPI_INT_STAT_C 0x15 +#define ADP5589_GPI_STATUS_A 0x16 +#define ADP5589_GPI_STATUS_B 0x17 +#define ADP5589_GPI_STATUS_C 0x18 +#define ADP5589_RPULL_CONFIG_A 0x19 +#define ADP5589_RPULL_CONFIG_B 0x1A +#define ADP5589_RPULL_CONFIG_C 0x1B +#define ADP5589_RPULL_CONFIG_D 0x1C +#define ADP5589_RPULL_CONFIG_E 0x1D +#define ADP5589_GPI_INT_LEVEL_A 0x1E +#define ADP5589_GPI_INT_LEVEL_B 0x1F +#define ADP5589_GPI_INT_LEVEL_C 0x20 +#define ADP5589_GPI_EVENT_EN_A 0x21 +#define ADP5589_GPI_EVENT_EN_B 0x22 +#define ADP5589_GPI_EVENT_EN_C 0x23 +#define ADP5589_GPI_INTERRUPT_EN_A 0x24 +#define ADP5589_GPI_INTERRUPT_EN_B 0x25 +#define ADP5589_GPI_INTERRUPT_EN_C 0x26 +#define ADP5589_DEBOUNCE_DIS_A 0x27 +#define ADP5589_DEBOUNCE_DIS_B 0x28 +#define ADP5589_DEBOUNCE_DIS_C 0x29 +#define ADP5589_GPO_DATA_OUT_A 0x2A +#define ADP5589_GPO_DATA_OUT_B 0x2B +#define ADP5589_GPO_DATA_OUT_C 0x2C +#define ADP5589_GPO_OUT_MODE_A 0x2D +#define ADP5589_GPO_OUT_MODE_B 0x2E +#define ADP5589_GPO_OUT_MODE_C 0x2F +#define ADP5589_GPIO_DIRECTION_A 0x30 +#define ADP5589_GPIO_DIRECTION_B 0x31 +#define ADP5589_GPIO_DIRECTION_C 0x32 +#define ADP5589_UNLOCK1 0x33 +#define ADP5589_UNLOCK2 0x34 +#define ADP5589_EXT_LOCK_EVENT 0x35 +#define ADP5589_UNLOCK_TIMERS 0x36 +#define ADP5589_LOCK_CFG 0x37 +#define ADP5589_RESET1_EVENT_A 0x38 +#define ADP5589_RESET1_EVENT_B 0x39 +#define ADP5589_RESET1_EVENT_C 0x3A +#define ADP5589_RESET2_EVENT_A 0x3B +#define ADP5589_RESET2_EVENT_B 0x3C +#define ADP5589_RESET_CFG 0x3D +#define ADP5589_PWM_OFFT_LOW 0x3E +#define ADP5589_PWM_OFFT_HIGH 0x3F +#define ADP5589_PWM_ONT_LOW 0x40 +#define ADP5589_PWM_ONT_HIGH 0x41 +#define ADP5589_PWM_CFG 0x42 +#define ADP5589_CLOCK_DIV_CFG 0x43 +#define ADP5589_LOGIC_1_CFG 0x44 +#define ADP5589_LOGIC_2_CFG 0x45 +#define ADP5589_LOGIC_FF_CFG 0x46 +#define ADP5589_LOGIC_INT_EVENT_EN 0x47 +#define ADP5589_POLL_PTIME_CFG 0x48 +#define ADP5589_PIN_CONFIG_A 0x49 +#define ADP5589_PIN_CONFIG_B 0x4A +#define ADP5589_PIN_CONFIG_C 0x4B +#define ADP5589_PIN_CONFIG_D 0x4C +#define ADP5589_GENERAL_CFG 0x4D +#define ADP5589_INT_EN 0x4E + +#define ADP5589_DEVICE_ID_MASK 0xF + +/* Put one of these structures in i2c_board_info platform_data */ + +#define ADP5589_KEYMAPSIZE 88 + +#define ADP5589_GPI_PIN_ROW0 97 +#define ADP5589_GPI_PIN_ROW1 98 +#define ADP5589_GPI_PIN_ROW2 99 +#define ADP5589_GPI_PIN_ROW3 100 +#define ADP5589_GPI_PIN_ROW4 101 +#define ADP5589_GPI_PIN_ROW5 102 +#define ADP5589_GPI_PIN_ROW6 103 +#define ADP5589_GPI_PIN_ROW7 104 +#define ADP5589_GPI_PIN_COL0 105 +#define ADP5589_GPI_PIN_COL1 106 +#define ADP5589_GPI_PIN_COL2 107 +#define ADP5589_GPI_PIN_COL3 108 +#define ADP5589_GPI_PIN_COL4 109 +#define ADP5589_GPI_PIN_COL5 110 +#define ADP5589_GPI_PIN_COL6 111 +#define ADP5589_GPI_PIN_COL7 112 +#define ADP5589_GPI_PIN_COL8 113 +#define ADP5589_GPI_PIN_COL9 114 +#define ADP5589_GPI_PIN_COL10 115 +#define GPI_LOGIC1 116 +#define GPI_LOGIC2 117 + +#define ADP5589_GPI_PIN_ROW_BASE ADP5589_GPI_PIN_ROW0 +#define ADP5589_GPI_PIN_ROW_END ADP5589_GPI_PIN_ROW7 +#define ADP5589_GPI_PIN_COL_BASE ADP5589_GPI_PIN_COL0 +#define ADP5589_GPI_PIN_COL_END ADP5589_GPI_PIN_COL10 + +#define ADP5589_GPI_PIN_BASE ADP5589_GPI_PIN_ROW_BASE +#define ADP5589_GPI_PIN_END ADP5589_GPI_PIN_COL_END + +#define ADP5589_GPIMAPSIZE_MAX (ADP5589_GPI_PIN_END - ADP5589_GPI_PIN_BASE + 1) + +struct adp5589_gpi_map { + unsigned short pin; + unsigned short sw_evt; +}; + +/* scan_cycle_time */ +#define ADP5589_SCAN_CYCLE_10ms 0 +#define ADP5589_SCAN_CYCLE_20ms 1 +#define ADP5589_SCAN_CYCLE_30ms 2 +#define ADP5589_SCAN_CYCLE_40ms 3 + +/* RESET_CFG */ +#define RESET_PULSE_WIDTH_500us 0 +#define RESET_PULSE_WIDTH_1ms 1 +#define RESET_PULSE_WIDTH_2ms 2 +#define RESET_PULSE_WIDTH_10ms 3 + +#define RESET_TRIG_TIME_0ms (0 << 2) +#define RESET_TRIG_TIME_1000ms (1 << 2) +#define RESET_TRIG_TIME_1500ms (2 << 2) +#define RESET_TRIG_TIME_2000ms (3 << 2) +#define RESET_TRIG_TIME_2500ms (4 << 2) +#define RESET_TRIG_TIME_3000ms (5 << 2) +#define RESET_TRIG_TIME_3500ms (6 << 2) +#define RESET_TRIG_TIME_4000ms (7 << 2) + +#define RESET_PASSTHRU_EN (1 << 5) +#define RESET1_POL_HIGH (1 << 6) +#define RESET1_POL_LOW (0 << 6) +#define RESET2_POL_HIGH (1 << 7) +#define RESET2_POL_LOW (0 << 7) + +/* Mask Bits: + * C C C C C C C C C C C | R R R R R R R R + * 1 9 8 7 6 5 4 3 2 1 0 | 7 6 5 4 3 2 1 0 + * 0 + * ---------------- BIT ------------------ + * 1 1 1 1 1 1 1 1 1 0 0 | 0 0 0 0 0 0 0 0 + * 8 7 6 5 4 3 2 1 0 9 8 | 7 6 5 4 3 2 1 0 + */ + +#define ADP_ROW(x) (1 << (x)) +#define ADP_COL(x) (1 << (x + 8)) + +struct adp5589_kpad_platform_data { + unsigned keypad_en_mask; /* Keypad (Rows/Columns) enable mask */ + const unsigned short *keymap; /* Pointer to keymap */ + unsigned short keymapsize; /* Keymap size */ + bool repeat; /* Enable key repeat */ + bool en_keylock; /* Enable key lock feature */ + unsigned char unlock_key1; /* Unlock Key 1 */ + unsigned char unlock_key2; /* Unlock Key 2 */ + unsigned char unlock_timer; /* Time in seconds [0..7] between the two unlock keys 0=disable */ + unsigned char scan_cycle_time; /* Time between consecutive scan cycles */ + unsigned char reset_cfg; /* Reset config */ + unsigned short reset1_key_1; /* Reset Key 1 */ + unsigned short reset1_key_2; /* Reset Key 2 */ + unsigned short reset1_key_3; /* Reset Key 3 */ + unsigned short reset2_key_1; /* Reset Key 1 */ + unsigned short reset2_key_2; /* Reset Key 2 */ + unsigned debounce_dis_mask; /* Disable debounce mask */ + unsigned pull_dis_mask; /* Disable all pull resistors mask */ + unsigned pullup_en_100k; /* Pull-Up 100k Enable Mask */ + unsigned pullup_en_300k; /* Pull-Up 300k Enable Mask */ + unsigned pulldown_en_300k; /* Pull-Down 300k Enable Mask */ + const struct adp5589_gpi_map *gpimap; + unsigned short gpimapsize; + const struct adp5589_gpio_platform_data *gpio_data; +}; + +struct i2c_client; /* forward declaration */ + +struct adp5589_gpio_platform_data { + int gpio_start; /* GPIO Chip base # */ + int (*setup)(struct i2c_client *client, + int gpio, unsigned ngpio, + void *context); + int (*teardown)(struct i2c_client *client, + int gpio, unsigned ngpio, + void *context); + void *context; +}; + +#endif -- cgit From b3ae52b6b0335eba547221aad2cb3c50902e3d2d Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Tue, 10 May 2011 23:31:30 +0200 Subject: SSB: Change fallback sprom to callback mechanism. Some embedded devices like the Netgear WNDR3300 have two SSB based cards without an own sprom on the pci bus. We have to provide two different fallback sproms for these and this was not possible with the old solution. In the bcm47xx architecture the sprom data is stored in the nvram in the main flash storage. The architecture code will be able to fill the sprom with the stored data based on the bus where the device was found. The bcm63xx code should do the same thing as before, just using the new API. Acked-by: Michael Buesch Cc: netdev@vger.kernel.org Cc: linux-wireless@vger.kernel.org Cc: Florian Fainelli Signed-off-by: Hauke Mehrtens Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/2362/ Signed-off-by: Ralf Baechle --- arch/mips/bcm63xx/boards/board_bcm963xx.c | 16 ++++++++++-- drivers/ssb/pci.c | 16 ++++++++---- drivers/ssb/sprom.c | 43 ++++++++++++++++++------------- drivers/ssb/ssb_private.h | 3 ++- include/linux/ssb/ssb.h | 4 ++- 5 files changed, 55 insertions(+), 27 deletions(-) (limited to 'include/linux') diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c index 8dba8cfb752f..40b223b603be 100644 --- a/arch/mips/bcm63xx/boards/board_bcm963xx.c +++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c @@ -643,6 +643,17 @@ static struct ssb_sprom bcm63xx_sprom = { .boardflags_lo = 0x2848, .boardflags_hi = 0x0000, }; + +int bcm63xx_get_fallback_sprom(struct ssb_bus *bus, struct ssb_sprom *out) +{ + if (bus->bustype == SSB_BUSTYPE_PCI) { + memcpy(out, &bcm63xx_sprom, sizeof(struct ssb_sprom)); + return 0; + } else { + printk(KERN_ERR PFX "unable to fill SPROM for given bustype.\n"); + return -EINVAL; + } +} #endif /* @@ -793,8 +804,9 @@ void __init board_prom_init(void) if (!board_get_mac_address(bcm63xx_sprom.il0mac)) { memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN); memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN); - if (ssb_arch_set_fallback_sprom(&bcm63xx_sprom) < 0) - printk(KERN_ERR "failed to register fallback SPROM\n"); + if (ssb_arch_register_fallback_sprom( + &bcm63xx_get_fallback_sprom) < 0) + printk(KERN_ERR PFX "failed to register fallback SPROM\n"); } #endif } diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index 6f34963b3c64..7ad48585c5e6 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c @@ -662,7 +662,6 @@ static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out, static int ssb_pci_sprom_get(struct ssb_bus *bus, struct ssb_sprom *sprom) { - const struct ssb_sprom *fallback; int err; u16 *buf; @@ -707,10 +706,17 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus, if (err) { /* All CRC attempts failed. * Maybe there is no SPROM on the device? - * If we have a fallback, use that. */ - fallback = ssb_get_fallback_sprom(); - if (fallback) { - memcpy(sprom, fallback, sizeof(*sprom)); + * Now we ask the arch code if there is some sprom + * available for this device in some other storage */ + err = ssb_fill_sprom_with_fallback(bus, sprom); + if (err) { + ssb_printk(KERN_WARNING PFX "WARNING: Using" + " fallback SPROM failed (err %d)\n", + err); + } else { + ssb_dprintk(KERN_DEBUG PFX "Using SPROM" + " revision %d provided by" + " platform.\n", sprom->revision); err = 0; goto out_free; } diff --git a/drivers/ssb/sprom.c b/drivers/ssb/sprom.c index 5f34d7a3e3a5..45ff0e3a3828 100644 --- a/drivers/ssb/sprom.c +++ b/drivers/ssb/sprom.c @@ -17,7 +17,7 @@ #include -static const struct ssb_sprom *fallback_sprom; +static int(*get_fallback_sprom)(struct ssb_bus *dev, struct ssb_sprom *out); static int sprom2hex(const u16 *sprom, char *buf, size_t buf_len, @@ -145,36 +145,43 @@ out: } /** - * ssb_arch_set_fallback_sprom - Set a fallback SPROM for use if no SPROM is found. + * ssb_arch_register_fallback_sprom - Registers a method providing a + * fallback SPROM if no SPROM is found. * - * @sprom: The SPROM data structure to register. + * @sprom_callback: The callback function. * - * With this function the architecture implementation may register a fallback - * SPROM data structure. The fallback is only used for PCI based SSB devices, - * where no valid SPROM can be found in the shadow registers. + * With this function the architecture implementation may register a + * callback handler which fills the SPROM data structure. The fallback is + * only used for PCI based SSB devices, where no valid SPROM can be found + * in the shadow registers. * - * This function is useful for weird architectures that have a half-assed SSB device - * hardwired to their PCI bus. + * This function is useful for weird architectures that have a half-assed + * SSB device hardwired to their PCI bus. * - * Note that it does only work with PCI attached SSB devices. PCMCIA devices currently - * don't use this fallback. - * Architectures must provide the SPROM for native SSB devices anyway, - * so the fallback also isn't used for native devices. + * Note that it does only work with PCI attached SSB devices. PCMCIA + * devices currently don't use this fallback. + * Architectures must provide the SPROM for native SSB devices anyway, so + * the fallback also isn't used for native devices. * - * This function is available for architecture code, only. So it is not exported. + * This function is available for architecture code, only. So it is not + * exported. */ -int ssb_arch_set_fallback_sprom(const struct ssb_sprom *sprom) +int ssb_arch_register_fallback_sprom(int (*sprom_callback)(struct ssb_bus *bus, + struct ssb_sprom *out)) { - if (fallback_sprom) + if (get_fallback_sprom) return -EEXIST; - fallback_sprom = sprom; + get_fallback_sprom = sprom_callback; return 0; } -const struct ssb_sprom *ssb_get_fallback_sprom(void) +int ssb_fill_sprom_with_fallback(struct ssb_bus *bus, struct ssb_sprom *out) { - return fallback_sprom; + if (!get_fallback_sprom) + return -ENOENT; + + return get_fallback_sprom(bus, out); } /* http://bcm-v4.sipsolutions.net/802.11/IsSpromAvailable */ diff --git a/drivers/ssb/ssb_private.h b/drivers/ssb/ssb_private.h index 0331139a726f..77653014db0b 100644 --- a/drivers/ssb/ssb_private.h +++ b/drivers/ssb/ssb_private.h @@ -171,7 +171,8 @@ ssize_t ssb_attr_sprom_store(struct ssb_bus *bus, const char *buf, size_t count, int (*sprom_check_crc)(const u16 *sprom, size_t size), int (*sprom_write)(struct ssb_bus *bus, const u16 *sprom)); -extern const struct ssb_sprom *ssb_get_fallback_sprom(void); +extern int ssb_fill_sprom_with_fallback(struct ssb_bus *bus, + struct ssb_sprom *out); /* core.c */ diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h index 9659eff52ca2..045f72ab5dfd 100644 --- a/include/linux/ssb/ssb.h +++ b/include/linux/ssb/ssb.h @@ -404,7 +404,9 @@ extern bool ssb_is_sprom_available(struct ssb_bus *bus); /* Set a fallback SPROM. * See kdoc at the function definition for complete documentation. */ -extern int ssb_arch_set_fallback_sprom(const struct ssb_sprom *sprom); +extern int ssb_arch_register_fallback_sprom( + int (*sprom_callback)(struct ssb_bus *bus, + struct ssb_sprom *out)); /* Suspend a SSB bus. * Call this from the parent bus suspend routine. */ -- cgit From 369db4c9524b7487faf1ff89646eee396c1363e1 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 18 May 2011 21:33:40 +0000 Subject: clocksource: Restructure clocksource struct members Group the hot path members of struct clocksource together so we have a better cache line footprint. Make it cacheline aligned. Signed-off-by: Thomas Gleixner Cc: John Stultz Cc: Eric Dumazet Reviewed-by: Ingo Molnar Link: http://lkml.kernel.org/r/%3C20110518210136.003081882%40linutronix.de%3E --- include/linux/clocksource.h | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) (limited to 'include/linux') diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h index 0fb0b7e79394..c918fbd33ee5 100644 --- a/include/linux/clocksource.h +++ b/include/linux/clocksource.h @@ -159,42 +159,38 @@ extern u64 timecounter_cyc2time(struct timecounter *tc, */ struct clocksource { /* - * First part of structure is read mostly + * Hotpath data, fits in a single cache line when the + * clocksource itself is cacheline aligned. */ - const char *name; - struct list_head list; - int rating; cycle_t (*read)(struct clocksource *cs); - int (*enable)(struct clocksource *cs); - void (*disable)(struct clocksource *cs); + cycle_t cycle_last; cycle_t mask; u32 mult; u32 shift; u64 max_idle_ns; - unsigned long flags; - cycle_t (*vread)(void); - void (*suspend)(struct clocksource *cs); - void (*resume)(struct clocksource *cs); + #ifdef CONFIG_IA64 void *fsys_mmio; /* used by fsyscall asm code */ #define CLKSRC_FSYS_MMIO_SET(mmio, addr) ((mmio) = (addr)) #else #define CLKSRC_FSYS_MMIO_SET(mmio, addr) do { } while (0) #endif - - /* - * Second part is written at each timer interrupt - * Keep it in a different cache line to dirty no - * more than one cache line. - */ - cycle_t cycle_last ____cacheline_aligned_in_smp; + const char *name; + struct list_head list; + int rating; + cycle_t (*vread)(void); + int (*enable)(struct clocksource *cs); + void (*disable)(struct clocksource *cs); + unsigned long flags; + void (*suspend)(struct clocksource *cs); + void (*resume)(struct clocksource *cs); #ifdef CONFIG_CLOCKSOURCE_WATCHDOG /* Watchdog related data, used by the framework */ struct list_head wd_list; cycle_t wd_last; #endif -}; +} ____cacheline_aligned; /* * Clock source flags bits:: -- cgit From 847b2f42be203f3cff7f243fdd3ee50c1e06c882 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 18 May 2011 21:33:41 +0000 Subject: clockevents: Restructure clock_event_device members Group the hot path members of struct clock_event_device together so we have a better cache line footprint. Make it cacheline aligned. Signed-off-by: Thomas Gleixner Cc: John Stultz Reviewed-by: Ingo Molnar Link: http://lkml.kernel.org/r/%3C20110518210136.223607682%40linutronix.de%3E --- include/linux/clockchips.h | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) (limited to 'include/linux') diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h index fc53492b6ad7..9466eebc8e19 100644 --- a/include/linux/clockchips.h +++ b/include/linux/clockchips.h @@ -56,46 +56,47 @@ enum clock_event_nofitiers { /** * struct clock_event_device - clock event device descriptor - * @name: ptr to clock event name - * @features: features + * @event_handler: Assigned by the framework to be called by the low + * level handler of the event source + * @set_next_event: set next event function + * @next_event: local storage for the next event in oneshot mode * @max_delta_ns: maximum delta value in ns * @min_delta_ns: minimum delta value in ns * @mult: nanosecond to cycles multiplier * @shift: nanoseconds to cycles divisor (power of two) + * @mode: operating mode assigned by the management code + * @features: features + * @retries: number of forced programming retries + * @set_mode: set mode function + * @broadcast: function to broadcast events + * @name: ptr to clock event name * @rating: variable to rate clock event devices * @irq: IRQ number (only for non CPU local devices) * @cpumask: cpumask to indicate for which CPUs this device works - * @set_next_event: set next event function - * @set_mode: set mode function - * @event_handler: Assigned by the framework to be called by the low - * level handler of the event source - * @broadcast: function to broadcast events * @list: list head for the management code - * @mode: operating mode assigned by the management code - * @next_event: local storage for the next event in oneshot mode - * @retries: number of forced programming retries */ struct clock_event_device { - const char *name; - unsigned int features; + void (*event_handler)(struct clock_event_device *); + int (*set_next_event)(unsigned long evt, + struct clock_event_device *); + ktime_t next_event; u64 max_delta_ns; u64 min_delta_ns; u32 mult; u32 shift; + enum clock_event_mode mode; + unsigned int features; + unsigned long retries; + + void (*broadcast)(const struct cpumask *mask); + void (*set_mode)(enum clock_event_mode mode, + struct clock_event_device *); + const char *name; int rating; int irq; const struct cpumask *cpumask; - int (*set_next_event)(unsigned long evt, - struct clock_event_device *); - void (*set_mode)(enum clock_event_mode mode, - struct clock_event_device *); - void (*event_handler)(struct clock_event_device *); - void (*broadcast)(const struct cpumask *mask); struct list_head list; - enum clock_event_mode mode; - ktime_t next_event; - unsigned long retries; -}; +} ____cacheline_aligned; /* * Calculate a multiplication factor for scaled math, which is used to convert -- cgit From 57f0fcbe1dea8a36c9d1673086326059991c5f81 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 18 May 2011 21:33:41 +0000 Subject: clockevents: Provide combined configure and register function All clockevent devices have the same open coded initialization functions. Provide an interface which does all necessary initialization in the core code. Signed-off-by: Thomas Gleixner Cc: John Stultz Reviewed-by: Ingo Molnar Link: http://lkml.kernel.org/r/%3C20110518210136.331975870%40linutronix.de%3E --- include/linux/clockchips.h | 9 +++++++++ kernel/time/clockevents.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) (limited to 'include/linux') diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h index 9466eebc8e19..80acc79e0dc5 100644 --- a/include/linux/clockchips.h +++ b/include/linux/clockchips.h @@ -69,6 +69,8 @@ enum clock_event_nofitiers { * @retries: number of forced programming retries * @set_mode: set mode function * @broadcast: function to broadcast events + * @min_delta_ticks: minimum delta value in ticks stored for reconfiguration + * @max_delta_ticks: maximum delta value in ticks stored for reconfiguration * @name: ptr to clock event name * @rating: variable to rate clock event devices * @irq: IRQ number (only for non CPU local devices) @@ -91,6 +93,9 @@ struct clock_event_device { void (*broadcast)(const struct cpumask *mask); void (*set_mode)(enum clock_event_mode mode, struct clock_event_device *); + unsigned long min_delta_ticks; + unsigned long max_delta_ticks; + const char *name; int rating; int irq; @@ -123,6 +128,10 @@ extern u64 clockevent_delta2ns(unsigned long latch, struct clock_event_device *evt); extern void clockevents_register_device(struct clock_event_device *dev); +extern void clockevents_config_and_register(struct clock_event_device *dev, + u32 freq, unsigned long min_delta, + unsigned long max_delta); + extern void clockevents_exchange_device(struct clock_event_device *old, struct clock_event_device *new); extern void clockevents_set_mode(struct clock_event_device *dev, diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c index 0d74b9ba90c8..c69e88c94446 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c @@ -194,6 +194,50 @@ void clockevents_register_device(struct clock_event_device *dev) } EXPORT_SYMBOL_GPL(clockevents_register_device); +static void clockevents_config(struct clock_event_device *dev, + u32 freq) +{ + unsigned long sec; + + if (!(dev->features & CLOCK_EVT_FEAT_ONESHOT)) + return; + + /* + * Calculate the maximum number of seconds we can sleep. Limit + * to 10 minutes for hardware which can program more than + * 32bit ticks so we still get reasonable conversion values. + */ + sec = dev->max_delta_ticks; + do_div(sec, freq); + if (!sec) + sec = 1; + else if (sec > 600 && dev->max_delta_ticks > UINT_MAX) + sec = 600; + + clockevents_calc_mult_shift(dev, freq, sec); + dev->min_delta_ns = clockevent_delta2ns(dev->min_delta_ticks, dev); + dev->max_delta_ns = clockevent_delta2ns(dev->max_delta_ticks, dev); +} + +/** + * clockevents_config_and_register - Configure and register a clock event device + * @dev: device to register + * @freq: The clock frequency + * @min_delta: The minimum clock ticks to program in oneshot mode + * @max_delta: The maximum clock ticks to program in oneshot mode + * + * min/max_delta can be 0 for devices which do not support oneshot mode. + */ +void clockevents_config_and_register(struct clock_event_device *dev, + u32 freq, unsigned long min_delta, + unsigned long max_delta) +{ + dev->min_delta_ticks = min_delta; + dev->max_delta_ticks = max_delta; + clockevents_config(dev, freq); + clockevents_register_device(dev); +} + /* * Noop handler when we shut down an event device */ -- cgit From 80b816b736cfa5b9582279127099b20a479ab7d9 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 18 May 2011 21:33:42 +0000 Subject: clockevents: Provide interface to reconfigure an active clock event device Some ARM SoCs have clock event devices which have their frequency modified due to frequency scaling. Provide an interface which allows to reconfigure an active device. After reconfiguration reprogram the current pending event. Signed-off-by: Thomas Gleixner Cc: LAK Cc: John Stultz Acked-by: Linus Walleij Reviewed-by: Ingo Molnar Link: http://lkml.kernel.org/r/%3C20110518210136.437459958%40linutronix.de%3E --- include/linux/clockchips.h | 2 ++ kernel/time/clockevents.c | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+) (limited to 'include/linux') diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h index 80acc79e0dc5..d6733e27af34 100644 --- a/include/linux/clockchips.h +++ b/include/linux/clockchips.h @@ -132,6 +132,8 @@ extern void clockevents_config_and_register(struct clock_event_device *dev, u32 freq, unsigned long min_delta, unsigned long max_delta); +extern int clockevents_update_freq(struct clock_event_device *ce, u32 freq); + extern void clockevents_exchange_device(struct clock_event_device *old, struct clock_event_device *new); extern void clockevents_set_mode(struct clock_event_device *dev, diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c index c69e88c94446..22a9da9a9c96 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c @@ -238,6 +238,26 @@ void clockevents_config_and_register(struct clock_event_device *dev, clockevents_register_device(dev); } +/** + * clockevents_update_freq - Update frequency and reprogram a clock event device. + * @dev: device to modify + * @freq: new device frequency + * + * Reconfigure and reprogram a clock event device in oneshot + * mode. Must be called on the cpu for which the device delivers per + * cpu timer events with interrupts disabled! Returns 0 on success, + * -ETIME when the event is in the past. + */ +int clockevents_update_freq(struct clock_event_device *dev, u32 freq) +{ + clockevents_config(dev, freq); + + if (dev->mode != CLOCK_EVT_MODE_ONESHOT) + return 0; + + return clockevents_program_event(dev, dev->next_event, ktime_get()); +} + /* * Noop handler when we shut down an event device */ -- cgit From 99a0378de9f887fd4d501f1baa50aaf16d01a8e8 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Tue, 12 Apr 2011 15:34:36 -0400 Subject: hwmon: (sht15) general code clean-up * Add a documentation file for the device. * Respect a bit more the kernel-doc syntax. * Rename some variables for clarity. * Use bool type for flags. * Use an enum for states (actions being done). Signed-off-by: Vivien Didelot Acked-by: Jonathan Cameron Signed-off-by: Guenter Roeck --- Documentation/hwmon/sht15 | 42 ++++++++ drivers/hwmon/sht15.c | 268 ++++++++++++++++++++++++++-------------------- include/linux/sht15.h | 12 ++- 3 files changed, 203 insertions(+), 119 deletions(-) create mode 100644 Documentation/hwmon/sht15 (limited to 'include/linux') diff --git a/Documentation/hwmon/sht15 b/Documentation/hwmon/sht15 new file mode 100644 index 000000000000..2919c516fdbc --- /dev/null +++ b/Documentation/hwmon/sht15 @@ -0,0 +1,42 @@ +Kernel driver sht15 +=================== + +Authors: + * Wouter Horre + * Jonathan Cameron + +Supported chips: + * Sensirion SHT10 + Prefix: 'sht10' + + * Sensirion SHT11 + Prefix: 'sht11' + + * Sensirion SHT15 + Prefix: 'sht15' + + * Sensirion SHT71 + Prefix: 'sht71' + + * Sensirion SHT75 + Prefix: 'sht75' + +Datasheet: Publicly available at the Sensirion website +http://www.sensirion.ch/en/pdf/product_information/Datasheet-humidity-sensor-SHT1x.pdf + +Description +----------- + +The SHT10, SHT11, SHT15, SHT71, and SHT75 are humidity and temperature +sensors. + +The devices communicate using two GPIO lines and use the default +resolution settings of 14 bits for temperature and 12 bits for humidity. + +Note: The regulator supply name is set to "vcc". + +Sysfs interface +--------------- + +* temp1_input: temperature input +* humidity1_input: humidity input diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c index f4e617adb220..080af75c517b 100644 --- a/drivers/hwmon/sht15.c +++ b/drivers/hwmon/sht15.c @@ -9,16 +9,7 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * - * Currently ignoring checksum on readings. - * Default resolution only (14bit temp, 12bit humidity) - * Ignoring battery status. - * Heater not enabled. - * Timings are all conservative. - * - * Data sheet available (1/2009) at - * http://www.sensirion.ch/en/pdf/product_information/Datasheet-humidity-sensor-SHT1x.pdf - * - * Regulator supply name = vcc + * For further information, see the Documentation/hwmon/sht15 file. */ #include @@ -39,17 +30,21 @@ #include #include -#define SHT15_MEASURE_TEMP 3 -#define SHT15_MEASURE_RH 5 +/* Commands */ +#define SHT15_MEASURE_TEMP 0x03 +#define SHT15_MEASURE_RH 0x05 -#define SHT15_READING_NOTHING 0 -#define SHT15_READING_TEMP 1 -#define SHT15_READING_HUMID 2 +/* Min timings */ +#define SHT15_TSCKL 100 /* (nsecs) clock low */ +#define SHT15_TSCKH 100 /* (nsecs) clock high */ +#define SHT15_TSU 150 /* (nsecs) data setup time */ -/* Min timings in nsecs */ -#define SHT15_TSCKL 100 /* clock low */ -#define SHT15_TSCKH 100 /* clock high */ -#define SHT15_TSU 150 /* data setup time */ +/* Actions the driver may be doing */ +enum sht15_state { + SHT15_READING_NOTHING, + SHT15_READING_TEMP, + SHT15_READING_HUMID +}; /** * struct sht15_temppair - elements of voltage dependent temp calc @@ -61,9 +56,7 @@ struct sht15_temppair { int d1; }; -/* Table 9 from data sheet - relates temperature calculation - * to supply voltage. - */ +/* Table 9 from datasheet - relates temperature calculation to supply voltage */ static const struct sht15_temppair temppoints[] = { { 2500000, -39400 }, { 3000000, -39600 }, @@ -74,27 +67,27 @@ static const struct sht15_temppair temppoints[] = { /** * struct sht15_data - device instance specific data - * @pdata: platform data (gpio's etc) - * @read_work: bh of interrupt handler - * @wait_queue: wait queue for getting values from device - * @val_temp: last temperature value read from device - * @val_humid: last humidity value read from device - * @flag: status flag used to identify what the last request was - * @valid: are the current stored values valid (start condition) - * @last_updat: time of last update - * @read_lock: mutex to ensure only one read in progress - * at a time. - * @dev: associate device structure - * @hwmon_dev: device associated with hwmon subsystem - * @reg: associated regulator (if specified) - * @nb: notifier block to handle notifications of voltage changes - * @supply_uV: local copy of supply voltage used to allow - * use of regulator consumer if available - * @supply_uV_valid: indicates that an updated value has not yet - * been obtained from the regulator and so any calculations - * based upon it will be invalid. - * @update_supply_work: work struct that is used to update the supply_uV - * @interrupt_handled: flag used to indicate a hander has been scheduled + * @pdata: platform data (gpio's etc). + * @read_work: bh of interrupt handler. + * @wait_queue: wait queue for getting values from device. + * @val_temp: last temperature value read from device. + * @val_humid: last humidity value read from device. + * @state: state identifying the action the driver is doing. + * @measurements_valid: are the current stored measures valid (start condition). + * @last_measurement: time of last measure. + * @read_lock: mutex to ensure only one read in progress at a time. + * @dev: associate device structure. + * @hwmon_dev: device associated with hwmon subsystem. + * @reg: associated regulator (if specified). + * @nb: notifier block to handle notifications of voltage + * changes. + * @supply_uV: local copy of supply voltage used to allow use of + * regulator consumer if available. + * @supply_uV_valid: indicates that an updated value has not yet been + * obtained from the regulator and so any calculations + * based upon it will be invalid. + * @update_supply_work: work struct that is used to update the supply_uV. + * @interrupt_handled: flag used to indicate a handler has been scheduled. */ struct sht15_data { struct sht15_platform_data *pdata; @@ -102,16 +95,16 @@ struct sht15_data { wait_queue_head_t wait_queue; uint16_t val_temp; uint16_t val_humid; - u8 flag; - u8 valid; - unsigned long last_updat; + enum sht15_state state; + bool measurements_valid; + unsigned long last_measurement; struct mutex read_lock; struct device *dev; struct device *hwmon_dev; struct regulator *reg; struct notifier_block nb; int supply_uV; - int supply_uV_valid; + bool supply_uV_valid; struct work_struct update_supply_work; atomic_t interrupt_handled; }; @@ -125,6 +118,7 @@ struct sht15_data { static void sht15_connection_reset(struct sht15_data *data) { int i; + gpio_direction_output(data->pdata->gpio_data, 1); ndelay(SHT15_TSCKL); gpio_set_value(data->pdata->gpio_sck, 0); @@ -136,14 +130,14 @@ static void sht15_connection_reset(struct sht15_data *data) ndelay(SHT15_TSCKL); } } + /** * sht15_send_bit() - send an individual bit to the device * @data: device state data * @val: value of bit to be sent - **/ + */ static inline void sht15_send_bit(struct sht15_data *data, int val) { - gpio_set_value(data->pdata->gpio_data, val); ndelay(SHT15_TSU); gpio_set_value(data->pdata->gpio_sck, 1); @@ -154,12 +148,12 @@ static inline void sht15_send_bit(struct sht15_data *data, int val) /** * sht15_transmission_start() - specific sequence for new transmission - * * @data: device state data + * * Timings for this are not documented on the data sheet, so very * conservative ones used in implementation. This implements * figure 12 on the data sheet. - **/ + */ static void sht15_transmission_start(struct sht15_data *data) { /* ensure data is high and output */ @@ -180,23 +174,26 @@ static void sht15_transmission_start(struct sht15_data *data) gpio_set_value(data->pdata->gpio_sck, 0); ndelay(SHT15_TSCKL); } + /** * sht15_send_byte() - send a single byte to the device * @data: device state * @byte: value to be sent - **/ + */ static void sht15_send_byte(struct sht15_data *data, u8 byte) { int i; + for (i = 0; i < 8; i++) { sht15_send_bit(data, !!(byte & 0x80)); byte <<= 1; } } + /** * sht15_wait_for_response() - checks for ack from device * @data: device state - **/ + */ static int sht15_wait_for_response(struct sht15_data *data) { gpio_direction_input(data->pdata->gpio_data); @@ -220,27 +217,30 @@ static int sht15_wait_for_response(struct sht15_data *data) * * On entry, sck is output low, data is output pull high * and the interrupt disabled. - **/ + */ static int sht15_send_cmd(struct sht15_data *data, u8 cmd) { int ret = 0; + sht15_transmission_start(data); sht15_send_byte(data, cmd); ret = sht15_wait_for_response(data); return ret; } + /** - * sht15_update_single_val() - get a new value from device + * sht15_measurement() - get a new value from device * @data: device instance specific data * @command: command sent to request value * @timeout_msecs: timeout after which comms are assumed * to have failed are reset. - **/ -static inline int sht15_update_single_val(struct sht15_data *data, - int command, - int timeout_msecs) + */ +static int sht15_measurement(struct sht15_data *data, + int command, + int timeout_msecs) { int ret; + ret = sht15_send_cmd(data, command); if (ret) return ret; @@ -256,7 +256,7 @@ static inline int sht15_update_single_val(struct sht15_data *data, schedule_work(&data->read_work); } ret = wait_event_timeout(data->wait_queue, - (data->flag == SHT15_READING_NOTHING), + (data->state == SHT15_READING_NOTHING), msecs_to_jiffies(timeout_msecs)); if (ret == 0) {/* timeout occurred */ disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data)); @@ -267,27 +267,27 @@ static inline int sht15_update_single_val(struct sht15_data *data, } /** - * sht15_update_vals() - get updated readings from device if too old + * sht15_update_measurements() - get updated measures from device if too old * @data: device state - **/ -static int sht15_update_vals(struct sht15_data *data) + */ +static int sht15_update_measurements(struct sht15_data *data) { int ret = 0; int timeout = HZ; mutex_lock(&data->read_lock); - if (time_after(jiffies, data->last_updat + timeout) - || !data->valid) { - data->flag = SHT15_READING_HUMID; - ret = sht15_update_single_val(data, SHT15_MEASURE_RH, 160); + if (time_after(jiffies, data->last_measurement + timeout) + || !data->measurements_valid) { + data->state = SHT15_READING_HUMID; + ret = sht15_measurement(data, SHT15_MEASURE_RH, 160); if (ret) goto error_ret; - data->flag = SHT15_READING_TEMP; - ret = sht15_update_single_val(data, SHT15_MEASURE_TEMP, 400); + data->state = SHT15_READING_TEMP; + ret = sht15_measurement(data, SHT15_MEASURE_TEMP, 400); if (ret) goto error_ret; - data->valid = 1; - data->last_updat = jiffies; + data->measurements_valid = true; + data->last_measurement = jiffies; } error_ret: mutex_unlock(&data->read_lock); @@ -300,7 +300,7 @@ error_ret: * @data: device state * * As per section 4.3 of the data sheet. - **/ + */ static inline int sht15_calc_temp(struct sht15_data *data) { int d1 = temppoints[0].d1; @@ -316,7 +316,7 @@ static inline int sht15_calc_temp(struct sht15_data *data) break; } - return data->val_temp*10 + d1; + return data->val_temp * 10 + d1; } /** @@ -325,23 +325,35 @@ static inline int sht15_calc_temp(struct sht15_data *data) * * This is the temperature compensated version as per section 4.2 of * the data sheet. - **/ + * + * The sensor is assumed to be V3, which is compatible with V4. + * Humidity conversion coefficients are shown in table 7 of the datasheet. + */ static inline int sht15_calc_humid(struct sht15_data *data) { - int RHlinear; /* milli percent */ + int rh_linear; /* milli percent */ int temp = sht15_calc_temp(data); const int c1 = -4; const int c2 = 40500; /* x 10 ^ -6 */ - const int c3 = -28; /* x 10 ^ -7 */ + const int c3 = -28; /* x 10 ^ -7 */ - RHlinear = c1*1000 - + c2 * data->val_humid/1000 + rh_linear = c1 * 1000 + + c2 * data->val_humid / 1000 + (data->val_humid * data->val_humid * c3) / 10000; return (temp - 25000) * (10000 + 80 * data->val_humid) - / 1000000 + RHlinear; + / 1000000 + rh_linear; } +/** + * sht15_show_temp() - show temperature measurement value in sysfs + * @dev: device. + * @attr: device attribute. + * @buf: sysfs buffer where measurement values are written to. + * + * Will be called on read access to temp1_input sysfs attribute. + * Returns number of bytes written into buffer, negative errno on error. + */ static ssize_t sht15_show_temp(struct device *dev, struct device_attribute *attr, char *buf) @@ -350,12 +362,21 @@ static ssize_t sht15_show_temp(struct device *dev, struct sht15_data *data = dev_get_drvdata(dev); /* Technically no need to read humidity as well */ - ret = sht15_update_vals(data); + ret = sht15_update_measurements(data); return ret ? ret : sprintf(buf, "%d\n", sht15_calc_temp(data)); } +/** + * sht15_show_humidity() - show humidity measurement value in sysfs + * @dev: device. + * @attr: device attribute. + * @buf: sysfs buffer where measurement values are written to. + * + * Will be called on read access to humidity1_input sysfs attribute. + * Returns number of bytes written into buffer, negative errno on error. + */ static ssize_t sht15_show_humidity(struct device *dev, struct device_attribute *attr, char *buf) @@ -363,11 +384,12 @@ static ssize_t sht15_show_humidity(struct device *dev, int ret; struct sht15_data *data = dev_get_drvdata(dev); - ret = sht15_update_vals(data); + ret = sht15_update_measurements(data); return ret ? ret : sprintf(buf, "%d\n", sht15_calc_humid(data)); -}; +} + static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf) @@ -376,12 +398,10 @@ static ssize_t show_name(struct device *dev, return sprintf(buf, "%s\n", pdev->name); } -static SENSOR_DEVICE_ATTR(temp1_input, - S_IRUGO, sht15_show_temp, - NULL, 0); -static SENSOR_DEVICE_ATTR(humidity1_input, - S_IRUGO, sht15_show_humidity, - NULL, 0); +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, + sht15_show_temp, NULL, 0); +static SENSOR_DEVICE_ATTR(humidity1_input, S_IRUGO, + sht15_show_humidity, NULL, 0); static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); static struct attribute *sht15_attrs[] = { &sensor_dev_attr_temp1_input.dev_attr.attr, @@ -397,16 +417,20 @@ static const struct attribute_group sht15_attr_group = { static irqreturn_t sht15_interrupt_fired(int irq, void *d) { struct sht15_data *data = d; + /* First disable the interrupt */ disable_irq_nosync(irq); atomic_inc(&data->interrupt_handled); /* Then schedule a reading work struct */ - if (data->flag != SHT15_READING_NOTHING) + if (data->state != SHT15_READING_NOTHING) schedule_work(&data->read_work); return IRQ_HANDLED; } -/* Each byte of data is acknowledged by pulling the data line +/** + * sht15_ack() - Send an ack to the device + * + * Each byte of data is acknowledged by pulling the data line * low for one clock pulse. */ static void sht15_ack(struct sht15_data *data) @@ -421,12 +445,13 @@ static void sht15_ack(struct sht15_data *data) gpio_direction_input(data->pdata->gpio_data); } + /** * sht15_end_transmission() - notify device of end of transmission * @data: device state * * This is basically a NAK. (single clock pulse, data high) - **/ + */ static void sht15_end_transmission(struct sht15_data *data) { gpio_direction_output(data->pdata->gpio_data, 1); @@ -444,12 +469,13 @@ static void sht15_bh_read_data(struct work_struct *work_s) struct sht15_data *data = container_of(work_s, struct sht15_data, read_work); + /* Firstly, verify the line is low */ if (gpio_get_value(data->pdata->gpio_data)) { - /* If not, then start the interrupt again - care - here as could have gone low in meantime so verify - it hasn't! - */ + /* + * If not, then start the interrupt again - care here as could + * have gone low in meantime so verify it hasn't! + */ atomic_set(&data->interrupt_handled, 0); enable_irq(gpio_to_irq(data->pdata->gpio_data)); /* If still not occurred or another handler has been scheduled */ @@ -457,6 +483,7 @@ static void sht15_bh_read_data(struct work_struct *work_s) || atomic_read(&data->interrupt_handled)) return; } + /* Read the data back from the device */ for (i = 0; i < 16; ++i) { val <<= 1; @@ -468,19 +495,22 @@ static void sht15_bh_read_data(struct work_struct *work_s) if (i == 7) sht15_ack(data); } + /* Tell the device we are done */ sht15_end_transmission(data); - switch (data->flag) { + switch (data->state) { case SHT15_READING_TEMP: data->val_temp = val; break; case SHT15_READING_HUMID: data->val_humid = val; break; + default: + break; } - data->flag = SHT15_READING_NOTHING; + data->state = SHT15_READING_NOTHING; wake_up(&data->wait_queue); } @@ -500,10 +530,10 @@ static void sht15_update_voltage(struct work_struct *work_s) * * Note that as the notification code holds the regulator lock, we have * to schedule an update of the supply voltage rather than getting it directly. - **/ + */ static int sht15_invalidate_voltage(struct notifier_block *nb, - unsigned long event, - void *ignored) + unsigned long event, + void *ignored) { struct sht15_data *data = container_of(nb, struct sht15_data, nb); @@ -521,7 +551,7 @@ static int __devinit sht15_probe(struct platform_device *pdev) if (!data) { ret = -ENOMEM; - dev_err(&pdev->dev, "kzalloc failed"); + dev_err(&pdev->dev, "kzalloc failed\n"); goto error_ret; } @@ -533,13 +563,16 @@ static int __devinit sht15_probe(struct platform_device *pdev) init_waitqueue_head(&data->wait_queue); if (pdev->dev.platform_data == NULL) { - dev_err(&pdev->dev, "no platform data supplied"); + dev_err(&pdev->dev, "no platform data supplied\n"); goto err_free_data; } data->pdata = pdev->dev.platform_data; - data->supply_uV = data->pdata->supply_mv*1000; + data->supply_uV = data->pdata->supply_mv * 1000; -/* If a regulator is available, query what the supply voltage actually is!*/ + /* + * If a regulator is available, + * query what the supply voltage actually is! + */ data->reg = regulator_get(data->dev, "vcc"); if (!IS_ERR(data->reg)) { int voltage; @@ -549,21 +582,25 @@ static int __devinit sht15_probe(struct platform_device *pdev) data->supply_uV = voltage; regulator_enable(data->reg); - /* setup a notifier block to update this if another device - * causes the voltage to change */ + /* + * Setup a notifier block to update this if another device + * causes the voltage to change + */ data->nb.notifier_call = &sht15_invalidate_voltage; ret = regulator_register_notifier(data->reg, &data->nb); } -/* Try requesting the GPIOs */ + + /* Try requesting the GPIOs */ ret = gpio_request(data->pdata->gpio_sck, "SHT15 sck"); if (ret) { - dev_err(&pdev->dev, "gpio request failed"); + dev_err(&pdev->dev, "gpio request failed\n"); goto err_free_data; } gpio_direction_output(data->pdata->gpio_sck, 0); + ret = gpio_request(data->pdata->gpio_data, "SHT15 data"); if (ret) { - dev_err(&pdev->dev, "gpio request failed"); + dev_err(&pdev->dev, "gpio request failed\n"); goto err_release_gpio_sck; } ret = sysfs_create_group(&pdev->dev.kobj, &sht15_attr_group); @@ -578,7 +615,7 @@ static int __devinit sht15_probe(struct platform_device *pdev) "sht15 data", data); if (ret) { - dev_err(&pdev->dev, "failed to get irq for data line"); + dev_err(&pdev->dev, "failed to get irq for data line\n"); goto err_release_gpio_data; } disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data)); @@ -590,6 +627,7 @@ static int __devinit sht15_probe(struct platform_device *pdev) ret = PTR_ERR(data->hwmon_dev); goto err_release_irq; } + return 0; err_release_irq: @@ -601,7 +639,6 @@ err_release_gpio_sck: err_free_data: kfree(data); error_ret: - return ret; } @@ -609,8 +646,10 @@ static int __devexit sht15_remove(struct platform_device *pdev) { struct sht15_data *data = platform_get_drvdata(pdev); - /* Make sure any reads from the device are done and - * prevent new ones from beginning */ + /* + * Make sure any reads from the device are done and + * prevent new ones beginning + */ mutex_lock(&data->read_lock); hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&pdev->dev.kobj, &sht15_attr_group); @@ -625,10 +664,10 @@ static int __devexit sht15_remove(struct platform_device *pdev) gpio_free(data->pdata->gpio_sck); mutex_unlock(&data->read_lock); kfree(data); + return 0; } - /* * sht_drivers simultaneously refers to __devinit and __devexit function * which causes spurious section mismatch warning. So use __refdata to @@ -673,7 +712,6 @@ static struct platform_driver __refdata sht_drivers[] = { }, }; - static int __init sht15_init(void) { int ret; diff --git a/include/linux/sht15.h b/include/linux/sht15.h index 046bce05ecab..1e302146bdc8 100644 --- a/include/linux/sht15.h +++ b/include/linux/sht15.h @@ -8,14 +8,18 @@ * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. + * + * For further information, see the Documentation/hwmon/sht15 file. */ /** * struct sht15_platform_data - sht15 connectivity info - * @gpio_data: no. of gpio to which bidirectional data line is connected - * @gpio_sck: no. of gpio to which the data clock is connected. - * @supply_mv: supply voltage in mv. Overridden by regulator if available. - **/ + * @gpio_data: no. of gpio to which bidirectional data line is + * connected. + * @gpio_sck: no. of gpio to which the data clock is connected. + * @supply_mv: supply voltage in mv. Overridden by regulator if + * available. + */ struct sht15_platform_data { int gpio_data; int gpio_sck; -- cgit From cc15c7ebb424e45ba2c5ceecbe52d025219ee970 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Tue, 12 Apr 2011 15:34:38 -0400 Subject: hwmon: (sht15) add support for the status register * Add support for: - Heater. - End of battery notice. - Ability not to reload from OTP. - Low resolution (12bit temp, 8bit humidity). * Add an utility function to read individual bytes from the device. Signed-off-by: Vivien Didelot Acked-by: Jonathan Cameron Signed-off-by: Guenter Roeck --- Documentation/hwmon/sht15 | 29 +++++- drivers/hwmon/sht15.c | 247 +++++++++++++++++++++++++++++++++++++++------- include/linux/sht15.h | 4 + 3 files changed, 245 insertions(+), 35 deletions(-) (limited to 'include/linux') diff --git a/Documentation/hwmon/sht15 b/Documentation/hwmon/sht15 index 2919c516fdbc..d1939b25eb16 100644 --- a/Documentation/hwmon/sht15 +++ b/Documentation/hwmon/sht15 @@ -4,6 +4,7 @@ Kernel driver sht15 Authors: * Wouter Horre * Jonathan Cameron + * Vivien Didelot Supported chips: * Sensirion SHT10 @@ -30,13 +31,37 @@ Description The SHT10, SHT11, SHT15, SHT71, and SHT75 are humidity and temperature sensors. -The devices communicate using two GPIO lines and use the default -resolution settings of 14 bits for temperature and 12 bits for humidity. +The devices communicate using two GPIO lines. + +Supported resolutions for the measurements are 14 bits for temperature and 12 +bits for humidity, or 12 bits for temperature and 8 bits for humidity. + +The humidity calibration coefficients are programmed into an OTP memory on the +chip. These coefficients are used to internally calibrate the signals from the +sensors. Disabling the reload of those coefficients allows saving 10ms for each +measurement and decrease power consumption, while loosing on precision. + +Some options may be set directly in the sht15_platform_data structure +or via sysfs attributes. Note: The regulator supply name is set to "vcc". +Platform data +------------- + +* no_otp_reload: + flag to indicate not to reload from OTP (default to false). +* low_resolution: + flag to indicate the temp/humidity resolution to use (default to false). + Sysfs interface --------------- * temp1_input: temperature input * humidity1_input: humidity input +* heater_enable: write 1 in this attribute to enable the on-chip heater, + 0 to disable it. Be careful not to enable the heater + for too long. +* temp1_fault: if 1, this means that the voltage is low (below 2.47V) and + measurement may be invalid. +* humidity1_fault: same as temp1_fault. diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c index 3182b3f578e2..49da089b5de9 100644 --- a/drivers/hwmon/sht15.c +++ b/drivers/hwmon/sht15.c @@ -1,6 +1,9 @@ /* * sht15.c - support for the SHT15 Temperature and Humidity Sensor * + * Portions Copyright (c) 2010-2011 Savoir-faire Linux Inc. + * Vivien Didelot + * * Copyright (c) 2009 Jonathan Cameron * * Copyright (c) 2007 Wouter Horre @@ -33,6 +36,8 @@ /* Commands */ #define SHT15_MEASURE_TEMP 0x03 #define SHT15_MEASURE_RH 0x05 +#define SHT15_WRITE_STATUS 0x06 +#define SHT15_READ_STATUS 0x07 #define SHT15_SOFT_RESET 0x1E /* Min timings */ @@ -41,6 +46,12 @@ #define SHT15_TSU 150 /* (nsecs) data setup time */ #define SHT15_TSRST 11 /* (msecs) soft reset time */ +/* Status Register Bits */ +#define SHT15_STATUS_LOW_RESOLUTION 0x01 +#define SHT15_STATUS_NO_OTP_RELOAD 0x02 +#define SHT15_STATUS_HEATER 0x04 +#define SHT15_STATUS_LOW_BATTERY 0x40 + /* Actions the driver may be doing */ enum sht15_state { SHT15_READING_NOTHING, @@ -74,9 +85,12 @@ static const struct sht15_temppair temppoints[] = { * @wait_queue: wait queue for getting values from device. * @val_temp: last temperature value read from device. * @val_humid: last humidity value read from device. + * @val_status: last status register value read from device. * @state: state identifying the action the driver is doing. * @measurements_valid: are the current stored measures valid (start condition). + * @status_valid: is the current stored status valid (start condition). * @last_measurement: time of last measure. + * @last_status: time of last status reading. * @read_lock: mutex to ensure only one read in progress at a time. * @dev: associate device structure. * @hwmon_dev: device associated with hwmon subsystem. @@ -97,9 +111,12 @@ struct sht15_data { wait_queue_head_t wait_queue; uint16_t val_temp; uint16_t val_humid; + u8 val_status; enum sht15_state state; bool measurements_valid; + bool status_valid; unsigned long last_measurement; + unsigned long last_status; struct mutex read_lock; struct device *dev; struct device *hwmon_dev; @@ -244,10 +261,105 @@ static int sht15_soft_reset(struct sht15_data *data) if (ret) return ret; msleep(SHT15_TSRST); + /* device resets default hardware status register value */ + data->val_status = 0; + + return ret; +} + +/** + * sht15_end_transmission() - notify device of end of transmission + * @data: device state. + * + * This is basically a NAK (single clock pulse, data high). + */ +static void sht15_end_transmission(struct sht15_data *data) +{ + gpio_direction_output(data->pdata->gpio_data, 1); + ndelay(SHT15_TSU); + gpio_set_value(data->pdata->gpio_sck, 1); + ndelay(SHT15_TSCKH); + gpio_set_value(data->pdata->gpio_sck, 0); + ndelay(SHT15_TSCKL); +} + +/** + * sht15_read_byte() - Read a byte back from the device + * @data: device state. + */ +static u8 sht15_read_byte(struct sht15_data *data) +{ + int i; + u8 byte = 0; + + for (i = 0; i < 8; ++i) { + byte <<= 1; + gpio_set_value(data->pdata->gpio_sck, 1); + ndelay(SHT15_TSCKH); + byte |= !!gpio_get_value(data->pdata->gpio_data); + gpio_set_value(data->pdata->gpio_sck, 0); + ndelay(SHT15_TSCKL); + } + return byte; +} + +/** + * sht15_send_status() - write the status register byte + * @data: sht15 specific data. + * @status: the byte to set the status register with. + * + * As described in figure 14 and table 5 of the datasheet. + */ +static int sht15_send_status(struct sht15_data *data, u8 status) +{ + int ret; + + ret = sht15_send_cmd(data, SHT15_WRITE_STATUS); + if (ret) + return ret; + gpio_direction_output(data->pdata->gpio_data, 1); + ndelay(SHT15_TSU); + sht15_send_byte(data, status); + ret = sht15_wait_for_response(data); + if (ret) + return ret; + data->val_status = status; return 0; } +/** + * sht15_update_status() - get updated status register from device if too old + * @data: device instance specific data. + * + * As described in figure 15 and table 5 of the datasheet. + */ +static int sht15_update_status(struct sht15_data *data) +{ + int ret = 0; + u8 status; + int timeout = HZ; + + mutex_lock(&data->read_lock); + if (time_after(jiffies, data->last_status + timeout) + || !data->status_valid) { + ret = sht15_send_cmd(data, SHT15_READ_STATUS); + if (ret) + goto error_ret; + status = sht15_read_byte(data); + + sht15_end_transmission(data); + + data->val_status = status; + data->status_valid = true; + data->last_status = jiffies; + } +error_ret: + mutex_unlock(&data->read_lock); + + return ret; +} + /** * sht15_measurement() - get a new value from device * @data: device instance specific data @@ -324,6 +436,7 @@ error_ret: static inline int sht15_calc_temp(struct sht15_data *data) { int d1 = temppoints[0].d1; + int d2 = (data->val_status & SHT15_STATUS_LOW_RESOLUTION) ? 40 : 10; int i; for (i = ARRAY_SIZE(temppoints) - 1; i > 0; i--) @@ -336,7 +449,7 @@ static inline int sht15_calc_temp(struct sht15_data *data) break; } - return data->val_temp * 10 + d1; + return data->val_temp * d2 + d1; } /** @@ -353,18 +466,85 @@ static inline int sht15_calc_humid(struct sht15_data *data) { int rh_linear; /* milli percent */ int temp = sht15_calc_temp(data); - + int c2, c3; + int t2; const int c1 = -4; - const int c2 = 40500; /* x 10 ^ -6 */ - const int c3 = -28; /* x 10 ^ -7 */ + + if (data->val_status & SHT15_STATUS_LOW_RESOLUTION) { + c2 = 648000; /* x 10 ^ -6 */ + c3 = -7200; /* x 10 ^ -7 */ + t2 = 1280; + } else { + c2 = 40500; /* x 10 ^ -6 */ + c3 = -28; /* x 10 ^ -7 */ + t2 = 80; + } rh_linear = c1 * 1000 + c2 * data->val_humid / 1000 + (data->val_humid * data->val_humid * c3) / 10000; - return (temp - 25000) * (10000 + 80 * data->val_humid) + return (temp - 25000) * (10000 + t2 * data->val_humid) / 1000000 + rh_linear; } +/** + * sht15_show_status() - show status information in sysfs + * @dev: device. + * @attr: device attribute. + * @buf: sysfs buffer where information is written to. + * + * Will be called on read access to temp1_fault, humidity1_fault + * and heater_enable sysfs attributes. + * Returns number of bytes written into buffer, negative errno on error. + */ +static ssize_t sht15_show_status(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + struct sht15_data *data = dev_get_drvdata(dev); + u8 bit = to_sensor_dev_attr(attr)->index; + + ret = sht15_update_status(data); + + return ret ? ret : sprintf(buf, "%d\n", !!(data->val_status & bit)); +} + +/** + * sht15_store_heater() - change heater state via sysfs + * @dev: device. + * @attr: device attribute. + * @buf: sysfs buffer to read the new heater state from. + * @count: length of the data. + * + * Will be called on read access to heater_enable sysfs attribute. + * Returns number of bytes actually decoded, negative errno on error. + */ +static ssize_t sht15_store_heater(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + struct sht15_data *data = dev_get_drvdata(dev); + long value; + u8 status; + + if (strict_strtol(buf, 10, &value)) + return -EINVAL; + + mutex_lock(&data->read_lock); + status = data->val_status & 0x07; + if (!!value) + status |= SHT15_STATUS_HEATER; + else + status &= ~SHT15_STATUS_HEATER; + + ret = sht15_send_status(data, status); + mutex_unlock(&data->read_lock); + + return ret ? ret : count; +} + /** * sht15_show_temp() - show temperature measurement value in sysfs * @dev: device. @@ -407,7 +587,6 @@ static ssize_t sht15_show_humidity(struct device *dev, ret = sht15_update_measurements(data); return ret ? ret : sprintf(buf, "%d\n", sht15_calc_humid(data)); - } static ssize_t show_name(struct device *dev, @@ -422,10 +601,19 @@ static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, sht15_show_temp, NULL, 0); static SENSOR_DEVICE_ATTR(humidity1_input, S_IRUGO, sht15_show_humidity, NULL, 0); +static SENSOR_DEVICE_ATTR(temp1_fault, S_IRUGO, sht15_show_status, NULL, + SHT15_STATUS_LOW_BATTERY); +static SENSOR_DEVICE_ATTR(humidity1_fault, S_IRUGO, sht15_show_status, NULL, + SHT15_STATUS_LOW_BATTERY); +static SENSOR_DEVICE_ATTR(heater_enable, S_IRUGO | S_IWUSR, sht15_show_status, + sht15_store_heater, SHT15_STATUS_HEATER); static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); static struct attribute *sht15_attrs[] = { &sensor_dev_attr_temp1_input.dev_attr.attr, &sensor_dev_attr_humidity1_input.dev_attr.attr, + &sensor_dev_attr_temp1_fault.dev_attr.attr, + &sensor_dev_attr_humidity1_fault.dev_attr.attr, + &sensor_dev_attr_heater_enable.dev_attr.attr, &dev_attr_name.attr, NULL, }; @@ -466,25 +654,8 @@ static void sht15_ack(struct sht15_data *data) gpio_direction_input(data->pdata->gpio_data); } -/** - * sht15_end_transmission() - notify device of end of transmission - * @data: device state - * - * This is basically a NAK. (single clock pulse, data high) - */ -static void sht15_end_transmission(struct sht15_data *data) -{ - gpio_direction_output(data->pdata->gpio_data, 1); - ndelay(SHT15_TSU); - gpio_set_value(data->pdata->gpio_sck, 1); - ndelay(SHT15_TSCKH); - gpio_set_value(data->pdata->gpio_sck, 0); - ndelay(SHT15_TSCKL); -} - static void sht15_bh_read_data(struct work_struct *work_s) { - int i; uint16_t val = 0; struct sht15_data *data = container_of(work_s, struct sht15_data, @@ -505,16 +676,10 @@ static void sht15_bh_read_data(struct work_struct *work_s) } /* Read the data back from the device */ - for (i = 0; i < 16; ++i) { - val <<= 1; - gpio_set_value(data->pdata->gpio_sck, 1); - ndelay(SHT15_TSCKH); - val |= !!gpio_get_value(data->pdata->gpio_data); - gpio_set_value(data->pdata->gpio_sck, 0); - ndelay(SHT15_TSCKL); - if (i == 7) - sht15_ack(data); - } + val = sht15_read_byte(data); + val <<= 8; + sht15_ack(data); + val |= sht15_read_byte(data); /* Tell the device we are done */ sht15_end_transmission(data); @@ -568,6 +733,7 @@ static int __devinit sht15_probe(struct platform_device *pdev) { int ret = 0; struct sht15_data *data = kzalloc(sizeof(*data), GFP_KERNEL); + u8 status = 0; if (!data) { ret = -ENOMEM; @@ -588,6 +754,10 @@ static int __devinit sht15_probe(struct platform_device *pdev) } data->pdata = pdev->dev.platform_data; data->supply_uV = data->pdata->supply_mv * 1000; + if (data->pdata->no_otp_reload) + status |= SHT15_STATUS_NO_OTP_RELOAD; + if (data->pdata->low_resolution) + status |= SHT15_STATUS_LOW_RESOLUTION; /* * If a regulator is available, @@ -646,6 +816,13 @@ static int __devinit sht15_probe(struct platform_device *pdev) if (ret) goto err_release_irq; + /* write status with platform data options */ + if (status) { + ret = sht15_send_status(data, status); + if (ret) + goto err_release_irq; + } + ret = sysfs_create_group(&pdev->dev.kobj, &sht15_attr_group); if (ret) { dev_err(&pdev->dev, "sysfs create failed\n"); @@ -689,6 +866,10 @@ static int __devexit sht15_remove(struct platform_device *pdev) * prevent new ones beginning */ mutex_lock(&data->read_lock); + if (sht15_soft_reset(data)) { + mutex_unlock(&data->read_lock); + return -EFAULT; + } hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&pdev->dev.kobj, &sht15_attr_group); if (!IS_ERR(data->reg)) { diff --git a/include/linux/sht15.h b/include/linux/sht15.h index 1e302146bdc8..d836ca617323 100644 --- a/include/linux/sht15.h +++ b/include/linux/sht15.h @@ -19,10 +19,14 @@ * @gpio_sck: no. of gpio to which the data clock is connected. * @supply_mv: supply voltage in mv. Overridden by regulator if * available. + * @no_otp_reload: flag to indicate no reload from OTP. + * @low_resolution: flag to indicate the temp/humidity resolution to use. */ struct sht15_platform_data { int gpio_data; int gpio_sck; int supply_mv; + bool no_otp_reload; + bool low_resolution; }; -- cgit From 82c7465b4dd013d19858bfeac084849ae17682c0 Mon Sep 17 00:00:00 2001 From: Jerome Oufella Date: Tue, 12 Apr 2011 15:34:39 -0400 Subject: hwmon: (sht15) add support for CRC validation The sht15 sensor allows validating exchanges to and from the device using a crc8 function. An utility function to reverse a byte has also been added. Signed-off-by: Jerome Oufella Acked-by: Jonathan Cameron Signed-off-by: Guenter Roeck --- Documentation/hwmon/sht15 | 9 ++- drivers/hwmon/sht15.c | 192 +++++++++++++++++++++++++++++++++++++++++----- include/linux/sht15.h | 2 + 3 files changed, 183 insertions(+), 20 deletions(-) (limited to 'include/linux') diff --git a/Documentation/hwmon/sht15 b/Documentation/hwmon/sht15 index d1939b25eb16..02850bdfac18 100644 --- a/Documentation/hwmon/sht15 +++ b/Documentation/hwmon/sht15 @@ -5,6 +5,7 @@ Authors: * Wouter Horre * Jonathan Cameron * Vivien Didelot + * Jerome Oufella Supported chips: * Sensirion SHT10 @@ -44,11 +45,17 @@ measurement and decrease power consumption, while loosing on precision. Some options may be set directly in the sht15_platform_data structure or via sysfs attributes. -Note: The regulator supply name is set to "vcc". +Notes: + * The regulator supply name is set to "vcc". + * If a CRC validation fails, a soft reset command is sent, which resets + status register to its hardware default value, but the driver will try to + restore the previous device configuration. Platform data ------------- +* checksum: + set it to true to enable CRC validation of the readings (default to false). * no_otp_reload: flag to indicate not to reload from OTP (default to false). * low_resolution: diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c index 49da089b5de9..cf4330b352ef 100644 --- a/drivers/hwmon/sht15.c +++ b/drivers/hwmon/sht15.c @@ -2,6 +2,7 @@ * sht15.c - support for the SHT15 Temperature and Humidity Sensor * * Portions Copyright (c) 2010-2011 Savoir-faire Linux Inc. + * Jerome Oufella * Vivien Didelot * * Copyright (c) 2009 Jonathan Cameron @@ -78,6 +79,42 @@ static const struct sht15_temppair temppoints[] = { { 5000000, -40100 }, }; +/* Table from CRC datasheet, section 2.4 */ +static const u8 sht15_crc8_table[] = { + 0, 49, 98, 83, 196, 245, 166, 151, + 185, 136, 219, 234, 125, 76, 31, 46, + 67, 114, 33, 16, 135, 182, 229, 212, + 250, 203, 152, 169, 62, 15, 92, 109, + 134, 183, 228, 213, 66, 115, 32, 17, + 63, 14, 93, 108, 251, 202, 153, 168, + 197, 244, 167, 150, 1, 48, 99, 82, + 124, 77, 30, 47, 184, 137, 218, 235, + 61, 12, 95, 110, 249, 200, 155, 170, + 132, 181, 230, 215, 64, 113, 34, 19, + 126, 79, 28, 45, 186, 139, 216, 233, + 199, 246, 165, 148, 3, 50, 97, 80, + 187, 138, 217, 232, 127, 78, 29, 44, + 2, 51, 96, 81, 198, 247, 164, 149, + 248, 201, 154, 171, 60, 13, 94, 111, + 65, 112, 35, 18, 133, 180, 231, 214, + 122, 75, 24, 41, 190, 143, 220, 237, + 195, 242, 161, 144, 7, 54, 101, 84, + 57, 8, 91, 106, 253, 204, 159, 174, + 128, 177, 226, 211, 68, 117, 38, 23, + 252, 205, 158, 175, 56, 9, 90, 107, + 69, 116, 39, 22, 129, 176, 227, 210, + 191, 142, 221, 236, 123, 74, 25, 40, + 6, 55, 100, 85, 194, 243, 160, 145, + 71, 118, 37, 20, 131, 178, 225, 208, + 254, 207, 156, 173, 58, 11, 88, 105, + 4, 53, 102, 87, 192, 241, 162, 147, + 189, 140, 223, 238, 121, 72, 27, 42, + 193, 240, 163, 146, 5, 52, 103, 86, + 120, 73, 26, 43, 188, 141, 222, 239, + 130, 179, 224, 209, 70, 119, 36, 21, + 59, 10, 89, 104, 255, 206, 157, 172 +}; + /** * struct sht15_data - device instance specific data * @pdata: platform data (gpio's etc). @@ -86,6 +123,8 @@ static const struct sht15_temppair temppoints[] = { * @val_temp: last temperature value read from device. * @val_humid: last humidity value read from device. * @val_status: last status register value read from device. + * @checksum_ok: last value read from the device passed CRC validation. + * @checksumming: flag used to enable the data validation with CRC. * @state: state identifying the action the driver is doing. * @measurements_valid: are the current stored measures valid (start condition). * @status_valid: is the current stored status valid (start condition). @@ -112,6 +151,8 @@ struct sht15_data { uint16_t val_temp; uint16_t val_humid; u8 val_status; + bool checksum_ok; + bool checksumming; enum sht15_state state; bool measurements_valid; bool status_valid; @@ -128,6 +169,40 @@ struct sht15_data { atomic_t interrupt_handled; }; +/** + * sht15_reverse() - reverse a byte + * @byte: byte to reverse. + */ +static u8 sht15_reverse(u8 byte) +{ + u8 i, c; + + for (c = 0, i = 0; i < 8; i++) + c |= (!!(byte & (1 << i))) << (7 - i); + return c; +} + +/** + * sht15_crc8() - compute crc8 + * @data: sht15 specific data. + * @value: sht15 retrieved data. + * + * This implements section 2 of the CRC datasheet. + */ +static u8 sht15_crc8(struct sht15_data *data, + const u8 *value, + int len) +{ + u8 crc = sht15_reverse(data->val_status & 0x0F); + + while (len--) { + crc = sht15_crc8_table[*value ^ crc]; + value++; + } + + return crc; +} + /** * sht15_connection_reset() - reset the comms interface * @data: sht15 specific data @@ -267,6 +342,26 @@ static int sht15_soft_reset(struct sht15_data *data) return ret; } +/** + * sht15_ack() - send a ack + * @data: sht15 specific data. + * + * Each byte of data is acknowledged by pulling the data line + * low for one clock pulse. + */ +static void sht15_ack(struct sht15_data *data) +{ + gpio_direction_output(data->pdata->gpio_data, 0); + ndelay(SHT15_TSU); + gpio_set_value(data->pdata->gpio_sck, 1); + ndelay(SHT15_TSU); + gpio_set_value(data->pdata->gpio_sck, 0); + ndelay(SHT15_TSU); + gpio_set_value(data->pdata->gpio_data, 1); + + gpio_direction_input(data->pdata->gpio_data); +} + /** * sht15_end_transmission() - notify device of end of transmission * @data: device state. @@ -338,6 +433,9 @@ static int sht15_update_status(struct sht15_data *data) { int ret = 0; u8 status; + u8 previous_config; + u8 dev_checksum = 0; + u8 checksum_vals[2]; int timeout = HZ; mutex_lock(&data->read_lock); @@ -348,8 +446,40 @@ static int sht15_update_status(struct sht15_data *data) goto error_ret; status = sht15_read_byte(data); + if (data->checksumming) { + sht15_ack(data); + dev_checksum = sht15_reverse(sht15_read_byte(data)); + checksum_vals[0] = SHT15_READ_STATUS; + checksum_vals[1] = status; + data->checksum_ok = (sht15_crc8(data, checksum_vals, 2) + == dev_checksum); + } + sht15_end_transmission(data); + /* + * Perform checksum validation on the received data. + * Specification mentions that in case a checksum verification + * fails, a soft reset command must be sent to the device. + */ + if (data->checksumming && !data->checksum_ok) { + previous_config = data->val_status & 0x07; + ret = sht15_soft_reset(data); + if (ret) + goto error_ret; + if (previous_config) { + ret = sht15_send_status(data, previous_config); + if (ret) { + dev_err(data->dev, + "CRC validation failed, unable " + "to restore device settings\n"); + goto error_ret; + } + } + ret = -EAGAIN; + goto error_ret; + } + data->val_status = status; data->status_valid = true; data->last_status = jiffies; @@ -372,6 +502,7 @@ static int sht15_measurement(struct sht15_data *data, int timeout_msecs) { int ret; + u8 previous_config; ret = sht15_send_cmd(data, command); if (ret) @@ -395,6 +526,29 @@ static int sht15_measurement(struct sht15_data *data, sht15_connection_reset(data); return -ETIME; } + + /* + * Perform checksum validation on the received data. + * Specification mentions that in case a checksum verification fails, + * a soft reset command must be sent to the device. + */ + if (data->checksumming && !data->checksum_ok) { + previous_config = data->val_status & 0x07; + ret = sht15_soft_reset(data); + if (ret) + return ret; + if (previous_config) { + ret = sht15_send_status(data, previous_config); + if (ret) { + dev_err(data->dev, + "CRC validation failed, unable " + "to restore device settings\n"); + return ret; + } + } + return -EAGAIN; + } + return 0; } @@ -635,28 +789,11 @@ static irqreturn_t sht15_interrupt_fired(int irq, void *d) return IRQ_HANDLED; } -/** - * sht15_ack() - Send an ack to the device - * - * Each byte of data is acknowledged by pulling the data line - * low for one clock pulse. - */ -static void sht15_ack(struct sht15_data *data) -{ - gpio_direction_output(data->pdata->gpio_data, 0); - ndelay(SHT15_TSU); - gpio_set_value(data->pdata->gpio_sck, 1); - ndelay(SHT15_TSU); - gpio_set_value(data->pdata->gpio_sck, 0); - ndelay(SHT15_TSU); - gpio_set_value(data->pdata->gpio_data, 1); - - gpio_direction_input(data->pdata->gpio_data); -} - static void sht15_bh_read_data(struct work_struct *work_s) { uint16_t val = 0; + u8 dev_checksum = 0; + u8 checksum_vals[3]; struct sht15_data *data = container_of(work_s, struct sht15_data, read_work); @@ -681,6 +818,21 @@ static void sht15_bh_read_data(struct work_struct *work_s) sht15_ack(data); val |= sht15_read_byte(data); + if (data->checksumming) { + /* + * Ask the device for a checksum and read it back. + * Note: the device sends the checksum byte reversed. + */ + sht15_ack(data); + dev_checksum = sht15_reverse(sht15_read_byte(data)); + checksum_vals[0] = (data->state == SHT15_READING_TEMP) ? + SHT15_MEASURE_TEMP : SHT15_MEASURE_RH; + checksum_vals[1] = (u8) (val >> 8); + checksum_vals[2] = (u8) val; + data->checksum_ok + = (sht15_crc8(data, checksum_vals, 3) == dev_checksum); + } + /* Tell the device we are done */ sht15_end_transmission(data); @@ -754,6 +906,8 @@ static int __devinit sht15_probe(struct platform_device *pdev) } data->pdata = pdev->dev.platform_data; data->supply_uV = data->pdata->supply_mv * 1000; + if (data->pdata->checksum) + data->checksumming = true; if (data->pdata->no_otp_reload) status |= SHT15_STATUS_NO_OTP_RELOAD; if (data->pdata->low_resolution) diff --git a/include/linux/sht15.h b/include/linux/sht15.h index d836ca617323..f85c7c523da0 100644 --- a/include/linux/sht15.h +++ b/include/linux/sht15.h @@ -19,6 +19,7 @@ * @gpio_sck: no. of gpio to which the data clock is connected. * @supply_mv: supply voltage in mv. Overridden by regulator if * available. + * @checksum: flag to indicate the checksum should be validated. * @no_otp_reload: flag to indicate no reload from OTP. * @low_resolution: flag to indicate the temp/humidity resolution to use. */ @@ -26,6 +27,7 @@ struct sht15_platform_data { int gpio_data; int gpio_sck; int supply_mv; + bool checksum; bool no_otp_reload; bool low_resolution; }; -- cgit From 7176ba23f8b589b1df3229574ff46fb904ce9ec5 Mon Sep 17 00:00:00 2001 From: Rhyland Klein Date: Mon, 16 May 2011 14:41:48 -0700 Subject: net: rfkill: add generic gpio rfkill driver This adds a new generic gpio rfkill driver to support rfkill switches which are controlled by gpios. The driver also supports passing in data about the clock for the radio, so that when rfkill is blocking, it can disable the clock. This driver assumes platform data is passed from the board files to configure it for specific devices. Original-patch-by: Anantha Idapalapati Signed-off-by: Rhyland Klein Signed-off-by: John W. Linville --- include/linux/rfkill-gpio.h | 43 +++++++++ net/rfkill/Kconfig | 9 ++ net/rfkill/Makefile | 1 + net/rfkill/rfkill-gpio.c | 227 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 280 insertions(+) create mode 100644 include/linux/rfkill-gpio.h create mode 100644 net/rfkill/rfkill-gpio.c (limited to 'include/linux') diff --git a/include/linux/rfkill-gpio.h b/include/linux/rfkill-gpio.h new file mode 100644 index 000000000000..a175d0598033 --- /dev/null +++ b/include/linux/rfkill-gpio.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2011, NVIDIA Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#ifndef __RFKILL_GPIO_H +#define __RFKILL_GPIO_H + +#include +#include + +/** + * struct rfkill_gpio_platform_data - platform data for rfkill gpio device. + * for unused gpio's, the expected value is -1. + * @name: name for the gpio rf kill instance + * @reset_gpio: GPIO which is used for reseting rfkill switch + * @shutdown_gpio: GPIO which is used for shutdown of rfkill switch + * @power_clk_name: [optional] name of clk to turn off while blocked + */ + +struct rfkill_gpio_platform_data { + char *name; + int reset_gpio; + int shutdown_gpio; + const char *power_clk_name; + enum rfkill_type type; +}; + +#endif /* __RFKILL_GPIO_H */ diff --git a/net/rfkill/Kconfig b/net/rfkill/Kconfig index 48464ca13b24..78efe895b663 100644 --- a/net/rfkill/Kconfig +++ b/net/rfkill/Kconfig @@ -33,3 +33,12 @@ config RFKILL_REGULATOR To compile this driver as a module, choose M here: the module will be called rfkill-regulator. + +config RFKILL_GPIO + tristate "GPIO RFKILL driver" + depends on RFKILL && GPIOLIB && HAVE_CLK + default n + help + If you say yes here you get support of a generic gpio RFKILL + driver. The platform should fill in the appropriate fields in the + rfkill_gpio_platform_data structure and pass that to the driver. diff --git a/net/rfkill/Makefile b/net/rfkill/Makefile index d9a5a58ffd8c..311768783f4a 100644 --- a/net/rfkill/Makefile +++ b/net/rfkill/Makefile @@ -6,3 +6,4 @@ rfkill-y += core.o rfkill-$(CONFIG_RFKILL_INPUT) += input.o obj-$(CONFIG_RFKILL) += rfkill.o obj-$(CONFIG_RFKILL_REGULATOR) += rfkill-regulator.o +obj-$(CONFIG_RFKILL_GPIO) += rfkill-gpio.o diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c new file mode 100644 index 000000000000..256c5ddd2d72 --- /dev/null +++ b/net/rfkill/rfkill-gpio.c @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2011, NVIDIA Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +enum rfkill_gpio_clk_state { + UNSPECIFIED = 0, + PWR_ENABLED, + PWR_DISABLED +}; + +#define PWR_CLK_SET(_RF, _EN) \ + ((_RF)->pwr_clk_enabled = (!(_EN) ? PWR_ENABLED : PWR_DISABLED)) +#define PWR_CLK_ENABLED(_RF) ((_RF)->pwr_clk_enabled == PWR_ENABLED) +#define PWR_CLK_DISABLED(_RF) ((_RF)->pwr_clk_enabled != PWR_ENABLED) + +struct rfkill_gpio_data { + struct rfkill_gpio_platform_data *pdata; + struct rfkill *rfkill_dev; + char *reset_name; + char *shutdown_name; + enum rfkill_gpio_clk_state pwr_clk_enabled; + struct clk *pwr_clk; +}; + +static int rfkill_gpio_set_power(void *data, bool blocked) +{ + struct rfkill_gpio_data *rfkill = data; + + if (blocked) { + if (gpio_is_valid(rfkill->pdata->shutdown_gpio)) + gpio_direction_output(rfkill->pdata->shutdown_gpio, 0); + if (gpio_is_valid(rfkill->pdata->reset_gpio)) + gpio_direction_output(rfkill->pdata->reset_gpio, 0); + if (rfkill->pwr_clk && PWR_CLK_ENABLED(rfkill)) + clk_disable(rfkill->pwr_clk); + } else { + if (rfkill->pwr_clk && PWR_CLK_DISABLED(rfkill)) + clk_enable(rfkill->pwr_clk); + if (gpio_is_valid(rfkill->pdata->reset_gpio)) + gpio_direction_output(rfkill->pdata->reset_gpio, 1); + if (gpio_is_valid(rfkill->pdata->shutdown_gpio)) + gpio_direction_output(rfkill->pdata->shutdown_gpio, 1); + } + + if (rfkill->pwr_clk) + PWR_CLK_SET(rfkill, blocked); + + return 0; +} + +static const struct rfkill_ops rfkill_gpio_ops = { + .set_block = rfkill_gpio_set_power, +}; + +static int rfkill_gpio_probe(struct platform_device *pdev) +{ + struct rfkill_gpio_data *rfkill; + struct rfkill_gpio_platform_data *pdata = pdev->dev.platform_data; + int ret = 0; + int len = 0; + + if (!pdata) { + pr_warn("%s: No platform data specified\n", __func__); + return -EINVAL; + } + + /* make sure at-least one of the GPIO is defined and that + * a name is specified for this instance */ + if (!pdata->name || (!gpio_is_valid(pdata->reset_gpio) && + !gpio_is_valid(pdata->shutdown_gpio))) { + pr_warn("%s: invalid platform data\n", __func__); + return -EINVAL; + } + + rfkill = kzalloc(sizeof(*rfkill), GFP_KERNEL); + if (!rfkill) + return -ENOMEM; + + rfkill->pdata = pdata; + + len = strlen(pdata->name); + rfkill->reset_name = kzalloc(len + 7, GFP_KERNEL); + if (!rfkill->reset_name) { + ret = -ENOMEM; + goto fail_alloc; + } + + rfkill->shutdown_name = kzalloc(len + 10, GFP_KERNEL); + if (!rfkill->shutdown_name) { + ret = -ENOMEM; + goto fail_reset_name; + } + + snprintf(rfkill->reset_name, len + 6 , "%s_reset", pdata->name); + snprintf(rfkill->shutdown_name, len + 9, "%s_shutdown", pdata->name); + + if (pdata->power_clk_name) { + rfkill->pwr_clk = clk_get(&pdev->dev, pdata->power_clk_name); + if (IS_ERR(rfkill->pwr_clk)) { + pr_warn("%s: can't find pwr_clk.\n", __func__); + goto fail_shutdown_name; + } + } + + if (gpio_is_valid(pdata->reset_gpio)) { + ret = gpio_request(pdata->reset_gpio, rfkill->reset_name); + if (ret) { + pr_warn("%s: failed to get reset gpio.\n", __func__); + goto fail_clock; + } + } + + if (gpio_is_valid(pdata->shutdown_gpio)) { + ret = gpio_request(pdata->shutdown_gpio, rfkill->shutdown_name); + if (ret) { + pr_warn("%s: failed to get shutdown gpio.\n", __func__); + goto fail_reset; + } + } + + rfkill->rfkill_dev = rfkill_alloc(pdata->name, &pdev->dev, pdata->type, + &rfkill_gpio_ops, rfkill); + if (!rfkill->rfkill_dev) + goto fail_shutdown; + + ret = rfkill_register(rfkill->rfkill_dev); + if (ret < 0) + goto fail_rfkill; + + platform_set_drvdata(pdev, rfkill); + + dev_info(&pdev->dev, "%s device registered.\n", pdata->name); + + return 0; + +fail_rfkill: + rfkill_destroy(rfkill->rfkill_dev); +fail_shutdown: + if (gpio_is_valid(pdata->shutdown_gpio)) + gpio_free(pdata->shutdown_gpio); +fail_reset: + if (gpio_is_valid(pdata->reset_gpio)) + gpio_free(pdata->reset_gpio); +fail_clock: + if (rfkill->pwr_clk) + clk_put(rfkill->pwr_clk); +fail_shutdown_name: + kfree(rfkill->shutdown_name); +fail_reset_name: + kfree(rfkill->reset_name); +fail_alloc: + kfree(rfkill); + + return ret; +} + +static int rfkill_gpio_remove(struct platform_device *pdev) +{ + struct rfkill_gpio_data *rfkill = platform_get_drvdata(pdev); + + rfkill_unregister(rfkill->rfkill_dev); + rfkill_destroy(rfkill->rfkill_dev); + if (gpio_is_valid(rfkill->pdata->shutdown_gpio)) + gpio_free(rfkill->pdata->shutdown_gpio); + if (gpio_is_valid(rfkill->pdata->reset_gpio)) + gpio_free(rfkill->pdata->reset_gpio); + if (rfkill->pwr_clk && PWR_CLK_ENABLED(rfkill)) + clk_disable(rfkill->pwr_clk); + if (rfkill->pwr_clk) + clk_put(rfkill->pwr_clk); + kfree(rfkill->shutdown_name); + kfree(rfkill->reset_name); + kfree(rfkill); + + return 0; +} + +static struct platform_driver rfkill_gpio_driver = { + .probe = rfkill_gpio_probe, + .remove = __devexit_p(rfkill_gpio_remove), + .driver = { + .name = "rfkill_gpio", + .owner = THIS_MODULE, + }, +}; + +static int __init rfkill_gpio_init(void) +{ + return platform_driver_register(&rfkill_gpio_driver); +} + +static void __exit rfkill_gpio_exit(void) +{ + platform_driver_unregister(&rfkill_gpio_driver); +} + +module_init(rfkill_gpio_init); +module_exit(rfkill_gpio_exit); + +MODULE_DESCRIPTION("gpio rfkill"); +MODULE_AUTHOR("NVIDIA"); +MODULE_LICENSE("GPL"); -- cgit From 75d65a425c0163d3ec476ddc12b51087217a070c Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 19 May 2011 13:50:07 -0700 Subject: hlist: remove software prefetching in hlist iterators They not only increase the code footprint, they actually make things slower rather than faster. On internationally acclaimed benchmarks ("make -j16" on an already fully built kernel source tree) the hlist prefetching slows down the build by up to 1%. (Almost all of it comes from hlist_for_each_entry_rcu() as used by avc_has_perm_noaudit(), which is very hot due to all the pathname lookups to see if there is anything to do). The cause seems to be two-fold: - on at least some Intel cores, prefetch(NULL) ends up with some microarchitectural stall due to the TLB miss that it incurs. The hlist case triggers this very commonly, since the NULL pointer is the last entry in the list. - the prefetch appears to cause more D$ activity, probably because it prefetches hash list entries that are never actually used (because we ended the search early due to a hit). Regardless, the numbers clearly say that the implicit prefetching is simply a bad idea. If some _particular_ user of the hlist iterators wants to prefetch the next list entry, they can do so themselves explicitly, rather than depend on all list iterators doing so implicitly. Acked-by: Ingo Molnar Acked-by: David S. Miller Cc: linux-arch@vger.kernel.org Signed-off-by: Linus Torvalds --- include/linux/list.h | 9 ++++----- include/linux/rculist.h | 10 +++++----- 2 files changed, 9 insertions(+), 10 deletions(-) (limited to 'include/linux') diff --git a/include/linux/list.h b/include/linux/list.h index 3a54266a1e85..9ac11148e037 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -664,8 +664,7 @@ static inline void hlist_move_list(struct hlist_head *old, #define hlist_entry(ptr, type, member) container_of(ptr,type,member) #define hlist_for_each(pos, head) \ - for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \ - pos = pos->next) + for (pos = (head)->first; pos ; pos = pos->next) #define hlist_for_each_safe(pos, n, head) \ for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \ @@ -680,7 +679,7 @@ static inline void hlist_move_list(struct hlist_head *old, */ #define hlist_for_each_entry(tpos, pos, head, member) \ for (pos = (head)->first; \ - pos && ({ prefetch(pos->next); 1;}) && \ + pos && \ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ pos = pos->next) @@ -692,7 +691,7 @@ static inline void hlist_move_list(struct hlist_head *old, */ #define hlist_for_each_entry_continue(tpos, pos, member) \ for (pos = (pos)->next; \ - pos && ({ prefetch(pos->next); 1;}) && \ + pos && \ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ pos = pos->next) @@ -703,7 +702,7 @@ static inline void hlist_move_list(struct hlist_head *old, * @member: the name of the hlist_node within the struct. */ #define hlist_for_each_entry_from(tpos, pos, member) \ - for (; pos && ({ prefetch(pos->next); 1;}) && \ + for (; pos && \ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ pos = pos->next) diff --git a/include/linux/rculist.h b/include/linux/rculist.h index 2dea94fc4402..900a97a44769 100644 --- a/include/linux/rculist.h +++ b/include/linux/rculist.h @@ -427,7 +427,7 @@ static inline void hlist_add_after_rcu(struct hlist_node *prev, #define __hlist_for_each_rcu(pos, head) \ for (pos = rcu_dereference(hlist_first_rcu(head)); \ - pos && ({ prefetch(pos->next); 1; }); \ + pos; \ pos = rcu_dereference(hlist_next_rcu(pos))) /** @@ -443,7 +443,7 @@ static inline void hlist_add_after_rcu(struct hlist_node *prev, */ #define hlist_for_each_entry_rcu(tpos, pos, head, member) \ for (pos = rcu_dereference_raw(hlist_first_rcu(head)); \ - pos && ({ prefetch(pos->next); 1; }) && \ + pos && \ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \ pos = rcu_dereference_raw(hlist_next_rcu(pos))) @@ -460,7 +460,7 @@ static inline void hlist_add_after_rcu(struct hlist_node *prev, */ #define hlist_for_each_entry_rcu_bh(tpos, pos, head, member) \ for (pos = rcu_dereference_bh((head)->first); \ - pos && ({ prefetch(pos->next); 1; }) && \ + pos && \ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \ pos = rcu_dereference_bh(pos->next)) @@ -472,7 +472,7 @@ static inline void hlist_add_after_rcu(struct hlist_node *prev, */ #define hlist_for_each_entry_continue_rcu(tpos, pos, member) \ for (pos = rcu_dereference((pos)->next); \ - pos && ({ prefetch(pos->next); 1; }) && \ + pos && \ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \ pos = rcu_dereference(pos->next)) @@ -484,7 +484,7 @@ static inline void hlist_add_after_rcu(struct hlist_node *prev, */ #define hlist_for_each_entry_continue_rcu_bh(tpos, pos, member) \ for (pos = rcu_dereference_bh((pos)->next); \ - pos && ({ prefetch(pos->next); 1; }) && \ + pos && \ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \ pos = rcu_dereference_bh(pos->next)) -- cgit From e66eed651fd18a961f11cda62f3b5286c8cc4f9f Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 19 May 2011 14:15:29 -0700 Subject: list: remove prefetching from regular list iterators This is removes the use of software prefetching from the regular list iterators. We don't want it. If you do want to prefetch in some iterator of yours, go right ahead. Just don't expect the iterator to do it, since normally the downsides are bigger than the upsides. It also replaces with , because the use of LIST_POISON ends up needing it. is sadly not self-contained, and including prefetch.h just happened to hide that. Suggested by David Miller (networking has a lot of regular lists that are often empty or a single entry, and prefetching is not going to do anything but add useless instructions). Acked-by: Ingo Molnar Acked-by: David S. Miller Cc: linux-arch@vger.kernel.org Signed-off-by: Linus Torvalds --- include/linux/list.h | 26 +++++++++++--------------- include/linux/rculist.h | 6 +++--- 2 files changed, 14 insertions(+), 18 deletions(-) (limited to 'include/linux') diff --git a/include/linux/list.h b/include/linux/list.h index 9ac11148e037..cc6d2aa6b415 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -4,7 +4,7 @@ #include #include #include -#include +#include /* * Simple doubly linked list implementation. @@ -367,18 +367,15 @@ static inline void list_splice_tail_init(struct list_head *list, * @head: the head for your list. */ #define list_for_each(pos, head) \ - for (pos = (head)->next; prefetch(pos->next), pos != (head); \ - pos = pos->next) + for (pos = (head)->next; pos != (head); pos = pos->next) /** * __list_for_each - iterate over a list * @pos: the &struct list_head to use as a loop cursor. * @head: the head for your list. * - * This variant differs from list_for_each() in that it's the - * simplest possible list iteration code, no prefetching is done. - * Use this for code that knows the list to be very short (empty - * or 1 entry) most of the time. + * This variant doesn't differ from list_for_each() any more. + * We don't do prefetching in either case. */ #define __list_for_each(pos, head) \ for (pos = (head)->next; pos != (head); pos = pos->next) @@ -389,8 +386,7 @@ static inline void list_splice_tail_init(struct list_head *list, * @head: the head for your list. */ #define list_for_each_prev(pos, head) \ - for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \ - pos = pos->prev) + for (pos = (head)->prev; pos != (head); pos = pos->prev) /** * list_for_each_safe - iterate over a list safe against removal of list entry @@ -410,7 +406,7 @@ static inline void list_splice_tail_init(struct list_head *list, */ #define list_for_each_prev_safe(pos, n, head) \ for (pos = (head)->prev, n = pos->prev; \ - prefetch(pos->prev), pos != (head); \ + pos != (head); \ pos = n, n = pos->prev) /** @@ -421,7 +417,7 @@ static inline void list_splice_tail_init(struct list_head *list, */ #define list_for_each_entry(pos, head, member) \ for (pos = list_entry((head)->next, typeof(*pos), member); \ - prefetch(pos->member.next), &pos->member != (head); \ + &pos->member != (head); \ pos = list_entry(pos->member.next, typeof(*pos), member)) /** @@ -432,7 +428,7 @@ static inline void list_splice_tail_init(struct list_head *list, */ #define list_for_each_entry_reverse(pos, head, member) \ for (pos = list_entry((head)->prev, typeof(*pos), member); \ - prefetch(pos->member.prev), &pos->member != (head); \ + &pos->member != (head); \ pos = list_entry(pos->member.prev, typeof(*pos), member)) /** @@ -457,7 +453,7 @@ static inline void list_splice_tail_init(struct list_head *list, */ #define list_for_each_entry_continue(pos, head, member) \ for (pos = list_entry(pos->member.next, typeof(*pos), member); \ - prefetch(pos->member.next), &pos->member != (head); \ + &pos->member != (head); \ pos = list_entry(pos->member.next, typeof(*pos), member)) /** @@ -471,7 +467,7 @@ static inline void list_splice_tail_init(struct list_head *list, */ #define list_for_each_entry_continue_reverse(pos, head, member) \ for (pos = list_entry(pos->member.prev, typeof(*pos), member); \ - prefetch(pos->member.prev), &pos->member != (head); \ + &pos->member != (head); \ pos = list_entry(pos->member.prev, typeof(*pos), member)) /** @@ -483,7 +479,7 @@ static inline void list_splice_tail_init(struct list_head *list, * Iterate over list of given type, continuing from current position. */ #define list_for_each_entry_from(pos, head, member) \ - for (; prefetch(pos->member.next), &pos->member != (head); \ + for (; &pos->member != (head); \ pos = list_entry(pos->member.next, typeof(*pos), member)) /** diff --git a/include/linux/rculist.h b/include/linux/rculist.h index 900a97a44769..e3beb315517a 100644 --- a/include/linux/rculist.h +++ b/include/linux/rculist.h @@ -253,7 +253,7 @@ static inline void list_splice_init_rcu(struct list_head *list, */ #define list_for_each_entry_rcu(pos, head, member) \ for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \ - prefetch(pos->member.next), &pos->member != (head); \ + &pos->member != (head); \ pos = list_entry_rcu(pos->member.next, typeof(*pos), member)) @@ -270,7 +270,7 @@ static inline void list_splice_init_rcu(struct list_head *list, */ #define list_for_each_continue_rcu(pos, head) \ for ((pos) = rcu_dereference_raw(list_next_rcu(pos)); \ - prefetch((pos)->next), (pos) != (head); \ + (pos) != (head); \ (pos) = rcu_dereference_raw(list_next_rcu(pos))) /** @@ -284,7 +284,7 @@ static inline void list_splice_init_rcu(struct list_head *list, */ #define list_for_each_entry_continue_rcu(pos, head, member) \ for (pos = list_entry_rcu(pos->member.next, typeof(*pos), member); \ - prefetch(pos->member.next), &pos->member != (head); \ + &pos->member != (head); \ pos = list_entry_rcu(pos->member.next, typeof(*pos), member)) /** -- cgit From d410fa4ef99112386de5f218dd7df7b4fca910b4 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 19 May 2011 15:59:38 -0700 Subject: Create Documentation/security/, move LSM-, credentials-, and keys-related files from Documentation/ to Documentation/security/, add Documentation/security/00-INDEX, and update all occurrences of Documentation/ to Documentation/security/. --- Documentation/00-INDEX | 6 +- Documentation/SELinux.txt | 27 - Documentation/Smack.txt | 541 --------- Documentation/apparmor.txt | 39 - Documentation/credentials.txt | 581 ---------- Documentation/filesystems/nfs/idmapper.txt | 4 +- Documentation/keys-request-key.txt | 202 ---- Documentation/keys-trusted-encrypted.txt | 145 --- Documentation/keys.txt | 1290 --------------------- Documentation/networking/dns_resolver.txt | 4 +- Documentation/security/00-INDEX | 18 + Documentation/security/SELinux.txt | 27 + Documentation/security/Smack.txt | 541 +++++++++ Documentation/security/apparmor.txt | 39 + Documentation/security/credentials.txt | 581 ++++++++++ Documentation/security/keys-request-key.txt | 202 ++++ Documentation/security/keys-trusted-encrypted.txt | 145 +++ Documentation/security/keys.txt | 1290 +++++++++++++++++++++ Documentation/security/tomoyo.txt | 55 + Documentation/tomoyo.txt | 55 - MAINTAINERS | 6 +- include/linux/cred.h | 2 +- include/linux/key.h | 2 +- kernel/cred.c | 2 +- scripts/selinux/README | 2 +- security/apparmor/match.c | 2 +- security/apparmor/policy_unpack.c | 4 +- security/keys/encrypted.c | 2 +- security/keys/request_key.c | 2 +- security/keys/request_key_auth.c | 2 +- security/keys/trusted.c | 2 +- 31 files changed, 2918 insertions(+), 2902 deletions(-) delete mode 100644 Documentation/SELinux.txt delete mode 100644 Documentation/Smack.txt delete mode 100644 Documentation/apparmor.txt delete mode 100644 Documentation/credentials.txt delete mode 100644 Documentation/keys-request-key.txt delete mode 100644 Documentation/keys-trusted-encrypted.txt delete mode 100644 Documentation/keys.txt create mode 100644 Documentation/security/00-INDEX create mode 100644 Documentation/security/SELinux.txt create mode 100644 Documentation/security/Smack.txt create mode 100644 Documentation/security/apparmor.txt create mode 100644 Documentation/security/credentials.txt create mode 100644 Documentation/security/keys-request-key.txt create mode 100644 Documentation/security/keys-trusted-encrypted.txt create mode 100644 Documentation/security/keys.txt create mode 100644 Documentation/security/tomoyo.txt delete mode 100644 Documentation/tomoyo.txt (limited to 'include/linux') diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX index c17cd4bb2290..c8c1cf631b37 100644 --- a/Documentation/00-INDEX +++ b/Documentation/00-INDEX @@ -192,10 +192,6 @@ kernel-docs.txt - listing of various WWW + books that document kernel internals. kernel-parameters.txt - summary listing of command line / boot prompt args for the kernel. -keys-request-key.txt - - description of the kernel key request service. -keys.txt - - description of the kernel key retention service. kobject.txt - info of the kobject infrastructure of the Linux kernel. kprobes.txt @@ -294,6 +290,8 @@ scheduler/ - directory with info on the scheduler. scsi/ - directory with info on Linux scsi support. +security/ + - directory that contains security-related info serial/ - directory with info on the low level serial API. serial-console.txt diff --git a/Documentation/SELinux.txt b/Documentation/SELinux.txt deleted file mode 100644 index 07eae00f3314..000000000000 --- a/Documentation/SELinux.txt +++ /dev/null @@ -1,27 +0,0 @@ -If you want to use SELinux, chances are you will want -to use the distro-provided policies, or install the -latest reference policy release from - http://oss.tresys.com/projects/refpolicy - -However, if you want to install a dummy policy for -testing, you can do using 'mdp' provided under -scripts/selinux. Note that this requires the selinux -userspace to be installed - in particular you will -need checkpolicy to compile a kernel, and setfiles and -fixfiles to label the filesystem. - - 1. Compile the kernel with selinux enabled. - 2. Type 'make' to compile mdp. - 3. Make sure that you are not running with - SELinux enabled and a real policy. If - you are, reboot with selinux disabled - before continuing. - 4. Run install_policy.sh: - cd scripts/selinux - sh install_policy.sh - -Step 4 will create a new dummy policy valid for your -kernel, with a single selinux user, role, and type. -It will compile the policy, will set your SELINUXTYPE to -dummy in /etc/selinux/config, install the compiled policy -as 'dummy', and relabel your filesystem. diff --git a/Documentation/Smack.txt b/Documentation/Smack.txt deleted file mode 100644 index e9dab41c0fe0..000000000000 --- a/Documentation/Smack.txt +++ /dev/null @@ -1,541 +0,0 @@ - - - "Good for you, you've decided to clean the elevator!" - - The Elevator, from Dark Star - -Smack is the the Simplified Mandatory Access Control Kernel. -Smack is a kernel based implementation of mandatory access -control that includes simplicity in its primary design goals. - -Smack is not the only Mandatory Access Control scheme -available for Linux. Those new to Mandatory Access Control -are encouraged to compare Smack with the other mechanisms -available to determine which is best suited to the problem -at hand. - -Smack consists of three major components: - - The kernel - - A start-up script and a few modified applications - - Configuration data - -The kernel component of Smack is implemented as a Linux -Security Modules (LSM) module. It requires netlabel and -works best with file systems that support extended attributes, -although xattr support is not strictly required. -It is safe to run a Smack kernel under a "vanilla" distribution. -Smack kernels use the CIPSO IP option. Some network -configurations are intolerant of IP options and can impede -access to systems that use them as Smack does. - -The startup script etc-init.d-smack should be installed -in /etc/init.d/smack and should be invoked early in the -start-up process. On Fedora rc5.d/S02smack is recommended. -This script ensures that certain devices have the correct -Smack attributes and loads the Smack configuration if -any is defined. This script invokes two programs that -ensure configuration data is properly formatted. These -programs are /usr/sbin/smackload and /usr/sin/smackcipso. -The system will run just fine without these programs, -but it will be difficult to set access rules properly. - -A version of "ls" that provides a "-M" option to display -Smack labels on long listing is available. - -A hacked version of sshd that allows network logins by users -with specific Smack labels is available. This version does -not work for scp. You must set the /etc/ssh/sshd_config -line: - UsePrivilegeSeparation no - -The format of /etc/smack/usr is: - - username smack - -In keeping with the intent of Smack, configuration data is -minimal and not strictly required. The most important -configuration step is mounting the smackfs pseudo filesystem. - -Add this line to /etc/fstab: - - smackfs /smack smackfs smackfsdef=* 0 0 - -and create the /smack directory for mounting. - -Smack uses extended attributes (xattrs) to store file labels. -The command to set a Smack label on a file is: - - # attr -S -s SMACK64 -V "value" path - -NOTE: Smack labels are limited to 23 characters. The attr command - does not enforce this restriction and can be used to set - invalid Smack labels on files. - -If you don't do anything special all users will get the floor ("_") -label when they log in. If you do want to log in via the hacked ssh -at other labels use the attr command to set the smack value on the -home directory and its contents. - -You can add access rules in /etc/smack/accesses. They take the form: - - subjectlabel objectlabel access - -access is a combination of the letters rwxa which specify the -kind of access permitted a subject with subjectlabel on an -object with objectlabel. If there is no rule no access is allowed. - -A process can see the smack label it is running with by -reading /proc/self/attr/current. A privileged process can -set the process smack by writing there. - -Look for additional programs on http://schaufler-ca.com - -From the Smack Whitepaper: - -The Simplified Mandatory Access Control Kernel - -Casey Schaufler -casey@schaufler-ca.com - -Mandatory Access Control - -Computer systems employ a variety of schemes to constrain how information is -shared among the people and services using the machine. Some of these schemes -allow the program or user to decide what other programs or users are allowed -access to pieces of data. These schemes are called discretionary access -control mechanisms because the access control is specified at the discretion -of the user. Other schemes do not leave the decision regarding what a user or -program can access up to users or programs. These schemes are called mandatory -access control mechanisms because you don't have a choice regarding the users -or programs that have access to pieces of data. - -Bell & LaPadula - -From the middle of the 1980's until the turn of the century Mandatory Access -Control (MAC) was very closely associated with the Bell & LaPadula security -model, a mathematical description of the United States Department of Defense -policy for marking paper documents. MAC in this form enjoyed a following -within the Capital Beltway and Scandinavian supercomputer centers but was -often sited as failing to address general needs. - -Domain Type Enforcement - -Around the turn of the century Domain Type Enforcement (DTE) became popular. -This scheme organizes users, programs, and data into domains that are -protected from each other. This scheme has been widely deployed as a component -of popular Linux distributions. The administrative overhead required to -maintain this scheme and the detailed understanding of the whole system -necessary to provide a secure domain mapping leads to the scheme being -disabled or used in limited ways in the majority of cases. - -Smack - -Smack is a Mandatory Access Control mechanism designed to provide useful MAC -while avoiding the pitfalls of its predecessors. The limitations of Bell & -LaPadula are addressed by providing a scheme whereby access can be controlled -according to the requirements of the system and its purpose rather than those -imposed by an arcane government policy. The complexity of Domain Type -Enforcement and avoided by defining access controls in terms of the access -modes already in use. - -Smack Terminology - -The jargon used to talk about Smack will be familiar to those who have dealt -with other MAC systems and shouldn't be too difficult for the uninitiated to -pick up. There are four terms that are used in a specific way and that are -especially important: - - Subject: A subject is an active entity on the computer system. - On Smack a subject is a task, which is in turn the basic unit - of execution. - - Object: An object is a passive entity on the computer system. - On Smack files of all types, IPC, and tasks can be objects. - - Access: Any attempt by a subject to put information into or get - information from an object is an access. - - Label: Data that identifies the Mandatory Access Control - characteristics of a subject or an object. - -These definitions are consistent with the traditional use in the security -community. There are also some terms from Linux that are likely to crop up: - - Capability: A task that possesses a capability has permission to - violate an aspect of the system security policy, as identified by - the specific capability. A task that possesses one or more - capabilities is a privileged task, whereas a task with no - capabilities is an unprivileged task. - - Privilege: A task that is allowed to violate the system security - policy is said to have privilege. As of this writing a task can - have privilege either by possessing capabilities or by having an - effective user of root. - -Smack Basics - -Smack is an extension to a Linux system. It enforces additional restrictions -on what subjects can access which objects, based on the labels attached to -each of the subject and the object. - -Labels - -Smack labels are ASCII character strings, one to twenty-three characters in -length. Single character labels using special characters, that being anything -other than a letter or digit, are reserved for use by the Smack development -team. Smack labels are unstructured, case sensitive, and the only operation -ever performed on them is comparison for equality. Smack labels cannot -contain unprintable characters, the "/" (slash), the "\" (backslash), the "'" -(quote) and '"' (double-quote) characters. -Smack labels cannot begin with a '-', which is reserved for special options. - -There are some predefined labels: - - _ Pronounced "floor", a single underscore character. - ^ Pronounced "hat", a single circumflex character. - * Pronounced "star", a single asterisk character. - ? Pronounced "huh", a single question mark character. - @ Pronounced "Internet", a single at sign character. - -Every task on a Smack system is assigned a label. System tasks, such as -init(8) and systems daemons, are run with the floor ("_") label. User tasks -are assigned labels according to the specification found in the -/etc/smack/user configuration file. - -Access Rules - -Smack uses the traditional access modes of Linux. These modes are read, -execute, write, and occasionally append. There are a few cases where the -access mode may not be obvious. These include: - - Signals: A signal is a write operation from the subject task to - the object task. - Internet Domain IPC: Transmission of a packet is considered a - write operation from the source task to the destination task. - -Smack restricts access based on the label attached to a subject and the label -attached to the object it is trying to access. The rules enforced are, in -order: - - 1. Any access requested by a task labeled "*" is denied. - 2. A read or execute access requested by a task labeled "^" - is permitted. - 3. A read or execute access requested on an object labeled "_" - is permitted. - 4. Any access requested on an object labeled "*" is permitted. - 5. Any access requested by a task on an object with the same - label is permitted. - 6. Any access requested that is explicitly defined in the loaded - rule set is permitted. - 7. Any other access is denied. - -Smack Access Rules - -With the isolation provided by Smack access separation is simple. There are -many interesting cases where limited access by subjects to objects with -different labels is desired. One example is the familiar spy model of -sensitivity, where a scientist working on a highly classified project would be -able to read documents of lower classifications and anything she writes will -be "born" highly classified. To accommodate such schemes Smack includes a -mechanism for specifying rules allowing access between labels. - -Access Rule Format - -The format of an access rule is: - - subject-label object-label access - -Where subject-label is the Smack label of the task, object-label is the Smack -label of the thing being accessed, and access is a string specifying the sort -of access allowed. The Smack labels are limited to 23 characters. The access -specification is searched for letters that describe access modes: - - a: indicates that append access should be granted. - r: indicates that read access should be granted. - w: indicates that write access should be granted. - x: indicates that execute access should be granted. - -Uppercase values for the specification letters are allowed as well. -Access mode specifications can be in any order. Examples of acceptable rules -are: - - TopSecret Secret rx - Secret Unclass R - Manager Game x - User HR w - New Old rRrRr - Closed Off - - -Examples of unacceptable rules are: - - Top Secret Secret rx - Ace Ace r - Odd spells waxbeans - -Spaces are not allowed in labels. Since a subject always has access to files -with the same label specifying a rule for that case is pointless. Only -valid letters (rwxaRWXA) and the dash ('-') character are allowed in -access specifications. The dash is a placeholder, so "a-r" is the same -as "ar". A lone dash is used to specify that no access should be allowed. - -Applying Access Rules - -The developers of Linux rarely define new sorts of things, usually importing -schemes and concepts from other systems. Most often, the other systems are -variants of Unix. Unix has many endearing properties, but consistency of -access control models is not one of them. Smack strives to treat accesses as -uniformly as is sensible while keeping with the spirit of the underlying -mechanism. - -File system objects including files, directories, named pipes, symbolic links, -and devices require access permissions that closely match those used by mode -bit access. To open a file for reading read access is required on the file. To -search a directory requires execute access. Creating a file with write access -requires both read and write access on the containing directory. Deleting a -file requires read and write access to the file and to the containing -directory. It is possible that a user may be able to see that a file exists -but not any of its attributes by the circumstance of having read access to the -containing directory but not to the differently labeled file. This is an -artifact of the file name being data in the directory, not a part of the file. - -IPC objects, message queues, semaphore sets, and memory segments exist in flat -namespaces and access requests are only required to match the object in -question. - -Process objects reflect tasks on the system and the Smack label used to access -them is the same Smack label that the task would use for its own access -attempts. Sending a signal via the kill() system call is a write operation -from the signaler to the recipient. Debugging a process requires both reading -and writing. Creating a new task is an internal operation that results in two -tasks with identical Smack labels and requires no access checks. - -Sockets are data structures attached to processes and sending a packet from -one process to another requires that the sender have write access to the -receiver. The receiver is not required to have read access to the sender. - -Setting Access Rules - -The configuration file /etc/smack/accesses contains the rules to be set at -system startup. The contents are written to the special file /smack/load. -Rules can be written to /smack/load at any time and take effect immediately. -For any pair of subject and object labels there can be only one rule, with the -most recently specified overriding any earlier specification. - -The program smackload is provided to ensure data is formatted -properly when written to /smack/load. This program reads lines -of the form - - subjectlabel objectlabel mode. - -Task Attribute - -The Smack label of a process can be read from /proc//attr/current. A -process can read its own Smack label from /proc/self/attr/current. A -privileged process can change its own Smack label by writing to -/proc/self/attr/current but not the label of another process. - -File Attribute - -The Smack label of a filesystem object is stored as an extended attribute -named SMACK64 on the file. This attribute is in the security namespace. It can -only be changed by a process with privilege. - -Privilege - -A process with CAP_MAC_OVERRIDE is privileged. - -Smack Networking - -As mentioned before, Smack enforces access control on network protocol -transmissions. Every packet sent by a Smack process is tagged with its Smack -label. This is done by adding a CIPSO tag to the header of the IP packet. Each -packet received is expected to have a CIPSO tag that identifies the label and -if it lacks such a tag the network ambient label is assumed. Before the packet -is delivered a check is made to determine that a subject with the label on the -packet has write access to the receiving process and if that is not the case -the packet is dropped. - -CIPSO Configuration - -It is normally unnecessary to specify the CIPSO configuration. The default -values used by the system handle all internal cases. Smack will compose CIPSO -label values to match the Smack labels being used without administrative -intervention. Unlabeled packets that come into the system will be given the -ambient label. - -Smack requires configuration in the case where packets from a system that is -not smack that speaks CIPSO may be encountered. Usually this will be a Trusted -Solaris system, but there are other, less widely deployed systems out there. -CIPSO provides 3 important values, a Domain Of Interpretation (DOI), a level, -and a category set with each packet. The DOI is intended to identify a group -of systems that use compatible labeling schemes, and the DOI specified on the -smack system must match that of the remote system or packets will be -discarded. The DOI is 3 by default. The value can be read from /smack/doi and -can be changed by writing to /smack/doi. - -The label and category set are mapped to a Smack label as defined in -/etc/smack/cipso. - -A Smack/CIPSO mapping has the form: - - smack level [category [category]*] - -Smack does not expect the level or category sets to be related in any -particular way and does not assume or assign accesses based on them. Some -examples of mappings: - - TopSecret 7 - TS:A,B 7 1 2 - SecBDE 5 2 4 6 - RAFTERS 7 12 26 - -The ":" and "," characters are permitted in a Smack label but have no special -meaning. - -The mapping of Smack labels to CIPSO values is defined by writing to -/smack/cipso. Again, the format of data written to this special file -is highly restrictive, so the program smackcipso is provided to -ensure the writes are done properly. This program takes mappings -on the standard input and sends them to /smack/cipso properly. - -In addition to explicit mappings Smack supports direct CIPSO mappings. One -CIPSO level is used to indicate that the category set passed in the packet is -in fact an encoding of the Smack label. The level used is 250 by default. The -value can be read from /smack/direct and changed by writing to /smack/direct. - -Socket Attributes - -There are two attributes that are associated with sockets. These attributes -can only be set by privileged tasks, but any task can read them for their own -sockets. - - SMACK64IPIN: The Smack label of the task object. A privileged - program that will enforce policy may set this to the star label. - - SMACK64IPOUT: The Smack label transmitted with outgoing packets. - A privileged program may set this to match the label of another - task with which it hopes to communicate. - -Smack Netlabel Exceptions - -You will often find that your labeled application has to talk to the outside, -unlabeled world. To do this there's a special file /smack/netlabel where you can -add some exceptions in the form of : -@IP1 LABEL1 or -@IP2/MASK LABEL2 - -It means that your application will have unlabeled access to @IP1 if it has -write access on LABEL1, and access to the subnet @IP2/MASK if it has write -access on LABEL2. - -Entries in the /smack/netlabel file are matched by longest mask first, like in -classless IPv4 routing. - -A special label '@' and an option '-CIPSO' can be used there : -@ means Internet, any application with any label has access to it --CIPSO means standard CIPSO networking - -If you don't know what CIPSO is and don't plan to use it, you can just do : -echo 127.0.0.1 -CIPSO > /smack/netlabel -echo 0.0.0.0/0 @ > /smack/netlabel - -If you use CIPSO on your 192.168.0.0/16 local network and need also unlabeled -Internet access, you can have : -echo 127.0.0.1 -CIPSO > /smack/netlabel -echo 192.168.0.0/16 -CIPSO > /smack/netlabel -echo 0.0.0.0/0 @ > /smack/netlabel - - -Writing Applications for Smack - -There are three sorts of applications that will run on a Smack system. How an -application interacts with Smack will determine what it will have to do to -work properly under Smack. - -Smack Ignorant Applications - -By far the majority of applications have no reason whatever to care about the -unique properties of Smack. Since invoking a program has no impact on the -Smack label associated with the process the only concern likely to arise is -whether the process has execute access to the program. - -Smack Relevant Applications - -Some programs can be improved by teaching them about Smack, but do not make -any security decisions themselves. The utility ls(1) is one example of such a -program. - -Smack Enforcing Applications - -These are special programs that not only know about Smack, but participate in -the enforcement of system policy. In most cases these are the programs that -set up user sessions. There are also network services that provide information -to processes running with various labels. - -File System Interfaces - -Smack maintains labels on file system objects using extended attributes. The -Smack label of a file, directory, or other file system object can be obtained -using getxattr(2). - - len = getxattr("/", "security.SMACK64", value, sizeof (value)); - -will put the Smack label of the root directory into value. A privileged -process can set the Smack label of a file system object with setxattr(2). - - len = strlen("Rubble"); - rc = setxattr("/foo", "security.SMACK64", "Rubble", len, 0); - -will set the Smack label of /foo to "Rubble" if the program has appropriate -privilege. - -Socket Interfaces - -The socket attributes can be read using fgetxattr(2). - -A privileged process can set the Smack label of outgoing packets with -fsetxattr(2). - - len = strlen("Rubble"); - rc = fsetxattr(fd, "security.SMACK64IPOUT", "Rubble", len, 0); - -will set the Smack label "Rubble" on packets going out from the socket if the -program has appropriate privilege. - - rc = fsetxattr(fd, "security.SMACK64IPIN, "*", strlen("*"), 0); - -will set the Smack label "*" as the object label against which incoming -packets will be checked if the program has appropriate privilege. - -Administration - -Smack supports some mount options: - - smackfsdef=label: specifies the label to give files that lack - the Smack label extended attribute. - - smackfsroot=label: specifies the label to assign the root of the - file system if it lacks the Smack extended attribute. - - smackfshat=label: specifies a label that must have read access to - all labels set on the filesystem. Not yet enforced. - - smackfsfloor=label: specifies a label to which all labels set on the - filesystem must have read access. Not yet enforced. - -These mount options apply to all file system types. - -Smack auditing - -If you want Smack auditing of security events, you need to set CONFIG_AUDIT -in your kernel configuration. -By default, all denied events will be audited. You can change this behavior by -writing a single character to the /smack/logging file : -0 : no logging -1 : log denied (default) -2 : log accepted -3 : log denied & accepted - -Events are logged as 'key=value' pairs, for each event you at least will get -the subjet, the object, the rights requested, the action, the kernel function -that triggered the event, plus other pairs depending on the type of event -audited. diff --git a/Documentation/apparmor.txt b/Documentation/apparmor.txt deleted file mode 100644 index 93c1fd7d0635..000000000000 --- a/Documentation/apparmor.txt +++ /dev/null @@ -1,39 +0,0 @@ ---- What is AppArmor? --- - -AppArmor is MAC style security extension for the Linux kernel. It implements -a task centered policy, with task "profiles" being created and loaded -from user space. Tasks on the system that do not have a profile defined for -them run in an unconfined state which is equivalent to standard Linux DAC -permissions. - ---- How to enable/disable --- - -set CONFIG_SECURITY_APPARMOR=y - -If AppArmor should be selected as the default security module then - set CONFIG_DEFAULT_SECURITY="apparmor" - and CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=1 - -Build the kernel - -If AppArmor is not the default security module it can be enabled by passing -security=apparmor on the kernel's command line. - -If AppArmor is the default security module it can be disabled by passing -apparmor=0, security=XXXX (where XXX is valid security module), on the -kernel's command line - -For AppArmor to enforce any restrictions beyond standard Linux DAC permissions -policy must be loaded into the kernel from user space (see the Documentation -and tools links). - ---- Documentation --- - -Documentation can be found on the wiki. - ---- Links --- - -Mailing List - apparmor@lists.ubuntu.com -Wiki - http://apparmor.wiki.kernel.org/ -User space tools - https://launchpad.net/apparmor -Kernel module - git://git.kernel.org/pub/scm/linux/kernel/git/jj/apparmor-dev.git diff --git a/Documentation/credentials.txt b/Documentation/credentials.txt deleted file mode 100644 index 995baf379c07..000000000000 --- a/Documentation/credentials.txt +++ /dev/null @@ -1,581 +0,0 @@ - ==================== - CREDENTIALS IN LINUX - ==================== - -By: David Howells - -Contents: - - (*) Overview. - - (*) Types of credentials. - - (*) File markings. - - (*) Task credentials. - - - Immutable credentials. - - Accessing task credentials. - - Accessing another task's credentials. - - Altering credentials. - - Managing credentials. - - (*) Open file credentials. - - (*) Overriding the VFS's use of credentials. - - -======== -OVERVIEW -======== - -There are several parts to the security check performed by Linux when one -object acts upon another: - - (1) Objects. - - Objects are things in the system that may be acted upon directly by - userspace programs. Linux has a variety of actionable objects, including: - - - Tasks - - Files/inodes - - Sockets - - Message queues - - Shared memory segments - - Semaphores - - Keys - - As a part of the description of all these objects there is a set of - credentials. What's in the set depends on the type of object. - - (2) Object ownership. - - Amongst the credentials of most objects, there will be a subset that - indicates the ownership of that object. This is used for resource - accounting and limitation (disk quotas and task rlimits for example). - - In a standard UNIX filesystem, for instance, this will be defined by the - UID marked on the inode. - - (3) The objective context. - - Also amongst the credentials of those objects, there will be a subset that - indicates the 'objective context' of that object. This may or may not be - the same set as in (2) - in standard UNIX files, for instance, this is the - defined by the UID and the GID marked on the inode. - - The objective context is used as part of the security calculation that is - carried out when an object is acted upon. - - (4) Subjects. - - A subject is an object that is acting upon another object. - - Most of the objects in the system are inactive: they don't act on other - objects within the system. Processes/tasks are the obvious exception: - they do stuff; they access and manipulate things. - - Objects other than tasks may under some circumstances also be subjects. - For instance an open file may send SIGIO to a task using the UID and EUID - given to it by a task that called fcntl(F_SETOWN) upon it. In this case, - the file struct will have a subjective context too. - - (5) The subjective context. - - A subject has an additional interpretation of its credentials. A subset - of its credentials forms the 'subjective context'. The subjective context - is used as part of the security calculation that is carried out when a - subject acts. - - A Linux task, for example, has the FSUID, FSGID and the supplementary - group list for when it is acting upon a file - which are quite separate - from the real UID and GID that normally form the objective context of the - task. - - (6) Actions. - - Linux has a number of actions available that a subject may perform upon an - object. The set of actions available depends on the nature of the subject - and the object. - - Actions include reading, writing, creating and deleting files; forking or - signalling and tracing tasks. - - (7) Rules, access control lists and security calculations. - - When a subject acts upon an object, a security calculation is made. This - involves taking the subjective context, the objective context and the - action, and searching one or more sets of rules to see whether the subject - is granted or denied permission to act in the desired manner on the - object, given those contexts. - - There are two main sources of rules: - - (a) Discretionary access control (DAC): - - Sometimes the object will include sets of rules as part of its - description. This is an 'Access Control List' or 'ACL'. A Linux - file may supply more than one ACL. - - A traditional UNIX file, for example, includes a permissions mask that - is an abbreviated ACL with three fixed classes of subject ('user', - 'group' and 'other'), each of which may be granted certain privileges - ('read', 'write' and 'execute' - whatever those map to for the object - in question). UNIX file permissions do not allow the arbitrary - specification of subjects, however, and so are of limited use. - - A Linux file might also sport a POSIX ACL. This is a list of rules - that grants various permissions to arbitrary subjects. - - (b) Mandatory access control (MAC): - - The system as a whole may have one or more sets of rules that get - applied to all subjects and objects, regardless of their source. - SELinux and Smack are examples of this. - - In the case of SELinux and Smack, each object is given a label as part - of its credentials. When an action is requested, they take the - subject label, the object label and the action and look for a rule - that says that this action is either granted or denied. - - -==================== -TYPES OF CREDENTIALS -==================== - -The Linux kernel supports the following types of credentials: - - (1) Traditional UNIX credentials. - - Real User ID - Real Group ID - - The UID and GID are carried by most, if not all, Linux objects, even if in - some cases it has to be invented (FAT or CIFS files for example, which are - derived from Windows). These (mostly) define the objective context of - that object, with tasks being slightly different in some cases. - - Effective, Saved and FS User ID - Effective, Saved and FS Group ID - Supplementary groups - - These are additional credentials used by tasks only. Usually, an - EUID/EGID/GROUPS will be used as the subjective context, and real UID/GID - will be used as the objective. For tasks, it should be noted that this is - not always true. - - (2) Capabilities. - - Set of permitted capabilities - Set of inheritable capabilities - Set of effective capabilities - Capability bounding set - - These are only carried by tasks. They indicate superior capabilities - granted piecemeal to a task that an ordinary task wouldn't otherwise have. - These are manipulated implicitly by changes to the traditional UNIX - credentials, but can also be manipulated directly by the capset() system - call. - - The permitted capabilities are those caps that the process might grant - itself to its effective or permitted sets through capset(). This - inheritable set might also be so constrained. - - The effective capabilities are the ones that a task is actually allowed to - make use of itself. - - The inheritable capabilities are the ones that may get passed across - execve(). - - The bounding set limits the capabilities that may be inherited across - execve(), especially when a binary is executed that will execute as UID 0. - - (3) Secure management flags (securebits). - - These are only carried by tasks. These govern the way the above - credentials are manipulated and inherited over certain operations such as - execve(). They aren't used directly as objective or subjective - credentials. - - (4) Keys and keyrings. - - These are only carried by tasks. They carry and cache security tokens - that don't fit into the other standard UNIX credentials. They are for - making such things as network filesystem keys available to the file - accesses performed by processes, without the necessity of ordinary - programs having to know about security details involved. - - Keyrings are a special type of key. They carry sets of other keys and can - be searched for the desired key. Each process may subscribe to a number - of keyrings: - - Per-thread keying - Per-process keyring - Per-session keyring - - When a process accesses a key, if not already present, it will normally be - cached on one of these keyrings for future accesses to find. - - For more information on using keys, see Documentation/keys.txt. - - (5) LSM - - The Linux Security Module allows extra controls to be placed over the - operations that a task may do. Currently Linux supports two main - alternate LSM options: SELinux and Smack. - - Both work by labelling the objects in a system and then applying sets of - rules (policies) that say what operations a task with one label may do to - an object with another label. - - (6) AF_KEY - - This is a socket-based approach to credential management for networking - stacks [RFC 2367]. It isn't discussed by this document as it doesn't - interact directly with task and file credentials; rather it keeps system - level credentials. - - -When a file is opened, part of the opening task's subjective context is -recorded in the file struct created. This allows operations using that file -struct to use those credentials instead of the subjective context of the task -that issued the operation. An example of this would be a file opened on a -network filesystem where the credentials of the opened file should be presented -to the server, regardless of who is actually doing a read or a write upon it. - - -============= -FILE MARKINGS -============= - -Files on disk or obtained over the network may have annotations that form the -objective security context of that file. Depending on the type of filesystem, -this may include one or more of the following: - - (*) UNIX UID, GID, mode; - - (*) Windows user ID; - - (*) Access control list; - - (*) LSM security label; - - (*) UNIX exec privilege escalation bits (SUID/SGID); - - (*) File capabilities exec privilege escalation bits. - -These are compared to the task's subjective security context, and certain -operations allowed or disallowed as a result. In the case of execve(), the -privilege escalation bits come into play, and may allow the resulting process -extra privileges, based on the annotations on the executable file. - - -================ -TASK CREDENTIALS -================ - -In Linux, all of a task's credentials are held in (uid, gid) or through -(groups, keys, LSM security) a refcounted structure of type 'struct cred'. -Each task points to its credentials by a pointer called 'cred' in its -task_struct. - -Once a set of credentials has been prepared and committed, it may not be -changed, barring the following exceptions: - - (1) its reference count may be changed; - - (2) the reference count on the group_info struct it points to may be changed; - - (3) the reference count on the security data it points to may be changed; - - (4) the reference count on any keyrings it points to may be changed; - - (5) any keyrings it points to may be revoked, expired or have their security - attributes changed; and - - (6) the contents of any keyrings to which it points may be changed (the whole - point of keyrings being a shared set of credentials, modifiable by anyone - with appropriate access). - -To alter anything in the cred struct, the copy-and-replace principle must be -adhered to. First take a copy, then alter the copy and then use RCU to change -the task pointer to make it point to the new copy. There are wrappers to aid -with this (see below). - -A task may only alter its _own_ credentials; it is no longer permitted for a -task to alter another's credentials. This means the capset() system call is no -longer permitted to take any PID other than the one of the current process. -Also keyctl_instantiate() and keyctl_negate() functions no longer permit -attachment to process-specific keyrings in the requesting process as the -instantiating process may need to create them. - - -IMMUTABLE CREDENTIALS ---------------------- - -Once a set of credentials has been made public (by calling commit_creds() for -example), it must be considered immutable, barring two exceptions: - - (1) The reference count may be altered. - - (2) Whilst the keyring subscriptions of a set of credentials may not be - changed, the keyrings subscribed to may have their contents altered. - -To catch accidental credential alteration at compile time, struct task_struct -has _const_ pointers to its credential sets, as does struct file. Furthermore, -certain functions such as get_cred() and put_cred() operate on const pointers, -thus rendering casts unnecessary, but require to temporarily ditch the const -qualification to be able to alter the reference count. - - -ACCESSING TASK CREDENTIALS --------------------------- - -A task being able to alter only its own credentials permits the current process -to read or replace its own credentials without the need for any form of locking -- which simplifies things greatly. It can just call: - - const struct cred *current_cred() - -to get a pointer to its credentials structure, and it doesn't have to release -it afterwards. - -There are convenience wrappers for retrieving specific aspects of a task's -credentials (the value is simply returned in each case): - - uid_t current_uid(void) Current's real UID - gid_t current_gid(void) Current's real GID - uid_t current_euid(void) Current's effective UID - gid_t current_egid(void) Current's effective GID - uid_t current_fsuid(void) Current's file access UID - gid_t current_fsgid(void) Current's file access GID - kernel_cap_t current_cap(void) Current's effective capabilities - void *current_security(void) Current's LSM security pointer - struct user_struct *current_user(void) Current's user account - -There are also convenience wrappers for retrieving specific associated pairs of -a task's credentials: - - void current_uid_gid(uid_t *, gid_t *); - void current_euid_egid(uid_t *, gid_t *); - void current_fsuid_fsgid(uid_t *, gid_t *); - -which return these pairs of values through their arguments after retrieving -them from the current task's credentials. - - -In addition, there is a function for obtaining a reference on the current -process's current set of credentials: - - const struct cred *get_current_cred(void); - -and functions for getting references to one of the credentials that don't -actually live in struct cred: - - struct user_struct *get_current_user(void); - struct group_info *get_current_groups(void); - -which get references to the current process's user accounting structure and -supplementary groups list respectively. - -Once a reference has been obtained, it must be released with put_cred(), -free_uid() or put_group_info() as appropriate. - - -ACCESSING ANOTHER TASK'S CREDENTIALS ------------------------------------- - -Whilst a task may access its own credentials without the need for locking, the -same is not true of a task wanting to access another task's credentials. It -must use the RCU read lock and rcu_dereference(). - -The rcu_dereference() is wrapped by: - - const struct cred *__task_cred(struct task_struct *task); - -This should be used inside the RCU read lock, as in the following example: - - void foo(struct task_struct *t, struct foo_data *f) - { - const struct cred *tcred; - ... - rcu_read_lock(); - tcred = __task_cred(t); - f->uid = tcred->uid; - f->gid = tcred->gid; - f->groups = get_group_info(tcred->groups); - rcu_read_unlock(); - ... - } - -Should it be necessary to hold another task's credentials for a long period of -time, and possibly to sleep whilst doing so, then the caller should get a -reference on them using: - - const struct cred *get_task_cred(struct task_struct *task); - -This does all the RCU magic inside of it. The caller must call put_cred() on -the credentials so obtained when they're finished with. - - [*] Note: The result of __task_cred() should not be passed directly to - get_cred() as this may race with commit_cred(). - -There are a couple of convenience functions to access bits of another task's -credentials, hiding the RCU magic from the caller: - - uid_t task_uid(task) Task's real UID - uid_t task_euid(task) Task's effective UID - -If the caller is holding the RCU read lock at the time anyway, then: - - __task_cred(task)->uid - __task_cred(task)->euid - -should be used instead. Similarly, if multiple aspects of a task's credentials -need to be accessed, RCU read lock should be used, __task_cred() called, the -result stored in a temporary pointer and then the credential aspects called -from that before dropping the lock. This prevents the potentially expensive -RCU magic from being invoked multiple times. - -Should some other single aspect of another task's credentials need to be -accessed, then this can be used: - - task_cred_xxx(task, member) - -where 'member' is a non-pointer member of the cred struct. For instance: - - uid_t task_cred_xxx(task, suid); - -will retrieve 'struct cred::suid' from the task, doing the appropriate RCU -magic. This may not be used for pointer members as what they point to may -disappear the moment the RCU read lock is dropped. - - -ALTERING CREDENTIALS --------------------- - -As previously mentioned, a task may only alter its own credentials, and may not -alter those of another task. This means that it doesn't need to use any -locking to alter its own credentials. - -To alter the current process's credentials, a function should first prepare a -new set of credentials by calling: - - struct cred *prepare_creds(void); - -this locks current->cred_replace_mutex and then allocates and constructs a -duplicate of the current process's credentials, returning with the mutex still -held if successful. It returns NULL if not successful (out of memory). - -The mutex prevents ptrace() from altering the ptrace state of a process whilst -security checks on credentials construction and changing is taking place as -the ptrace state may alter the outcome, particularly in the case of execve(). - -The new credentials set should be altered appropriately, and any security -checks and hooks done. Both the current and the proposed sets of credentials -are available for this purpose as current_cred() will return the current set -still at this point. - - -When the credential set is ready, it should be committed to the current process -by calling: - - int commit_creds(struct cred *new); - -This will alter various aspects of the credentials and the process, giving the -LSM a chance to do likewise, then it will use rcu_assign_pointer() to actually -commit the new credentials to current->cred, it will release -current->cred_replace_mutex to allow ptrace() to take place, and it will notify -the scheduler and others of the changes. - -This function is guaranteed to return 0, so that it can be tail-called at the -end of such functions as sys_setresuid(). - -Note that this function consumes the caller's reference to the new credentials. -The caller should _not_ call put_cred() on the new credentials afterwards. - -Furthermore, once this function has been called on a new set of credentials, -those credentials may _not_ be changed further. - - -Should the security checks fail or some other error occur after prepare_creds() -has been called, then the following function should be invoked: - - void abort_creds(struct cred *new); - -This releases the lock on current->cred_replace_mutex that prepare_creds() got -and then releases the new credentials. - - -A typical credentials alteration function would look something like this: - - int alter_suid(uid_t suid) - { - struct cred *new; - int ret; - - new = prepare_creds(); - if (!new) - return -ENOMEM; - - new->suid = suid; - ret = security_alter_suid(new); - if (ret < 0) { - abort_creds(new); - return ret; - } - - return commit_creds(new); - } - - -MANAGING CREDENTIALS --------------------- - -There are some functions to help manage credentials: - - (*) void put_cred(const struct cred *cred); - - This releases a reference to the given set of credentials. If the - reference count reaches zero, the credentials will be scheduled for - destruction by the RCU system. - - (*) const struct cred *get_cred(const struct cred *cred); - - This gets a reference on a live set of credentials, returning a pointer to - that set of credentials. - - (*) struct cred *get_new_cred(struct cred *cred); - - This gets a reference on a set of credentials that is under construction - and is thus still mutable, returning a pointer to that set of credentials. - - -===================== -OPEN FILE CREDENTIALS -===================== - -When a new file is opened, a reference is obtained on the opening task's -credentials and this is attached to the file struct as 'f_cred' in place of -'f_uid' and 'f_gid'. Code that used to access file->f_uid and file->f_gid -should now access file->f_cred->fsuid and file->f_cred->fsgid. - -It is safe to access f_cred without the use of RCU or locking because the -pointer will not change over the lifetime of the file struct, and nor will the -contents of the cred struct pointed to, barring the exceptions listed above -(see the Task Credentials section). - - -======================================= -OVERRIDING THE VFS'S USE OF CREDENTIALS -======================================= - -Under some circumstances it is desirable to override the credentials used by -the VFS, and that can be done by calling into such as vfs_mkdir() with a -different set of credentials. This is done in the following places: - - (*) sys_faccessat(). - - (*) do_coredump(). - - (*) nfs4recover.c. diff --git a/Documentation/filesystems/nfs/idmapper.txt b/Documentation/filesystems/nfs/idmapper.txt index b9b4192ea8b5..9c8fd6148656 100644 --- a/Documentation/filesystems/nfs/idmapper.txt +++ b/Documentation/filesystems/nfs/idmapper.txt @@ -47,8 +47,8 @@ request-key will find the first matching line and corresponding program. In this case, /some/other/program will handle all uid lookups and /usr/sbin/nfs.idmap will handle gid, user, and group lookups. -See for more information about the -request-key function. +See for more information +about the request-key function. ========= diff --git a/Documentation/keys-request-key.txt b/Documentation/keys-request-key.txt deleted file mode 100644 index 69686ad12c66..000000000000 --- a/Documentation/keys-request-key.txt +++ /dev/null @@ -1,202 +0,0 @@ - =================== - KEY REQUEST SERVICE - =================== - -The key request service is part of the key retention service (refer to -Documentation/keys.txt). This document explains more fully how the requesting -algorithm works. - -The process starts by either the kernel requesting a service by calling -request_key*(): - - struct key *request_key(const struct key_type *type, - const char *description, - const char *callout_info); - -or: - - struct key *request_key_with_auxdata(const struct key_type *type, - const char *description, - const char *callout_info, - size_t callout_len, - void *aux); - -or: - - struct key *request_key_async(const struct key_type *type, - const char *description, - const char *callout_info, - size_t callout_len); - -or: - - struct key *request_key_async_with_auxdata(const struct key_type *type, - const char *description, - const char *callout_info, - size_t callout_len, - void *aux); - -Or by userspace invoking the request_key system call: - - key_serial_t request_key(const char *type, - const char *description, - const char *callout_info, - key_serial_t dest_keyring); - -The main difference between the access points is that the in-kernel interface -does not need to link the key to a keyring to prevent it from being immediately -destroyed. The kernel interface returns a pointer directly to the key, and -it's up to the caller to destroy the key. - -The request_key*_with_auxdata() calls are like the in-kernel request_key*() -calls, except that they permit auxiliary data to be passed to the upcaller (the -default is NULL). This is only useful for those key types that define their -own upcall mechanism rather than using /sbin/request-key. - -The two async in-kernel calls may return keys that are still in the process of -being constructed. The two non-async ones will wait for construction to -complete first. - -The userspace interface links the key to a keyring associated with the process -to prevent the key from going away, and returns the serial number of the key to -the caller. - - -The following example assumes that the key types involved don't define their -own upcall mechanisms. If they do, then those should be substituted for the -forking and execution of /sbin/request-key. - - -=========== -THE PROCESS -=========== - -A request proceeds in the following manner: - - (1) Process A calls request_key() [the userspace syscall calls the kernel - interface]. - - (2) request_key() searches the process's subscribed keyrings to see if there's - a suitable key there. If there is, it returns the key. If there isn't, - and callout_info is not set, an error is returned. Otherwise the process - proceeds to the next step. - - (3) request_key() sees that A doesn't have the desired key yet, so it creates - two things: - - (a) An uninstantiated key U of requested type and description. - - (b) An authorisation key V that refers to key U and notes that process A - is the context in which key U should be instantiated and secured, and - from which associated key requests may be satisfied. - - (4) request_key() then forks and executes /sbin/request-key with a new session - keyring that contains a link to auth key V. - - (5) /sbin/request-key assumes the authority associated with key U. - - (6) /sbin/request-key execs an appropriate program to perform the actual - instantiation. - - (7) The program may want to access another key from A's context (say a - Kerberos TGT key). It just requests the appropriate key, and the keyring - search notes that the session keyring has auth key V in its bottom level. - - This will permit it to then search the keyrings of process A with the - UID, GID, groups and security info of process A as if it was process A, - and come up with key W. - - (8) The program then does what it must to get the data with which to - instantiate key U, using key W as a reference (perhaps it contacts a - Kerberos server using the TGT) and then instantiates key U. - - (9) Upon instantiating key U, auth key V is automatically revoked so that it - may not be used again. - -(10) The program then exits 0 and request_key() deletes key V and returns key - U to the caller. - -This also extends further. If key W (step 7 above) didn't exist, key W would -be created uninstantiated, another auth key (X) would be created (as per step -3) and another copy of /sbin/request-key spawned (as per step 4); but the -context specified by auth key X will still be process A, as it was in auth key -V. - -This is because process A's keyrings can't simply be attached to -/sbin/request-key at the appropriate places because (a) execve will discard two -of them, and (b) it requires the same UID/GID/Groups all the way through. - - -==================================== -NEGATIVE INSTANTIATION AND REJECTION -==================================== - -Rather than instantiating a key, it is possible for the possessor of an -authorisation key to negatively instantiate a key that's under construction. -This is a short duration placeholder that causes any attempt at re-requesting -the key whilst it exists to fail with error ENOKEY if negated or the specified -error if rejected. - -This is provided to prevent excessive repeated spawning of /sbin/request-key -processes for a key that will never be obtainable. - -Should the /sbin/request-key process exit anything other than 0 or die on a -signal, the key under construction will be automatically negatively -instantiated for a short amount of time. - - -==================== -THE SEARCH ALGORITHM -==================== - -A search of any particular keyring proceeds in the following fashion: - - (1) When the key management code searches for a key (keyring_search_aux) it - firstly calls key_permission(SEARCH) on the keyring it's starting with, - if this denies permission, it doesn't search further. - - (2) It considers all the non-keyring keys within that keyring and, if any key - matches the criteria specified, calls key_permission(SEARCH) on it to see - if the key is allowed to be found. If it is, that key is returned; if - not, the search continues, and the error code is retained if of higher - priority than the one currently set. - - (3) It then considers all the keyring-type keys in the keyring it's currently - searching. It calls key_permission(SEARCH) on each keyring, and if this - grants permission, it recurses, executing steps (2) and (3) on that - keyring. - -The process stops immediately a valid key is found with permission granted to -use it. Any error from a previous match attempt is discarded and the key is -returned. - -When search_process_keyrings() is invoked, it performs the following searches -until one succeeds: - - (1) If extant, the process's thread keyring is searched. - - (2) If extant, the process's process keyring is searched. - - (3) The process's session keyring is searched. - - (4) If the process has assumed the authority associated with a request_key() - authorisation key then: - - (a) If extant, the calling process's thread keyring is searched. - - (b) If extant, the calling process's process keyring is searched. - - (c) The calling process's session keyring is searched. - -The moment one succeeds, all pending errors are discarded and the found key is -returned. - -Only if all these fail does the whole thing fail with the highest priority -error. Note that several errors may have come from LSM. - -The error priority is: - - EKEYREVOKED > EKEYEXPIRED > ENOKEY - -EACCES/EPERM are only returned on a direct search of a specific keyring where -the basal keyring does not grant Search permission. diff --git a/Documentation/keys-trusted-encrypted.txt b/Documentation/keys-trusted-encrypted.txt deleted file mode 100644 index 8fb79bc1ac4b..000000000000 --- a/Documentation/keys-trusted-encrypted.txt +++ /dev/null @@ -1,145 +0,0 @@ - Trusted and Encrypted Keys - -Trusted and Encrypted Keys are two new key types added to the existing kernel -key ring service. Both of these new types are variable length symmetic keys, -and in both cases all keys are created in the kernel, and user space sees, -stores, and loads only encrypted blobs. Trusted Keys require the availability -of a Trusted Platform Module (TPM) chip for greater security, while Encrypted -Keys can be used on any system. All user level blobs, are displayed and loaded -in hex ascii for convenience, and are integrity verified. - -Trusted Keys use a TPM both to generate and to seal the keys. Keys are sealed -under a 2048 bit RSA key in the TPM, and optionally sealed to specified PCR -(integrity measurement) values, and only unsealed by the TPM, if PCRs and blob -integrity verifications match. A loaded Trusted Key can be updated with new -(future) PCR values, so keys are easily migrated to new pcr values, such as -when the kernel and initramfs are updated. The same key can have many saved -blobs under different PCR values, so multiple boots are easily supported. - -By default, trusted keys are sealed under the SRK, which has the default -authorization value (20 zeros). This can be set at takeownership time with the -trouser's utility: "tpm_takeownership -u -z". - -Usage: - keyctl add trusted name "new keylen [options]" ring - keyctl add trusted name "load hex_blob [pcrlock=pcrnum]" ring - keyctl update key "update [options]" - keyctl print keyid - - options: - keyhandle= ascii hex value of sealing key default 0x40000000 (SRK) - keyauth= ascii hex auth for sealing key default 0x00...i - (40 ascii zeros) - blobauth= ascii hex auth for sealed data default 0x00... - (40 ascii zeros) - blobauth= ascii hex auth for sealed data default 0x00... - (40 ascii zeros) - pcrinfo= ascii hex of PCR_INFO or PCR_INFO_LONG (no default) - pcrlock= pcr number to be extended to "lock" blob - migratable= 0|1 indicating permission to reseal to new PCR values, - default 1 (resealing allowed) - -"keyctl print" returns an ascii hex copy of the sealed key, which is in standard -TPM_STORED_DATA format. The key length for new keys are always in bytes. -Trusted Keys can be 32 - 128 bytes (256 - 1024 bits), the upper limit is to fit -within the 2048 bit SRK (RSA) keylength, with all necessary structure/padding. - -Encrypted keys do not depend on a TPM, and are faster, as they use AES for -encryption/decryption. New keys are created from kernel generated random -numbers, and are encrypted/decrypted using a specified 'master' key. The -'master' key can either be a trusted-key or user-key type. The main -disadvantage of encrypted keys is that if they are not rooted in a trusted key, -they are only as secure as the user key encrypting them. The master user key -should therefore be loaded in as secure a way as possible, preferably early in -boot. - -Usage: - keyctl add encrypted name "new key-type:master-key-name keylen" ring - keyctl add encrypted name "load hex_blob" ring - keyctl update keyid "update key-type:master-key-name" - -where 'key-type' is either 'trusted' or 'user'. - -Examples of trusted and encrypted key usage: - -Create and save a trusted key named "kmk" of length 32 bytes: - - $ keyctl add trusted kmk "new 32" @u - 440502848 - - $ keyctl show - Session Keyring - -3 --alswrv 500 500 keyring: _ses - 97833714 --alswrv 500 -1 \_ keyring: _uid.500 - 440502848 --alswrv 500 500 \_ trusted: kmk - - $ keyctl print 440502848 - 0101000000000000000001005d01b7e3f4a6be5709930f3b70a743cbb42e0cc95e18e915 - 3f60da455bbf1144ad12e4f92b452f966929f6105fd29ca28e4d4d5a031d068478bacb0b - 27351119f822911b0a11ba3d3498ba6a32e50dac7f32894dd890eb9ad578e4e292c83722 - a52e56a097e6a68b3f56f7a52ece0cdccba1eb62cad7d817f6dc58898b3ac15f36026fec - d568bd4a706cb60bb37be6d8f1240661199d640b66fb0fe3b079f97f450b9ef9c22c6d5d - dd379f0facd1cd020281dfa3c70ba21a3fa6fc2471dc6d13ecf8298b946f65345faa5ef0 - f1f8fff03ad0acb083725535636addb08d73dedb9832da198081e5deae84bfaf0409c22b - e4a8aea2b607ec96931e6f4d4fe563ba - - $ keyctl pipe 440502848 > kmk.blob - -Load a trusted key from the saved blob: - - $ keyctl add trusted kmk "load `cat kmk.blob`" @u - 268728824 - - $ keyctl print 268728824 - 0101000000000000000001005d01b7e3f4a6be5709930f3b70a743cbb42e0cc95e18e915 - 3f60da455bbf1144ad12e4f92b452f966929f6105fd29ca28e4d4d5a031d068478bacb0b - 27351119f822911b0a11ba3d3498ba6a32e50dac7f32894dd890eb9ad578e4e292c83722 - a52e56a097e6a68b3f56f7a52ece0cdccba1eb62cad7d817f6dc58898b3ac15f36026fec - d568bd4a706cb60bb37be6d8f1240661199d640b66fb0fe3b079f97f450b9ef9c22c6d5d - dd379f0facd1cd020281dfa3c70ba21a3fa6fc2471dc6d13ecf8298b946f65345faa5ef0 - f1f8fff03ad0acb083725535636addb08d73dedb9832da198081e5deae84bfaf0409c22b - e4a8aea2b607ec96931e6f4d4fe563ba - -Reseal a trusted key under new pcr values: - - $ keyctl update 268728824 "update pcrinfo=`cat pcr.blob`" - $ keyctl print 268728824 - 010100000000002c0002800093c35a09b70fff26e7a98ae786c641e678ec6ffb6b46d805 - 77c8a6377aed9d3219c6dfec4b23ffe3000001005d37d472ac8a44023fbb3d18583a4f73 - d3a076c0858f6f1dcaa39ea0f119911ff03f5406df4f7f27f41da8d7194f45c9f4e00f2e - df449f266253aa3f52e55c53de147773e00f0f9aca86c64d94c95382265968c354c5eab4 - 9638c5ae99c89de1e0997242edfb0b501744e11ff9762dfd951cffd93227cc513384e7e6 - e782c29435c7ec2edafaa2f4c1fe6e7a781b59549ff5296371b42133777dcc5b8b971610 - 94bc67ede19e43ddb9dc2baacad374a36feaf0314d700af0a65c164b7082401740e489c9 - 7ef6a24defe4846104209bf0c3eced7fa1a672ed5b125fc9d8cd88b476a658a4434644ef - df8ae9a178e9f83ba9f08d10fa47e4226b98b0702f06b3b8 - -Create and save an encrypted key "evm" using the above trusted key "kmk": - - $ keyctl add encrypted evm "new trusted:kmk 32" @u - 159771175 - - $ keyctl print 159771175 - trusted:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b382dbbc55 - be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e024717c64 - 5972dcb82ab2dde83376d82b2e3c09ffc - - $ keyctl pipe 159771175 > evm.blob - -Load an encrypted key "evm" from saved blob: - - $ keyctl add encrypted evm "load `cat evm.blob`" @u - 831684262 - - $ keyctl print 831684262 - trusted:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b382dbbc55 - be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e024717c64 - 5972dcb82ab2dde83376d82b2e3c09ffc - - -The initial consumer of trusted keys is EVM, which at boot time needs a high -quality symmetric key for HMAC protection of file metadata. The use of a -trusted key provides strong guarantees that the EVM key has not been -compromised by a user level problem, and when sealed to specific boot PCR -values, protects against boot and offline attacks. Other uses for trusted and -encrypted keys, such as for disk and file encryption are anticipated. diff --git a/Documentation/keys.txt b/Documentation/keys.txt deleted file mode 100644 index 6523a9e6f293..000000000000 --- a/Documentation/keys.txt +++ /dev/null @@ -1,1290 +0,0 @@ - ============================ - KERNEL KEY RETENTION SERVICE - ============================ - -This service allows cryptographic keys, authentication tokens, cross-domain -user mappings, and similar to be cached in the kernel for the use of -filesystems and other kernel services. - -Keyrings are permitted; these are a special type of key that can hold links to -other keys. Processes each have three standard keyring subscriptions that a -kernel service can search for relevant keys. - -The key service can be configured on by enabling: - - "Security options"/"Enable access key retention support" (CONFIG_KEYS) - -This document has the following sections: - - - Key overview - - Key service overview - - Key access permissions - - SELinux support - - New procfs files - - Userspace system call interface - - Kernel services - - Notes on accessing payload contents - - Defining a key type - - Request-key callback service - - Garbage collection - - -============ -KEY OVERVIEW -============ - -In this context, keys represent units of cryptographic data, authentication -tokens, keyrings, etc.. These are represented in the kernel by struct key. - -Each key has a number of attributes: - - - A serial number. - - A type. - - A description (for matching a key in a search). - - Access control information. - - An expiry time. - - A payload. - - State. - - - (*) Each key is issued a serial number of type key_serial_t that is unique for - the lifetime of that key. All serial numbers are positive non-zero 32-bit - integers. - - Userspace programs can use a key's serial numbers as a way to gain access - to it, subject to permission checking. - - (*) Each key is of a defined "type". Types must be registered inside the - kernel by a kernel service (such as a filesystem) before keys of that type - can be added or used. Userspace programs cannot define new types directly. - - Key types are represented in the kernel by struct key_type. This defines a - number of operations that can be performed on a key of that type. - - Should a type be removed from the system, all the keys of that type will - be invalidated. - - (*) Each key has a description. This should be a printable string. The key - type provides an operation to perform a match between the description on a - key and a criterion string. - - (*) Each key has an owner user ID, a group ID and a permissions mask. These - are used to control what a process may do to a key from userspace, and - whether a kernel service will be able to find the key. - - (*) Each key can be set to expire at a specific time by the key type's - instantiation function. Keys can also be immortal. - - (*) Each key can have a payload. This is a quantity of data that represent the - actual "key". In the case of a keyring, this is a list of keys to which - the keyring links; in the case of a user-defined key, it's an arbitrary - blob of data. - - Having a payload is not required; and the payload can, in fact, just be a - value stored in the struct key itself. - - When a key is instantiated, the key type's instantiation function is - called with a blob of data, and that then creates the key's payload in - some way. - - Similarly, when userspace wants to read back the contents of the key, if - permitted, another key type operation will be called to convert the key's - attached payload back into a blob of data. - - (*) Each key can be in one of a number of basic states: - - (*) Uninstantiated. The key exists, but does not have any data attached. - Keys being requested from userspace will be in this state. - - (*) Instantiated. This is the normal state. The key is fully formed, and - has data attached. - - (*) Negative. This is a relatively short-lived state. The key acts as a - note saying that a previous call out to userspace failed, and acts as - a throttle on key lookups. A negative key can be updated to a normal - state. - - (*) Expired. Keys can have lifetimes set. If their lifetime is exceeded, - they traverse to this state. An expired key can be updated back to a - normal state. - - (*) Revoked. A key is put in this state by userspace action. It can't be - found or operated upon (apart from by unlinking it). - - (*) Dead. The key's type was unregistered, and so the key is now useless. - -Keys in the last three states are subject to garbage collection. See the -section on "Garbage collection". - - -==================== -KEY SERVICE OVERVIEW -==================== - -The key service provides a number of features besides keys: - - (*) The key service defines two special key types: - - (+) "keyring" - - Keyrings are special keys that contain a list of other keys. Keyring - lists can be modified using various system calls. Keyrings should not - be given a payload when created. - - (+) "user" - - A key of this type has a description and a payload that are arbitrary - blobs of data. These can be created, updated and read by userspace, - and aren't intended for use by kernel services. - - (*) Each process subscribes to three keyrings: a thread-specific keyring, a - process-specific keyring, and a session-specific keyring. - - The thread-specific keyring is discarded from the child when any sort of - clone, fork, vfork or execve occurs. A new keyring is created only when - required. - - The process-specific keyring is replaced with an empty one in the child on - clone, fork, vfork unless CLONE_THREAD is supplied, in which case it is - shared. execve also discards the process's process keyring and creates a - new one. - - The session-specific keyring is persistent across clone, fork, vfork and - execve, even when the latter executes a set-UID or set-GID binary. A - process can, however, replace its current session keyring with a new one - by using PR_JOIN_SESSION_KEYRING. It is permitted to request an anonymous - new one, or to attempt to create or join one of a specific name. - - The ownership of the thread keyring changes when the real UID and GID of - the thread changes. - - (*) Each user ID resident in the system holds two special keyrings: a user - specific keyring and a default user session keyring. The default session - keyring is initialised with a link to the user-specific keyring. - - When a process changes its real UID, if it used to have no session key, it - will be subscribed to the default session key for the new UID. - - If a process attempts to access its session key when it doesn't have one, - it will be subscribed to the default for its current UID. - - (*) Each user has two quotas against which the keys they own are tracked. One - limits the total number of keys and keyrings, the other limits the total - amount of description and payload space that can be consumed. - - The user can view information on this and other statistics through procfs - files. The root user may also alter the quota limits through sysctl files - (see the section "New procfs files"). - - Process-specific and thread-specific keyrings are not counted towards a - user's quota. - - If a system call that modifies a key or keyring in some way would put the - user over quota, the operation is refused and error EDQUOT is returned. - - (*) There's a system call interface by which userspace programs can create and - manipulate keys and keyrings. - - (*) There's a kernel interface by which services can register types and search - for keys. - - (*) There's a way for the a search done from the kernel to call back to - userspace to request a key that can't be found in a process's keyrings. - - (*) An optional filesystem is available through which the key database can be - viewed and manipulated. - - -====================== -KEY ACCESS PERMISSIONS -====================== - -Keys have an owner user ID, a group access ID, and a permissions mask. The mask -has up to eight bits each for possessor, user, group and other access. Only -six of each set of eight bits are defined. These permissions granted are: - - (*) View - - This permits a key or keyring's attributes to be viewed - including key - type and description. - - (*) Read - - This permits a key's payload to be viewed or a keyring's list of linked - keys. - - (*) Write - - This permits a key's payload to be instantiated or updated, or it allows a - link to be added to or removed from a keyring. - - (*) Search - - This permits keyrings to be searched and keys to be found. Searches can - only recurse into nested keyrings that have search permission set. - - (*) Link - - This permits a key or keyring to be linked to. To create a link from a - keyring to a key, a process must have Write permission on the keyring and - Link permission on the key. - - (*) Set Attribute - - This permits a key's UID, GID and permissions mask to be changed. - -For changing the ownership, group ID or permissions mask, being the owner of -the key or having the sysadmin capability is sufficient. - - -=============== -SELINUX SUPPORT -=============== - -The security class "key" has been added to SELinux so that mandatory access -controls can be applied to keys created within various contexts. This support -is preliminary, and is likely to change quite significantly in the near future. -Currently, all of the basic permissions explained above are provided in SELinux -as well; SELinux is simply invoked after all basic permission checks have been -performed. - -The value of the file /proc/self/attr/keycreate influences the labeling of -newly-created keys. If the contents of that file correspond to an SELinux -security context, then the key will be assigned that context. Otherwise, the -key will be assigned the current context of the task that invoked the key -creation request. Tasks must be granted explicit permission to assign a -particular context to newly-created keys, using the "create" permission in the -key security class. - -The default keyrings associated with users will be labeled with the default -context of the user if and only if the login programs have been instrumented to -properly initialize keycreate during the login process. Otherwise, they will -be labeled with the context of the login program itself. - -Note, however, that the default keyrings associated with the root user are -labeled with the default kernel context, since they are created early in the -boot process, before root has a chance to log in. - -The keyrings associated with new threads are each labeled with the context of -their associated thread, and both session and process keyrings are handled -similarly. - - -================ -NEW PROCFS FILES -================ - -Two files have been added to procfs by which an administrator can find out -about the status of the key service: - - (*) /proc/keys - - This lists the keys that are currently viewable by the task reading the - file, giving information about their type, description and permissions. - It is not possible to view the payload of the key this way, though some - information about it may be given. - - The only keys included in the list are those that grant View permission to - the reading process whether or not it possesses them. Note that LSM - security checks are still performed, and may further filter out keys that - the current process is not authorised to view. - - The contents of the file look like this: - - SERIAL FLAGS USAGE EXPY PERM UID GID TYPE DESCRIPTION: SUMMARY - 00000001 I----- 39 perm 1f3f0000 0 0 keyring _uid_ses.0: 1/4 - 00000002 I----- 2 perm 1f3f0000 0 0 keyring _uid.0: empty - 00000007 I----- 1 perm 1f3f0000 0 0 keyring _pid.1: empty - 0000018d I----- 1 perm 1f3f0000 0 0 keyring _pid.412: empty - 000004d2 I--Q-- 1 perm 1f3f0000 32 -1 keyring _uid.32: 1/4 - 000004d3 I--Q-- 3 perm 1f3f0000 32 -1 keyring _uid_ses.32: empty - 00000892 I--QU- 1 perm 1f000000 0 0 user metal:copper: 0 - 00000893 I--Q-N 1 35s 1f3f0000 0 0 user metal:silver: 0 - 00000894 I--Q-- 1 10h 003f0000 0 0 user metal:gold: 0 - - The flags are: - - I Instantiated - R Revoked - D Dead - Q Contributes to user's quota - U Under construction by callback to userspace - N Negative key - - This file must be enabled at kernel configuration time as it allows anyone - to list the keys database. - - (*) /proc/key-users - - This file lists the tracking data for each user that has at least one key - on the system. Such data includes quota information and statistics: - - [root@andromeda root]# cat /proc/key-users - 0: 46 45/45 1/100 13/10000 - 29: 2 2/2 2/100 40/10000 - 32: 2 2/2 2/100 40/10000 - 38: 2 2/2 2/100 40/10000 - - The format of each line is - : User ID to which this applies - Structure refcount - / Total number of keys and number instantiated - / Key count quota - / Key size quota - - -Four new sysctl files have been added also for the purpose of controlling the -quota limits on keys: - - (*) /proc/sys/kernel/keys/root_maxkeys - /proc/sys/kernel/keys/root_maxbytes - - These files hold the maximum number of keys that root may have and the - maximum total number of bytes of data that root may have stored in those - keys. - - (*) /proc/sys/kernel/keys/maxkeys - /proc/sys/kernel/keys/maxbytes - - These files hold the maximum number of keys that each non-root user may - have and the maximum total number of bytes of data that each of those - users may have stored in their keys. - -Root may alter these by writing each new limit as a decimal number string to -the appropriate file. - - -=============================== -USERSPACE SYSTEM CALL INTERFACE -=============================== - -Userspace can manipulate keys directly through three new syscalls: add_key, -request_key and keyctl. The latter provides a number of functions for -manipulating keys. - -When referring to a key directly, userspace programs should use the key's -serial number (a positive 32-bit integer). However, there are some special -values available for referring to special keys and keyrings that relate to the -process making the call: - - CONSTANT VALUE KEY REFERENCED - ============================== ====== =========================== - KEY_SPEC_THREAD_KEYRING -1 thread-specific keyring - KEY_SPEC_PROCESS_KEYRING -2 process-specific keyring - KEY_SPEC_SESSION_KEYRING -3 session-specific keyring - KEY_SPEC_USER_KEYRING -4 UID-specific keyring - KEY_SPEC_USER_SESSION_KEYRING -5 UID-session keyring - KEY_SPEC_GROUP_KEYRING -6 GID-specific keyring - KEY_SPEC_REQKEY_AUTH_KEY -7 assumed request_key() - authorisation key - - -The main syscalls are: - - (*) Create a new key of given type, description and payload and add it to the - nominated keyring: - - key_serial_t add_key(const char *type, const char *desc, - const void *payload, size_t plen, - key_serial_t keyring); - - If a key of the same type and description as that proposed already exists - in the keyring, this will try to update it with the given payload, or it - will return error EEXIST if that function is not supported by the key - type. The process must also have permission to write to the key to be able - to update it. The new key will have all user permissions granted and no - group or third party permissions. - - Otherwise, this will attempt to create a new key of the specified type and - description, and to instantiate it with the supplied payload and attach it - to the keyring. In this case, an error will be generated if the process - does not have permission to write to the keyring. - - The payload is optional, and the pointer can be NULL if not required by - the type. The payload is plen in size, and plen can be zero for an empty - payload. - - A new keyring can be generated by setting type "keyring", the keyring name - as the description (or NULL) and setting the payload to NULL. - - User defined keys can be created by specifying type "user". It is - recommended that a user defined key's description by prefixed with a type - ID and a colon, such as "krb5tgt:" for a Kerberos 5 ticket granting - ticket. - - Any other type must have been registered with the kernel in advance by a - kernel service such as a filesystem. - - The ID of the new or updated key is returned if successful. - - - (*) Search the process's keyrings for a key, potentially calling out to - userspace to create it. - - key_serial_t request_key(const char *type, const char *description, - const char *callout_info, - key_serial_t dest_keyring); - - This function searches all the process's keyrings in the order thread, - process, session for a matching key. This works very much like - KEYCTL_SEARCH, including the optional attachment of the discovered key to - a keyring. - - If a key cannot be found, and if callout_info is not NULL, then - /sbin/request-key will be invoked in an attempt to obtain a key. The - callout_info string will be passed as an argument to the program. - - See also Documentation/keys-request-key.txt. - - -The keyctl syscall functions are: - - (*) Map a special key ID to a real key ID for this process: - - key_serial_t keyctl(KEYCTL_GET_KEYRING_ID, key_serial_t id, - int create); - - The special key specified by "id" is looked up (with the key being created - if necessary) and the ID of the key or keyring thus found is returned if - it exists. - - If the key does not yet exist, the key will be created if "create" is - non-zero; and the error ENOKEY will be returned if "create" is zero. - - - (*) Replace the session keyring this process subscribes to with a new one: - - key_serial_t keyctl(KEYCTL_JOIN_SESSION_KEYRING, const char *name); - - If name is NULL, an anonymous keyring is created attached to the process - as its session keyring, displacing the old session keyring. - - If name is not NULL, if a keyring of that name exists, the process - attempts to attach it as the session keyring, returning an error if that - is not permitted; otherwise a new keyring of that name is created and - attached as the session keyring. - - To attach to a named keyring, the keyring must have search permission for - the process's ownership. - - The ID of the new session keyring is returned if successful. - - - (*) Update the specified key: - - long keyctl(KEYCTL_UPDATE, key_serial_t key, const void *payload, - size_t plen); - - This will try to update the specified key with the given payload, or it - will return error EOPNOTSUPP if that function is not supported by the key - type. The process must also have permission to write to the key to be able - to update it. - - The payload is of length plen, and may be absent or empty as for - add_key(). - - - (*) Revoke a key: - - long keyctl(KEYCTL_REVOKE, key_serial_t key); - - This makes a key unavailable for further operations. Further attempts to - use the key will be met with error EKEYREVOKED, and the key will no longer - be findable. - - - (*) Change the ownership of a key: - - long keyctl(KEYCTL_CHOWN, key_serial_t key, uid_t uid, gid_t gid); - - This function permits a key's owner and group ID to be changed. Either one - of uid or gid can be set to -1 to suppress that change. - - Only the superuser can change a key's owner to something other than the - key's current owner. Similarly, only the superuser can change a key's - group ID to something other than the calling process's group ID or one of - its group list members. - - - (*) Change the permissions mask on a key: - - long keyctl(KEYCTL_SETPERM, key_serial_t key, key_perm_t perm); - - This function permits the owner of a key or the superuser to change the - permissions mask on a key. - - Only bits the available bits are permitted; if any other bits are set, - error EINVAL will be returned. - - - (*) Describe a key: - - long keyctl(KEYCTL_DESCRIBE, key_serial_t key, char *buffer, - size_t buflen); - - This function returns a summary of the key's attributes (but not its - payload data) as a string in the buffer provided. - - Unless there's an error, it always returns the amount of data it could - produce, even if that's too big for the buffer, but it won't copy more - than requested to userspace. If the buffer pointer is NULL then no copy - will take place. - - A process must have view permission on the key for this function to be - successful. - - If successful, a string is placed in the buffer in the following format: - - ;;;; - - Where type and description are strings, uid and gid are decimal, and perm - is hexadecimal. A NUL character is included at the end of the string if - the buffer is sufficiently big. - - This can be parsed with - - sscanf(buffer, "%[^;];%d;%d;%o;%s", type, &uid, &gid, &mode, desc); - - - (*) Clear out a keyring: - - long keyctl(KEYCTL_CLEAR, key_serial_t keyring); - - This function clears the list of keys attached to a keyring. The calling - process must have write permission on the keyring, and it must be a - keyring (or else error ENOTDIR will result). - - - (*) Link a key into a keyring: - - long keyctl(KEYCTL_LINK, key_serial_t keyring, key_serial_t key); - - This function creates a link from the keyring to the key. The process must - have write permission on the keyring and must have link permission on the - key. - - Should the keyring not be a keyring, error ENOTDIR will result; and if the - keyring is full, error ENFILE will result. - - The link procedure checks the nesting of the keyrings, returning ELOOP if - it appears too deep or EDEADLK if the link would introduce a cycle. - - Any links within the keyring to keys that match the new key in terms of - type and description will be discarded from the keyring as the new one is - added. - - - (*) Unlink a key or keyring from another keyring: - - long keyctl(KEYCTL_UNLINK, key_serial_t keyring, key_serial_t key); - - This function looks through the keyring for the first link to the - specified key, and removes it if found. Subsequent links to that key are - ignored. The process must have write permission on the keyring. - - If the keyring is not a keyring, error ENOTDIR will result; and if the key - is not present, error ENOENT will be the result. - - - (*) Search a keyring tree for a key: - - key_serial_t keyctl(KEYCTL_SEARCH, key_serial_t keyring, - const char *type, const char *description, - key_serial_t dest_keyring); - - This searches the keyring tree headed by the specified keyring until a key - is found that matches the type and description criteria. Each keyring is - checked for keys before recursion into its children occurs. - - The process must have search permission on the top level keyring, or else - error EACCES will result. Only keyrings that the process has search - permission on will be recursed into, and only keys and keyrings for which - a process has search permission can be matched. If the specified keyring - is not a keyring, ENOTDIR will result. - - If the search succeeds, the function will attempt to link the found key - into the destination keyring if one is supplied (non-zero ID). All the - constraints applicable to KEYCTL_LINK apply in this case too. - - Error ENOKEY, EKEYREVOKED or EKEYEXPIRED will be returned if the search - fails. On success, the resulting key ID will be returned. - - - (*) Read the payload data from a key: - - long keyctl(KEYCTL_READ, key_serial_t keyring, char *buffer, - size_t buflen); - - This function attempts to read the payload data from the specified key - into the buffer. The process must have read permission on the key to - succeed. - - The returned data will be processed for presentation by the key type. For - instance, a keyring will return an array of key_serial_t entries - representing the IDs of all the keys to which it is subscribed. The user - defined key type will return its data as is. If a key type does not - implement this function, error EOPNOTSUPP will result. - - As much of the data as can be fitted into the buffer will be copied to - userspace if the buffer pointer is not NULL. - - On a successful return, the function will always return the amount of data - available rather than the amount copied. - - - (*) Instantiate a partially constructed key. - - long keyctl(KEYCTL_INSTANTIATE, key_serial_t key, - const void *payload, size_t plen, - key_serial_t keyring); - long keyctl(KEYCTL_INSTANTIATE_IOV, key_serial_t key, - const struct iovec *payload_iov, unsigned ioc, - key_serial_t keyring); - - If the kernel calls back to userspace to complete the instantiation of a - key, userspace should use this call to supply data for the key before the - invoked process returns, or else the key will be marked negative - automatically. - - The process must have write access on the key to be able to instantiate - it, and the key must be uninstantiated. - - If a keyring is specified (non-zero), the key will also be linked into - that keyring, however all the constraints applying in KEYCTL_LINK apply in - this case too. - - The payload and plen arguments describe the payload data as for add_key(). - - The payload_iov and ioc arguments describe the payload data in an iovec - array instead of a single buffer. - - - (*) Negatively instantiate a partially constructed key. - - long keyctl(KEYCTL_NEGATE, key_serial_t key, - unsigned timeout, key_serial_t keyring); - long keyctl(KEYCTL_REJECT, key_serial_t key, - unsigned timeout, unsigned error, key_serial_t keyring); - - If the kernel calls back to userspace to complete the instantiation of a - key, userspace should use this call mark the key as negative before the - invoked process returns if it is unable to fulfil the request. - - The process must have write access on the key to be able to instantiate - it, and the key must be uninstantiated. - - If a keyring is specified (non-zero), the key will also be linked into - that keyring, however all the constraints applying in KEYCTL_LINK apply in - this case too. - - If the key is rejected, future searches for it will return the specified - error code until the rejected key expires. Negating the key is the same - as rejecting the key with ENOKEY as the error code. - - - (*) Set the default request-key destination keyring. - - long keyctl(KEYCTL_SET_REQKEY_KEYRING, int reqkey_defl); - - This sets the default keyring to which implicitly requested keys will be - attached for this thread. reqkey_defl should be one of these constants: - - CONSTANT VALUE NEW DEFAULT KEYRING - ====================================== ====== ======================= - KEY_REQKEY_DEFL_NO_CHANGE -1 No change - KEY_REQKEY_DEFL_DEFAULT 0 Default[1] - KEY_REQKEY_DEFL_THREAD_KEYRING 1 Thread keyring - KEY_REQKEY_DEFL_PROCESS_KEYRING 2 Process keyring - KEY_REQKEY_DEFL_SESSION_KEYRING 3 Session keyring - KEY_REQKEY_DEFL_USER_KEYRING 4 User keyring - KEY_REQKEY_DEFL_USER_SESSION_KEYRING 5 User session keyring - KEY_REQKEY_DEFL_GROUP_KEYRING 6 Group keyring - - The old default will be returned if successful and error EINVAL will be - returned if reqkey_defl is not one of the above values. - - The default keyring can be overridden by the keyring indicated to the - request_key() system call. - - Note that this setting is inherited across fork/exec. - - [1] The default is: the thread keyring if there is one, otherwise - the process keyring if there is one, otherwise the session keyring if - there is one, otherwise the user default session keyring. - - - (*) Set the timeout on a key. - - long keyctl(KEYCTL_SET_TIMEOUT, key_serial_t key, unsigned timeout); - - This sets or clears the timeout on a key. The timeout can be 0 to clear - the timeout or a number of seconds to set the expiry time that far into - the future. - - The process must have attribute modification access on a key to set its - timeout. Timeouts may not be set with this function on negative, revoked - or expired keys. - - - (*) Assume the authority granted to instantiate a key - - long keyctl(KEYCTL_ASSUME_AUTHORITY, key_serial_t key); - - This assumes or divests the authority required to instantiate the - specified key. Authority can only be assumed if the thread has the - authorisation key associated with the specified key in its keyrings - somewhere. - - Once authority is assumed, searches for keys will also search the - requester's keyrings using the requester's security label, UID, GID and - groups. - - If the requested authority is unavailable, error EPERM will be returned, - likewise if the authority has been revoked because the target key is - already instantiated. - - If the specified key is 0, then any assumed authority will be divested. - - The assumed authoritative key is inherited across fork and exec. - - - (*) Get the LSM security context attached to a key. - - long keyctl(KEYCTL_GET_SECURITY, key_serial_t key, char *buffer, - size_t buflen) - - This function returns a string that represents the LSM security context - attached to a key in the buffer provided. - - Unless there's an error, it always returns the amount of data it could - produce, even if that's too big for the buffer, but it won't copy more - than requested to userspace. If the buffer pointer is NULL then no copy - will take place. - - A NUL character is included at the end of the string if the buffer is - sufficiently big. This is included in the returned count. If no LSM is - in force then an empty string will be returned. - - A process must have view permission on the key for this function to be - successful. - - - (*) Install the calling process's session keyring on its parent. - - long keyctl(KEYCTL_SESSION_TO_PARENT); - - This functions attempts to install the calling process's session keyring - on to the calling process's parent, replacing the parent's current session - keyring. - - The calling process must have the same ownership as its parent, the - keyring must have the same ownership as the calling process, the calling - process must have LINK permission on the keyring and the active LSM module - mustn't deny permission, otherwise error EPERM will be returned. - - Error ENOMEM will be returned if there was insufficient memory to complete - the operation, otherwise 0 will be returned to indicate success. - - The keyring will be replaced next time the parent process leaves the - kernel and resumes executing userspace. - - -=============== -KERNEL SERVICES -=============== - -The kernel services for key management are fairly simple to deal with. They can -be broken down into two areas: keys and key types. - -Dealing with keys is fairly straightforward. Firstly, the kernel service -registers its type, then it searches for a key of that type. It should retain -the key as long as it has need of it, and then it should release it. For a -filesystem or device file, a search would probably be performed during the open -call, and the key released upon close. How to deal with conflicting keys due to -two different users opening the same file is left to the filesystem author to -solve. - -To access the key manager, the following header must be #included: - - - -Specific key types should have a header file under include/keys/ that should be -used to access that type. For keys of type "user", for example, that would be: - - - -Note that there are two different types of pointers to keys that may be -encountered: - - (*) struct key * - - This simply points to the key structure itself. Key structures will be at - least four-byte aligned. - - (*) key_ref_t - - This is equivalent to a struct key *, but the least significant bit is set - if the caller "possesses" the key. By "possession" it is meant that the - calling processes has a searchable link to the key from one of its - keyrings. There are three functions for dealing with these: - - key_ref_t make_key_ref(const struct key *key, - unsigned long possession); - - struct key *key_ref_to_ptr(const key_ref_t key_ref); - - unsigned long is_key_possessed(const key_ref_t key_ref); - - The first function constructs a key reference from a key pointer and - possession information (which must be 0 or 1 and not any other value). - - The second function retrieves the key pointer from a reference and the - third retrieves the possession flag. - -When accessing a key's payload contents, certain precautions must be taken to -prevent access vs modification races. See the section "Notes on accessing -payload contents" for more information. - -(*) To search for a key, call: - - struct key *request_key(const struct key_type *type, - const char *description, - const char *callout_info); - - This is used to request a key or keyring with a description that matches - the description specified according to the key type's match function. This - permits approximate matching to occur. If callout_string is not NULL, then - /sbin/request-key will be invoked in an attempt to obtain the key from - userspace. In that case, callout_string will be passed as an argument to - the program. - - Should the function fail error ENOKEY, EKEYEXPIRED or EKEYREVOKED will be - returned. - - If successful, the key will have been attached to the default keyring for - implicitly obtained request-key keys, as set by KEYCTL_SET_REQKEY_KEYRING. - - See also Documentation/keys-request-key.txt. - - -(*) To search for a key, passing auxiliary data to the upcaller, call: - - struct key *request_key_with_auxdata(const struct key_type *type, - const char *description, - const void *callout_info, - size_t callout_len, - void *aux); - - This is identical to request_key(), except that the auxiliary data is - passed to the key_type->request_key() op if it exists, and the callout_info - is a blob of length callout_len, if given (the length may be 0). - - -(*) A key can be requested asynchronously by calling one of: - - struct key *request_key_async(const struct key_type *type, - const char *description, - const void *callout_info, - size_t callout_len); - - or: - - struct key *request_key_async_with_auxdata(const struct key_type *type, - const char *description, - const char *callout_info, - size_t callout_len, - void *aux); - - which are asynchronous equivalents of request_key() and - request_key_with_auxdata() respectively. - - These two functions return with the key potentially still under - construction. To wait for construction completion, the following should be - called: - - int wait_for_key_construction(struct key *key, bool intr); - - The function will wait for the key to finish being constructed and then - invokes key_validate() to return an appropriate value to indicate the state - of the key (0 indicates the key is usable). - - If intr is true, then the wait can be interrupted by a signal, in which - case error ERESTARTSYS will be returned. - - -(*) When it is no longer required, the key should be released using: - - void key_put(struct key *key); - - Or: - - void key_ref_put(key_ref_t key_ref); - - These can be called from interrupt context. If CONFIG_KEYS is not set then - the argument will not be parsed. - - -(*) Extra references can be made to a key by calling the following function: - - struct key *key_get(struct key *key); - - These need to be disposed of by calling key_put() when they've been - finished with. The key pointer passed in will be returned. If the pointer - is NULL or CONFIG_KEYS is not set then the key will not be dereferenced and - no increment will take place. - - -(*) A key's serial number can be obtained by calling: - - key_serial_t key_serial(struct key *key); - - If key is NULL or if CONFIG_KEYS is not set then 0 will be returned (in the - latter case without parsing the argument). - - -(*) If a keyring was found in the search, this can be further searched by: - - key_ref_t keyring_search(key_ref_t keyring_ref, - const struct key_type *type, - const char *description) - - This searches the keyring tree specified for a matching key. Error ENOKEY - is returned upon failure (use IS_ERR/PTR_ERR to determine). If successful, - the returned key will need to be released. - - The possession attribute from the keyring reference is used to control - access through the permissions mask and is propagated to the returned key - reference pointer if successful. - - -(*) To check the validity of a key, this function can be called: - - int validate_key(struct key *key); - - This checks that the key in question hasn't expired or and hasn't been - revoked. Should the key be invalid, error EKEYEXPIRED or EKEYREVOKED will - be returned. If the key is NULL or if CONFIG_KEYS is not set then 0 will be - returned (in the latter case without parsing the argument). - - -(*) To register a key type, the following function should be called: - - int register_key_type(struct key_type *type); - - This will return error EEXIST if a type of the same name is already - present. - - -(*) To unregister a key type, call: - - void unregister_key_type(struct key_type *type); - - -Under some circumstances, it may be desirable to deal with a bundle of keys. -The facility provides access to the keyring type for managing such a bundle: - - struct key_type key_type_keyring; - -This can be used with a function such as request_key() to find a specific -keyring in a process's keyrings. A keyring thus found can then be searched -with keyring_search(). Note that it is not possible to use request_key() to -search a specific keyring, so using keyrings in this way is of limited utility. - - -=================================== -NOTES ON ACCESSING PAYLOAD CONTENTS -=================================== - -The simplest payload is just a number in key->payload.value. In this case, -there's no need to indulge in RCU or locking when accessing the payload. - -More complex payload contents must be allocated and a pointer to them set in -key->payload.data. One of the following ways must be selected to access the -data: - - (1) Unmodifiable key type. - - If the key type does not have a modify method, then the key's payload can - be accessed without any form of locking, provided that it's known to be - instantiated (uninstantiated keys cannot be "found"). - - (2) The key's semaphore. - - The semaphore could be used to govern access to the payload and to control - the payload pointer. It must be write-locked for modifications and would - have to be read-locked for general access. The disadvantage of doing this - is that the accessor may be required to sleep. - - (3) RCU. - - RCU must be used when the semaphore isn't already held; if the semaphore - is held then the contents can't change under you unexpectedly as the - semaphore must still be used to serialise modifications to the key. The - key management code takes care of this for the key type. - - However, this means using: - - rcu_read_lock() ... rcu_dereference() ... rcu_read_unlock() - - to read the pointer, and: - - rcu_dereference() ... rcu_assign_pointer() ... call_rcu() - - to set the pointer and dispose of the old contents after a grace period. - Note that only the key type should ever modify a key's payload. - - Furthermore, an RCU controlled payload must hold a struct rcu_head for the - use of call_rcu() and, if the payload is of variable size, the length of - the payload. key->datalen cannot be relied upon to be consistent with the - payload just dereferenced if the key's semaphore is not held. - - -=================== -DEFINING A KEY TYPE -=================== - -A kernel service may want to define its own key type. For instance, an AFS -filesystem might want to define a Kerberos 5 ticket key type. To do this, it -author fills in a key_type struct and registers it with the system. - -Source files that implement key types should include the following header file: - - - -The structure has a number of fields, some of which are mandatory: - - (*) const char *name - - The name of the key type. This is used to translate a key type name - supplied by userspace into a pointer to the structure. - - - (*) size_t def_datalen - - This is optional - it supplies the default payload data length as - contributed to the quota. If the key type's payload is always or almost - always the same size, then this is a more efficient way to do things. - - The data length (and quota) on a particular key can always be changed - during instantiation or update by calling: - - int key_payload_reserve(struct key *key, size_t datalen); - - With the revised data length. Error EDQUOT will be returned if this is not - viable. - - - (*) int (*vet_description)(const char *description); - - This optional method is called to vet a key description. If the key type - doesn't approve of the key description, it may return an error, otherwise - it should return 0. - - - (*) int (*instantiate)(struct key *key, const void *data, size_t datalen); - - This method is called to attach a payload to a key during construction. - The payload attached need not bear any relation to the data passed to this - function. - - If the amount of data attached to the key differs from the size in - keytype->def_datalen, then key_payload_reserve() should be called. - - This method does not have to lock the key in order to attach a payload. - The fact that KEY_FLAG_INSTANTIATED is not set in key->flags prevents - anything else from gaining access to the key. - - It is safe to sleep in this method. - - - (*) int (*update)(struct key *key, const void *data, size_t datalen); - - If this type of key can be updated, then this method should be provided. - It is called to update a key's payload from the blob of data provided. - - key_payload_reserve() should be called if the data length might change - before any changes are actually made. Note that if this succeeds, the type - is committed to changing the key because it's already been altered, so all - memory allocation must be done first. - - The key will have its semaphore write-locked before this method is called, - but this only deters other writers; any changes to the key's payload must - be made under RCU conditions, and call_rcu() must be used to dispose of - the old payload. - - key_payload_reserve() should be called before the changes are made, but - after all allocations and other potentially failing function calls are - made. - - It is safe to sleep in this method. - - - (*) int (*match)(const struct key *key, const void *desc); - - This method is called to match a key against a description. It should - return non-zero if the two match, zero if they don't. - - This method should not need to lock the key in any way. The type and - description can be considered invariant, and the payload should not be - accessed (the key may not yet be instantiated). - - It is not safe to sleep in this method; the caller may hold spinlocks. - - - (*) void (*revoke)(struct key *key); - - This method is optional. It is called to discard part of the payload - data upon a key being revoked. The caller will have the key semaphore - write-locked. - - It is safe to sleep in this method, though care should be taken to avoid - a deadlock against the key semaphore. - - - (*) void (*destroy)(struct key *key); - - This method is optional. It is called to discard the payload data on a key - when it is being destroyed. - - This method does not need to lock the key to access the payload; it can - consider the key as being inaccessible at this time. Note that the key's - type may have been changed before this function is called. - - It is not safe to sleep in this method; the caller may hold spinlocks. - - - (*) void (*describe)(const struct key *key, struct seq_file *p); - - This method is optional. It is called during /proc/keys reading to - summarise a key's description and payload in text form. - - This method will be called with the RCU read lock held. rcu_dereference() - should be used to read the payload pointer if the payload is to be - accessed. key->datalen cannot be trusted to stay consistent with the - contents of the payload. - - The description will not change, though the key's state may. - - It is not safe to sleep in this method; the RCU read lock is held by the - caller. - - - (*) long (*read)(const struct key *key, char __user *buffer, size_t buflen); - - This method is optional. It is called by KEYCTL_READ to translate the - key's payload into something a blob of data for userspace to deal with. - Ideally, the blob should be in the same format as that passed in to the - instantiate and update methods. - - If successful, the blob size that could be produced should be returned - rather than the size copied. - - This method will be called with the key's semaphore read-locked. This will - prevent the key's payload changing. It is not necessary to use RCU locking - when accessing the key's payload. It is safe to sleep in this method, such - as might happen when the userspace buffer is accessed. - - - (*) int (*request_key)(struct key_construction *cons, const char *op, - void *aux); - - This method is optional. If provided, request_key() and friends will - invoke this function rather than upcalling to /sbin/request-key to operate - upon a key of this type. - - The aux parameter is as passed to request_key_async_with_auxdata() and - similar or is NULL otherwise. Also passed are the construction record for - the key to be operated upon and the operation type (currently only - "create"). - - This method is permitted to return before the upcall is complete, but the - following function must be called under all circumstances to complete the - instantiation process, whether or not it succeeds, whether or not there's - an error: - - void complete_request_key(struct key_construction *cons, int error); - - The error parameter should be 0 on success, -ve on error. The - construction record is destroyed by this action and the authorisation key - will be revoked. If an error is indicated, the key under construction - will be negatively instantiated if it wasn't already instantiated. - - If this method returns an error, that error will be returned to the - caller of request_key*(). complete_request_key() must be called prior to - returning. - - The key under construction and the authorisation key can be found in the - key_construction struct pointed to by cons: - - (*) struct key *key; - - The key under construction. - - (*) struct key *authkey; - - The authorisation key. - - -============================ -REQUEST-KEY CALLBACK SERVICE -============================ - -To create a new key, the kernel will attempt to execute the following command -line: - - /sbin/request-key create \ - - - is the key being constructed, and the three keyrings are the process -keyrings from the process that caused the search to be issued. These are -included for two reasons: - - (1) There may be an authentication token in one of the keyrings that is - required to obtain the key, eg: a Kerberos Ticket-Granting Ticket. - - (2) The new key should probably be cached in one of these rings. - -This program should set it UID and GID to those specified before attempting to -access any more keys. It may then look around for a user specific process to -hand the request off to (perhaps a path held in placed in another key by, for -example, the KDE desktop manager). - -The program (or whatever it calls) should finish construction of the key by -calling KEYCTL_INSTANTIATE or KEYCTL_INSTANTIATE_IOV, which also permits it to -cache the key in one of the keyrings (probably the session ring) before -returning. Alternatively, the key can be marked as negative with KEYCTL_NEGATE -or KEYCTL_REJECT; this also permits the key to be cached in one of the -keyrings. - -If it returns with the key remaining in the unconstructed state, the key will -be marked as being negative, it will be added to the session keyring, and an -error will be returned to the key requestor. - -Supplementary information may be provided from whoever or whatever invoked this -service. This will be passed as the parameter. If no such -information was made available, then "-" will be passed as this parameter -instead. - - -Similarly, the kernel may attempt to update an expired or a soon to expire key -by executing: - - /sbin/request-key update \ - - -In this case, the program isn't required to actually attach the key to a ring; -the rings are provided for reference. - - -================== -GARBAGE COLLECTION -================== - -Dead keys (for which the type has been removed) will be automatically unlinked -from those keyrings that point to them and deleted as soon as possible by a -background garbage collector. - -Similarly, revoked and expired keys will be garbage collected, but only after a -certain amount of time has passed. This time is set as a number of seconds in: - - /proc/sys/kernel/keys/gc_delay diff --git a/Documentation/networking/dns_resolver.txt b/Documentation/networking/dns_resolver.txt index 04ca06325b08..7f531ad83285 100644 --- a/Documentation/networking/dns_resolver.txt +++ b/Documentation/networking/dns_resolver.txt @@ -139,8 +139,8 @@ the key will be discarded and recreated when the data it holds has expired. dns_query() returns a copy of the value attached to the key, or an error if that is indicated instead. -See for further information about -request-key function. +See for further +information about request-key function. ========= diff --git a/Documentation/security/00-INDEX b/Documentation/security/00-INDEX new file mode 100644 index 000000000000..19bc49439cac --- /dev/null +++ b/Documentation/security/00-INDEX @@ -0,0 +1,18 @@ +00-INDEX + - this file. +SELinux.txt + - how to get started with the SELinux security enhancement. +Smack.txt + - documentation on the Smack Linux Security Module. +apparmor.txt + - documentation on the AppArmor security extension. +credentials.txt + - documentation about credentials in Linux. +keys-request-key.txt + - description of the kernel key request service. +keys-trusted-encrypted.txt + - info on the Trusted and Encrypted keys in the kernel key ring service. +keys.txt + - description of the kernel key retention service. +tomoyo.txt + - documentation on the TOMOYO Linux Security Module. diff --git a/Documentation/security/SELinux.txt b/Documentation/security/SELinux.txt new file mode 100644 index 000000000000..07eae00f3314 --- /dev/null +++ b/Documentation/security/SELinux.txt @@ -0,0 +1,27 @@ +If you want to use SELinux, chances are you will want +to use the distro-provided policies, or install the +latest reference policy release from + http://oss.tresys.com/projects/refpolicy + +However, if you want to install a dummy policy for +testing, you can do using 'mdp' provided under +scripts/selinux. Note that this requires the selinux +userspace to be installed - in particular you will +need checkpolicy to compile a kernel, and setfiles and +fixfiles to label the filesystem. + + 1. Compile the kernel with selinux enabled. + 2. Type 'make' to compile mdp. + 3. Make sure that you are not running with + SELinux enabled and a real policy. If + you are, reboot with selinux disabled + before continuing. + 4. Run install_policy.sh: + cd scripts/selinux + sh install_policy.sh + +Step 4 will create a new dummy policy valid for your +kernel, with a single selinux user, role, and type. +It will compile the policy, will set your SELINUXTYPE to +dummy in /etc/selinux/config, install the compiled policy +as 'dummy', and relabel your filesystem. diff --git a/Documentation/security/Smack.txt b/Documentation/security/Smack.txt new file mode 100644 index 000000000000..e9dab41c0fe0 --- /dev/null +++ b/Documentation/security/Smack.txt @@ -0,0 +1,541 @@ + + + "Good for you, you've decided to clean the elevator!" + - The Elevator, from Dark Star + +Smack is the the Simplified Mandatory Access Control Kernel. +Smack is a kernel based implementation of mandatory access +control that includes simplicity in its primary design goals. + +Smack is not the only Mandatory Access Control scheme +available for Linux. Those new to Mandatory Access Control +are encouraged to compare Smack with the other mechanisms +available to determine which is best suited to the problem +at hand. + +Smack consists of three major components: + - The kernel + - A start-up script and a few modified applications + - Configuration data + +The kernel component of Smack is implemented as a Linux +Security Modules (LSM) module. It requires netlabel and +works best with file systems that support extended attributes, +although xattr support is not strictly required. +It is safe to run a Smack kernel under a "vanilla" distribution. +Smack kernels use the CIPSO IP option. Some network +configurations are intolerant of IP options and can impede +access to systems that use them as Smack does. + +The startup script etc-init.d-smack should be installed +in /etc/init.d/smack and should be invoked early in the +start-up process. On Fedora rc5.d/S02smack is recommended. +This script ensures that certain devices have the correct +Smack attributes and loads the Smack configuration if +any is defined. This script invokes two programs that +ensure configuration data is properly formatted. These +programs are /usr/sbin/smackload and /usr/sin/smackcipso. +The system will run just fine without these programs, +but it will be difficult to set access rules properly. + +A version of "ls" that provides a "-M" option to display +Smack labels on long listing is available. + +A hacked version of sshd that allows network logins by users +with specific Smack labels is available. This version does +not work for scp. You must set the /etc/ssh/sshd_config +line: + UsePrivilegeSeparation no + +The format of /etc/smack/usr is: + + username smack + +In keeping with the intent of Smack, configuration data is +minimal and not strictly required. The most important +configuration step is mounting the smackfs pseudo filesystem. + +Add this line to /etc/fstab: + + smackfs /smack smackfs smackfsdef=* 0 0 + +and create the /smack directory for mounting. + +Smack uses extended attributes (xattrs) to store file labels. +The command to set a Smack label on a file is: + + # attr -S -s SMACK64 -V "value" path + +NOTE: Smack labels are limited to 23 characters. The attr command + does not enforce this restriction and can be used to set + invalid Smack labels on files. + +If you don't do anything special all users will get the floor ("_") +label when they log in. If you do want to log in via the hacked ssh +at other labels use the attr command to set the smack value on the +home directory and its contents. + +You can add access rules in /etc/smack/accesses. They take the form: + + subjectlabel objectlabel access + +access is a combination of the letters rwxa which specify the +kind of access permitted a subject with subjectlabel on an +object with objectlabel. If there is no rule no access is allowed. + +A process can see the smack label it is running with by +reading /proc/self/attr/current. A privileged process can +set the process smack by writing there. + +Look for additional programs on http://schaufler-ca.com + +From the Smack Whitepaper: + +The Simplified Mandatory Access Control Kernel + +Casey Schaufler +casey@schaufler-ca.com + +Mandatory Access Control + +Computer systems employ a variety of schemes to constrain how information is +shared among the people and services using the machine. Some of these schemes +allow the program or user to decide what other programs or users are allowed +access to pieces of data. These schemes are called discretionary access +control mechanisms because the access control is specified at the discretion +of the user. Other schemes do not leave the decision regarding what a user or +program can access up to users or programs. These schemes are called mandatory +access control mechanisms because you don't have a choice regarding the users +or programs that have access to pieces of data. + +Bell & LaPadula + +From the middle of the 1980's until the turn of the century Mandatory Access +Control (MAC) was very closely associated with the Bell & LaPadula security +model, a mathematical description of the United States Department of Defense +policy for marking paper documents. MAC in this form enjoyed a following +within the Capital Beltway and Scandinavian supercomputer centers but was +often sited as failing to address general needs. + +Domain Type Enforcement + +Around the turn of the century Domain Type Enforcement (DTE) became popular. +This scheme organizes users, programs, and data into domains that are +protected from each other. This scheme has been widely deployed as a component +of popular Linux distributions. The administrative overhead required to +maintain this scheme and the detailed understanding of the whole system +necessary to provide a secure domain mapping leads to the scheme being +disabled or used in limited ways in the majority of cases. + +Smack + +Smack is a Mandatory Access Control mechanism designed to provide useful MAC +while avoiding the pitfalls of its predecessors. The limitations of Bell & +LaPadula are addressed by providing a scheme whereby access can be controlled +according to the requirements of the system and its purpose rather than those +imposed by an arcane government policy. The complexity of Domain Type +Enforcement and avoided by defining access controls in terms of the access +modes already in use. + +Smack Terminology + +The jargon used to talk about Smack will be familiar to those who have dealt +with other MAC systems and shouldn't be too difficult for the uninitiated to +pick up. There are four terms that are used in a specific way and that are +especially important: + + Subject: A subject is an active entity on the computer system. + On Smack a subject is a task, which is in turn the basic unit + of execution. + + Object: An object is a passive entity on the computer system. + On Smack files of all types, IPC, and tasks can be objects. + + Access: Any attempt by a subject to put information into or get + information from an object is an access. + + Label: Data that identifies the Mandatory Access Control + characteristics of a subject or an object. + +These definitions are consistent with the traditional use in the security +community. There are also some terms from Linux that are likely to crop up: + + Capability: A task that possesses a capability has permission to + violate an aspect of the system security policy, as identified by + the specific capability. A task that possesses one or more + capabilities is a privileged task, whereas a task with no + capabilities is an unprivileged task. + + Privilege: A task that is allowed to violate the system security + policy is said to have privilege. As of this writing a task can + have privilege either by possessing capabilities or by having an + effective user of root. + +Smack Basics + +Smack is an extension to a Linux system. It enforces additional restrictions +on what subjects can access which objects, based on the labels attached to +each of the subject and the object. + +Labels + +Smack labels are ASCII character strings, one to twenty-three characters in +length. Single character labels using special characters, that being anything +other than a letter or digit, are reserved for use by the Smack development +team. Smack labels are unstructured, case sensitive, and the only operation +ever performed on them is comparison for equality. Smack labels cannot +contain unprintable characters, the "/" (slash), the "\" (backslash), the "'" +(quote) and '"' (double-quote) characters. +Smack labels cannot begin with a '-', which is reserved for special options. + +There are some predefined labels: + + _ Pronounced "floor", a single underscore character. + ^ Pronounced "hat", a single circumflex character. + * Pronounced "star", a single asterisk character. + ? Pronounced "huh", a single question mark character. + @ Pronounced "Internet", a single at sign character. + +Every task on a Smack system is assigned a label. System tasks, such as +init(8) and systems daemons, are run with the floor ("_") label. User tasks +are assigned labels according to the specification found in the +/etc/smack/user configuration file. + +Access Rules + +Smack uses the traditional access modes of Linux. These modes are read, +execute, write, and occasionally append. There are a few cases where the +access mode may not be obvious. These include: + + Signals: A signal is a write operation from the subject task to + the object task. + Internet Domain IPC: Transmission of a packet is considered a + write operation from the source task to the destination task. + +Smack restricts access based on the label attached to a subject and the label +attached to the object it is trying to access. The rules enforced are, in +order: + + 1. Any access requested by a task labeled "*" is denied. + 2. A read or execute access requested by a task labeled "^" + is permitted. + 3. A read or execute access requested on an object labeled "_" + is permitted. + 4. Any access requested on an object labeled "*" is permitted. + 5. Any access requested by a task on an object with the same + label is permitted. + 6. Any access requested that is explicitly defined in the loaded + rule set is permitted. + 7. Any other access is denied. + +Smack Access Rules + +With the isolation provided by Smack access separation is simple. There are +many interesting cases where limited access by subjects to objects with +different labels is desired. One example is the familiar spy model of +sensitivity, where a scientist working on a highly classified project would be +able to read documents of lower classifications and anything she writes will +be "born" highly classified. To accommodate such schemes Smack includes a +mechanism for specifying rules allowing access between labels. + +Access Rule Format + +The format of an access rule is: + + subject-label object-label access + +Where subject-label is the Smack label of the task, object-label is the Smack +label of the thing being accessed, and access is a string specifying the sort +of access allowed. The Smack labels are limited to 23 characters. The access +specification is searched for letters that describe access modes: + + a: indicates that append access should be granted. + r: indicates that read access should be granted. + w: indicates that write access should be granted. + x: indicates that execute access should be granted. + +Uppercase values for the specification letters are allowed as well. +Access mode specifications can be in any order. Examples of acceptable rules +are: + + TopSecret Secret rx + Secret Unclass R + Manager Game x + User HR w + New Old rRrRr + Closed Off - + +Examples of unacceptable rules are: + + Top Secret Secret rx + Ace Ace r + Odd spells waxbeans + +Spaces are not allowed in labels. Since a subject always has access to files +with the same label specifying a rule for that case is pointless. Only +valid letters (rwxaRWXA) and the dash ('-') character are allowed in +access specifications. The dash is a placeholder, so "a-r" is the same +as "ar". A lone dash is used to specify that no access should be allowed. + +Applying Access Rules + +The developers of Linux rarely define new sorts of things, usually importing +schemes and concepts from other systems. Most often, the other systems are +variants of Unix. Unix has many endearing properties, but consistency of +access control models is not one of them. Smack strives to treat accesses as +uniformly as is sensible while keeping with the spirit of the underlying +mechanism. + +File system objects including files, directories, named pipes, symbolic links, +and devices require access permissions that closely match those used by mode +bit access. To open a file for reading read access is required on the file. To +search a directory requires execute access. Creating a file with write access +requires both read and write access on the containing directory. Deleting a +file requires read and write access to the file and to the containing +directory. It is possible that a user may be able to see that a file exists +but not any of its attributes by the circumstance of having read access to the +containing directory but not to the differently labeled file. This is an +artifact of the file name being data in the directory, not a part of the file. + +IPC objects, message queues, semaphore sets, and memory segments exist in flat +namespaces and access requests are only required to match the object in +question. + +Process objects reflect tasks on the system and the Smack label used to access +them is the same Smack label that the task would use for its own access +attempts. Sending a signal via the kill() system call is a write operation +from the signaler to the recipient. Debugging a process requires both reading +and writing. Creating a new task is an internal operation that results in two +tasks with identical Smack labels and requires no access checks. + +Sockets are data structures attached to processes and sending a packet from +one process to another requires that the sender have write access to the +receiver. The receiver is not required to have read access to the sender. + +Setting Access Rules + +The configuration file /etc/smack/accesses contains the rules to be set at +system startup. The contents are written to the special file /smack/load. +Rules can be written to /smack/load at any time and take effect immediately. +For any pair of subject and object labels there can be only one rule, with the +most recently specified overriding any earlier specification. + +The program smackload is provided to ensure data is formatted +properly when written to /smack/load. This program reads lines +of the form + + subjectlabel objectlabel mode. + +Task Attribute + +The Smack label of a process can be read from /proc//attr/current. A +process can read its own Smack label from /proc/self/attr/current. A +privileged process can change its own Smack label by writing to +/proc/self/attr/current but not the label of another process. + +File Attribute + +The Smack label of a filesystem object is stored as an extended attribute +named SMACK64 on the file. This attribute is in the security namespace. It can +only be changed by a process with privilege. + +Privilege + +A process with CAP_MAC_OVERRIDE is privileged. + +Smack Networking + +As mentioned before, Smack enforces access control on network protocol +transmissions. Every packet sent by a Smack process is tagged with its Smack +label. This is done by adding a CIPSO tag to the header of the IP packet. Each +packet received is expected to have a CIPSO tag that identifies the label and +if it lacks such a tag the network ambient label is assumed. Before the packet +is delivered a check is made to determine that a subject with the label on the +packet has write access to the receiving process and if that is not the case +the packet is dropped. + +CIPSO Configuration + +It is normally unnecessary to specify the CIPSO configuration. The default +values used by the system handle all internal cases. Smack will compose CIPSO +label values to match the Smack labels being used without administrative +intervention. Unlabeled packets that come into the system will be given the +ambient label. + +Smack requires configuration in the case where packets from a system that is +not smack that speaks CIPSO may be encountered. Usually this will be a Trusted +Solaris system, but there are other, less widely deployed systems out there. +CIPSO provides 3 important values, a Domain Of Interpretation (DOI), a level, +and a category set with each packet. The DOI is intended to identify a group +of systems that use compatible labeling schemes, and the DOI specified on the +smack system must match that of the remote system or packets will be +discarded. The DOI is 3 by default. The value can be read from /smack/doi and +can be changed by writing to /smack/doi. + +The label and category set are mapped to a Smack label as defined in +/etc/smack/cipso. + +A Smack/CIPSO mapping has the form: + + smack level [category [category]*] + +Smack does not expect the level or category sets to be related in any +particular way and does not assume or assign accesses based on them. Some +examples of mappings: + + TopSecret 7 + TS:A,B 7 1 2 + SecBDE 5 2 4 6 + RAFTERS 7 12 26 + +The ":" and "," characters are permitted in a Smack label but have no special +meaning. + +The mapping of Smack labels to CIPSO values is defined by writing to +/smack/cipso. Again, the format of data written to this special file +is highly restrictive, so the program smackcipso is provided to +ensure the writes are done properly. This program takes mappings +on the standard input and sends them to /smack/cipso properly. + +In addition to explicit mappings Smack supports direct CIPSO mappings. One +CIPSO level is used to indicate that the category set passed in the packet is +in fact an encoding of the Smack label. The level used is 250 by default. The +value can be read from /smack/direct and changed by writing to /smack/direct. + +Socket Attributes + +There are two attributes that are associated with sockets. These attributes +can only be set by privileged tasks, but any task can read them for their own +sockets. + + SMACK64IPIN: The Smack label of the task object. A privileged + program that will enforce policy may set this to the star label. + + SMACK64IPOUT: The Smack label transmitted with outgoing packets. + A privileged program may set this to match the label of another + task with which it hopes to communicate. + +Smack Netlabel Exceptions + +You will often find that your labeled application has to talk to the outside, +unlabeled world. To do this there's a special file /smack/netlabel where you can +add some exceptions in the form of : +@IP1 LABEL1 or +@IP2/MASK LABEL2 + +It means that your application will have unlabeled access to @IP1 if it has +write access on LABEL1, and access to the subnet @IP2/MASK if it has write +access on LABEL2. + +Entries in the /smack/netlabel file are matched by longest mask first, like in +classless IPv4 routing. + +A special label '@' and an option '-CIPSO' can be used there : +@ means Internet, any application with any label has access to it +-CIPSO means standard CIPSO networking + +If you don't know what CIPSO is and don't plan to use it, you can just do : +echo 127.0.0.1 -CIPSO > /smack/netlabel +echo 0.0.0.0/0 @ > /smack/netlabel + +If you use CIPSO on your 192.168.0.0/16 local network and need also unlabeled +Internet access, you can have : +echo 127.0.0.1 -CIPSO > /smack/netlabel +echo 192.168.0.0/16 -CIPSO > /smack/netlabel +echo 0.0.0.0/0 @ > /smack/netlabel + + +Writing Applications for Smack + +There are three sorts of applications that will run on a Smack system. How an +application interacts with Smack will determine what it will have to do to +work properly under Smack. + +Smack Ignorant Applications + +By far the majority of applications have no reason whatever to care about the +unique properties of Smack. Since invoking a program has no impact on the +Smack label associated with the process the only concern likely to arise is +whether the process has execute access to the program. + +Smack Relevant Applications + +Some programs can be improved by teaching them about Smack, but do not make +any security decisions themselves. The utility ls(1) is one example of such a +program. + +Smack Enforcing Applications + +These are special programs that not only know about Smack, but participate in +the enforcement of system policy. In most cases these are the programs that +set up user sessions. There are also network services that provide information +to processes running with various labels. + +File System Interfaces + +Smack maintains labels on file system objects using extended attributes. The +Smack label of a file, directory, or other file system object can be obtained +using getxattr(2). + + len = getxattr("/", "security.SMACK64", value, sizeof (value)); + +will put the Smack label of the root directory into value. A privileged +process can set the Smack label of a file system object with setxattr(2). + + len = strlen("Rubble"); + rc = setxattr("/foo", "security.SMACK64", "Rubble", len, 0); + +will set the Smack label of /foo to "Rubble" if the program has appropriate +privilege. + +Socket Interfaces + +The socket attributes can be read using fgetxattr(2). + +A privileged process can set the Smack label of outgoing packets with +fsetxattr(2). + + len = strlen("Rubble"); + rc = fsetxattr(fd, "security.SMACK64IPOUT", "Rubble", len, 0); + +will set the Smack label "Rubble" on packets going out from the socket if the +program has appropriate privilege. + + rc = fsetxattr(fd, "security.SMACK64IPIN, "*", strlen("*"), 0); + +will set the Smack label "*" as the object label against which incoming +packets will be checked if the program has appropriate privilege. + +Administration + +Smack supports some mount options: + + smackfsdef=label: specifies the label to give files that lack + the Smack label extended attribute. + + smackfsroot=label: specifies the label to assign the root of the + file system if it lacks the Smack extended attribute. + + smackfshat=label: specifies a label that must have read access to + all labels set on the filesystem. Not yet enforced. + + smackfsfloor=label: specifies a label to which all labels set on the + filesystem must have read access. Not yet enforced. + +These mount options apply to all file system types. + +Smack auditing + +If you want Smack auditing of security events, you need to set CONFIG_AUDIT +in your kernel configuration. +By default, all denied events will be audited. You can change this behavior by +writing a single character to the /smack/logging file : +0 : no logging +1 : log denied (default) +2 : log accepted +3 : log denied & accepted + +Events are logged as 'key=value' pairs, for each event you at least will get +the subjet, the object, the rights requested, the action, the kernel function +that triggered the event, plus other pairs depending on the type of event +audited. diff --git a/Documentation/security/apparmor.txt b/Documentation/security/apparmor.txt new file mode 100644 index 000000000000..93c1fd7d0635 --- /dev/null +++ b/Documentation/security/apparmor.txt @@ -0,0 +1,39 @@ +--- What is AppArmor? --- + +AppArmor is MAC style security extension for the Linux kernel. It implements +a task centered policy, with task "profiles" being created and loaded +from user space. Tasks on the system that do not have a profile defined for +them run in an unconfined state which is equivalent to standard Linux DAC +permissions. + +--- How to enable/disable --- + +set CONFIG_SECURITY_APPARMOR=y + +If AppArmor should be selected as the default security module then + set CONFIG_DEFAULT_SECURITY="apparmor" + and CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=1 + +Build the kernel + +If AppArmor is not the default security module it can be enabled by passing +security=apparmor on the kernel's command line. + +If AppArmor is the default security module it can be disabled by passing +apparmor=0, security=XXXX (where XXX is valid security module), on the +kernel's command line + +For AppArmor to enforce any restrictions beyond standard Linux DAC permissions +policy must be loaded into the kernel from user space (see the Documentation +and tools links). + +--- Documentation --- + +Documentation can be found on the wiki. + +--- Links --- + +Mailing List - apparmor@lists.ubuntu.com +Wiki - http://apparmor.wiki.kernel.org/ +User space tools - https://launchpad.net/apparmor +Kernel module - git://git.kernel.org/pub/scm/linux/kernel/git/jj/apparmor-dev.git diff --git a/Documentation/security/credentials.txt b/Documentation/security/credentials.txt new file mode 100644 index 000000000000..fc0366cbd7ce --- /dev/null +++ b/Documentation/security/credentials.txt @@ -0,0 +1,581 @@ + ==================== + CREDENTIALS IN LINUX + ==================== + +By: David Howells + +Contents: + + (*) Overview. + + (*) Types of credentials. + + (*) File markings. + + (*) Task credentials. + + - Immutable credentials. + - Accessing task credentials. + - Accessing another task's credentials. + - Altering credentials. + - Managing credentials. + + (*) Open file credentials. + + (*) Overriding the VFS's use of credentials. + + +======== +OVERVIEW +======== + +There are several parts to the security check performed by Linux when one +object acts upon another: + + (1) Objects. + + Objects are things in the system that may be acted upon directly by + userspace programs. Linux has a variety of actionable objects, including: + + - Tasks + - Files/inodes + - Sockets + - Message queues + - Shared memory segments + - Semaphores + - Keys + + As a part of the description of all these objects there is a set of + credentials. What's in the set depends on the type of object. + + (2) Object ownership. + + Amongst the credentials of most objects, there will be a subset that + indicates the ownership of that object. This is used for resource + accounting and limitation (disk quotas and task rlimits for example). + + In a standard UNIX filesystem, for instance, this will be defined by the + UID marked on the inode. + + (3) The objective context. + + Also amongst the credentials of those objects, there will be a subset that + indicates the 'objective context' of that object. This may or may not be + the same set as in (2) - in standard UNIX files, for instance, this is the + defined by the UID and the GID marked on the inode. + + The objective context is used as part of the security calculation that is + carried out when an object is acted upon. + + (4) Subjects. + + A subject is an object that is acting upon another object. + + Most of the objects in the system are inactive: they don't act on other + objects within the system. Processes/tasks are the obvious exception: + they do stuff; they access and manipulate things. + + Objects other than tasks may under some circumstances also be subjects. + For instance an open file may send SIGIO to a task using the UID and EUID + given to it by a task that called fcntl(F_SETOWN) upon it. In this case, + the file struct will have a subjective context too. + + (5) The subjective context. + + A subject has an additional interpretation of its credentials. A subset + of its credentials forms the 'subjective context'. The subjective context + is used as part of the security calculation that is carried out when a + subject acts. + + A Linux task, for example, has the FSUID, FSGID and the supplementary + group list for when it is acting upon a file - which are quite separate + from the real UID and GID that normally form the objective context of the + task. + + (6) Actions. + + Linux has a number of actions available that a subject may perform upon an + object. The set of actions available depends on the nature of the subject + and the object. + + Actions include reading, writing, creating and deleting files; forking or + signalling and tracing tasks. + + (7) Rules, access control lists and security calculations. + + When a subject acts upon an object, a security calculation is made. This + involves taking the subjective context, the objective context and the + action, and searching one or more sets of rules to see whether the subject + is granted or denied permission to act in the desired manner on the + object, given those contexts. + + There are two main sources of rules: + + (a) Discretionary access control (DAC): + + Sometimes the object will include sets of rules as part of its + description. This is an 'Access Control List' or 'ACL'. A Linux + file may supply more than one ACL. + + A traditional UNIX file, for example, includes a permissions mask that + is an abbreviated ACL with three fixed classes of subject ('user', + 'group' and 'other'), each of which may be granted certain privileges + ('read', 'write' and 'execute' - whatever those map to for the object + in question). UNIX file permissions do not allow the arbitrary + specification of subjects, however, and so are of limited use. + + A Linux file might also sport a POSIX ACL. This is a list of rules + that grants various permissions to arbitrary subjects. + + (b) Mandatory access control (MAC): + + The system as a whole may have one or more sets of rules that get + applied to all subjects and objects, regardless of their source. + SELinux and Smack are examples of this. + + In the case of SELinux and Smack, each object is given a label as part + of its credentials. When an action is requested, they take the + subject label, the object label and the action and look for a rule + that says that this action is either granted or denied. + + +==================== +TYPES OF CREDENTIALS +==================== + +The Linux kernel supports the following types of credentials: + + (1) Traditional UNIX credentials. + + Real User ID + Real Group ID + + The UID and GID are carried by most, if not all, Linux objects, even if in + some cases it has to be invented (FAT or CIFS files for example, which are + derived from Windows). These (mostly) define the objective context of + that object, with tasks being slightly different in some cases. + + Effective, Saved and FS User ID + Effective, Saved and FS Group ID + Supplementary groups + + These are additional credentials used by tasks only. Usually, an + EUID/EGID/GROUPS will be used as the subjective context, and real UID/GID + will be used as the objective. For tasks, it should be noted that this is + not always true. + + (2) Capabilities. + + Set of permitted capabilities + Set of inheritable capabilities + Set of effective capabilities + Capability bounding set + + These are only carried by tasks. They indicate superior capabilities + granted piecemeal to a task that an ordinary task wouldn't otherwise have. + These are manipulated implicitly by changes to the traditional UNIX + credentials, but can also be manipulated directly by the capset() system + call. + + The permitted capabilities are those caps that the process might grant + itself to its effective or permitted sets through capset(). This + inheritable set might also be so constrained. + + The effective capabilities are the ones that a task is actually allowed to + make use of itself. + + The inheritable capabilities are the ones that may get passed across + execve(). + + The bounding set limits the capabilities that may be inherited across + execve(), especially when a binary is executed that will execute as UID 0. + + (3) Secure management flags (securebits). + + These are only carried by tasks. These govern the way the above + credentials are manipulated and inherited over certain operations such as + execve(). They aren't used directly as objective or subjective + credentials. + + (4) Keys and keyrings. + + These are only carried by tasks. They carry and cache security tokens + that don't fit into the other standard UNIX credentials. They are for + making such things as network filesystem keys available to the file + accesses performed by processes, without the necessity of ordinary + programs having to know about security details involved. + + Keyrings are a special type of key. They carry sets of other keys and can + be searched for the desired key. Each process may subscribe to a number + of keyrings: + + Per-thread keying + Per-process keyring + Per-session keyring + + When a process accesses a key, if not already present, it will normally be + cached on one of these keyrings for future accesses to find. + + For more information on using keys, see Documentation/security/keys.txt. + + (5) LSM + + The Linux Security Module allows extra controls to be placed over the + operations that a task may do. Currently Linux supports two main + alternate LSM options: SELinux and Smack. + + Both work by labelling the objects in a system and then applying sets of + rules (policies) that say what operations a task with one label may do to + an object with another label. + + (6) AF_KEY + + This is a socket-based approach to credential management for networking + stacks [RFC 2367]. It isn't discussed by this document as it doesn't + interact directly with task and file credentials; rather it keeps system + level credentials. + + +When a file is opened, part of the opening task's subjective context is +recorded in the file struct created. This allows operations using that file +struct to use those credentials instead of the subjective context of the task +that issued the operation. An example of this would be a file opened on a +network filesystem where the credentials of the opened file should be presented +to the server, regardless of who is actually doing a read or a write upon it. + + +============= +FILE MARKINGS +============= + +Files on disk or obtained over the network may have annotations that form the +objective security context of that file. Depending on the type of filesystem, +this may include one or more of the following: + + (*) UNIX UID, GID, mode; + + (*) Windows user ID; + + (*) Access control list; + + (*) LSM security label; + + (*) UNIX exec privilege escalation bits (SUID/SGID); + + (*) File capabilities exec privilege escalation bits. + +These are compared to the task's subjective security context, and certain +operations allowed or disallowed as a result. In the case of execve(), the +privilege escalation bits come into play, and may allow the resulting process +extra privileges, based on the annotations on the executable file. + + +================ +TASK CREDENTIALS +================ + +In Linux, all of a task's credentials are held in (uid, gid) or through +(groups, keys, LSM security) a refcounted structure of type 'struct cred'. +Each task points to its credentials by a pointer called 'cred' in its +task_struct. + +Once a set of credentials has been prepared and committed, it may not be +changed, barring the following exceptions: + + (1) its reference count may be changed; + + (2) the reference count on the group_info struct it points to may be changed; + + (3) the reference count on the security data it points to may be changed; + + (4) the reference count on any keyrings it points to may be changed; + + (5) any keyrings it points to may be revoked, expired or have their security + attributes changed; and + + (6) the contents of any keyrings to which it points may be changed (the whole + point of keyrings being a shared set of credentials, modifiable by anyone + with appropriate access). + +To alter anything in the cred struct, the copy-and-replace principle must be +adhered to. First take a copy, then alter the copy and then use RCU to change +the task pointer to make it point to the new copy. There are wrappers to aid +with this (see below). + +A task may only alter its _own_ credentials; it is no longer permitted for a +task to alter another's credentials. This means the capset() system call is no +longer permitted to take any PID other than the one of the current process. +Also keyctl_instantiate() and keyctl_negate() functions no longer permit +attachment to process-specific keyrings in the requesting process as the +instantiating process may need to create them. + + +IMMUTABLE CREDENTIALS +--------------------- + +Once a set of credentials has been made public (by calling commit_creds() for +example), it must be considered immutable, barring two exceptions: + + (1) The reference count may be altered. + + (2) Whilst the keyring subscriptions of a set of credentials may not be + changed, the keyrings subscribed to may have their contents altered. + +To catch accidental credential alteration at compile time, struct task_struct +has _const_ pointers to its credential sets, as does struct file. Furthermore, +certain functions such as get_cred() and put_cred() operate on const pointers, +thus rendering casts unnecessary, but require to temporarily ditch the const +qualification to be able to alter the reference count. + + +ACCESSING TASK CREDENTIALS +-------------------------- + +A task being able to alter only its own credentials permits the current process +to read or replace its own credentials without the need for any form of locking +- which simplifies things greatly. It can just call: + + const struct cred *current_cred() + +to get a pointer to its credentials structure, and it doesn't have to release +it afterwards. + +There are convenience wrappers for retrieving specific aspects of a task's +credentials (the value is simply returned in each case): + + uid_t current_uid(void) Current's real UID + gid_t current_gid(void) Current's real GID + uid_t current_euid(void) Current's effective UID + gid_t current_egid(void) Current's effective GID + uid_t current_fsuid(void) Current's file access UID + gid_t current_fsgid(void) Current's file access GID + kernel_cap_t current_cap(void) Current's effective capabilities + void *current_security(void) Current's LSM security pointer + struct user_struct *current_user(void) Current's user account + +There are also convenience wrappers for retrieving specific associated pairs of +a task's credentials: + + void current_uid_gid(uid_t *, gid_t *); + void current_euid_egid(uid_t *, gid_t *); + void current_fsuid_fsgid(uid_t *, gid_t *); + +which return these pairs of values through their arguments after retrieving +them from the current task's credentials. + + +In addition, there is a function for obtaining a reference on the current +process's current set of credentials: + + const struct cred *get_current_cred(void); + +and functions for getting references to one of the credentials that don't +actually live in struct cred: + + struct user_struct *get_current_user(void); + struct group_info *get_current_groups(void); + +which get references to the current process's user accounting structure and +supplementary groups list respectively. + +Once a reference has been obtained, it must be released with put_cred(), +free_uid() or put_group_info() as appropriate. + + +ACCESSING ANOTHER TASK'S CREDENTIALS +------------------------------------ + +Whilst a task may access its own credentials without the need for locking, the +same is not true of a task wanting to access another task's credentials. It +must use the RCU read lock and rcu_dereference(). + +The rcu_dereference() is wrapped by: + + const struct cred *__task_cred(struct task_struct *task); + +This should be used inside the RCU read lock, as in the following example: + + void foo(struct task_struct *t, struct foo_data *f) + { + const struct cred *tcred; + ... + rcu_read_lock(); + tcred = __task_cred(t); + f->uid = tcred->uid; + f->gid = tcred->gid; + f->groups = get_group_info(tcred->groups); + rcu_read_unlock(); + ... + } + +Should it be necessary to hold another task's credentials for a long period of +time, and possibly to sleep whilst doing so, then the caller should get a +reference on them using: + + const struct cred *get_task_cred(struct task_struct *task); + +This does all the RCU magic inside of it. The caller must call put_cred() on +the credentials so obtained when they're finished with. + + [*] Note: The result of __task_cred() should not be passed directly to + get_cred() as this may race with commit_cred(). + +There are a couple of convenience functions to access bits of another task's +credentials, hiding the RCU magic from the caller: + + uid_t task_uid(task) Task's real UID + uid_t task_euid(task) Task's effective UID + +If the caller is holding the RCU read lock at the time anyway, then: + + __task_cred(task)->uid + __task_cred(task)->euid + +should be used instead. Similarly, if multiple aspects of a task's credentials +need to be accessed, RCU read lock should be used, __task_cred() called, the +result stored in a temporary pointer and then the credential aspects called +from that before dropping the lock. This prevents the potentially expensive +RCU magic from being invoked multiple times. + +Should some other single aspect of another task's credentials need to be +accessed, then this can be used: + + task_cred_xxx(task, member) + +where 'member' is a non-pointer member of the cred struct. For instance: + + uid_t task_cred_xxx(task, suid); + +will retrieve 'struct cred::suid' from the task, doing the appropriate RCU +magic. This may not be used for pointer members as what they point to may +disappear the moment the RCU read lock is dropped. + + +ALTERING CREDENTIALS +-------------------- + +As previously mentioned, a task may only alter its own credentials, and may not +alter those of another task. This means that it doesn't need to use any +locking to alter its own credentials. + +To alter the current process's credentials, a function should first prepare a +new set of credentials by calling: + + struct cred *prepare_creds(void); + +this locks current->cred_replace_mutex and then allocates and constructs a +duplicate of the current process's credentials, returning with the mutex still +held if successful. It returns NULL if not successful (out of memory). + +The mutex prevents ptrace() from altering the ptrace state of a process whilst +security checks on credentials construction and changing is taking place as +the ptrace state may alter the outcome, particularly in the case of execve(). + +The new credentials set should be altered appropriately, and any security +checks and hooks done. Both the current and the proposed sets of credentials +are available for this purpose as current_cred() will return the current set +still at this point. + + +When the credential set is ready, it should be committed to the current process +by calling: + + int commit_creds(struct cred *new); + +This will alter various aspects of the credentials and the process, giving the +LSM a chance to do likewise, then it will use rcu_assign_pointer() to actually +commit the new credentials to current->cred, it will release +current->cred_replace_mutex to allow ptrace() to take place, and it will notify +the scheduler and others of the changes. + +This function is guaranteed to return 0, so that it can be tail-called at the +end of such functions as sys_setresuid(). + +Note that this function consumes the caller's reference to the new credentials. +The caller should _not_ call put_cred() on the new credentials afterwards. + +Furthermore, once this function has been called on a new set of credentials, +those credentials may _not_ be changed further. + + +Should the security checks fail or some other error occur after prepare_creds() +has been called, then the following function should be invoked: + + void abort_creds(struct cred *new); + +This releases the lock on current->cred_replace_mutex that prepare_creds() got +and then releases the new credentials. + + +A typical credentials alteration function would look something like this: + + int alter_suid(uid_t suid) + { + struct cred *new; + int ret; + + new = prepare_creds(); + if (!new) + return -ENOMEM; + + new->suid = suid; + ret = security_alter_suid(new); + if (ret < 0) { + abort_creds(new); + return ret; + } + + return commit_creds(new); + } + + +MANAGING CREDENTIALS +-------------------- + +There are some functions to help manage credentials: + + (*) void put_cred(const struct cred *cred); + + This releases a reference to the given set of credentials. If the + reference count reaches zero, the credentials will be scheduled for + destruction by the RCU system. + + (*) const struct cred *get_cred(const struct cred *cred); + + This gets a reference on a live set of credentials, returning a pointer to + that set of credentials. + + (*) struct cred *get_new_cred(struct cred *cred); + + This gets a reference on a set of credentials that is under construction + and is thus still mutable, returning a pointer to that set of credentials. + + +===================== +OPEN FILE CREDENTIALS +===================== + +When a new file is opened, a reference is obtained on the opening task's +credentials and this is attached to the file struct as 'f_cred' in place of +'f_uid' and 'f_gid'. Code that used to access file->f_uid and file->f_gid +should now access file->f_cred->fsuid and file->f_cred->fsgid. + +It is safe to access f_cred without the use of RCU or locking because the +pointer will not change over the lifetime of the file struct, and nor will the +contents of the cred struct pointed to, barring the exceptions listed above +(see the Task Credentials section). + + +======================================= +OVERRIDING THE VFS'S USE OF CREDENTIALS +======================================= + +Under some circumstances it is desirable to override the credentials used by +the VFS, and that can be done by calling into such as vfs_mkdir() with a +different set of credentials. This is done in the following places: + + (*) sys_faccessat(). + + (*) do_coredump(). + + (*) nfs4recover.c. diff --git a/Documentation/security/keys-request-key.txt b/Documentation/security/keys-request-key.txt new file mode 100644 index 000000000000..51987bfecfed --- /dev/null +++ b/Documentation/security/keys-request-key.txt @@ -0,0 +1,202 @@ + =================== + KEY REQUEST SERVICE + =================== + +The key request service is part of the key retention service (refer to +Documentation/security/keys.txt). This document explains more fully how +the requesting algorithm works. + +The process starts by either the kernel requesting a service by calling +request_key*(): + + struct key *request_key(const struct key_type *type, + const char *description, + const char *callout_info); + +or: + + struct key *request_key_with_auxdata(const struct key_type *type, + const char *description, + const char *callout_info, + size_t callout_len, + void *aux); + +or: + + struct key *request_key_async(const struct key_type *type, + const char *description, + const char *callout_info, + size_t callout_len); + +or: + + struct key *request_key_async_with_auxdata(const struct key_type *type, + const char *description, + const char *callout_info, + size_t callout_len, + void *aux); + +Or by userspace invoking the request_key system call: + + key_serial_t request_key(const char *type, + const char *description, + const char *callout_info, + key_serial_t dest_keyring); + +The main difference between the access points is that the in-kernel interface +does not need to link the key to a keyring to prevent it from being immediately +destroyed. The kernel interface returns a pointer directly to the key, and +it's up to the caller to destroy the key. + +The request_key*_with_auxdata() calls are like the in-kernel request_key*() +calls, except that they permit auxiliary data to be passed to the upcaller (the +default is NULL). This is only useful for those key types that define their +own upcall mechanism rather than using /sbin/request-key. + +The two async in-kernel calls may return keys that are still in the process of +being constructed. The two non-async ones will wait for construction to +complete first. + +The userspace interface links the key to a keyring associated with the process +to prevent the key from going away, and returns the serial number of the key to +the caller. + + +The following example assumes that the key types involved don't define their +own upcall mechanisms. If they do, then those should be substituted for the +forking and execution of /sbin/request-key. + + +=========== +THE PROCESS +=========== + +A request proceeds in the following manner: + + (1) Process A calls request_key() [the userspace syscall calls the kernel + interface]. + + (2) request_key() searches the process's subscribed keyrings to see if there's + a suitable key there. If there is, it returns the key. If there isn't, + and callout_info is not set, an error is returned. Otherwise the process + proceeds to the next step. + + (3) request_key() sees that A doesn't have the desired key yet, so it creates + two things: + + (a) An uninstantiated key U of requested type and description. + + (b) An authorisation key V that refers to key U and notes that process A + is the context in which key U should be instantiated and secured, and + from which associated key requests may be satisfied. + + (4) request_key() then forks and executes /sbin/request-key with a new session + keyring that contains a link to auth key V. + + (5) /sbin/request-key assumes the authority associated with key U. + + (6) /sbin/request-key execs an appropriate program to perform the actual + instantiation. + + (7) The program may want to access another key from A's context (say a + Kerberos TGT key). It just requests the appropriate key, and the keyring + search notes that the session keyring has auth key V in its bottom level. + + This will permit it to then search the keyrings of process A with the + UID, GID, groups and security info of process A as if it was process A, + and come up with key W. + + (8) The program then does what it must to get the data with which to + instantiate key U, using key W as a reference (perhaps it contacts a + Kerberos server using the TGT) and then instantiates key U. + + (9) Upon instantiating key U, auth key V is automatically revoked so that it + may not be used again. + +(10) The program then exits 0 and request_key() deletes key V and returns key + U to the caller. + +This also extends further. If key W (step 7 above) didn't exist, key W would +be created uninstantiated, another auth key (X) would be created (as per step +3) and another copy of /sbin/request-key spawned (as per step 4); but the +context specified by auth key X will still be process A, as it was in auth key +V. + +This is because process A's keyrings can't simply be attached to +/sbin/request-key at the appropriate places because (a) execve will discard two +of them, and (b) it requires the same UID/GID/Groups all the way through. + + +==================================== +NEGATIVE INSTANTIATION AND REJECTION +==================================== + +Rather than instantiating a key, it is possible for the possessor of an +authorisation key to negatively instantiate a key that's under construction. +This is a short duration placeholder that causes any attempt at re-requesting +the key whilst it exists to fail with error ENOKEY if negated or the specified +error if rejected. + +This is provided to prevent excessive repeated spawning of /sbin/request-key +processes for a key that will never be obtainable. + +Should the /sbin/request-key process exit anything other than 0 or die on a +signal, the key under construction will be automatically negatively +instantiated for a short amount of time. + + +==================== +THE SEARCH ALGORITHM +==================== + +A search of any particular keyring proceeds in the following fashion: + + (1) When the key management code searches for a key (keyring_search_aux) it + firstly calls key_permission(SEARCH) on the keyring it's starting with, + if this denies permission, it doesn't search further. + + (2) It considers all the non-keyring keys within that keyring and, if any key + matches the criteria specified, calls key_permission(SEARCH) on it to see + if the key is allowed to be found. If it is, that key is returned; if + not, the search continues, and the error code is retained if of higher + priority than the one currently set. + + (3) It then considers all the keyring-type keys in the keyring it's currently + searching. It calls key_permission(SEARCH) on each keyring, and if this + grants permission, it recurses, executing steps (2) and (3) on that + keyring. + +The process stops immediately a valid key is found with permission granted to +use it. Any error from a previous match attempt is discarded and the key is +returned. + +When search_process_keyrings() is invoked, it performs the following searches +until one succeeds: + + (1) If extant, the process's thread keyring is searched. + + (2) If extant, the process's process keyring is searched. + + (3) The process's session keyring is searched. + + (4) If the process has assumed the authority associated with a request_key() + authorisation key then: + + (a) If extant, the calling process's thread keyring is searched. + + (b) If extant, the calling process's process keyring is searched. + + (c) The calling process's session keyring is searched. + +The moment one succeeds, all pending errors are discarded and the found key is +returned. + +Only if all these fail does the whole thing fail with the highest priority +error. Note that several errors may have come from LSM. + +The error priority is: + + EKEYREVOKED > EKEYEXPIRED > ENOKEY + +EACCES/EPERM are only returned on a direct search of a specific keyring where +the basal keyring does not grant Search permission. diff --git a/Documentation/security/keys-trusted-encrypted.txt b/Documentation/security/keys-trusted-encrypted.txt new file mode 100644 index 000000000000..8fb79bc1ac4b --- /dev/null +++ b/Documentation/security/keys-trusted-encrypted.txt @@ -0,0 +1,145 @@ + Trusted and Encrypted Keys + +Trusted and Encrypted Keys are two new key types added to the existing kernel +key ring service. Both of these new types are variable length symmetic keys, +and in both cases all keys are created in the kernel, and user space sees, +stores, and loads only encrypted blobs. Trusted Keys require the availability +of a Trusted Platform Module (TPM) chip for greater security, while Encrypted +Keys can be used on any system. All user level blobs, are displayed and loaded +in hex ascii for convenience, and are integrity verified. + +Trusted Keys use a TPM both to generate and to seal the keys. Keys are sealed +under a 2048 bit RSA key in the TPM, and optionally sealed to specified PCR +(integrity measurement) values, and only unsealed by the TPM, if PCRs and blob +integrity verifications match. A loaded Trusted Key can be updated with new +(future) PCR values, so keys are easily migrated to new pcr values, such as +when the kernel and initramfs are updated. The same key can have many saved +blobs under different PCR values, so multiple boots are easily supported. + +By default, trusted keys are sealed under the SRK, which has the default +authorization value (20 zeros). This can be set at takeownership time with the +trouser's utility: "tpm_takeownership -u -z". + +Usage: + keyctl add trusted name "new keylen [options]" ring + keyctl add trusted name "load hex_blob [pcrlock=pcrnum]" ring + keyctl update key "update [options]" + keyctl print keyid + + options: + keyhandle= ascii hex value of sealing key default 0x40000000 (SRK) + keyauth= ascii hex auth for sealing key default 0x00...i + (40 ascii zeros) + blobauth= ascii hex auth for sealed data default 0x00... + (40 ascii zeros) + blobauth= ascii hex auth for sealed data default 0x00... + (40 ascii zeros) + pcrinfo= ascii hex of PCR_INFO or PCR_INFO_LONG (no default) + pcrlock= pcr number to be extended to "lock" blob + migratable= 0|1 indicating permission to reseal to new PCR values, + default 1 (resealing allowed) + +"keyctl print" returns an ascii hex copy of the sealed key, which is in standard +TPM_STORED_DATA format. The key length for new keys are always in bytes. +Trusted Keys can be 32 - 128 bytes (256 - 1024 bits), the upper limit is to fit +within the 2048 bit SRK (RSA) keylength, with all necessary structure/padding. + +Encrypted keys do not depend on a TPM, and are faster, as they use AES for +encryption/decryption. New keys are created from kernel generated random +numbers, and are encrypted/decrypted using a specified 'master' key. The +'master' key can either be a trusted-key or user-key type. The main +disadvantage of encrypted keys is that if they are not rooted in a trusted key, +they are only as secure as the user key encrypting them. The master user key +should therefore be loaded in as secure a way as possible, preferably early in +boot. + +Usage: + keyctl add encrypted name "new key-type:master-key-name keylen" ring + keyctl add encrypted name "load hex_blob" ring + keyctl update keyid "update key-type:master-key-name" + +where 'key-type' is either 'trusted' or 'user'. + +Examples of trusted and encrypted key usage: + +Create and save a trusted key named "kmk" of length 32 bytes: + + $ keyctl add trusted kmk "new 32" @u + 440502848 + + $ keyctl show + Session Keyring + -3 --alswrv 500 500 keyring: _ses + 97833714 --alswrv 500 -1 \_ keyring: _uid.500 + 440502848 --alswrv 500 500 \_ trusted: kmk + + $ keyctl print 440502848 + 0101000000000000000001005d01b7e3f4a6be5709930f3b70a743cbb42e0cc95e18e915 + 3f60da455bbf1144ad12e4f92b452f966929f6105fd29ca28e4d4d5a031d068478bacb0b + 27351119f822911b0a11ba3d3498ba6a32e50dac7f32894dd890eb9ad578e4e292c83722 + a52e56a097e6a68b3f56f7a52ece0cdccba1eb62cad7d817f6dc58898b3ac15f36026fec + d568bd4a706cb60bb37be6d8f1240661199d640b66fb0fe3b079f97f450b9ef9c22c6d5d + dd379f0facd1cd020281dfa3c70ba21a3fa6fc2471dc6d13ecf8298b946f65345faa5ef0 + f1f8fff03ad0acb083725535636addb08d73dedb9832da198081e5deae84bfaf0409c22b + e4a8aea2b607ec96931e6f4d4fe563ba + + $ keyctl pipe 440502848 > kmk.blob + +Load a trusted key from the saved blob: + + $ keyctl add trusted kmk "load `cat kmk.blob`" @u + 268728824 + + $ keyctl print 268728824 + 0101000000000000000001005d01b7e3f4a6be5709930f3b70a743cbb42e0cc95e18e915 + 3f60da455bbf1144ad12e4f92b452f966929f6105fd29ca28e4d4d5a031d068478bacb0b + 27351119f822911b0a11ba3d3498ba6a32e50dac7f32894dd890eb9ad578e4e292c83722 + a52e56a097e6a68b3f56f7a52ece0cdccba1eb62cad7d817f6dc58898b3ac15f36026fec + d568bd4a706cb60bb37be6d8f1240661199d640b66fb0fe3b079f97f450b9ef9c22c6d5d + dd379f0facd1cd020281dfa3c70ba21a3fa6fc2471dc6d13ecf8298b946f65345faa5ef0 + f1f8fff03ad0acb083725535636addb08d73dedb9832da198081e5deae84bfaf0409c22b + e4a8aea2b607ec96931e6f4d4fe563ba + +Reseal a trusted key under new pcr values: + + $ keyctl update 268728824 "update pcrinfo=`cat pcr.blob`" + $ keyctl print 268728824 + 010100000000002c0002800093c35a09b70fff26e7a98ae786c641e678ec6ffb6b46d805 + 77c8a6377aed9d3219c6dfec4b23ffe3000001005d37d472ac8a44023fbb3d18583a4f73 + d3a076c0858f6f1dcaa39ea0f119911ff03f5406df4f7f27f41da8d7194f45c9f4e00f2e + df449f266253aa3f52e55c53de147773e00f0f9aca86c64d94c95382265968c354c5eab4 + 9638c5ae99c89de1e0997242edfb0b501744e11ff9762dfd951cffd93227cc513384e7e6 + e782c29435c7ec2edafaa2f4c1fe6e7a781b59549ff5296371b42133777dcc5b8b971610 + 94bc67ede19e43ddb9dc2baacad374a36feaf0314d700af0a65c164b7082401740e489c9 + 7ef6a24defe4846104209bf0c3eced7fa1a672ed5b125fc9d8cd88b476a658a4434644ef + df8ae9a178e9f83ba9f08d10fa47e4226b98b0702f06b3b8 + +Create and save an encrypted key "evm" using the above trusted key "kmk": + + $ keyctl add encrypted evm "new trusted:kmk 32" @u + 159771175 + + $ keyctl print 159771175 + trusted:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b382dbbc55 + be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e024717c64 + 5972dcb82ab2dde83376d82b2e3c09ffc + + $ keyctl pipe 159771175 > evm.blob + +Load an encrypted key "evm" from saved blob: + + $ keyctl add encrypted evm "load `cat evm.blob`" @u + 831684262 + + $ keyctl print 831684262 + trusted:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b382dbbc55 + be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e024717c64 + 5972dcb82ab2dde83376d82b2e3c09ffc + + +The initial consumer of trusted keys is EVM, which at boot time needs a high +quality symmetric key for HMAC protection of file metadata. The use of a +trusted key provides strong guarantees that the EVM key has not been +compromised by a user level problem, and when sealed to specific boot PCR +values, protects against boot and offline attacks. Other uses for trusted and +encrypted keys, such as for disk and file encryption are anticipated. diff --git a/Documentation/security/keys.txt b/Documentation/security/keys.txt new file mode 100644 index 000000000000..4d75931d2d79 --- /dev/null +++ b/Documentation/security/keys.txt @@ -0,0 +1,1290 @@ + ============================ + KERNEL KEY RETENTION SERVICE + ============================ + +This service allows cryptographic keys, authentication tokens, cross-domain +user mappings, and similar to be cached in the kernel for the use of +filesystems and other kernel services. + +Keyrings are permitted; these are a special type of key that can hold links to +other keys. Processes each have three standard keyring subscriptions that a +kernel service can search for relevant keys. + +The key service can be configured on by enabling: + + "Security options"/"Enable access key retention support" (CONFIG_KEYS) + +This document has the following sections: + + - Key overview + - Key service overview + - Key access permissions + - SELinux support + - New procfs files + - Userspace system call interface + - Kernel services + - Notes on accessing payload contents + - Defining a key type + - Request-key callback service + - Garbage collection + + +============ +KEY OVERVIEW +============ + +In this context, keys represent units of cryptographic data, authentication +tokens, keyrings, etc.. These are represented in the kernel by struct key. + +Each key has a number of attributes: + + - A serial number. + - A type. + - A description (for matching a key in a search). + - Access control information. + - An expiry time. + - A payload. + - State. + + + (*) Each key is issued a serial number of type key_serial_t that is unique for + the lifetime of that key. All serial numbers are positive non-zero 32-bit + integers. + + Userspace programs can use a key's serial numbers as a way to gain access + to it, subject to permission checking. + + (*) Each key is of a defined "type". Types must be registered inside the + kernel by a kernel service (such as a filesystem) before keys of that type + can be added or used. Userspace programs cannot define new types directly. + + Key types are represented in the kernel by struct key_type. This defines a + number of operations that can be performed on a key of that type. + + Should a type be removed from the system, all the keys of that type will + be invalidated. + + (*) Each key has a description. This should be a printable string. The key + type provides an operation to perform a match between the description on a + key and a criterion string. + + (*) Each key has an owner user ID, a group ID and a permissions mask. These + are used to control what a process may do to a key from userspace, and + whether a kernel service will be able to find the key. + + (*) Each key can be set to expire at a specific time by the key type's + instantiation function. Keys can also be immortal. + + (*) Each key can have a payload. This is a quantity of data that represent the + actual "key". In the case of a keyring, this is a list of keys to which + the keyring links; in the case of a user-defined key, it's an arbitrary + blob of data. + + Having a payload is not required; and the payload can, in fact, just be a + value stored in the struct key itself. + + When a key is instantiated, the key type's instantiation function is + called with a blob of data, and that then creates the key's payload in + some way. + + Similarly, when userspace wants to read back the contents of the key, if + permitted, another key type operation will be called to convert the key's + attached payload back into a blob of data. + + (*) Each key can be in one of a number of basic states: + + (*) Uninstantiated. The key exists, but does not have any data attached. + Keys being requested from userspace will be in this state. + + (*) Instantiated. This is the normal state. The key is fully formed, and + has data attached. + + (*) Negative. This is a relatively short-lived state. The key acts as a + note saying that a previous call out to userspace failed, and acts as + a throttle on key lookups. A negative key can be updated to a normal + state. + + (*) Expired. Keys can have lifetimes set. If their lifetime is exceeded, + they traverse to this state. An expired key can be updated back to a + normal state. + + (*) Revoked. A key is put in this state by userspace action. It can't be + found or operated upon (apart from by unlinking it). + + (*) Dead. The key's type was unregistered, and so the key is now useless. + +Keys in the last three states are subject to garbage collection. See the +section on "Garbage collection". + + +==================== +KEY SERVICE OVERVIEW +==================== + +The key service provides a number of features besides keys: + + (*) The key service defines two special key types: + + (+) "keyring" + + Keyrings are special keys that contain a list of other keys. Keyring + lists can be modified using various system calls. Keyrings should not + be given a payload when created. + + (+) "user" + + A key of this type has a description and a payload that are arbitrary + blobs of data. These can be created, updated and read by userspace, + and aren't intended for use by kernel services. + + (*) Each process subscribes to three keyrings: a thread-specific keyring, a + process-specific keyring, and a session-specific keyring. + + The thread-specific keyring is discarded from the child when any sort of + clone, fork, vfork or execve occurs. A new keyring is created only when + required. + + The process-specific keyring is replaced with an empty one in the child on + clone, fork, vfork unless CLONE_THREAD is supplied, in which case it is + shared. execve also discards the process's process keyring and creates a + new one. + + The session-specific keyring is persistent across clone, fork, vfork and + execve, even when the latter executes a set-UID or set-GID binary. A + process can, however, replace its current session keyring with a new one + by using PR_JOIN_SESSION_KEYRING. It is permitted to request an anonymous + new one, or to attempt to create or join one of a specific name. + + The ownership of the thread keyring changes when the real UID and GID of + the thread changes. + + (*) Each user ID resident in the system holds two special keyrings: a user + specific keyring and a default user session keyring. The default session + keyring is initialised with a link to the user-specific keyring. + + When a process changes its real UID, if it used to have no session key, it + will be subscribed to the default session key for the new UID. + + If a process attempts to access its session key when it doesn't have one, + it will be subscribed to the default for its current UID. + + (*) Each user has two quotas against which the keys they own are tracked. One + limits the total number of keys and keyrings, the other limits the total + amount of description and payload space that can be consumed. + + The user can view information on this and other statistics through procfs + files. The root user may also alter the quota limits through sysctl files + (see the section "New procfs files"). + + Process-specific and thread-specific keyrings are not counted towards a + user's quota. + + If a system call that modifies a key or keyring in some way would put the + user over quota, the operation is refused and error EDQUOT is returned. + + (*) There's a system call interface by which userspace programs can create and + manipulate keys and keyrings. + + (*) There's a kernel interface by which services can register types and search + for keys. + + (*) There's a way for the a search done from the kernel to call back to + userspace to request a key that can't be found in a process's keyrings. + + (*) An optional filesystem is available through which the key database can be + viewed and manipulated. + + +====================== +KEY ACCESS PERMISSIONS +====================== + +Keys have an owner user ID, a group access ID, and a permissions mask. The mask +has up to eight bits each for possessor, user, group and other access. Only +six of each set of eight bits are defined. These permissions granted are: + + (*) View + + This permits a key or keyring's attributes to be viewed - including key + type and description. + + (*) Read + + This permits a key's payload to be viewed or a keyring's list of linked + keys. + + (*) Write + + This permits a key's payload to be instantiated or updated, or it allows a + link to be added to or removed from a keyring. + + (*) Search + + This permits keyrings to be searched and keys to be found. Searches can + only recurse into nested keyrings that have search permission set. + + (*) Link + + This permits a key or keyring to be linked to. To create a link from a + keyring to a key, a process must have Write permission on the keyring and + Link permission on the key. + + (*) Set Attribute + + This permits a key's UID, GID and permissions mask to be changed. + +For changing the ownership, group ID or permissions mask, being the owner of +the key or having the sysadmin capability is sufficient. + + +=============== +SELINUX SUPPORT +=============== + +The security class "key" has been added to SELinux so that mandatory access +controls can be applied to keys created within various contexts. This support +is preliminary, and is likely to change quite significantly in the near future. +Currently, all of the basic permissions explained above are provided in SELinux +as well; SELinux is simply invoked after all basic permission checks have been +performed. + +The value of the file /proc/self/attr/keycreate influences the labeling of +newly-created keys. If the contents of that file correspond to an SELinux +security context, then the key will be assigned that context. Otherwise, the +key will be assigned the current context of the task that invoked the key +creation request. Tasks must be granted explicit permission to assign a +particular context to newly-created keys, using the "create" permission in the +key security class. + +The default keyrings associated with users will be labeled with the default +context of the user if and only if the login programs have been instrumented to +properly initialize keycreate during the login process. Otherwise, they will +be labeled with the context of the login program itself. + +Note, however, that the default keyrings associated with the root user are +labeled with the default kernel context, since they are created early in the +boot process, before root has a chance to log in. + +The keyrings associated with new threads are each labeled with the context of +their associated thread, and both session and process keyrings are handled +similarly. + + +================ +NEW PROCFS FILES +================ + +Two files have been added to procfs by which an administrator can find out +about the status of the key service: + + (*) /proc/keys + + This lists the keys that are currently viewable by the task reading the + file, giving information about their type, description and permissions. + It is not possible to view the payload of the key this way, though some + information about it may be given. + + The only keys included in the list are those that grant View permission to + the reading process whether or not it possesses them. Note that LSM + security checks are still performed, and may further filter out keys that + the current process is not authorised to view. + + The contents of the file look like this: + + SERIAL FLAGS USAGE EXPY PERM UID GID TYPE DESCRIPTION: SUMMARY + 00000001 I----- 39 perm 1f3f0000 0 0 keyring _uid_ses.0: 1/4 + 00000002 I----- 2 perm 1f3f0000 0 0 keyring _uid.0: empty + 00000007 I----- 1 perm 1f3f0000 0 0 keyring _pid.1: empty + 0000018d I----- 1 perm 1f3f0000 0 0 keyring _pid.412: empty + 000004d2 I--Q-- 1 perm 1f3f0000 32 -1 keyring _uid.32: 1/4 + 000004d3 I--Q-- 3 perm 1f3f0000 32 -1 keyring _uid_ses.32: empty + 00000892 I--QU- 1 perm 1f000000 0 0 user metal:copper: 0 + 00000893 I--Q-N 1 35s 1f3f0000 0 0 user metal:silver: 0 + 00000894 I--Q-- 1 10h 003f0000 0 0 user metal:gold: 0 + + The flags are: + + I Instantiated + R Revoked + D Dead + Q Contributes to user's quota + U Under construction by callback to userspace + N Negative key + + This file must be enabled at kernel configuration time as it allows anyone + to list the keys database. + + (*) /proc/key-users + + This file lists the tracking data for each user that has at least one key + on the system. Such data includes quota information and statistics: + + [root@andromeda root]# cat /proc/key-users + 0: 46 45/45 1/100 13/10000 + 29: 2 2/2 2/100 40/10000 + 32: 2 2/2 2/100 40/10000 + 38: 2 2/2 2/100 40/10000 + + The format of each line is + : User ID to which this applies + Structure refcount + / Total number of keys and number instantiated + / Key count quota + / Key size quota + + +Four new sysctl files have been added also for the purpose of controlling the +quota limits on keys: + + (*) /proc/sys/kernel/keys/root_maxkeys + /proc/sys/kernel/keys/root_maxbytes + + These files hold the maximum number of keys that root may have and the + maximum total number of bytes of data that root may have stored in those + keys. + + (*) /proc/sys/kernel/keys/maxkeys + /proc/sys/kernel/keys/maxbytes + + These files hold the maximum number of keys that each non-root user may + have and the maximum total number of bytes of data that each of those + users may have stored in their keys. + +Root may alter these by writing each new limit as a decimal number string to +the appropriate file. + + +=============================== +USERSPACE SYSTEM CALL INTERFACE +=============================== + +Userspace can manipulate keys directly through three new syscalls: add_key, +request_key and keyctl. The latter provides a number of functions for +manipulating keys. + +When referring to a key directly, userspace programs should use the key's +serial number (a positive 32-bit integer). However, there are some special +values available for referring to special keys and keyrings that relate to the +process making the call: + + CONSTANT VALUE KEY REFERENCED + ============================== ====== =========================== + KEY_SPEC_THREAD_KEYRING -1 thread-specific keyring + KEY_SPEC_PROCESS_KEYRING -2 process-specific keyring + KEY_SPEC_SESSION_KEYRING -3 session-specific keyring + KEY_SPEC_USER_KEYRING -4 UID-specific keyring + KEY_SPEC_USER_SESSION_KEYRING -5 UID-session keyring + KEY_SPEC_GROUP_KEYRING -6 GID-specific keyring + KEY_SPEC_REQKEY_AUTH_KEY -7 assumed request_key() + authorisation key + + +The main syscalls are: + + (*) Create a new key of given type, description and payload and add it to the + nominated keyring: + + key_serial_t add_key(const char *type, const char *desc, + const void *payload, size_t plen, + key_serial_t keyring); + + If a key of the same type and description as that proposed already exists + in the keyring, this will try to update it with the given payload, or it + will return error EEXIST if that function is not supported by the key + type. The process must also have permission to write to the key to be able + to update it. The new key will have all user permissions granted and no + group or third party permissions. + + Otherwise, this will attempt to create a new key of the specified type and + description, and to instantiate it with the supplied payload and attach it + to the keyring. In this case, an error will be generated if the process + does not have permission to write to the keyring. + + The payload is optional, and the pointer can be NULL if not required by + the type. The payload is plen in size, and plen can be zero for an empty + payload. + + A new keyring can be generated by setting type "keyring", the keyring name + as the description (or NULL) and setting the payload to NULL. + + User defined keys can be created by specifying type "user". It is + recommended that a user defined key's description by prefixed with a type + ID and a colon, such as "krb5tgt:" for a Kerberos 5 ticket granting + ticket. + + Any other type must have been registered with the kernel in advance by a + kernel service such as a filesystem. + + The ID of the new or updated key is returned if successful. + + + (*) Search the process's keyrings for a key, potentially calling out to + userspace to create it. + + key_serial_t request_key(const char *type, const char *description, + const char *callout_info, + key_serial_t dest_keyring); + + This function searches all the process's keyrings in the order thread, + process, session for a matching key. This works very much like + KEYCTL_SEARCH, including the optional attachment of the discovered key to + a keyring. + + If a key cannot be found, and if callout_info is not NULL, then + /sbin/request-key will be invoked in an attempt to obtain a key. The + callout_info string will be passed as an argument to the program. + + See also Documentation/security/keys-request-key.txt. + + +The keyctl syscall functions are: + + (*) Map a special key ID to a real key ID for this process: + + key_serial_t keyctl(KEYCTL_GET_KEYRING_ID, key_serial_t id, + int create); + + The special key specified by "id" is looked up (with the key being created + if necessary) and the ID of the key or keyring thus found is returned if + it exists. + + If the key does not yet exist, the key will be created if "create" is + non-zero; and the error ENOKEY will be returned if "create" is zero. + + + (*) Replace the session keyring this process subscribes to with a new one: + + key_serial_t keyctl(KEYCTL_JOIN_SESSION_KEYRING, const char *name); + + If name is NULL, an anonymous keyring is created attached to the process + as its session keyring, displacing the old session keyring. + + If name is not NULL, if a keyring of that name exists, the process + attempts to attach it as the session keyring, returning an error if that + is not permitted; otherwise a new keyring of that name is created and + attached as the session keyring. + + To attach to a named keyring, the keyring must have search permission for + the process's ownership. + + The ID of the new session keyring is returned if successful. + + + (*) Update the specified key: + + long keyctl(KEYCTL_UPDATE, key_serial_t key, const void *payload, + size_t plen); + + This will try to update the specified key with the given payload, or it + will return error EOPNOTSUPP if that function is not supported by the key + type. The process must also have permission to write to the key to be able + to update it. + + The payload is of length plen, and may be absent or empty as for + add_key(). + + + (*) Revoke a key: + + long keyctl(KEYCTL_REVOKE, key_serial_t key); + + This makes a key unavailable for further operations. Further attempts to + use the key will be met with error EKEYREVOKED, and the key will no longer + be findable. + + + (*) Change the ownership of a key: + + long keyctl(KEYCTL_CHOWN, key_serial_t key, uid_t uid, gid_t gid); + + This function permits a key's owner and group ID to be changed. Either one + of uid or gid can be set to -1 to suppress that change. + + Only the superuser can change a key's owner to something other than the + key's current owner. Similarly, only the superuser can change a key's + group ID to something other than the calling process's group ID or one of + its group list members. + + + (*) Change the permissions mask on a key: + + long keyctl(KEYCTL_SETPERM, key_serial_t key, key_perm_t perm); + + This function permits the owner of a key or the superuser to change the + permissions mask on a key. + + Only bits the available bits are permitted; if any other bits are set, + error EINVAL will be returned. + + + (*) Describe a key: + + long keyctl(KEYCTL_DESCRIBE, key_serial_t key, char *buffer, + size_t buflen); + + This function returns a summary of the key's attributes (but not its + payload data) as a string in the buffer provided. + + Unless there's an error, it always returns the amount of data it could + produce, even if that's too big for the buffer, but it won't copy more + than requested to userspace. If the buffer pointer is NULL then no copy + will take place. + + A process must have view permission on the key for this function to be + successful. + + If successful, a string is placed in the buffer in the following format: + + ;;;; + + Where type and description are strings, uid and gid are decimal, and perm + is hexadecimal. A NUL character is included at the end of the string if + the buffer is sufficiently big. + + This can be parsed with + + sscanf(buffer, "%[^;];%d;%d;%o;%s", type, &uid, &gid, &mode, desc); + + + (*) Clear out a keyring: + + long keyctl(KEYCTL_CLEAR, key_serial_t keyring); + + This function clears the list of keys attached to a keyring. The calling + process must have write permission on the keyring, and it must be a + keyring (or else error ENOTDIR will result). + + + (*) Link a key into a keyring: + + long keyctl(KEYCTL_LINK, key_serial_t keyring, key_serial_t key); + + This function creates a link from the keyring to the key. The process must + have write permission on the keyring and must have link permission on the + key. + + Should the keyring not be a keyring, error ENOTDIR will result; and if the + keyring is full, error ENFILE will result. + + The link procedure checks the nesting of the keyrings, returning ELOOP if + it appears too deep or EDEADLK if the link would introduce a cycle. + + Any links within the keyring to keys that match the new key in terms of + type and description will be discarded from the keyring as the new one is + added. + + + (*) Unlink a key or keyring from another keyring: + + long keyctl(KEYCTL_UNLINK, key_serial_t keyring, key_serial_t key); + + This function looks through the keyring for the first link to the + specified key, and removes it if found. Subsequent links to that key are + ignored. The process must have write permission on the keyring. + + If the keyring is not a keyring, error ENOTDIR will result; and if the key + is not present, error ENOENT will be the result. + + + (*) Search a keyring tree for a key: + + key_serial_t keyctl(KEYCTL_SEARCH, key_serial_t keyring, + const char *type, const char *description, + key_serial_t dest_keyring); + + This searches the keyring tree headed by the specified keyring until a key + is found that matches the type and description criteria. Each keyring is + checked for keys before recursion into its children occurs. + + The process must have search permission on the top level keyring, or else + error EACCES will result. Only keyrings that the process has search + permission on will be recursed into, and only keys and keyrings for which + a process has search permission can be matched. If the specified keyring + is not a keyring, ENOTDIR will result. + + If the search succeeds, the function will attempt to link the found key + into the destination keyring if one is supplied (non-zero ID). All the + constraints applicable to KEYCTL_LINK apply in this case too. + + Error ENOKEY, EKEYREVOKED or EKEYEXPIRED will be returned if the search + fails. On success, the resulting key ID will be returned. + + + (*) Read the payload data from a key: + + long keyctl(KEYCTL_READ, key_serial_t keyring, char *buffer, + size_t buflen); + + This function attempts to read the payload data from the specified key + into the buffer. The process must have read permission on the key to + succeed. + + The returned data will be processed for presentation by the key type. For + instance, a keyring will return an array of key_serial_t entries + representing the IDs of all the keys to which it is subscribed. The user + defined key type will return its data as is. If a key type does not + implement this function, error EOPNOTSUPP will result. + + As much of the data as can be fitted into the buffer will be copied to + userspace if the buffer pointer is not NULL. + + On a successful return, the function will always return the amount of data + available rather than the amount copied. + + + (*) Instantiate a partially constructed key. + + long keyctl(KEYCTL_INSTANTIATE, key_serial_t key, + const void *payload, size_t plen, + key_serial_t keyring); + long keyctl(KEYCTL_INSTANTIATE_IOV, key_serial_t key, + const struct iovec *payload_iov, unsigned ioc, + key_serial_t keyring); + + If the kernel calls back to userspace to complete the instantiation of a + key, userspace should use this call to supply data for the key before the + invoked process returns, or else the key will be marked negative + automatically. + + The process must have write access on the key to be able to instantiate + it, and the key must be uninstantiated. + + If a keyring is specified (non-zero), the key will also be linked into + that keyring, however all the constraints applying in KEYCTL_LINK apply in + this case too. + + The payload and plen arguments describe the payload data as for add_key(). + + The payload_iov and ioc arguments describe the payload data in an iovec + array instead of a single buffer. + + + (*) Negatively instantiate a partially constructed key. + + long keyctl(KEYCTL_NEGATE, key_serial_t key, + unsigned timeout, key_serial_t keyring); + long keyctl(KEYCTL_REJECT, key_serial_t key, + unsigned timeout, unsigned error, key_serial_t keyring); + + If the kernel calls back to userspace to complete the instantiation of a + key, userspace should use this call mark the key as negative before the + invoked process returns if it is unable to fulfil the request. + + The process must have write access on the key to be able to instantiate + it, and the key must be uninstantiated. + + If a keyring is specified (non-zero), the key will also be linked into + that keyring, however all the constraints applying in KEYCTL_LINK apply in + this case too. + + If the key is rejected, future searches for it will return the specified + error code until the rejected key expires. Negating the key is the same + as rejecting the key with ENOKEY as the error code. + + + (*) Set the default request-key destination keyring. + + long keyctl(KEYCTL_SET_REQKEY_KEYRING, int reqkey_defl); + + This sets the default keyring to which implicitly requested keys will be + attached for this thread. reqkey_defl should be one of these constants: + + CONSTANT VALUE NEW DEFAULT KEYRING + ====================================== ====== ======================= + KEY_REQKEY_DEFL_NO_CHANGE -1 No change + KEY_REQKEY_DEFL_DEFAULT 0 Default[1] + KEY_REQKEY_DEFL_THREAD_KEYRING 1 Thread keyring + KEY_REQKEY_DEFL_PROCESS_KEYRING 2 Process keyring + KEY_REQKEY_DEFL_SESSION_KEYRING 3 Session keyring + KEY_REQKEY_DEFL_USER_KEYRING 4 User keyring + KEY_REQKEY_DEFL_USER_SESSION_KEYRING 5 User session keyring + KEY_REQKEY_DEFL_GROUP_KEYRING 6 Group keyring + + The old default will be returned if successful and error EINVAL will be + returned if reqkey_defl is not one of the above values. + + The default keyring can be overridden by the keyring indicated to the + request_key() system call. + + Note that this setting is inherited across fork/exec. + + [1] The default is: the thread keyring if there is one, otherwise + the process keyring if there is one, otherwise the session keyring if + there is one, otherwise the user default session keyring. + + + (*) Set the timeout on a key. + + long keyctl(KEYCTL_SET_TIMEOUT, key_serial_t key, unsigned timeout); + + This sets or clears the timeout on a key. The timeout can be 0 to clear + the timeout or a number of seconds to set the expiry time that far into + the future. + + The process must have attribute modification access on a key to set its + timeout. Timeouts may not be set with this function on negative, revoked + or expired keys. + + + (*) Assume the authority granted to instantiate a key + + long keyctl(KEYCTL_ASSUME_AUTHORITY, key_serial_t key); + + This assumes or divests the authority required to instantiate the + specified key. Authority can only be assumed if the thread has the + authorisation key associated with the specified key in its keyrings + somewhere. + + Once authority is assumed, searches for keys will also search the + requester's keyrings using the requester's security label, UID, GID and + groups. + + If the requested authority is unavailable, error EPERM will be returned, + likewise if the authority has been revoked because the target key is + already instantiated. + + If the specified key is 0, then any assumed authority will be divested. + + The assumed authoritative key is inherited across fork and exec. + + + (*) Get the LSM security context attached to a key. + + long keyctl(KEYCTL_GET_SECURITY, key_serial_t key, char *buffer, + size_t buflen) + + This function returns a string that represents the LSM security context + attached to a key in the buffer provided. + + Unless there's an error, it always returns the amount of data it could + produce, even if that's too big for the buffer, but it won't copy more + than requested to userspace. If the buffer pointer is NULL then no copy + will take place. + + A NUL character is included at the end of the string if the buffer is + sufficiently big. This is included in the returned count. If no LSM is + in force then an empty string will be returned. + + A process must have view permission on the key for this function to be + successful. + + + (*) Install the calling process's session keyring on its parent. + + long keyctl(KEYCTL_SESSION_TO_PARENT); + + This functions attempts to install the calling process's session keyring + on to the calling process's parent, replacing the parent's current session + keyring. + + The calling process must have the same ownership as its parent, the + keyring must have the same ownership as the calling process, the calling + process must have LINK permission on the keyring and the active LSM module + mustn't deny permission, otherwise error EPERM will be returned. + + Error ENOMEM will be returned if there was insufficient memory to complete + the operation, otherwise 0 will be returned to indicate success. + + The keyring will be replaced next time the parent process leaves the + kernel and resumes executing userspace. + + +=============== +KERNEL SERVICES +=============== + +The kernel services for key management are fairly simple to deal with. They can +be broken down into two areas: keys and key types. + +Dealing with keys is fairly straightforward. Firstly, the kernel service +registers its type, then it searches for a key of that type. It should retain +the key as long as it has need of it, and then it should release it. For a +filesystem or device file, a search would probably be performed during the open +call, and the key released upon close. How to deal with conflicting keys due to +two different users opening the same file is left to the filesystem author to +solve. + +To access the key manager, the following header must be #included: + + + +Specific key types should have a header file under include/keys/ that should be +used to access that type. For keys of type "user", for example, that would be: + + + +Note that there are two different types of pointers to keys that may be +encountered: + + (*) struct key * + + This simply points to the key structure itself. Key structures will be at + least four-byte aligned. + + (*) key_ref_t + + This is equivalent to a struct key *, but the least significant bit is set + if the caller "possesses" the key. By "possession" it is meant that the + calling processes has a searchable link to the key from one of its + keyrings. There are three functions for dealing with these: + + key_ref_t make_key_ref(const struct key *key, + unsigned long possession); + + struct key *key_ref_to_ptr(const key_ref_t key_ref); + + unsigned long is_key_possessed(const key_ref_t key_ref); + + The first function constructs a key reference from a key pointer and + possession information (which must be 0 or 1 and not any other value). + + The second function retrieves the key pointer from a reference and the + third retrieves the possession flag. + +When accessing a key's payload contents, certain precautions must be taken to +prevent access vs modification races. See the section "Notes on accessing +payload contents" for more information. + +(*) To search for a key, call: + + struct key *request_key(const struct key_type *type, + const char *description, + const char *callout_info); + + This is used to request a key or keyring with a description that matches + the description specified according to the key type's match function. This + permits approximate matching to occur. If callout_string is not NULL, then + /sbin/request-key will be invoked in an attempt to obtain the key from + userspace. In that case, callout_string will be passed as an argument to + the program. + + Should the function fail error ENOKEY, EKEYEXPIRED or EKEYREVOKED will be + returned. + + If successful, the key will have been attached to the default keyring for + implicitly obtained request-key keys, as set by KEYCTL_SET_REQKEY_KEYRING. + + See also Documentation/security/keys-request-key.txt. + + +(*) To search for a key, passing auxiliary data to the upcaller, call: + + struct key *request_key_with_auxdata(const struct key_type *type, + const char *description, + const void *callout_info, + size_t callout_len, + void *aux); + + This is identical to request_key(), except that the auxiliary data is + passed to the key_type->request_key() op if it exists, and the callout_info + is a blob of length callout_len, if given (the length may be 0). + + +(*) A key can be requested asynchronously by calling one of: + + struct key *request_key_async(const struct key_type *type, + const char *description, + const void *callout_info, + size_t callout_len); + + or: + + struct key *request_key_async_with_auxdata(const struct key_type *type, + const char *description, + const char *callout_info, + size_t callout_len, + void *aux); + + which are asynchronous equivalents of request_key() and + request_key_with_auxdata() respectively. + + These two functions return with the key potentially still under + construction. To wait for construction completion, the following should be + called: + + int wait_for_key_construction(struct key *key, bool intr); + + The function will wait for the key to finish being constructed and then + invokes key_validate() to return an appropriate value to indicate the state + of the key (0 indicates the key is usable). + + If intr is true, then the wait can be interrupted by a signal, in which + case error ERESTARTSYS will be returned. + + +(*) When it is no longer required, the key should be released using: + + void key_put(struct key *key); + + Or: + + void key_ref_put(key_ref_t key_ref); + + These can be called from interrupt context. If CONFIG_KEYS is not set then + the argument will not be parsed. + + +(*) Extra references can be made to a key by calling the following function: + + struct key *key_get(struct key *key); + + These need to be disposed of by calling key_put() when they've been + finished with. The key pointer passed in will be returned. If the pointer + is NULL or CONFIG_KEYS is not set then the key will not be dereferenced and + no increment will take place. + + +(*) A key's serial number can be obtained by calling: + + key_serial_t key_serial(struct key *key); + + If key is NULL or if CONFIG_KEYS is not set then 0 will be returned (in the + latter case without parsing the argument). + + +(*) If a keyring was found in the search, this can be further searched by: + + key_ref_t keyring_search(key_ref_t keyring_ref, + const struct key_type *type, + const char *description) + + This searches the keyring tree specified for a matching key. Error ENOKEY + is returned upon failure (use IS_ERR/PTR_ERR to determine). If successful, + the returned key will need to be released. + + The possession attribute from the keyring reference is used to control + access through the permissions mask and is propagated to the returned key + reference pointer if successful. + + +(*) To check the validity of a key, this function can be called: + + int validate_key(struct key *key); + + This checks that the key in question hasn't expired or and hasn't been + revoked. Should the key be invalid, error EKEYEXPIRED or EKEYREVOKED will + be returned. If the key is NULL or if CONFIG_KEYS is not set then 0 will be + returned (in the latter case without parsing the argument). + + +(*) To register a key type, the following function should be called: + + int register_key_type(struct key_type *type); + + This will return error EEXIST if a type of the same name is already + present. + + +(*) To unregister a key type, call: + + void unregister_key_type(struct key_type *type); + + +Under some circumstances, it may be desirable to deal with a bundle of keys. +The facility provides access to the keyring type for managing such a bundle: + + struct key_type key_type_keyring; + +This can be used with a function such as request_key() to find a specific +keyring in a process's keyrings. A keyring thus found can then be searched +with keyring_search(). Note that it is not possible to use request_key() to +search a specific keyring, so using keyrings in this way is of limited utility. + + +=================================== +NOTES ON ACCESSING PAYLOAD CONTENTS +=================================== + +The simplest payload is just a number in key->payload.value. In this case, +there's no need to indulge in RCU or locking when accessing the payload. + +More complex payload contents must be allocated and a pointer to them set in +key->payload.data. One of the following ways must be selected to access the +data: + + (1) Unmodifiable key type. + + If the key type does not have a modify method, then the key's payload can + be accessed without any form of locking, provided that it's known to be + instantiated (uninstantiated keys cannot be "found"). + + (2) The key's semaphore. + + The semaphore could be used to govern access to the payload and to control + the payload pointer. It must be write-locked for modifications and would + have to be read-locked for general access. The disadvantage of doing this + is that the accessor may be required to sleep. + + (3) RCU. + + RCU must be used when the semaphore isn't already held; if the semaphore + is held then the contents can't change under you unexpectedly as the + semaphore must still be used to serialise modifications to the key. The + key management code takes care of this for the key type. + + However, this means using: + + rcu_read_lock() ... rcu_dereference() ... rcu_read_unlock() + + to read the pointer, and: + + rcu_dereference() ... rcu_assign_pointer() ... call_rcu() + + to set the pointer and dispose of the old contents after a grace period. + Note that only the key type should ever modify a key's payload. + + Furthermore, an RCU controlled payload must hold a struct rcu_head for the + use of call_rcu() and, if the payload is of variable size, the length of + the payload. key->datalen cannot be relied upon to be consistent with the + payload just dereferenced if the key's semaphore is not held. + + +=================== +DEFINING A KEY TYPE +=================== + +A kernel service may want to define its own key type. For instance, an AFS +filesystem might want to define a Kerberos 5 ticket key type. To do this, it +author fills in a key_type struct and registers it with the system. + +Source files that implement key types should include the following header file: + + + +The structure has a number of fields, some of which are mandatory: + + (*) const char *name + + The name of the key type. This is used to translate a key type name + supplied by userspace into a pointer to the structure. + + + (*) size_t def_datalen + + This is optional - it supplies the default payload data length as + contributed to the quota. If the key type's payload is always or almost + always the same size, then this is a more efficient way to do things. + + The data length (and quota) on a particular key can always be changed + during instantiation or update by calling: + + int key_payload_reserve(struct key *key, size_t datalen); + + With the revised data length. Error EDQUOT will be returned if this is not + viable. + + + (*) int (*vet_description)(const char *description); + + This optional method is called to vet a key description. If the key type + doesn't approve of the key description, it may return an error, otherwise + it should return 0. + + + (*) int (*instantiate)(struct key *key, const void *data, size_t datalen); + + This method is called to attach a payload to a key during construction. + The payload attached need not bear any relation to the data passed to this + function. + + If the amount of data attached to the key differs from the size in + keytype->def_datalen, then key_payload_reserve() should be called. + + This method does not have to lock the key in order to attach a payload. + The fact that KEY_FLAG_INSTANTIATED is not set in key->flags prevents + anything else from gaining access to the key. + + It is safe to sleep in this method. + + + (*) int (*update)(struct key *key, const void *data, size_t datalen); + + If this type of key can be updated, then this method should be provided. + It is called to update a key's payload from the blob of data provided. + + key_payload_reserve() should be called if the data length might change + before any changes are actually made. Note that if this succeeds, the type + is committed to changing the key because it's already been altered, so all + memory allocation must be done first. + + The key will have its semaphore write-locked before this method is called, + but this only deters other writers; any changes to the key's payload must + be made under RCU conditions, and call_rcu() must be used to dispose of + the old payload. + + key_payload_reserve() should be called before the changes are made, but + after all allocations and other potentially failing function calls are + made. + + It is safe to sleep in this method. + + + (*) int (*match)(const struct key *key, const void *desc); + + This method is called to match a key against a description. It should + return non-zero if the two match, zero if they don't. + + This method should not need to lock the key in any way. The type and + description can be considered invariant, and the payload should not be + accessed (the key may not yet be instantiated). + + It is not safe to sleep in this method; the caller may hold spinlocks. + + + (*) void (*revoke)(struct key *key); + + This method is optional. It is called to discard part of the payload + data upon a key being revoked. The caller will have the key semaphore + write-locked. + + It is safe to sleep in this method, though care should be taken to avoid + a deadlock against the key semaphore. + + + (*) void (*destroy)(struct key *key); + + This method is optional. It is called to discard the payload data on a key + when it is being destroyed. + + This method does not need to lock the key to access the payload; it can + consider the key as being inaccessible at this time. Note that the key's + type may have been changed before this function is called. + + It is not safe to sleep in this method; the caller may hold spinlocks. + + + (*) void (*describe)(const struct key *key, struct seq_file *p); + + This method is optional. It is called during /proc/keys reading to + summarise a key's description and payload in text form. + + This method will be called with the RCU read lock held. rcu_dereference() + should be used to read the payload pointer if the payload is to be + accessed. key->datalen cannot be trusted to stay consistent with the + contents of the payload. + + The description will not change, though the key's state may. + + It is not safe to sleep in this method; the RCU read lock is held by the + caller. + + + (*) long (*read)(const struct key *key, char __user *buffer, size_t buflen); + + This method is optional. It is called by KEYCTL_READ to translate the + key's payload into something a blob of data for userspace to deal with. + Ideally, the blob should be in the same format as that passed in to the + instantiate and update methods. + + If successful, the blob size that could be produced should be returned + rather than the size copied. + + This method will be called with the key's semaphore read-locked. This will + prevent the key's payload changing. It is not necessary to use RCU locking + when accessing the key's payload. It is safe to sleep in this method, such + as might happen when the userspace buffer is accessed. + + + (*) int (*request_key)(struct key_construction *cons, const char *op, + void *aux); + + This method is optional. If provided, request_key() and friends will + invoke this function rather than upcalling to /sbin/request-key to operate + upon a key of this type. + + The aux parameter is as passed to request_key_async_with_auxdata() and + similar or is NULL otherwise. Also passed are the construction record for + the key to be operated upon and the operation type (currently only + "create"). + + This method is permitted to return before the upcall is complete, but the + following function must be called under all circumstances to complete the + instantiation process, whether or not it succeeds, whether or not there's + an error: + + void complete_request_key(struct key_construction *cons, int error); + + The error parameter should be 0 on success, -ve on error. The + construction record is destroyed by this action and the authorisation key + will be revoked. If an error is indicated, the key under construction + will be negatively instantiated if it wasn't already instantiated. + + If this method returns an error, that error will be returned to the + caller of request_key*(). complete_request_key() must be called prior to + returning. + + The key under construction and the authorisation key can be found in the + key_construction struct pointed to by cons: + + (*) struct key *key; + + The key under construction. + + (*) struct key *authkey; + + The authorisation key. + + +============================ +REQUEST-KEY CALLBACK SERVICE +============================ + +To create a new key, the kernel will attempt to execute the following command +line: + + /sbin/request-key create \ + + + is the key being constructed, and the three keyrings are the process +keyrings from the process that caused the search to be issued. These are +included for two reasons: + + (1) There may be an authentication token in one of the keyrings that is + required to obtain the key, eg: a Kerberos Ticket-Granting Ticket. + + (2) The new key should probably be cached in one of these rings. + +This program should set it UID and GID to those specified before attempting to +access any more keys. It may then look around for a user specific process to +hand the request off to (perhaps a path held in placed in another key by, for +example, the KDE desktop manager). + +The program (or whatever it calls) should finish construction of the key by +calling KEYCTL_INSTANTIATE or KEYCTL_INSTANTIATE_IOV, which also permits it to +cache the key in one of the keyrings (probably the session ring) before +returning. Alternatively, the key can be marked as negative with KEYCTL_NEGATE +or KEYCTL_REJECT; this also permits the key to be cached in one of the +keyrings. + +If it returns with the key remaining in the unconstructed state, the key will +be marked as being negative, it will be added to the session keyring, and an +error will be returned to the key requestor. + +Supplementary information may be provided from whoever or whatever invoked this +service. This will be passed as the parameter. If no such +information was made available, then "-" will be passed as this parameter +instead. + + +Similarly, the kernel may attempt to update an expired or a soon to expire key +by executing: + + /sbin/request-key update \ + + +In this case, the program isn't required to actually attach the key to a ring; +the rings are provided for reference. + + +================== +GARBAGE COLLECTION +================== + +Dead keys (for which the type has been removed) will be automatically unlinked +from those keyrings that point to them and deleted as soon as possible by a +background garbage collector. + +Similarly, revoked and expired keys will be garbage collected, but only after a +certain amount of time has passed. This time is set as a number of seconds in: + + /proc/sys/kernel/keys/gc_delay diff --git a/Documentation/security/tomoyo.txt b/Documentation/security/tomoyo.txt new file mode 100644 index 000000000000..200a2d37cbc8 --- /dev/null +++ b/Documentation/security/tomoyo.txt @@ -0,0 +1,55 @@ +--- What is TOMOYO? --- + +TOMOYO is a name-based MAC extension (LSM module) for the Linux kernel. + +LiveCD-based tutorials are available at +http://tomoyo.sourceforge.jp/1.7/1st-step/ubuntu10.04-live/ +http://tomoyo.sourceforge.jp/1.7/1st-step/centos5-live/ . +Though these tutorials use non-LSM version of TOMOYO, they are useful for you +to know what TOMOYO is. + +--- How to enable TOMOYO? --- + +Build the kernel with CONFIG_SECURITY_TOMOYO=y and pass "security=tomoyo" on +kernel's command line. + +Please see http://tomoyo.sourceforge.jp/2.3/ for details. + +--- Where is documentation? --- + +User <-> Kernel interface documentation is available at +http://tomoyo.sourceforge.jp/2.3/policy-reference.html . + +Materials we prepared for seminars and symposiums are available at +http://sourceforge.jp/projects/tomoyo/docs/?category_id=532&language_id=1 . +Below lists are chosen from three aspects. + +What is TOMOYO? + TOMOYO Linux Overview + http://sourceforge.jp/projects/tomoyo/docs/lca2009-takeda.pdf + TOMOYO Linux: pragmatic and manageable security for Linux + http://sourceforge.jp/projects/tomoyo/docs/freedomhectaipei-tomoyo.pdf + TOMOYO Linux: A Practical Method to Understand and Protect Your Own Linux Box + http://sourceforge.jp/projects/tomoyo/docs/PacSec2007-en-no-demo.pdf + +What can TOMOYO do? + Deep inside TOMOYO Linux + http://sourceforge.jp/projects/tomoyo/docs/lca2009-kumaneko.pdf + The role of "pathname based access control" in security. + http://sourceforge.jp/projects/tomoyo/docs/lfj2008-bof.pdf + +History of TOMOYO? + Realities of Mainlining + http://sourceforge.jp/projects/tomoyo/docs/lfj2008.pdf + +--- What is future plan? --- + +We believe that inode based security and name based security are complementary +and both should be used together. But unfortunately, so far, we cannot enable +multiple LSM modules at the same time. We feel sorry that you have to give up +SELinux/SMACK/AppArmor etc. when you want to use TOMOYO. + +We hope that LSM becomes stackable in future. Meanwhile, you can use non-LSM +version of TOMOYO, available at http://tomoyo.sourceforge.jp/1.7/ . +LSM version of TOMOYO is a subset of non-LSM version of TOMOYO. We are planning +to port non-LSM version's functionalities to LSM versions. diff --git a/Documentation/tomoyo.txt b/Documentation/tomoyo.txt deleted file mode 100644 index 200a2d37cbc8..000000000000 --- a/Documentation/tomoyo.txt +++ /dev/null @@ -1,55 +0,0 @@ ---- What is TOMOYO? --- - -TOMOYO is a name-based MAC extension (LSM module) for the Linux kernel. - -LiveCD-based tutorials are available at -http://tomoyo.sourceforge.jp/1.7/1st-step/ubuntu10.04-live/ -http://tomoyo.sourceforge.jp/1.7/1st-step/centos5-live/ . -Though these tutorials use non-LSM version of TOMOYO, they are useful for you -to know what TOMOYO is. - ---- How to enable TOMOYO? --- - -Build the kernel with CONFIG_SECURITY_TOMOYO=y and pass "security=tomoyo" on -kernel's command line. - -Please see http://tomoyo.sourceforge.jp/2.3/ for details. - ---- Where is documentation? --- - -User <-> Kernel interface documentation is available at -http://tomoyo.sourceforge.jp/2.3/policy-reference.html . - -Materials we prepared for seminars and symposiums are available at -http://sourceforge.jp/projects/tomoyo/docs/?category_id=532&language_id=1 . -Below lists are chosen from three aspects. - -What is TOMOYO? - TOMOYO Linux Overview - http://sourceforge.jp/projects/tomoyo/docs/lca2009-takeda.pdf - TOMOYO Linux: pragmatic and manageable security for Linux - http://sourceforge.jp/projects/tomoyo/docs/freedomhectaipei-tomoyo.pdf - TOMOYO Linux: A Practical Method to Understand and Protect Your Own Linux Box - http://sourceforge.jp/projects/tomoyo/docs/PacSec2007-en-no-demo.pdf - -What can TOMOYO do? - Deep inside TOMOYO Linux - http://sourceforge.jp/projects/tomoyo/docs/lca2009-kumaneko.pdf - The role of "pathname based access control" in security. - http://sourceforge.jp/projects/tomoyo/docs/lfj2008-bof.pdf - -History of TOMOYO? - Realities of Mainlining - http://sourceforge.jp/projects/tomoyo/docs/lfj2008.pdf - ---- What is future plan? --- - -We believe that inode based security and name based security are complementary -and both should be used together. But unfortunately, so far, we cannot enable -multiple LSM modules at the same time. We feel sorry that you have to give up -SELinux/SMACK/AppArmor etc. when you want to use TOMOYO. - -We hope that LSM becomes stackable in future. Meanwhile, you can use non-LSM -version of TOMOYO, available at http://tomoyo.sourceforge.jp/1.7/ . -LSM version of TOMOYO is a subset of non-LSM version of TOMOYO. We are planning -to port non-LSM version's functionalities to LSM versions. diff --git a/MAINTAINERS b/MAINTAINERS index 69f19f10314a..3fa170ba5f98 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3705,7 +3705,7 @@ KEYS/KEYRINGS: M: David Howells L: keyrings@linux-nfs.org S: Maintained -F: Documentation/keys.txt +F: Documentation/security/keys.txt F: include/linux/key.h F: include/linux/key-type.h F: include/keys/ @@ -3717,7 +3717,7 @@ M: Mimi Zohar L: linux-security-module@vger.kernel.org L: keyrings@linux-nfs.org S: Supported -F: Documentation/keys-trusted-encrypted.txt +F: Documentation/security/keys-trusted-encrypted.txt F: include/keys/trusted-type.h F: security/keys/trusted.c F: security/keys/trusted.h @@ -3728,7 +3728,7 @@ M: David Safford L: linux-security-module@vger.kernel.org L: keyrings@linux-nfs.org S: Supported -F: Documentation/keys-trusted-encrypted.txt +F: Documentation/security/keys-trusted-encrypted.txt F: include/keys/encrypted-type.h F: security/keys/encrypted.c F: security/keys/encrypted.h diff --git a/include/linux/cred.h b/include/linux/cred.h index be16b61283cc..82607992f308 100644 --- a/include/linux/cred.h +++ b/include/linux/cred.h @@ -1,4 +1,4 @@ -/* Credentials management - see Documentation/credentials.txt +/* Credentials management - see Documentation/security/credentials.txt * * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) diff --git a/include/linux/key.h b/include/linux/key.h index b2bb01719561..303982a69933 100644 --- a/include/linux/key.h +++ b/include/linux/key.h @@ -9,7 +9,7 @@ * 2 of the License, or (at your option) any later version. * * - * See Documentation/keys.txt for information on keys/keyrings. + * See Documentation/security/keys.txt for information on keys/keyrings. */ #ifndef _LINUX_KEY_H diff --git a/kernel/cred.c b/kernel/cred.c index 8093c16b84b1..004e3679624d 100644 --- a/kernel/cred.c +++ b/kernel/cred.c @@ -1,4 +1,4 @@ -/* Task credentials management - see Documentation/credentials.txt +/* Task credentials management - see Documentation/security/credentials.txt * * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) diff --git a/scripts/selinux/README b/scripts/selinux/README index a936315ba2c8..4d020ecb7524 100644 --- a/scripts/selinux/README +++ b/scripts/selinux/README @@ -1,2 +1,2 @@ -Please see Documentation/SELinux.txt for information on +Please see Documentation/security/SELinux.txt for information on installing a dummy SELinux policy. diff --git a/security/apparmor/match.c b/security/apparmor/match.c index 06d764ccbbe5..94de6b4907c8 100644 --- a/security/apparmor/match.c +++ b/security/apparmor/match.c @@ -194,7 +194,7 @@ void aa_dfa_free_kref(struct kref *kref) * @flags: flags controlling what type of accept tables are acceptable * * Unpack a dfa that has been serialized. To find information on the dfa - * format look in Documentation/apparmor.txt + * format look in Documentation/security/apparmor.txt * Assumes the dfa @blob stream has been aligned on a 8 byte boundary * * Returns: an unpacked dfa ready for matching or ERR_PTR on failure diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c index e33aaf7e5744..d6d9a57b5652 100644 --- a/security/apparmor/policy_unpack.c +++ b/security/apparmor/policy_unpack.c @@ -12,8 +12,8 @@ * published by the Free Software Foundation, version 2 of the * License. * - * AppArmor uses a serialized binary format for loading policy. - * To find policy format documentation look in Documentation/apparmor.txt + * AppArmor uses a serialized binary format for loading policy. To find + * policy format documentation look in Documentation/security/apparmor.txt * All policy is validated before it is used. */ diff --git a/security/keys/encrypted.c b/security/keys/encrypted.c index 69907a58a683..b1cba5bf0a5e 100644 --- a/security/keys/encrypted.c +++ b/security/keys/encrypted.c @@ -8,7 +8,7 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 2 of the License. * - * See Documentation/keys-trusted-encrypted.txt + * See Documentation/security/keys-trusted-encrypted.txt */ #include diff --git a/security/keys/request_key.c b/security/keys/request_key.c index df3c0417ee40..d41cc153a313 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c @@ -8,7 +8,7 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * - * See Documentation/keys-request-key.txt + * See Documentation/security/keys-request-key.txt */ #include diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c index 68164031a74e..3c0cfdec6e37 100644 --- a/security/keys/request_key_auth.c +++ b/security/keys/request_key_auth.c @@ -8,7 +8,7 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * - * See Documentation/keys-request-key.txt + * See Documentation/security/keys-request-key.txt */ #include diff --git a/security/keys/trusted.c b/security/keys/trusted.c index c99b9368368c..0c33e2ea1f3c 100644 --- a/security/keys/trusted.c +++ b/security/keys/trusted.c @@ -8,7 +8,7 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 2 of the License. * - * See Documentation/keys-trusted-encrypted.txt + * See Documentation/security/keys-trusted-encrypted.txt */ #include -- cgit From 4539c24fe4f92c09ee668ef959d3e8180df619b9 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 17 May 2011 16:12:36 -0600 Subject: tty/serial: Add explicit PORT_TEGRA type Tegra's UART is currently auto-detected as PORT_XSCALE due to register bit UART_IER.UUE being writable. However, the Tegra documentation states that this register bit is reserved. Hence, we should not program it. Instead, the documentation specifies that the UART is 16550 compatible. However, Tegra does need register bit UART_IER.RTOIE set, which is not enabled by any 16550 port type. This was not noticed before, since PORT_XSCALE enables CAP_UUE, which conflates both UUE and RTOIE bit programming. This change defines PORT_TEGRA that doesn't set UART_CAP_UUE, but does set UART_CAP_RTOIE, which is a new capability indicating that the RTOIE bit needs to be enabled. Based-on-code-by: Laxman Dewangan Cc: Laxman Dewangan Signed-off-by: Stephen Warren Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250.c | 14 ++++++++++++-- drivers/tty/serial/8250.h | 1 + include/linux/serial_core.h | 3 ++- include/linux/serial_reg.h | 1 + 4 files changed, 16 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c index 54482d724fee..a5e290de8c93 100644 --- a/drivers/tty/serial/8250.c +++ b/drivers/tty/serial/8250.c @@ -271,7 +271,7 @@ static const struct serial8250_config uart_config[] = { .fifo_size = 32, .tx_loadsz = 32, .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, - .flags = UART_CAP_FIFO | UART_CAP_UUE, + .flags = UART_CAP_FIFO | UART_CAP_UUE | UART_CAP_RTOIE, }, [PORT_RM9000] = { .name = "RM9000", @@ -301,6 +301,14 @@ static const struct serial8250_config uart_config[] = { .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, .flags = UART_CAP_FIFO | UART_CAP_AFE, }, + [PORT_TEGRA] = { + .name = "Tegra", + .fifo_size = 32, + .tx_loadsz = 8, + .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 | + UART_FCR_T_TRIG_01, + .flags = UART_CAP_FIFO | UART_CAP_RTOIE, + }, }; #if defined(CONFIG_MIPS_ALCHEMY) @@ -2403,7 +2411,9 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, UART_ENABLE_MS(&up->port, termios->c_cflag)) up->ier |= UART_IER_MSI; if (up->capabilities & UART_CAP_UUE) - up->ier |= UART_IER_UUE | UART_IER_RTOIE; + up->ier |= UART_IER_UUE; + if (up->capabilities & UART_CAP_RTOIE) + up->ier |= UART_IER_RTOIE; serial_out(up, UART_IER, up->ier); diff --git a/drivers/tty/serial/8250.h b/drivers/tty/serial/8250.h index d13b586c0f72..6edf4a6a22d4 100644 --- a/drivers/tty/serial/8250.h +++ b/drivers/tty/serial/8250.h @@ -42,6 +42,7 @@ struct serial8250_config { #define UART_CAP_SLEEP (1 << 10) /* UART has IER sleep */ #define UART_CAP_AFE (1 << 11) /* MCR-based hw flow control */ #define UART_CAP_UUE (1 << 12) /* UART needs IER bit 6 set (Xscale) */ +#define UART_CAP_RTOIE (1 << 13) /* UART needs IER bit 4 set (Xscale, Tegra) */ #define UART_BUG_QUOT (1 << 0) /* UART has buggy quot LSB */ #define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */ diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 95d479ba514e..a5c31146a337 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -45,7 +45,8 @@ #define PORT_OCTEON 17 /* Cavium OCTEON internal UART */ #define PORT_AR7 18 /* Texas Instruments AR7 internal UART */ #define PORT_U6_16550A 19 /* ST-Ericsson U6xxx internal UART */ -#define PORT_MAX_8250 19 /* max port ID */ +#define PORT_TEGRA 20 /* NVIDIA Tegra internal UART */ +#define PORT_MAX_8250 20 /* max port ID */ /* * ARM specific type numbers. These are not currently guaranteed diff --git a/include/linux/serial_reg.h b/include/linux/serial_reg.h index 3ecb71a9e505..5f66e8499fb9 100644 --- a/include/linux/serial_reg.h +++ b/include/linux/serial_reg.h @@ -57,6 +57,7 @@ * ST16C654: 8 16 56 60 8 16 32 56 PORT_16654 * TI16C750: 1 16 32 56 xx xx xx xx PORT_16750 * TI16C752: 8 16 56 60 8 16 32 56 + * Tegra: 1 4 8 14 16 8 4 1 PORT_TEGRA */ #define UART_FCR_R_TRIG_00 0x00 #define UART_FCR_R_TRIG_01 0x40 -- cgit From 5f873bae704cf8b7cbd64b5720912266286c9146 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 17 May 2011 16:12:37 -0600 Subject: tty/serial: Fix break handling for PORT_TEGRA When a break is received, Tegra's UART apparently fills the FIFO with 0 bytes. These must be drained so that they aren't interpreted as actual data received. This allows e.g. MAGIC_SYSRQ to work on Tegra's UARTs. v2: Added FIXME comment to clear_rx_fifo Originally-by: Laxman Dewangan Cc: Laxman Dewangan Signed-off-by: Stephen Warren Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250.c | 28 ++++++++++++++++++++++++++++ include/linux/serial_reg.h | 1 + 2 files changed, 29 insertions(+) (limited to 'include/linux') diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c index a5e290de8c93..b40f7b90c81d 100644 --- a/drivers/tty/serial/8250.c +++ b/drivers/tty/serial/8250.c @@ -1433,6 +1433,27 @@ static void serial8250_enable_ms(struct uart_port *port) serial_out(up, UART_IER, up->ier); } +/* + * Clear the Tegra rx fifo after a break + * + * FIXME: This needs to become a port specific callback once we have a + * framework for this + */ +static void clear_rx_fifo(struct uart_8250_port *up) +{ + unsigned int status, tmout = 10000; + do { + status = serial_in(up, UART_LSR); + if (status & (UART_LSR_FIFOE | UART_LSR_BRK_ERROR_BITS)) + status = serial_in(up, UART_RX); + else + break; + if (--tmout == 0) + break; + udelay(1); + } while (1); +} + static void receive_chars(struct uart_8250_port *up, unsigned int *status) { @@ -1467,6 +1488,13 @@ receive_chars(struct uart_8250_port *up, unsigned int *status) if (lsr & UART_LSR_BI) { lsr &= ~(UART_LSR_FE | UART_LSR_PE); up->port.icount.brk++; + /* + * If tegra port then clear the rx fifo to + * accept another break/character. + */ + if (up->port.type == PORT_TEGRA) + clear_rx_fifo(up); + /* * We do the SysRQ and SAK checking * here because otherwise the break diff --git a/include/linux/serial_reg.h b/include/linux/serial_reg.h index 5f66e8499fb9..c75bda37c18e 100644 --- a/include/linux/serial_reg.h +++ b/include/linux/serial_reg.h @@ -119,6 +119,7 @@ #define UART_MCR_DTR 0x01 /* DTR complement */ #define UART_LSR 5 /* In: Line Status Register */ +#define UART_LSR_FIFOE 0x80 /* Fifo error */ #define UART_LSR_TEMT 0x40 /* Transmitter empty */ #define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */ #define UART_LSR_BI 0x10 /* Break interrupt indicator */ -- cgit From 8a745f1f39b7a20047a362b67ce9151c07d14440 Mon Sep 17 00:00:00 2001 From: Kristen Carlson Accardi Date: Fri, 4 Mar 2011 10:24:11 -0800 Subject: libata: Power off empty ports Give users the option of completely powering off unoccupied SATA ports using the existing min_power link_power_management_policy option. When the use selects this option on an empty port, we will power the port off by setting DET to off. For occupied ports, behavior is unchanged. Signed-off-by: Kristen Carlson Accardi Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 10 ++++++++-- drivers/ata/libata-eh.c | 2 +- include/linux/libata.h | 1 + 3 files changed, 10 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 76c3c15cb1e6..736bee5dafeb 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -3619,8 +3619,14 @@ int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy, scontrol |= (0x2 << 8); break; case ATA_LPM_MIN_POWER: - /* no restrictions on LPM transitions */ - scontrol &= ~(0x3 << 8); + if (ata_link_nr_enabled(link) > 0) + /* no restrictions on LPM transitions */ + scontrol &= ~(0x3 << 8); + else { + /* empty port, power off */ + scontrol &= ~0xf; + scontrol |= (0x1 << 2); + } break; default: WARN_ON(1); diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index dad9fd660f37..dfb6e9d3d759 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -3423,7 +3423,7 @@ fail: return rc; } -static int ata_link_nr_enabled(struct ata_link *link) +int ata_link_nr_enabled(struct ata_link *link) { struct ata_device *dev; int cnt = 0; diff --git a/include/linux/libata.h b/include/linux/libata.h index 04f32a3eb26b..5a9926b34072 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1151,6 +1151,7 @@ extern void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset, ata_reset_fn_t softreset, ata_reset_fn_t hardreset, ata_postreset_fn_t postreset); extern void ata_std_error_handler(struct ata_port *ap); +extern int ata_link_nr_enabled(struct ata_link *link); /* * Base operations to inherit from and initializers for sht -- cgit From 1477fcc290b3d5c2614bde98bf3b1154c538860d Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Fri, 20 May 2011 11:11:53 +1000 Subject: signal.h need a definition of struct task_struct This fixes these build errors on powerpc: In file included from arch/powerpc/mm/fault.c:18: include/linux/signal.h:239: error: 'struct task_struct' declared inside parameter list include/linux/signal.h:239: error: its scope is only this definition or declaration, which is probably not what you want include/linux/signal.h:240: error: 'struct task_struct' declared inside parameter list .. Exposed by commit e66eed651fd1 ("list: remove prefetching from regular list iterators"), which removed the include of from . Without that, linux/signal.h no longer accidentally got the declaration of 'struct task_struct'. Fix by properly declaring the struct, rather than introducing any new header file dependency. Signed-off-by: Stephen Rothwell Signed-off-by: Linus Torvalds --- include/linux/signal.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/signal.h b/include/linux/signal.h index fcd2b14b1932..29a68ac7af83 100644 --- a/include/linux/signal.h +++ b/include/linux/signal.h @@ -7,6 +7,8 @@ #ifdef __KERNEL__ #include +struct task_struct; + /* for sysctl */ extern int print_fatal_signals; /* -- cgit From 4800a5bb13c09a572f7c74662a77c9eca229eba1 Mon Sep 17 00:00:00 2001 From: Chris Metcalf Date: Tue, 17 May 2011 14:41:06 -0400 Subject: include/linux/compat.h: coding-style fixes I touched this file when adding support for the "tilegx" sub-architecture, and Andrew Morton observed "The file's a mismash of old-style, wrong-style and right-style. There's no point in doing mishmash preservation! May as well fix things up when we touch them." Accordingly, this change makes as checkpatch-clean as possible. It makes no semantic changes whatsoever. Signed-off-by: Chris Metcalf Signed-off-by: Andrew Morton --- include/linux/compat.h | 74 ++++++++++++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 33 deletions(-) (limited to 'include/linux') diff --git a/include/linux/compat.h b/include/linux/compat.h index e94184834b71..644e1a4692b1 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -27,7 +27,7 @@ typedef __compat_gid32_t compat_gid_t; struct compat_sel_arg_struct; struct rusage; -struct compat_itimerspec { +struct compat_itimerspec { struct compat_timespec it_interval; struct compat_timespec it_value; }; @@ -71,9 +71,9 @@ struct compat_timex { compat_long_t stbcnt; compat_int_t tai; - compat_int_t :32; compat_int_t :32; compat_int_t :32; compat_int_t :32; - compat_int_t :32; compat_int_t :32; compat_int_t :32; compat_int_t :32; - compat_int_t :32; compat_int_t :32; compat_int_t :32; + compat_int_t:32; compat_int_t:32; compat_int_t:32; compat_int_t:32; + compat_int_t:32; compat_int_t:32; compat_int_t:32; compat_int_t:32; + compat_int_t:32; compat_int_t:32; compat_int_t:32; }; #define _COMPAT_NSIG_WORDS (_COMPAT_NSIG / _COMPAT_NSIG_BPW) @@ -82,8 +82,10 @@ typedef struct { compat_sigset_word sig[_COMPAT_NSIG_WORDS]; } compat_sigset_t; -extern int get_compat_timespec(struct timespec *, const struct compat_timespec __user *); -extern int put_compat_timespec(const struct timespec *, struct compat_timespec __user *); +extern int get_compat_timespec(struct timespec *, + const struct compat_timespec __user *); +extern int put_compat_timespec(const struct timespec *, + struct compat_timespec __user *); struct compat_iovec { compat_uptr_t iov_base; @@ -114,7 +116,8 @@ struct compat_rusage { compat_long_t ru_nivcsw; }; -extern int put_compat_rusage(const struct rusage *, struct compat_rusage __user *); +extern int put_compat_rusage(const struct rusage *, + struct compat_rusage __user *); struct compat_siginfo; @@ -167,8 +170,7 @@ struct compat_ifmap { unsigned char port; }; -struct compat_if_settings -{ +struct compat_if_settings { unsigned int type; /* Type of physical device or protocol */ unsigned int size; /* Size of the data allocated by the caller */ compat_uptr_t ifs_ifsu; /* union of pointers */ @@ -196,8 +198,8 @@ struct compat_ifreq { }; struct compat_ifconf { - compat_int_t ifc_len; /* size of buffer */ - compat_caddr_t ifcbuf; + compat_int_t ifc_len; /* size of buffer */ + compat_caddr_t ifcbuf; }; struct compat_robust_list { @@ -256,8 +258,8 @@ asmlinkage ssize_t compat_sys_pwritev(unsigned long fd, const struct compat_iovec __user *vec, unsigned long vlen, u32 pos_low, u32 pos_high); -int compat_do_execve(char * filename, compat_uptr_t __user *argv, - compat_uptr_t __user *envp, struct pt_regs * regs); +int compat_do_execve(char *filename, compat_uptr_t __user *argv, + compat_uptr_t __user *envp, struct pt_regs *regs); asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp, compat_ulong_t __user *outp, compat_ulong_t __user *exp, @@ -346,14 +348,16 @@ asmlinkage long compat_sys_epoll_pwait(int epfd, asmlinkage long compat_sys_utime(const char __user *filename, struct compat_utimbuf __user *t); -asmlinkage long compat_sys_utimensat(unsigned int dfd, const char __user *filename, - struct compat_timespec __user *t, int flags); +asmlinkage long compat_sys_utimensat(unsigned int dfd, + const char __user *filename, + struct compat_timespec __user *t, + int flags); asmlinkage long compat_sys_time(compat_time_t __user *tloc); asmlinkage long compat_sys_stime(compat_time_t __user *tptr); asmlinkage long compat_sys_signalfd(int ufd, - const compat_sigset_t __user *sigmask, - compat_size_t sigsetsize); + const compat_sigset_t __user *sigmask, + compat_size_t sigsetsize); asmlinkage long compat_sys_timerfd_settime(int ufd, int flags, const struct compat_itimerspec __user *utmr, struct compat_itimerspec __user *otmr); @@ -365,19 +369,21 @@ asmlinkage long compat_sys_move_pages(pid_t pid, unsigned long nr_page, const int __user *nodes, int __user *status, int flags); -asmlinkage long compat_sys_futimesat(unsigned int dfd, const char __user *filename, +asmlinkage long compat_sys_futimesat(unsigned int dfd, + const char __user *filename, struct compat_timeval __user *t); asmlinkage long compat_sys_utimes(const char __user *filename, struct compat_timeval __user *t); -asmlinkage long compat_sys_newstat(const char __user * filename, +asmlinkage long compat_sys_newstat(const char __user *filename, struct compat_stat __user *statbuf); -asmlinkage long compat_sys_newlstat(const char __user * filename, +asmlinkage long compat_sys_newlstat(const char __user *filename, struct compat_stat __user *statbuf); -asmlinkage long compat_sys_newfstatat(unsigned int dfd, const char __user * filename, +asmlinkage long compat_sys_newfstatat(unsigned int dfd, + const char __user *filename, struct compat_stat __user *statbuf, int flag); asmlinkage long compat_sys_newfstat(unsigned int fd, - struct compat_stat __user * statbuf); + struct compat_stat __user *statbuf); asmlinkage long compat_sys_statfs(const char __user *pathname, struct compat_statfs __user *buf); asmlinkage long compat_sys_fstatfs(unsigned int fd, @@ -399,10 +405,10 @@ asmlinkage long compat_sys_io_getevents(aio_context_t ctx_id, struct compat_timespec __user *timeout); asmlinkage long compat_sys_io_submit(aio_context_t ctx_id, int nr, u32 __user *iocb); -asmlinkage long compat_sys_mount(const char __user * dev_name, - const char __user * dir_name, - const char __user * type, unsigned long flags, - const void __user * data); +asmlinkage long compat_sys_mount(const char __user *dev_name, + const char __user *dir_name, + const char __user *type, unsigned long flags, + const void __user *data); asmlinkage long compat_sys_old_readdir(unsigned int fd, struct compat_old_linux_dirent __user *, unsigned int count); @@ -410,7 +416,7 @@ asmlinkage long compat_sys_getdents(unsigned int fd, struct compat_linux_dirent __user *dirent, unsigned int count); asmlinkage long compat_sys_getdents64(unsigned int fd, - struct linux_dirent64 __user * dirent, + struct linux_dirent64 __user *dirent, unsigned int count); asmlinkage long compat_sys_vmsplice(int fd, const struct compat_iovec __user *, unsigned int nr_segs, unsigned int flags); @@ -431,14 +437,15 @@ asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds, struct compat_timespec __user *tsp, const compat_sigset_t __user *sigmask, compat_size_t sigsetsize); -#if (defined(CONFIG_NFSD) || defined(CONFIG_NFSD_MODULE)) && !defined(CONFIG_NFSD_DEPRECATED) +#if (defined(CONFIG_NFSD) || defined(CONFIG_NFSD_MODULE)) && \ + !defined(CONFIG_NFSD_DEPRECATED) union compat_nfsctl_res; struct compat_nfsctl_arg; asmlinkage long compat_sys_nfsservctl(int cmd, struct compat_nfsctl_arg __user *arg, union compat_nfsctl_res __user *res); #else -long asmlinkage compat_sys_nfsservctl(int cmd, void *notused, void *notused2); +asmlinkage long compat_sys_nfsservctl(int cmd, void *notused, void *notused2); #endif asmlinkage long compat_sys_signalfd4(int ufd, const compat_sigset_t __user *sigmask, @@ -479,8 +486,8 @@ asmlinkage long compat_sys_setitimer(int which, asmlinkage long compat_sys_times(struct compat_tms __user *tbuf); asmlinkage long compat_sys_setrlimit(unsigned int resource, struct compat_rlimit __user *rlim); -asmlinkage long compat_sys_getrlimit (unsigned int resource, - struct compat_rlimit __user *rlim); +asmlinkage long compat_sys_getrlimit(unsigned int resource, + struct compat_rlimit __user *rlim); asmlinkage long compat_sys_getrusage(int who, struct compat_rusage __user *ru); asmlinkage long compat_sys_sched_setaffinity(compat_pid_t pid, unsigned int len, @@ -507,7 +514,7 @@ asmlinkage long compat_sys_clock_getres(clockid_t which_clock, asmlinkage long compat_sys_clock_nanosleep(clockid_t which_clock, int flags, struct compat_timespec __user *rqtp, struct compat_timespec __user *rmtp); -asmlinkage long compat_sys_rt_sigtimedwait (compat_sigset_t __user *uthese, +asmlinkage long compat_sys_rt_sigtimedwait(compat_sigset_t __user *uthese, struct compat_siginfo __user *uinfo, struct compat_timespec __user *uts, compat_size_t sigsetsize); asmlinkage long compat_sys_rt_sigsuspend(compat_sigset_t __user *unewset, @@ -544,7 +551,8 @@ asmlinkage long compat_sys_socketcall(int call, u32 __user *args); asmlinkage long compat_sys_sysctl(struct compat_sysctl_args __user *args); extern ssize_t compat_rw_copy_check_uvector(int type, - const struct compat_iovec __user *uvector, unsigned long nr_segs, + const struct compat_iovec __user *uvector, + unsigned long nr_segs, unsigned long fast_segs, struct iovec *fast_pointer, struct iovec **ret_pointer); -- cgit From 449f4544267e73d5db372971da63634707c32299 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 19 May 2011 12:24:16 +0000 Subject: macvlan: remove one synchronize_rcu() call When one macvlan device is dismantled, we can avoid one synchronize_rcu() call done after deletion from hash list, since caller will perform a synchronize_net() call after its ndo_stop() call. Add a new netdev->dismantle field to signal this dismantle intent. Reduces RTNL hold time. Signed-off-by: Eric Dumazet CC: Patrick McHardy CC: Ben Greear Signed-off-by: David S. Miller --- drivers/net/macvlan.c | 9 +++++---- include/linux/netdevice.h | 4 +++- net/core/dev.c | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index d7c0bc62da7f..07bcb8084d78 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -70,16 +70,17 @@ static void macvlan_hash_add(struct macvlan_dev *vlan) hlist_add_head_rcu(&vlan->hlist, &port->vlan_hash[addr[5]]); } -static void macvlan_hash_del(struct macvlan_dev *vlan) +static void macvlan_hash_del(struct macvlan_dev *vlan, bool sync) { hlist_del_rcu(&vlan->hlist); - synchronize_rcu(); + if (sync) + synchronize_rcu(); } static void macvlan_hash_change_addr(struct macvlan_dev *vlan, const unsigned char *addr) { - macvlan_hash_del(vlan); + macvlan_hash_del(vlan, true); /* Now that we are unhashed it is safe to change the device * address without confusing packet delivery. */ @@ -345,7 +346,7 @@ static int macvlan_stop(struct net_device *dev) dev_uc_del(lowerdev, dev->dev_addr); hash_del: - macvlan_hash_del(vlan); + macvlan_hash_del(vlan, !dev->dismantle); return 0; } diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index a134d809125b..ca333e79e10f 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1293,7 +1293,9 @@ struct net_device { NETREG_UNREGISTERED, /* completed unregister todo */ NETREG_RELEASED, /* called free_netdev */ NETREG_DUMMY, /* dummy device for NAPI poll */ - } reg_state:16; + } reg_state:8; + + bool dismantle; /* device is going do be freed */ enum { RTNL_LINK_INITIALIZED, diff --git a/net/core/dev.c b/net/core/dev.c index 155de2094e71..d94537914a71 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -5126,7 +5126,7 @@ static void rollback_registered_many(struct list_head *head) list_del(&dev->unreg_list); continue; } - + dev->dismantle = true; BUG_ON(dev->reg_state != NETREG_REGISTERED); } -- cgit From 924e7a9fc6da124588e27c611841d07047c157b4 Mon Sep 17 00:00:00 2001 From: Jamie Iles Date: Fri, 20 May 2011 00:40:15 -0600 Subject: basic_mmio_gpio: allow overriding number of gpio Some platforms may have a number of GPIO that is less than the register width of the peripheral. Signed-off-by: Jamie Iles Acked-by: Anton Vorontsov Signed-off-by: Grant Likely --- drivers/gpio/basic_mmio_gpio.c | 18 ++++++++++++------ include/linux/basic_mmio_gpio.h | 1 + 2 files changed, 13 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/drivers/gpio/basic_mmio_gpio.c b/drivers/gpio/basic_mmio_gpio.c index 5db5de438324..2b2d38454463 100644 --- a/drivers/gpio/basic_mmio_gpio.c +++ b/drivers/gpio/basic_mmio_gpio.c @@ -239,6 +239,7 @@ static int __devinit bgpio_probe(struct platform_device *pdev) resource_size_t dat_sz; int bits; int ret; + int ngpio; res_dat = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dat"); if (!res_dat) @@ -249,6 +250,7 @@ static int __devinit bgpio_probe(struct platform_device *pdev) return -EINVAL; bits = dat_sz * 8; + ngpio = bits; if (bits > BITS_PER_LONG) return -EINVAL; @@ -277,13 +279,22 @@ static int __devinit bgpio_probe(struct platform_device *pdev) spin_lock_init(&bgc->lock); + if (pdata) { + bgc->gc.base = pdata->base; + if (pdata->ngpio > 0) + ngpio = pdata->ngpio; + } else { + bgc->gc.base = -1; + } + bgc->bits = bits; ret = bgpio_setup_accessors(pdev, bgc); if (ret) return ret; bgc->data = bgc->read_reg(bgc->reg_dat); - bgc->gc.ngpio = bits; + + bgc->gc.ngpio = ngpio; bgc->gc.direction_input = bgpio_dir_in; bgc->gc.direction_output = bgpio_dir_out; bgc->gc.get = bgpio_get; @@ -291,11 +302,6 @@ static int __devinit bgpio_probe(struct platform_device *pdev) bgc->gc.dev = dev; bgc->gc.label = dev_name(dev); - if (pdata) - bgc->gc.base = pdata->base; - else - bgc->gc.base = -1; - platform_set_drvdata(pdev, bgc); ret = gpiochip_add(&bgc->gc); diff --git a/include/linux/basic_mmio_gpio.h b/include/linux/basic_mmio_gpio.h index 198087a16fc4..f23ec73b944b 100644 --- a/include/linux/basic_mmio_gpio.h +++ b/include/linux/basic_mmio_gpio.h @@ -15,6 +15,7 @@ struct bgpio_pdata { int base; + int ngpio; }; #endif /* __BASIC_MMIO_GPIO_H */ -- cgit From 280df6b3c3ad777a91f1011cd98d50df891bfef8 Mon Sep 17 00:00:00 2001 From: Jamie Iles Date: Fri, 20 May 2011 00:40:19 -0600 Subject: basic_mmio_gpio: split into a gpio library and platform device Allow GPIO_BASIC_MMIO_CORE to be used to provide an accessor library for implementing GPIO drivers whilst abstracting the register access detail. Based on a patch from Anton Vorontsov[1] and adapted to allow bgpio_chip to be embedded in another structure. Changes since v1: - Register the gpio_chip in the platform device probe 1. https://lkml.org/lkml/2011/4/19/401 Signed-off-by: Anton Vorontsov Signed-off-by: Jamie Iles Signed-off-by: Grant Likely --- drivers/gpio/Kconfig | 6 + drivers/gpio/Makefile | 1 + drivers/gpio/basic_mmio_gpio.c | 317 +++++++++++++++++++++------------------- include/linux/basic_mmio_gpio.h | 55 +++++++ 4 files changed, 231 insertions(+), 148 deletions(-) (limited to 'include/linux') diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 44235bd4f9dd..b57ec09af891 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -70,8 +70,14 @@ config GPIO_MAX730X comment "Memory mapped GPIO drivers:" +config GPIO_BASIC_MMIO_CORE + tristate + help + Provides core functionality for basic memory-mapped GPIO controllers. + config GPIO_BASIC_MMIO tristate "Basic memory-mapped GPIO controllers support" + select GPIO_BASIC_MMIO_CORE help Say yes here to support basic memory-mapped GPIO controllers. diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 7b2bdceca080..d92ce3a62ae5 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_GPIOLIB) += gpiolib.o obj-$(CONFIG_GPIO_ADP5520) += adp5520-gpio.o obj-$(CONFIG_GPIO_ADP5588) += adp5588-gpio.o +obj-$(CONFIG_GPIO_BASIC_MMIO_CORE) += basic_mmio_gpio.o obj-$(CONFIG_GPIO_BASIC_MMIO) += basic_mmio_gpio.o obj-$(CONFIG_GPIO_LANGWELL) += langwell_gpio.o obj-$(CONFIG_GPIO_MAX730X) += max730x.o diff --git a/drivers/gpio/basic_mmio_gpio.c b/drivers/gpio/basic_mmio_gpio.c index b2ec45ffe447..8152e9f516b0 100644 --- a/drivers/gpio/basic_mmio_gpio.c +++ b/drivers/gpio/basic_mmio_gpio.c @@ -45,6 +45,7 @@ o ` ~~~~\___/~~~~ ` controller in FPGA is ,.` */ #include +#include #include #include #include @@ -61,44 +62,6 @@ o ` ~~~~\___/~~~~ ` controller in FPGA is ,.` #include #include -struct bgpio_chip { - struct gpio_chip gc; - - unsigned long (*read_reg)(void __iomem *reg); - void (*write_reg)(void __iomem *reg, unsigned long data); - - void __iomem *reg_dat; - void __iomem *reg_set; - void __iomem *reg_clr; - void __iomem *reg_dir; - - /* Number of bits (GPIOs): * 8. */ - int bits; - - /* - * Some GPIO controllers work with the big-endian bits notation, - * e.g. in a 8-bits register, GPIO7 is the least significant bit. - */ - unsigned long (*pin2mask)(struct bgpio_chip *bgc, unsigned int pin); - - /* - * Used to lock bgpio_chip->data. Also, this is needed to keep - * shadowed and real data registers writes together. - */ - spinlock_t lock; - - /* Shadowed data register to clear/set bits safely. */ - unsigned long data; - - /* Shadowed direction registers to clear/set direction safely. */ - unsigned long dir; -}; - -static struct bgpio_chip *to_bgpio_chip(struct gpio_chip *gc) -{ - return container_of(gc, struct bgpio_chip, gc); -} - static void bgpio_write8(void __iomem *reg, unsigned long data) { writeb(data, reg); @@ -284,20 +247,10 @@ static int bgpio_dir_out_inv(struct gpio_chip *gc, unsigned int gpio, int val) return 0; } -static void __iomem *bgpio_request_and_map(struct device *dev, - struct resource *res) -{ - if (!devm_request_mem_region(dev, res->start, resource_size(res), - res->name ?: "mmio_gpio")) - return NULL; - - return devm_ioremap(dev, res->start, resource_size(res)); -} - -static int bgpio_setup_accessors(struct platform_device *pdev, - struct bgpio_chip *bgc) +static int bgpio_setup_accessors(struct device *dev, + struct bgpio_chip *bgc, + bool be) { - const struct platform_device_id *platid = platform_get_device_id(pdev); switch (bgc->bits) { case 8: @@ -319,13 +272,11 @@ static int bgpio_setup_accessors(struct platform_device *pdev, break; #endif /* BITS_PER_LONG >= 64 */ default: - dev_err(&pdev->dev, "unsupported data width %u bits\n", - bgc->bits); + dev_err(dev, "unsupported data width %u bits\n", bgc->bits); return -EINVAL; } - bgc->pin2mask = strcmp(platid->name, "basic-mmio-gpio-be") ? - bgpio_pin2mask : bgpio_pin2mask_be; + bgc->pin2mask = be ? bgpio_pin2mask_be : bgpio_pin2mask; return 0; } @@ -352,51 +303,22 @@ static int bgpio_setup_accessors(struct platform_device *pdev, * - an input direction register (named "dirin") where a 1 bit indicates * the GPIO is an input. */ -static int bgpio_setup_io(struct platform_device *pdev, - struct bgpio_chip *bgc) +static int bgpio_setup_io(struct bgpio_chip *bgc, + void __iomem *dat, + void __iomem *set, + void __iomem *clr) { - struct resource *res_set; - struct resource *res_clr; - struct resource *res_dat; - resource_size_t dat_sz; - res_dat = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dat"); - if (!res_dat) - return -EINVAL; - - dat_sz = resource_size(res_dat); - if (!is_power_of_2(dat_sz)) - return -EINVAL; - - bgc->bits = dat_sz * 8; - if (bgc->bits > BITS_PER_LONG) - return -EINVAL; - - bgc->reg_dat = bgpio_request_and_map(&pdev->dev, res_dat); + bgc->reg_dat = dat; if (!bgc->reg_dat) - return -ENOMEM; - - res_set = platform_get_resource_byname(pdev, IORESOURCE_MEM, "set"); - res_clr = platform_get_resource_byname(pdev, IORESOURCE_MEM, "clr"); - if (res_set && res_clr) { - if (resource_size(res_set) != resource_size(res_clr) || - resource_size(res_set) != resource_size(res_dat)) - return -EINVAL; - - bgc->reg_set = bgpio_request_and_map(&pdev->dev, res_set); - bgc->reg_clr = bgpio_request_and_map(&pdev->dev, res_clr); - if (!bgc->reg_set || !bgc->reg_clr) - return -ENOMEM; + return -EINVAL; + if (set && clr) { + bgc->reg_set = set; + bgc->reg_clr = clr; bgc->gc.set = bgpio_set_with_clear; - } else if (res_set && !res_clr) { - if (resource_size(res_set) != resource_size(res_dat)) - return -EINVAL; - - bgc->reg_set = bgpio_request_and_map(&pdev->dev, res_set); - if (!bgc->reg_set) - return -ENOMEM; - + } else if (set && !clr) { + bgc->reg_set = set; bgc->gc.set = bgpio_set_set; } else { bgc->gc.set = bgpio_set; @@ -407,27 +329,18 @@ static int bgpio_setup_io(struct platform_device *pdev, return 0; } -static int bgpio_setup_direction(struct platform_device *pdev, - struct bgpio_chip *bgc) +static int bgpio_setup_direction(struct bgpio_chip *bgc, + void __iomem *dirout, + void __iomem *dirin) { - struct resource *res_dirout; - struct resource *res_dirin; - - res_dirout = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "dirout"); - res_dirin = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dirin"); - if (res_dirout && res_dirin) { + if (dirout && dirin) { return -EINVAL; - } else if (res_dirout) { - bgc->reg_dir = bgpio_request_and_map(&pdev->dev, res_dirout); - if (!bgc->reg_dir) - return -ENOMEM; + } else if (dirout) { + bgc->reg_dir = dirout; bgc->gc.direction_output = bgpio_dir_out; bgc->gc.direction_input = bgpio_dir_in; - } else if (res_dirin) { - bgc->reg_dir = bgpio_request_and_map(&pdev->dev, res_dirin); - if (!bgc->reg_dir) - return -ENOMEM; + } else if (dirin) { + bgc->reg_dir = dirin; bgc->gc.direction_output = bgpio_dir_out_inv; bgc->gc.direction_input = bgpio_dir_in_inv; } else { @@ -438,60 +351,166 @@ static int bgpio_setup_direction(struct platform_device *pdev, return 0; } -static int __devinit bgpio_probe(struct platform_device *pdev) +int __devexit bgpio_remove(struct bgpio_chip *bgc) +{ + int err = gpiochip_remove(&bgc->gc); + + kfree(bgc); + + return err; +} +EXPORT_SYMBOL_GPL(bgpio_remove); + +int __devinit bgpio_init(struct bgpio_chip *bgc, + struct device *dev, + unsigned long sz, + void __iomem *dat, + void __iomem *set, + void __iomem *clr, + void __iomem *dirout, + void __iomem *dirin, + bool big_endian) { - struct device *dev = &pdev->dev; - struct bgpio_pdata *pdata = dev_get_platdata(dev); - struct bgpio_chip *bgc; int ret; - int ngpio; - bgc = devm_kzalloc(dev, sizeof(*bgc), GFP_KERNEL); - if (!bgc) - return -ENOMEM; + if (!is_power_of_2(sz)) + return -EINVAL; - ret = bgpio_setup_io(pdev, bgc); + bgc->bits = sz * 8; + if (bgc->bits > BITS_PER_LONG) + return -EINVAL; + + spin_lock_init(&bgc->lock); + bgc->gc.dev = dev; + bgc->gc.label = dev_name(dev); + bgc->gc.base = -1; + bgc->gc.ngpio = bgc->bits; + + ret = bgpio_setup_io(bgc, dat, set, clr); if (ret) return ret; - ngpio = bgc->bits; - if (pdata) { - bgc->gc.base = pdata->base; - if (pdata->ngpio > 0) - ngpio = pdata->ngpio; - } else { - bgc->gc.base = -1; - } - - ret = bgpio_setup_accessors(pdev, bgc); + ret = bgpio_setup_accessors(dev, bgc, big_endian); if (ret) return ret; - spin_lock_init(&bgc->lock); - ret = bgpio_setup_direction(pdev, bgc); + ret = bgpio_setup_direction(bgc, dirout, dirin); if (ret) return ret; bgc->data = bgc->read_reg(bgc->reg_dat); - bgc->gc.ngpio = ngpio; - bgc->gc.dev = dev; - bgc->gc.label = dev_name(dev); + return ret; +} +EXPORT_SYMBOL_GPL(bgpio_init); - platform_set_drvdata(pdev, bgc); +#ifdef CONFIG_GPIO_BASIC_MMIO - ret = gpiochip_add(&bgc->gc); - if (ret) - dev_err(dev, "gpiochip_add() failed: %d\n", ret); +static void __iomem *bgpio_map(struct platform_device *pdev, + const char *name, + resource_size_t sane_sz, + int *err) +{ + struct device *dev = &pdev->dev; + struct resource *r; + resource_size_t start; + resource_size_t sz; + void __iomem *ret; + + *err = 0; + + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); + if (!r) + return NULL; + + sz = resource_size(r); + if (sz != sane_sz) { + *err = -EINVAL; + return NULL; + } + + start = r->start; + if (!devm_request_mem_region(dev, start, sz, r->name)) { + *err = -EBUSY; + return NULL; + } + + ret = devm_ioremap(dev, start, sz); + if (!ret) { + *err = -ENOMEM; + return NULL; + } return ret; } -static int __devexit bgpio_remove(struct platform_device *pdev) +static int __devinit bgpio_pdev_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct resource *r; + void __iomem *dat; + void __iomem *set; + void __iomem *clr; + void __iomem *dirout; + void __iomem *dirin; + unsigned long sz; + bool be; + int err; + struct bgpio_chip *bgc; + struct bgpio_pdata *pdata = dev_get_platdata(dev); + + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dat"); + if (!r) + return -EINVAL; + + sz = resource_size(r); + + dat = bgpio_map(pdev, "dat", sz, &err); + if (!dat) + return err ? err : -EINVAL; + + set = bgpio_map(pdev, "set", sz, &err); + if (err) + return err; + + clr = bgpio_map(pdev, "clr", sz, &err); + if (err) + return err; + + dirout = bgpio_map(pdev, "dirout", sz, &err); + if (err) + return err; + + dirin = bgpio_map(pdev, "dirin", sz, &err); + if (err) + return err; + + be = !strcmp(platform_get_device_id(pdev)->name, "basic-mmio-gpio-be"); + + bgc = devm_kzalloc(&pdev->dev, sizeof(*bgc), GFP_KERNEL); + if (!bgc) + return -ENOMEM; + + err = bgpio_init(bgc, dev, sz, dat, set, clr, dirout, dirin, be); + if (err) + return err; + + if (pdata) { + bgc->gc.base = pdata->base; + if (pdata->ngpio > 0) + bgc->gc.ngpio = pdata->ngpio; + } + + platform_set_drvdata(pdev, bgc); + + return gpiochip_add(&bgc->gc); +} + +static int __devexit bgpio_pdev_remove(struct platform_device *pdev) { struct bgpio_chip *bgc = platform_get_drvdata(pdev); - return gpiochip_remove(&bgc->gc); + return bgpio_remove(bgc); } static const struct platform_device_id bgpio_id_table[] = { @@ -506,21 +525,23 @@ static struct platform_driver bgpio_driver = { .name = "basic-mmio-gpio", }, .id_table = bgpio_id_table, - .probe = bgpio_probe, - .remove = __devexit_p(bgpio_remove), + .probe = bgpio_pdev_probe, + .remove = __devexit_p(bgpio_pdev_remove), }; -static int __init bgpio_init(void) +static int __init bgpio_platform_init(void) { return platform_driver_register(&bgpio_driver); } -module_init(bgpio_init); +module_init(bgpio_platform_init); -static void __exit bgpio_exit(void) +static void __exit bgpio_platform_exit(void) { platform_driver_unregister(&bgpio_driver); } -module_exit(bgpio_exit); +module_exit(bgpio_platform_exit); + +#endif /* CONFIG_GPIO_BASIC_MMIO */ MODULE_DESCRIPTION("Driver for basic memory-mapped GPIO controllers"); MODULE_AUTHOR("Anton Vorontsov "); diff --git a/include/linux/basic_mmio_gpio.h b/include/linux/basic_mmio_gpio.h index f23ec73b944b..1ae12710d732 100644 --- a/include/linux/basic_mmio_gpio.h +++ b/include/linux/basic_mmio_gpio.h @@ -13,9 +13,64 @@ #ifndef __BASIC_MMIO_GPIO_H #define __BASIC_MMIO_GPIO_H +#include +#include +#include + struct bgpio_pdata { int base; int ngpio; }; +struct device; + +struct bgpio_chip { + struct gpio_chip gc; + + unsigned long (*read_reg)(void __iomem *reg); + void (*write_reg)(void __iomem *reg, unsigned long data); + + void __iomem *reg_dat; + void __iomem *reg_set; + void __iomem *reg_clr; + void __iomem *reg_dir; + + /* Number of bits (GPIOs): * 8. */ + int bits; + + /* + * Some GPIO controllers work with the big-endian bits notation, + * e.g. in a 8-bits register, GPIO7 is the least significant bit. + */ + unsigned long (*pin2mask)(struct bgpio_chip *bgc, unsigned int pin); + + /* + * Used to lock bgpio_chip->data. Also, this is needed to keep + * shadowed and real data registers writes together. + */ + spinlock_t lock; + + /* Shadowed data register to clear/set bits safely. */ + unsigned long data; + + /* Shadowed direction registers to clear/set direction safely. */ + unsigned long dir; +}; + +static inline struct bgpio_chip *to_bgpio_chip(struct gpio_chip *gc) +{ + return container_of(gc, struct bgpio_chip, gc); +} + +int __devexit bgpio_remove(struct bgpio_chip *bgc); +int __devinit bgpio_init(struct bgpio_chip *bgc, + struct device *dev, + unsigned long sz, + void __iomem *dat, + void __iomem *set, + void __iomem *clr, + void __iomem *dirout, + void __iomem *dirin, + bool big_endian); + #endif /* __BASIC_MMIO_GPIO_H */ -- cgit From 0c4a1590189b426814748d2e03b95541852b3af6 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 11 May 2011 00:09:30 +0200 Subject: spi: Use void pointers for data in simple SPI I/O operations Currently the simple SPI I/O operations all take pointers to u8 * buffers to operate on. This creates needless type compatibility issues and the underlying spi_transfer structure uses void pointers anyway so convert the API over to take void pointers too. Signed-off-by: Mark Brown Signed-off-by: Grant Likely --- drivers/spi/spi.c | 4 ++-- include/linux/spi/spi.h | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 82b9a428c323..2e13a14bba3f 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1047,8 +1047,8 @@ static u8 *buf; * spi_{async,sync}() calls with dma-safe buffers. */ int spi_write_then_read(struct spi_device *spi, - const u8 *txbuf, unsigned n_tx, - u8 *rxbuf, unsigned n_rx) + const void *txbuf, unsigned n_tx, + void *rxbuf, unsigned n_rx) { static DEFINE_MUTEX(lock); diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index b4d7710bc38d..bb4f5fbbbd8e 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -581,7 +581,7 @@ extern int spi_bus_unlock(struct spi_master *master); * Callable only from contexts that can sleep. */ static inline int -spi_write(struct spi_device *spi, const u8 *buf, size_t len) +spi_write(struct spi_device *spi, const void *buf, size_t len) { struct spi_transfer t = { .tx_buf = buf, @@ -605,7 +605,7 @@ spi_write(struct spi_device *spi, const u8 *buf, size_t len) * Callable only from contexts that can sleep. */ static inline int -spi_read(struct spi_device *spi, u8 *buf, size_t len) +spi_read(struct spi_device *spi, void *buf, size_t len) { struct spi_transfer t = { .rx_buf = buf, @@ -620,8 +620,8 @@ spi_read(struct spi_device *spi, u8 *buf, size_t len) /* this copies txbuf and rxbuf data; for small transfers only! */ extern int spi_write_then_read(struct spi_device *spi, - const u8 *txbuf, unsigned n_tx, - u8 *rxbuf, unsigned n_rx); + const void *txbuf, unsigned n_tx, + void *rxbuf, unsigned n_rx); /** * spi_w8r8 - SPI synchronous 8 bit write followed by 8 bit read -- cgit From 1399fa7807a1a5998bbf147e80668e9950661dfa Mon Sep 17 00:00:00 2001 From: Nikhil Rao Date: Wed, 18 May 2011 10:09:39 -0700 Subject: sched: Introduce SCHED_POWER_SCALE to scale cpu_power calculations SCHED_LOAD_SCALE is used to increase nice resolution and to scale cpu_power calculations in the scheduler. This patch introduces SCHED_POWER_SCALE and converts all uses of SCHED_LOAD_SCALE for scaling cpu_power to use SCHED_POWER_SCALE instead. This is a preparatory patch for increasing the resolution of SCHED_LOAD_SCALE, and there is no need to increase resolution for cpu_power calculations. Signed-off-by: Nikhil Rao Acked-by: Peter Zijlstra Cc: Nikunj A. Dadhania Cc: Srivatsa Vaddagiri Cc: Stephan Barwolf Cc: Mike Galbraith Link: http://lkml.kernel.org/r/1305738580-9924-3-git-send-email-ncrao@google.com Signed-off-by: Ingo Molnar --- include/linux/sched.h | 13 ++++++++----- kernel/sched.c | 4 ++-- kernel/sched_fair.c | 52 ++++++++++++++++++++++++++------------------------- 3 files changed, 37 insertions(+), 32 deletions(-) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index 12211e1666e2..f2f440221b70 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -787,18 +787,21 @@ enum cpu_idle_type { CPU_MAX_IDLE_TYPES }; -/* - * sched-domains (multiprocessor balancing) declarations: - */ - /* * Increase resolution of nice-level calculations: */ #define SCHED_LOAD_SHIFT 10 #define SCHED_LOAD_SCALE (1L << SCHED_LOAD_SHIFT) -#define SCHED_LOAD_SCALE_FUZZ SCHED_LOAD_SCALE +/* + * Increase resolution of cpu_power calculations + */ +#define SCHED_POWER_SHIFT 10 +#define SCHED_POWER_SCALE (1L << SCHED_POWER_SHIFT) +/* + * sched-domains (multiprocessor balancing) declarations: + */ #ifdef CONFIG_SMP #define SD_LOAD_BALANCE 0x0001 /* Do load balancing on this domain. */ #define SD_BALANCE_NEWIDLE 0x0002 /* Balance when about to become idle */ diff --git a/kernel/sched.c b/kernel/sched.c index d036048b59a4..375e9c677d58 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -6530,7 +6530,7 @@ static int sched_domain_debug_one(struct sched_domain *sd, int cpu, int level, cpulist_scnprintf(str, sizeof(str), sched_group_cpus(group)); printk(KERN_CONT " %s", str); - if (group->cpu_power != SCHED_LOAD_SCALE) { + if (group->cpu_power != SCHED_POWER_SCALE) { printk(KERN_CONT " (cpu_power = %d)", group->cpu_power); } @@ -7905,7 +7905,7 @@ void __init sched_init(void) #ifdef CONFIG_SMP rq->sd = NULL; rq->rd = NULL; - rq->cpu_power = SCHED_LOAD_SCALE; + rq->cpu_power = SCHED_POWER_SCALE; rq->post_schedule = 0; rq->active_balance = 0; rq->next_balance = jiffies; diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 37f22626225e..e32a9b70ee9c 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -1584,7 +1584,7 @@ find_idlest_group(struct sched_domain *sd, struct task_struct *p, } /* Adjust by relative CPU power of the group */ - avg_load = (avg_load * SCHED_LOAD_SCALE) / group->cpu_power; + avg_load = (avg_load * SCHED_POWER_SCALE) / group->cpu_power; if (local_group) { this_load = avg_load; @@ -1722,7 +1722,7 @@ select_task_rq_fair(struct task_struct *p, int sd_flag, int wake_flags) nr_running += cpu_rq(i)->cfs.nr_running; } - capacity = DIV_ROUND_CLOSEST(power, SCHED_LOAD_SCALE); + capacity = DIV_ROUND_CLOSEST(power, SCHED_POWER_SCALE); if (tmp->flags & SD_POWERSAVINGS_BALANCE) nr_running /= 2; @@ -2570,7 +2570,7 @@ static inline int check_power_save_busiest_group(struct sd_lb_stats *sds, unsigned long default_scale_freq_power(struct sched_domain *sd, int cpu) { - return SCHED_LOAD_SCALE; + return SCHED_POWER_SCALE; } unsigned long __weak arch_scale_freq_power(struct sched_domain *sd, int cpu) @@ -2607,10 +2607,10 @@ unsigned long scale_rt_power(int cpu) available = total - rq->rt_avg; } - if (unlikely((s64)total < SCHED_LOAD_SCALE)) - total = SCHED_LOAD_SCALE; + if (unlikely((s64)total < SCHED_POWER_SCALE)) + total = SCHED_POWER_SCALE; - total >>= SCHED_LOAD_SHIFT; + total >>= SCHED_POWER_SHIFT; return div_u64(available, total); } @@ -2618,7 +2618,7 @@ unsigned long scale_rt_power(int cpu) static void update_cpu_power(struct sched_domain *sd, int cpu) { unsigned long weight = sd->span_weight; - unsigned long power = SCHED_LOAD_SCALE; + unsigned long power = SCHED_POWER_SCALE; struct sched_group *sdg = sd->groups; if ((sd->flags & SD_SHARE_CPUPOWER) && weight > 1) { @@ -2627,7 +2627,7 @@ static void update_cpu_power(struct sched_domain *sd, int cpu) else power *= default_scale_smt_power(sd, cpu); - power >>= SCHED_LOAD_SHIFT; + power >>= SCHED_POWER_SHIFT; } sdg->cpu_power_orig = power; @@ -2637,10 +2637,10 @@ static void update_cpu_power(struct sched_domain *sd, int cpu) else power *= default_scale_freq_power(sd, cpu); - power >>= SCHED_LOAD_SHIFT; + power >>= SCHED_POWER_SHIFT; power *= scale_rt_power(cpu); - power >>= SCHED_LOAD_SHIFT; + power >>= SCHED_POWER_SHIFT; if (!power) power = 1; @@ -2682,7 +2682,7 @@ static inline int fix_small_capacity(struct sched_domain *sd, struct sched_group *group) { /* - * Only siblings can have significantly less than SCHED_LOAD_SCALE + * Only siblings can have significantly less than SCHED_POWER_SCALE */ if (!(sd->flags & SD_SHARE_CPUPOWER)) return 0; @@ -2770,7 +2770,7 @@ static inline void update_sg_lb_stats(struct sched_domain *sd, } /* Adjust by relative CPU power of the group */ - sgs->avg_load = (sgs->group_load * SCHED_LOAD_SCALE) / group->cpu_power; + sgs->avg_load = (sgs->group_load*SCHED_POWER_SCALE) / group->cpu_power; /* * Consider the group unbalanced when the imbalance is larger @@ -2787,7 +2787,8 @@ static inline void update_sg_lb_stats(struct sched_domain *sd, if ((max_cpu_load - min_cpu_load) >= avg_load_per_task && max_nr_running > 1) sgs->group_imb = 1; - sgs->group_capacity = DIV_ROUND_CLOSEST(group->cpu_power, SCHED_LOAD_SCALE); + sgs->group_capacity = DIV_ROUND_CLOSEST(group->cpu_power, + SCHED_POWER_SCALE); if (!sgs->group_capacity) sgs->group_capacity = fix_small_capacity(sd, group); sgs->group_weight = group->group_weight; @@ -2961,7 +2962,7 @@ static int check_asym_packing(struct sched_domain *sd, return 0; *imbalance = DIV_ROUND_CLOSEST(sds->max_load * sds->busiest->cpu_power, - SCHED_LOAD_SCALE); + SCHED_POWER_SCALE); return 1; } @@ -2990,7 +2991,7 @@ static inline void fix_small_imbalance(struct sd_lb_stats *sds, cpu_avg_load_per_task(this_cpu); scaled_busy_load_per_task = sds->busiest_load_per_task - * SCHED_LOAD_SCALE; + * SCHED_POWER_SCALE; scaled_busy_load_per_task /= sds->busiest->cpu_power; if (sds->max_load - sds->this_load + scaled_busy_load_per_task >= @@ -3009,10 +3010,10 @@ static inline void fix_small_imbalance(struct sd_lb_stats *sds, min(sds->busiest_load_per_task, sds->max_load); pwr_now += sds->this->cpu_power * min(sds->this_load_per_task, sds->this_load); - pwr_now /= SCHED_LOAD_SCALE; + pwr_now /= SCHED_POWER_SCALE; /* Amount of load we'd subtract */ - tmp = (sds->busiest_load_per_task * SCHED_LOAD_SCALE) / + tmp = (sds->busiest_load_per_task * SCHED_POWER_SCALE) / sds->busiest->cpu_power; if (sds->max_load > tmp) pwr_move += sds->busiest->cpu_power * @@ -3020,15 +3021,15 @@ static inline void fix_small_imbalance(struct sd_lb_stats *sds, /* Amount of load we'd add */ if (sds->max_load * sds->busiest->cpu_power < - sds->busiest_load_per_task * SCHED_LOAD_SCALE) + sds->busiest_load_per_task * SCHED_POWER_SCALE) tmp = (sds->max_load * sds->busiest->cpu_power) / sds->this->cpu_power; else - tmp = (sds->busiest_load_per_task * SCHED_LOAD_SCALE) / + tmp = (sds->busiest_load_per_task * SCHED_POWER_SCALE) / sds->this->cpu_power; pwr_move += sds->this->cpu_power * min(sds->this_load_per_task, sds->this_load + tmp); - pwr_move /= SCHED_LOAD_SCALE; + pwr_move /= SCHED_POWER_SCALE; /* Move if we gain throughput */ if (pwr_move > pwr_now) @@ -3070,7 +3071,7 @@ static inline void calculate_imbalance(struct sd_lb_stats *sds, int this_cpu, load_above_capacity = (sds->busiest_nr_running - sds->busiest_group_capacity); - load_above_capacity *= (SCHED_LOAD_SCALE * SCHED_LOAD_SCALE); + load_above_capacity *= (SCHED_LOAD_SCALE * SCHED_POWER_SCALE); load_above_capacity /= sds->busiest->cpu_power; } @@ -3090,7 +3091,7 @@ static inline void calculate_imbalance(struct sd_lb_stats *sds, int this_cpu, /* How much load to actually move to equalise the imbalance */ *imbalance = min(max_pull * sds->busiest->cpu_power, (sds->avg_load - sds->this_load) * sds->this->cpu_power) - / SCHED_LOAD_SCALE; + / SCHED_POWER_SCALE; /* * if *imbalance is less than the average load per runnable task @@ -3159,7 +3160,7 @@ find_busiest_group(struct sched_domain *sd, int this_cpu, if (!sds.busiest || sds.busiest_nr_running == 0) goto out_balanced; - sds.avg_load = (SCHED_LOAD_SCALE * sds.total_load) / sds.total_pwr; + sds.avg_load = (SCHED_POWER_SCALE * sds.total_load) / sds.total_pwr; /* * If the busiest group is imbalanced the below checks don't @@ -3238,7 +3239,8 @@ find_busiest_queue(struct sched_domain *sd, struct sched_group *group, for_each_cpu(i, sched_group_cpus(group)) { unsigned long power = power_of(i); - unsigned long capacity = DIV_ROUND_CLOSEST(power, SCHED_LOAD_SCALE); + unsigned long capacity = DIV_ROUND_CLOSEST(power, + SCHED_POWER_SCALE); unsigned long wl; if (!capacity) @@ -3263,7 +3265,7 @@ find_busiest_queue(struct sched_domain *sd, struct sched_group *group, * the load can be moved away from the cpu that is potentially * running at a lower capacity. */ - wl = (wl * SCHED_LOAD_SCALE) / power; + wl = (wl * SCHED_POWER_SCALE) / power; if (wl > max_load) { max_load = wl; -- cgit From c8b281161dfa4bb5d5be63fb036ce19347b88c63 Mon Sep 17 00:00:00 2001 From: Nikhil Rao Date: Wed, 18 May 2011 14:37:48 -0700 Subject: sched: Increase SCHED_LOAD_SCALE resolution Introduce SCHED_LOAD_RESOLUTION, which scales is added to SCHED_LOAD_SHIFT and increases the resolution of SCHED_LOAD_SCALE. This patch sets the value of SCHED_LOAD_RESOLUTION to 10, scaling up the weights for all sched entities by a factor of 1024. With this extra resolution, we can handle deeper cgroup hiearchies and the scheduler can do better shares distribution and load load balancing on larger systems (especially for low weight task groups). This does not change the existing user interface, the scaled weights are only used internally. We do not modify prio_to_weight values or inverses, but use the original weights when calculating the inverse which is used to scale execution time delta in calc_delta_mine(). This ensures we do not lose accuracy when accounting time to the sched entities. Thanks to Nikunj Dadhania for fixing an bug in c_d_m() that broken fairness. Below is some analysis of the performance costs/improvements of this patch. 1. Micro-arch performance costs: Experiment was to run Ingo's pipe_test_100k 200 times with the task pinned to one cpu. I measured instruction, cycles and stalled-cycles for the runs. See: http://thread.gmane.org/gmane.linux.kernel/1129232/focus=1129389 for more info. -tip (baseline): Performance counter stats for '/root/load-scale/pipe-test-100k' (200 runs): 964,991,769 instructions # 0.82 insns per cycle # 0.33 stalled cycles per insn # ( +- 0.05% ) 1,171,186,635 cycles # 0.000 GHz ( +- 0.08% ) 306,373,664 stalled-cycles-backend # 26.16% backend cycles idle ( +- 0.28% ) 314,933,621 stalled-cycles-frontend # 26.89% frontend cycles idle ( +- 0.34% ) 1.122405684 seconds time elapsed ( +- 0.05% ) -tip+patches: Performance counter stats for './load-scale/pipe-test-100k' (200 runs): 963,624,821 instructions # 0.82 insns per cycle # 0.33 stalled cycles per insn # ( +- 0.04% ) 1,175,215,649 cycles # 0.000 GHz ( +- 0.08% ) 315,321,126 stalled-cycles-backend # 26.83% backend cycles idle ( +- 0.28% ) 316,835,873 stalled-cycles-frontend # 26.96% frontend cycles idle ( +- 0.29% ) 1.122238659 seconds time elapsed ( +- 0.06% ) With this patch, instructions decrease by ~0.10% and cycles increase by 0.27%. This doesn't look statistically significant. The number of stalled cycles in the backend increased from 26.16% to 26.83%. This can be attributed to the shifts we do in c_d_m() and other places. The fraction of stalled cycles in the frontend remains about the same, at 26.96% compared to 26.89% in -tip. 2. Balancing low-weight task groups Test setup: run 50 tasks with random sleep/busy times (biased around 100ms) in a low weight container (with cpu.shares = 2). Measure %idle as reported by mpstat over a 10s window. -tip (baseline): 06:47:48 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle intr/s 06:47:49 PM all 94.32 0.00 0.06 0.00 0.00 0.00 0.00 0.00 5.62 15888.00 06:47:50 PM all 94.57 0.00 0.62 0.00 0.00 0.00 0.00 0.00 4.81 16180.00 06:47:51 PM all 94.69 0.00 0.06 0.00 0.00 0.00 0.00 0.00 5.25 15966.00 06:47:52 PM all 95.81 0.00 0.00 0.00 0.00 0.00 0.00 0.00 4.19 16053.00 06:47:53 PM all 94.88 0.06 0.00 0.00 0.00 0.00 0.00 0.00 5.06 15984.00 06:47:54 PM all 93.31 0.00 0.00 0.00 0.00 0.00 0.00 0.00 6.69 15806.00 06:47:55 PM all 94.19 0.00 0.06 0.00 0.00 0.00 0.00 0.00 5.75 15896.00 06:47:56 PM all 92.87 0.00 0.00 0.00 0.00 0.00 0.00 0.00 7.13 15716.00 06:47:57 PM all 94.88 0.00 0.00 0.00 0.00 0.00 0.00 0.00 5.12 15982.00 06:47:58 PM all 95.44 0.00 0.00 0.00 0.00 0.00 0.00 0.00 4.56 16075.00 Average: all 94.49 0.01 0.08 0.00 0.00 0.00 0.00 0.00 5.42 15954.60 -tip+patches: 06:47:03 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle intr/s 06:47:04 PM all 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 16630.00 06:47:05 PM all 99.69 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.31 16580.20 06:47:06 PM all 99.69 0.00 0.06 0.00 0.00 0.00 0.00 0.00 0.25 16596.00 06:47:07 PM all 99.20 0.00 0.74 0.00 0.00 0.06 0.00 0.00 0.00 17838.61 06:47:08 PM all 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 16540.00 06:47:09 PM all 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 16575.00 06:47:10 PM all 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 16614.00 06:47:11 PM all 99.94 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.06 16588.00 06:47:12 PM all 99.94 0.00 0.06 0.00 0.00 0.00 0.00 0.00 0.00 16593.00 06:47:13 PM all 99.94 0.00 0.06 0.00 0.00 0.00 0.00 0.00 0.00 16551.00 Average: all 99.84 0.00 0.09 0.00 0.00 0.01 0.00 0.00 0.06 16711.58 We see an improvement in idle% on the system (drops from 5.42% on -tip to 0.06% with the patches). We see an improvement in idle% on the system (drops from 5.42% on -tip to 0.06% with the patches). Signed-off-by: Nikhil Rao Acked-by: Peter Zijlstra Cc: Nikunj A. Dadhania Cc: Srivatsa Vaddagiri Cc: Stephan Barwolf Cc: Mike Galbraith Cc: Linus Torvalds Cc: Andrew Morton Link: http://lkml.kernel.org/r/1305754668-18792-1-git-send-email-ncrao@google.com Signed-off-by: Ingo Molnar --- include/linux/sched.h | 23 +++++++++++++++++++++-- kernel/sched.c | 28 ++++++++++++++++++++-------- 2 files changed, 41 insertions(+), 10 deletions(-) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index f2f440221b70..c34a718e20dd 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -788,9 +788,28 @@ enum cpu_idle_type { }; /* - * Increase resolution of nice-level calculations: + * Increase resolution of nice-level calculations for 64-bit architectures. + * The extra resolution improves shares distribution and load balancing of + * low-weight task groups (eg. nice +19 on an autogroup), deeper taskgroup + * hierarchies, especially on larger systems. This is not a user-visible change + * and does not change the user-interface for setting shares/weights. + * + * We increase resolution only if we have enough bits to allow this increased + * resolution (i.e. BITS_PER_LONG > 32). The costs for increasing resolution + * when BITS_PER_LONG <= 32 are pretty high and the returns do not justify the + * increased costs. */ -#define SCHED_LOAD_SHIFT 10 +#if BITS_PER_LONG > 32 +# define SCHED_LOAD_RESOLUTION 10 +# define scale_load(w) ((w) << SCHED_LOAD_RESOLUTION) +# define scale_load_down(w) ((w) >> SCHED_LOAD_RESOLUTION) +#else +# define SCHED_LOAD_RESOLUTION 0 +# define scale_load(w) (w) +# define scale_load_down(w) (w) +#endif + +#define SCHED_LOAD_SHIFT (10 + SCHED_LOAD_RESOLUTION) #define SCHED_LOAD_SCALE (1L << SCHED_LOAD_SHIFT) /* diff --git a/kernel/sched.c b/kernel/sched.c index 375e9c677d58..bb504e1839e5 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -293,7 +293,7 @@ static DEFINE_SPINLOCK(task_group_lock); * limitation from this.) */ #define MIN_SHARES 2 -#define MAX_SHARES (1UL << 18) +#define MAX_SHARES (1UL << (18 + SCHED_LOAD_RESOLUTION)) static int root_task_group_load = ROOT_TASK_GROUP_LOAD; #endif @@ -1330,13 +1330,25 @@ calc_delta_mine(unsigned long delta_exec, unsigned long weight, { u64 tmp; - tmp = (u64)delta_exec * weight; + /* + * weight can be less than 2^SCHED_LOAD_RESOLUTION for task group sched + * entities since MIN_SHARES = 2. Treat weight as 1 if less than + * 2^SCHED_LOAD_RESOLUTION. + */ + if (likely(weight > (1UL << SCHED_LOAD_RESOLUTION))) + tmp = (u64)delta_exec * scale_load_down(weight); + else + tmp = (u64)delta_exec; if (!lw->inv_weight) { - if (BITS_PER_LONG > 32 && unlikely(lw->weight >= WMULT_CONST)) + unsigned long w = scale_load_down(lw->weight); + + if (BITS_PER_LONG > 32 && unlikely(w >= WMULT_CONST)) lw->inv_weight = 1; + else if (unlikely(!w)) + lw->inv_weight = WMULT_CONST; else - lw->inv_weight = WMULT_CONST / lw->weight; + lw->inv_weight = WMULT_CONST / w; } /* @@ -1785,12 +1797,12 @@ static void set_load_weight(struct task_struct *p) * SCHED_IDLE tasks get minimal weight: */ if (p->policy == SCHED_IDLE) { - load->weight = WEIGHT_IDLEPRIO; + load->weight = scale_load(WEIGHT_IDLEPRIO); load->inv_weight = WMULT_IDLEPRIO; return; } - load->weight = prio_to_weight[prio]; + load->weight = scale_load(prio_to_weight[prio]); load->inv_weight = prio_to_wmult[prio]; } @@ -8809,14 +8821,14 @@ cpu_cgroup_exit(struct cgroup_subsys *ss, struct cgroup *cgrp, static int cpu_shares_write_u64(struct cgroup *cgrp, struct cftype *cftype, u64 shareval) { - return sched_group_set_shares(cgroup_tg(cgrp), shareval); + return sched_group_set_shares(cgroup_tg(cgrp), scale_load(shareval)); } static u64 cpu_shares_read_u64(struct cgroup *cgrp, struct cftype *cft) { struct task_group *tg = cgroup_tg(cgrp); - return (u64) tg->shares; + return (u64) scale_load_down(tg->shares); } #endif /* CONFIG_FAIR_GROUP_SCHED */ -- cgit From 8bb36c2139f7bcea32a78472272f1d0de3b00f7b Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Thu, 7 Apr 2011 12:45:51 -0300 Subject: [media] Add Y10B, a 10 bpp bit-packed greyscale format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a 10 bits per pixel greyscale format in a bit-packed array representation, naming it Y10B. Such pixel format is supplied for instance by the Kinect sensor device. Signed-off-by: Antonio Ospite Signed-off-by: Jean-François Moine Signed-off-by: Mauro Carvalho Chehab --- Documentation/DocBook/media-entities.tmpl | 1 + Documentation/DocBook/v4l/pixfmt-y10b.xml | 43 +++++++++++++++++++++++++++++++ Documentation/DocBook/v4l/pixfmt.xml | 1 + Documentation/DocBook/v4l/videodev2.h.xml | 3 +++ include/linux/videodev2.h | 3 +++ 5 files changed, 51 insertions(+) create mode 100644 Documentation/DocBook/v4l/pixfmt-y10b.xml (limited to 'include/linux') diff --git a/Documentation/DocBook/media-entities.tmpl b/Documentation/DocBook/media-entities.tmpl index fea63b45471a..7a9570887d21 100644 --- a/Documentation/DocBook/media-entities.tmpl +++ b/Documentation/DocBook/media-entities.tmpl @@ -295,6 +295,7 @@ + diff --git a/Documentation/DocBook/v4l/pixfmt-y10b.xml b/Documentation/DocBook/v4l/pixfmt-y10b.xml new file mode 100644 index 000000000000..adb0ad808c93 --- /dev/null +++ b/Documentation/DocBook/v4l/pixfmt-y10b.xml @@ -0,0 +1,43 @@ + + + V4L2_PIX_FMT_Y10BPACK ('Y10B') + &manvol; + + + V4L2_PIX_FMT_Y10BPACK + Grey-scale image as a bit-packed array + + + Description + + This is a packed grey-scale image format with a depth of 10 bits per + pixel. Pixels are stored in a bit-packed array of 10bit bits per pixel, + with no padding between them and with the most significant bits coming + first from the left. + + + <constant>V4L2_PIX_FMT_Y10BPACK</constant> 4 pixel data stream taking 5 bytes + + + Bit-packed representation + pixels cross the byte boundary and have a ratio of 5 bytes for each 4 + pixels. + + + + + + Y'00[9:2] + Y'00[1:0]Y'01[9:4] + Y'01[3:0]Y'02[9:6] + Y'02[5:0]Y'03[9:8] + Y'03[7:0] + + + + + + + + + diff --git a/Documentation/DocBook/v4l/pixfmt.xml b/Documentation/DocBook/v4l/pixfmt.xml index 40af4beb48b9..3486a068fe46 100644 --- a/Documentation/DocBook/v4l/pixfmt.xml +++ b/Documentation/DocBook/v4l/pixfmt.xml @@ -697,6 +697,7 @@ information. &sub-grey; &sub-y10; &sub-y12; + &sub-y10b; &sub-y16; &sub-yuyv; &sub-uyvy; diff --git a/Documentation/DocBook/v4l/videodev2.h.xml b/Documentation/DocBook/v4l/videodev2.h.xml index 2b796a2ee98a..937acf54da9c 100644 --- a/Documentation/DocBook/v4l/videodev2.h.xml +++ b/Documentation/DocBook/v4l/videodev2.h.xml @@ -311,6 +311,9 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_Y10 v4l2_fourcc('Y', '1', '0', ' ') /* 10 Greyscale */ #define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y', '1', '6', ' ') /* 16 Greyscale */ +/* Grey bit-packed formats */ +#define V4L2_PIX_FMT_Y10BPACK v4l2_fourcc('Y', '1', '0', 'B') /* 10 Greyscale bit-packed */ + /* Palette formats */ #define V4L2_PIX_FMT_PAL8 v4l2_fourcc('P', 'A', 'L', '8') /* 8 8-bit palette */ diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index be82c8ead1af..a417270b337f 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -311,6 +311,9 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_Y12 v4l2_fourcc('Y', '1', '2', ' ') /* 12 Greyscale */ #define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y', '1', '6', ' ') /* 16 Greyscale */ +/* Grey bit-packed formats */ +#define V4L2_PIX_FMT_Y10BPACK v4l2_fourcc('Y', '1', '0', 'B') /* 10 Greyscale bit-packed */ + /* Palette formats */ #define V4L2_PIX_FMT_PAL8 v4l2_fourcc('P', 'A', 'L', '8') /* 8 8-bit palette */ -- cgit From 5f7088127e800df2cd5ff08140bdca087ab0fbac Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sun, 21 Nov 2010 17:15:44 -0300 Subject: [media] uvcvideo: Make the API public Move the public API definitions to include/linux/uvcvideo.h and bump the version number to 1.1.0. Compatibility with the old API is kept, application can still be compiled against the private header and will not break. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- Documentation/ioctl/ioctl-number.txt | 2 +- drivers/media/video/uvc/uvc_v4l2.c | 13 +++---- drivers/media/video/uvc/uvcvideo.h | 68 ++++++++++++++++------------------- include/linux/Kbuild | 1 + include/linux/uvcvideo.h | 69 ++++++++++++++++++++++++++++++++++++ 5 files changed, 108 insertions(+), 45 deletions(-) create mode 100644 include/linux/uvcvideo.h (limited to 'include/linux') diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt index a0a5d82b6b0b..2d1ad12e2b3e 100644 --- a/Documentation/ioctl/ioctl-number.txt +++ b/Documentation/ioctl/ioctl-number.txt @@ -166,7 +166,6 @@ Code Seq#(hex) Include File Comments 'T' all arch/x86/include/asm/ioctls.h conflict! 'T' C0-DF linux/if_tun.h conflict! 'U' all sound/asound.h conflict! -'U' 00-0F drivers/media/video/uvc/uvcvideo.h conflict! 'U' 00-CF linux/uinput.h conflict! 'U' 00-EF linux/usbdevice_fs.h 'U' C0-CF drivers/bluetooth/hci_uart.h @@ -259,6 +258,7 @@ Code Seq#(hex) Include File Comments 't' 80-8F linux/isdn_ppp.h 't' 90 linux/toshiba.h 'u' 00-1F linux/smb_fs.h gone +'u' 20-3F linux/uvcvideo.h USB video class host driver 'v' 00-1F linux/ext2_fs.h conflict! 'v' 00-1F linux/fs.h conflict! 'v' 00-0F linux/sonypi.h conflict! diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c index 2e2a556d1666..6e8aad44c4bd 100644 --- a/drivers/media/video/uvc/uvc_v4l2.c +++ b/drivers/media/video/uvc/uvc_v4l2.c @@ -1036,24 +1036,25 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) * UVCIOC_CTRL_GET and UVCIOC_CTRL_SET are deprecated and scheduled for * removal in 2.6.42. */ - case UVCIOC_CTRL_ADD: + case __UVCIOC_CTRL_ADD: uvc_v4l2_ioctl_warn(); return -EEXIST; - case UVCIOC_CTRL_MAP_OLD: + case __UVCIOC_CTRL_MAP_OLD: uvc_v4l2_ioctl_warn(); + case __UVCIOC_CTRL_MAP: case UVCIOC_CTRL_MAP: return uvc_ioctl_ctrl_map(chain, arg, - cmd == UVCIOC_CTRL_MAP_OLD); + cmd == __UVCIOC_CTRL_MAP_OLD); - case UVCIOC_CTRL_GET: - case UVCIOC_CTRL_SET: + case __UVCIOC_CTRL_GET: + case __UVCIOC_CTRL_SET: { struct uvc_xu_control *xctrl = arg; struct uvc_xu_control_query xqry = { .unit = xctrl->unit, .selector = xctrl->selector, - .query = cmd == UVCIOC_CTRL_GET + .query = cmd == __UVCIOC_CTRL_GET ? UVC_GET_CUR : UVC_SET_CUR, .size = xctrl->size, .data = xctrl->data, diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index cd58ea81320b..38dd4e18a2ca 100644 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h @@ -4,6 +4,14 @@ #include #include +#ifndef __KERNEL__ +/* + * This header provides binary compatibility with applications using the private + * uvcvideo API. This API is deprecated and will be removed in 2.6.42. + * Applications should be recompiled against the public linux/uvcvideo.h header. + */ +#warn "The uvcvideo.h header is deprecated, use linux/uvcvideo.h instead." + /* * Dynamic controls */ @@ -17,23 +25,6 @@ #define UVC_CTRL_DATA_TYPE_BITMASK 5 /* Control flags */ -#define UVC_CTRL_FLAG_SET_CUR (1 << 0) -#define UVC_CTRL_FLAG_GET_CUR (1 << 1) -#define UVC_CTRL_FLAG_GET_MIN (1 << 2) -#define UVC_CTRL_FLAG_GET_MAX (1 << 3) -#define UVC_CTRL_FLAG_GET_RES (1 << 4) -#define UVC_CTRL_FLAG_GET_DEF (1 << 5) -/* Control should be saved at suspend and restored at resume. */ -#define UVC_CTRL_FLAG_RESTORE (1 << 6) -/* Control can be updated by the camera. */ -#define UVC_CTRL_FLAG_AUTO_UPDATE (1 << 7) - -#define UVC_CTRL_FLAG_GET_RANGE \ - (UVC_CTRL_FLAG_GET_CUR | UVC_CTRL_FLAG_GET_MIN | \ - UVC_CTRL_FLAG_GET_MAX | UVC_CTRL_FLAG_GET_RES | \ - UVC_CTRL_FLAG_GET_DEF) - -/* Old control flags, don't use */ #define UVC_CONTROL_SET_CUR (1 << 0) #define UVC_CONTROL_GET_CUR (1 << 1) #define UVC_CONTROL_GET_MIN (1 << 2) @@ -47,23 +38,11 @@ UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES | \ UVC_CONTROL_GET_DEF) -struct uvc_xu_control_info { - __u8 entity[16]; - __u8 index; - __u8 selector; - __u16 size; - __u32 flags; -}; - struct uvc_menu_info { __u32 value; __u8 name[32]; }; -struct uvc_xu_control_mapping_old { - __u8 reserved[64]; -}; - struct uvc_xu_control_mapping { __u32 id; __u8 name[32]; @@ -81,32 +60,46 @@ struct uvc_xu_control_mapping { __u32 reserved[4]; }; -struct uvc_xu_control { - __u8 unit; +#endif + +struct uvc_xu_control_info { + __u8 entity[16]; + __u8 index; __u8 selector; __u16 size; - __u8 __user *data; + __u32 flags; }; -struct uvc_xu_control_query { +struct uvc_xu_control_mapping_old { + __u8 reserved[64]; +}; + +struct uvc_xu_control { __u8 unit; __u8 selector; - __u8 query; __u16 size; __u8 __user *data; }; +#ifndef __KERNEL__ #define UVCIOC_CTRL_ADD _IOW('U', 1, struct uvc_xu_control_info) #define UVCIOC_CTRL_MAP_OLD _IOWR('U', 2, struct uvc_xu_control_mapping_old) #define UVCIOC_CTRL_MAP _IOWR('U', 2, struct uvc_xu_control_mapping) #define UVCIOC_CTRL_GET _IOWR('U', 3, struct uvc_xu_control) #define UVCIOC_CTRL_SET _IOW('U', 4, struct uvc_xu_control) -#define UVCIOC_CTRL_QUERY _IOWR('U', 5, struct uvc_xu_control_query) +#else +#define __UVCIOC_CTRL_ADD _IOW('U', 1, struct uvc_xu_control_info) +#define __UVCIOC_CTRL_MAP_OLD _IOWR('U', 2, struct uvc_xu_control_mapping_old) +#define __UVCIOC_CTRL_MAP _IOWR('U', 2, struct uvc_xu_control_mapping) +#define __UVCIOC_CTRL_GET _IOWR('U', 3, struct uvc_xu_control) +#define __UVCIOC_CTRL_SET _IOW('U', 4, struct uvc_xu_control) +#endif #ifdef __KERNEL__ #include #include +#include /* -------------------------------------------------------------------------- * UVC constants @@ -184,8 +177,8 @@ struct uvc_xu_control_query { * Driver specific constants. */ -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(1, 0, 0) -#define DRIVER_VERSION "v1.0.0" +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(1, 1, 0) +#define DRIVER_VERSION "v1.1.0" /* Number of isochronous URBs. */ #define UVC_URBS 5 @@ -682,4 +675,3 @@ void uvc_video_decode_isight(struct urb *urb, struct uvc_streaming *stream, #endif /* __KERNEL__ */ #endif - diff --git a/include/linux/Kbuild b/include/linux/Kbuild index 75cf611641e6..cb1ded2bd545 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild @@ -372,6 +372,7 @@ header-y += unistd.h header-y += usbdevice_fs.h header-y += utime.h header-y += utsname.h +header-y += uvcvideo.h header-y += v4l2-mediabus.h header-y += v4l2-subdev.h header-y += veth.h diff --git a/include/linux/uvcvideo.h b/include/linux/uvcvideo.h new file mode 100644 index 000000000000..f46a53f060d7 --- /dev/null +++ b/include/linux/uvcvideo.h @@ -0,0 +1,69 @@ +#ifndef __LINUX_UVCVIDEO_H_ +#define __LINUX_UVCVIDEO_H_ + +#include +#include + +/* + * Dynamic controls + */ + +/* Data types for UVC control data */ +#define UVC_CTRL_DATA_TYPE_RAW 0 +#define UVC_CTRL_DATA_TYPE_SIGNED 1 +#define UVC_CTRL_DATA_TYPE_UNSIGNED 2 +#define UVC_CTRL_DATA_TYPE_BOOLEAN 3 +#define UVC_CTRL_DATA_TYPE_ENUM 4 +#define UVC_CTRL_DATA_TYPE_BITMASK 5 + +/* Control flags */ +#define UVC_CTRL_FLAG_SET_CUR (1 << 0) +#define UVC_CTRL_FLAG_GET_CUR (1 << 1) +#define UVC_CTRL_FLAG_GET_MIN (1 << 2) +#define UVC_CTRL_FLAG_GET_MAX (1 << 3) +#define UVC_CTRL_FLAG_GET_RES (1 << 4) +#define UVC_CTRL_FLAG_GET_DEF (1 << 5) +/* Control should be saved at suspend and restored at resume. */ +#define UVC_CTRL_FLAG_RESTORE (1 << 6) +/* Control can be updated by the camera. */ +#define UVC_CTRL_FLAG_AUTO_UPDATE (1 << 7) + +#define UVC_CTRL_FLAG_GET_RANGE \ + (UVC_CTRL_FLAG_GET_CUR | UVC_CTRL_FLAG_GET_MIN | \ + UVC_CTRL_FLAG_GET_MAX | UVC_CTRL_FLAG_GET_RES | \ + UVC_CTRL_FLAG_GET_DEF) + +struct uvc_menu_info { + __u32 value; + __u8 name[32]; +}; + +struct uvc_xu_control_mapping { + __u32 id; + __u8 name[32]; + __u8 entity[16]; + __u8 selector; + + __u8 size; + __u8 offset; + __u32 v4l2_type; + __u32 data_type; + + struct uvc_menu_info __user *menu_info; + __u32 menu_count; + + __u32 reserved[4]; +}; + +struct uvc_xu_control_query { + __u8 unit; + __u8 selector; + __u8 query; + __u16 size; + __u8 __user *data; +}; + +#define UVCIOC_CTRL_MAP _IOWR('u', 0x20, struct uvc_xu_control_mapping) +#define UVCIOC_CTRL_QUERY _IOWR('u', 0x21, struct uvc_xu_control_query) + +#endif -- cgit From 16846524afc200e795aaae659356001780fa91db Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Fri, 25 Mar 2011 12:09:43 -0300 Subject: [media] v4l: Add V4L2_MBUS_FMT_JPEG_1X8 media bus format Add V4L2_MBUS_FMT_JPEG_1X8 format and the corresponding Docbook documentation. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- Documentation/DocBook/v4l/subdev-formats.xml | 46 ++++++++++++++++++++++++++++ include/linux/v4l2-mediabus.h | 3 ++ 2 files changed, 49 insertions(+) (limited to 'include/linux') diff --git a/Documentation/DocBook/v4l/subdev-formats.xml b/Documentation/DocBook/v4l/subdev-formats.xml index d7ccd25edcc1..a26b10c07857 100644 --- a/Documentation/DocBook/v4l/subdev-formats.xml +++ b/Documentation/DocBook/v4l/subdev-formats.xml @@ -2522,5 +2522,51 @@ + +
+ JPEG Compressed Formats + + Those data formats consist of an ordered sequence of 8-bit bytes + obtained from JPEG compression process. Additionally to the + _JPEG prefix the format code is made of + the following information. + + The number of bus samples per entropy encoded byte. + The bus width. + + + For instance, for a JPEG baseline process and an 8-bit bus width + the format will be named V4L2_MBUS_FMT_JPEG_1X8. + + + + The following table lists existing JPEG compressed formats. + + + JPEG Formats + + + + + + + Identifier + Code + Remarks + + + + + V4L2_MBUS_FMT_JPEG_1X8 + 0x4001 + Besides of its usage for the parallel bus this format is + recommended for transmission of JPEG data over MIPI CSI bus + using the User Defined 8-bit Data types. + + + + +
+
diff --git a/include/linux/v4l2-mediabus.h b/include/linux/v4l2-mediabus.h index de5c15921025..5ea7f753a348 100644 --- a/include/linux/v4l2-mediabus.h +++ b/include/linux/v4l2-mediabus.h @@ -89,6 +89,9 @@ enum v4l2_mbus_pixelcode { V4L2_MBUS_FMT_SGBRG12_1X12 = 0x3010, V4L2_MBUS_FMT_SGRBG12_1X12 = 0x3011, V4L2_MBUS_FMT_SRGGB12_1X12 = 0x3012, + + /* JPEG compressed formats - next is 0x4002 */ + V4L2_MBUS_FMT_JPEG_1X8 = 0x4001, }; /** -- cgit From 0e59fd0592430cee4595c600427899a3404861e7 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 11 May 2011 09:56:20 -0300 Subject: [media] v4l: Add M420 format definition M420 is a hybrid YUV 4:2:0 packet/planar format. Two Y lines are followed by an interleaved U/V line. Signed-off-by: Hans de Goede [laurent.pinchart@ideasonboard.com: split into v4l/uvcvideo patches] [laurent.pinchart@ideasonboard.com: add documentation] Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- Documentation/DocBook/media-entities.tmpl | 1 + Documentation/DocBook/v4l/pixfmt-m420.xml | 147 ++++++++++++++++++++++++++++++ Documentation/DocBook/v4l/pixfmt.xml | 1 + Documentation/DocBook/v4l/videodev2.h.xml | 1 + include/linux/videodev2.h | 1 + 5 files changed, 151 insertions(+) create mode 100644 Documentation/DocBook/v4l/pixfmt-m420.xml (limited to 'include/linux') diff --git a/Documentation/DocBook/media-entities.tmpl b/Documentation/DocBook/media-entities.tmpl index 7a9570887d21..c8abb23ef1e7 100644 --- a/Documentation/DocBook/media-entities.tmpl +++ b/Documentation/DocBook/media-entities.tmpl @@ -270,6 +270,7 @@ + diff --git a/Documentation/DocBook/v4l/pixfmt-m420.xml b/Documentation/DocBook/v4l/pixfmt-m420.xml new file mode 100644 index 000000000000..ce4bc019e5c0 --- /dev/null +++ b/Documentation/DocBook/v4l/pixfmt-m420.xml @@ -0,0 +1,147 @@ + + + V4L2_PIX_FMT_M420 ('M420') + &manvol; + + + V4L2_PIX_FMT_M420 + Format with ½ horizontal and vertical chroma + resolution, also known as YUV 4:2:0. Hybrid plane line-interleaved + layout. + + + Description + + M420 is a YUV format with ½ horizontal and vertical chroma + subsampling (YUV 4:2:0). Pixels are organized as interleaved luma and + chroma planes. Two lines of luma data are followed by one line of chroma + data. + The luma plane has one byte per pixel. The chroma plane contains + interleaved CbCr pixels subsampled by ½ in the horizontal and + vertical directions. Each CbCr pair belongs to four pixels. For example, +Cb0/Cr0 belongs to +Y'00, Y'01, +Y'10, Y'11. + + All line lengths are identical: if the Y lines include pad bytes + so do the CbCr lines. + + + <constant>V4L2_PIX_FMT_M420</constant> 4 × 4 +pixel image + + + Byte Order. + Each cell is one byte. + + + + + + start + 0: + Y'00 + Y'01 + Y'02 + Y'03 + + + start + 4: + Y'10 + Y'11 + Y'12 + Y'13 + + + start + 8: + Cb00 + Cr00 + Cb01 + Cr01 + + + start + 16: + Y'20 + Y'21 + Y'22 + Y'23 + + + start + 20: + Y'30 + Y'31 + Y'32 + Y'33 + + + start + 24: + Cb10 + Cr10 + Cb11 + Cr11 + + + + + + + + + Color Sample Location. + + + + + + + 01 + 23 + + + 0 + YY + YY + + + + C + C + + + 1 + YY + YY + + + + + + 2 + YY + YY + + + + C + C + + + 3 + YY + YY + + + + + + + + + + + diff --git a/Documentation/DocBook/v4l/pixfmt.xml b/Documentation/DocBook/v4l/pixfmt.xml index 3486a068fe46..dbfe3b08435f 100644 --- a/Documentation/DocBook/v4l/pixfmt.xml +++ b/Documentation/DocBook/v4l/pixfmt.xml @@ -713,6 +713,7 @@ information. &sub-nv12m; &sub-nv12mt; &sub-nv16; + &sub-m420;
diff --git a/Documentation/DocBook/v4l/videodev2.h.xml b/Documentation/DocBook/v4l/videodev2.h.xml index 937acf54da9c..c50536a4f596 100644 --- a/Documentation/DocBook/v4l/videodev2.h.xml +++ b/Documentation/DocBook/v4l/videodev2.h.xml @@ -336,6 +336,7 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_YUV420 v4l2_fourcc('Y', 'U', '1', '2') /* 12 YUV 4:2:0 */ #define V4L2_PIX_FMT_HI240 v4l2_fourcc('H', 'I', '2', '4') /* 8 8-bit color */ #define V4L2_PIX_FMT_HM12 v4l2_fourcc('H', 'M', '1', '2') /* 8 YUV 4:2:0 16x16 macroblocks */ +#define V4L2_PIX_FMT_M420 v4l2_fourcc('M', '4', '2', '0') /* 12 YUV 4:2:0 2 lines y, 1 line uv interleaved */ /* two planes -- one Y, one Cr + Cb interleaved */ #define V4L2_PIX_FMT_NV12 v4l2_fourcc('N', 'V', '1', '2') /* 12 Y/CbCr 4:2:0 */ diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index a417270b337f..8a4c309d2344 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -336,6 +336,7 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_YUV420 v4l2_fourcc('Y', 'U', '1', '2') /* 12 YUV 4:2:0 */ #define V4L2_PIX_FMT_HI240 v4l2_fourcc('H', 'I', '2', '4') /* 8 8-bit color */ #define V4L2_PIX_FMT_HM12 v4l2_fourcc('H', 'M', '1', '2') /* 8 YUV 4:2:0 16x16 macroblocks */ +#define V4L2_PIX_FMT_M420 v4l2_fourcc('M', '4', '2', '0') /* 12 YUV 4:2:0 2 lines y, 1 line uv interleaved */ /* two planes -- one Y, one Cr + Cb interleaved */ #define V4L2_PIX_FMT_NV12 v4l2_fourcc('N', 'V', '1', '2') /* 12 Y/CbCr 4:2:0 */ -- cgit From b2cbae2c248776d81cc265ff7d48405b6a4cc463 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Fri, 20 May 2011 11:46:11 -0700 Subject: RDMA: Add netlink infrastructure Add basic RDMA netlink infrastructure that allows for registration of RDMA clients for which data is to be exported and supplies message construction callbacks. Signed-off-by: Nir Muchtar [ Reorganize a few things, add CONFIG_NET dependency. - Roland ] Signed-off-by: Roland Dreier --- drivers/infiniband/Kconfig | 1 + drivers/infiniband/core/Makefile | 2 +- drivers/infiniband/core/device.c | 13 ++- drivers/infiniband/core/netlink.c | 190 ++++++++++++++++++++++++++++++++++++++ drivers/infiniband/hw/qib/Kconfig | 2 +- include/linux/netlink.h | 1 + include/rdma/rdma_netlink.h | 64 +++++++++++++ 7 files changed, 270 insertions(+), 3 deletions(-) create mode 100644 drivers/infiniband/core/netlink.c create mode 100644 include/rdma/rdma_netlink.h (limited to 'include/linux') diff --git a/drivers/infiniband/Kconfig b/drivers/infiniband/Kconfig index 6e35eccc9caa..0f9a84c1046a 100644 --- a/drivers/infiniband/Kconfig +++ b/drivers/infiniband/Kconfig @@ -2,6 +2,7 @@ menuconfig INFINIBAND tristate "InfiniBand support" depends on PCI || BROKEN depends on HAS_IOMEM + depends on NET ---help--- Core support for InfiniBand (IB). Make sure to also select any protocols you wish to use as well as drivers for your diff --git a/drivers/infiniband/core/Makefile b/drivers/infiniband/core/Makefile index cb1ab3ea4998..c8bbaef1becb 100644 --- a/drivers/infiniband/core/Makefile +++ b/drivers/infiniband/core/Makefile @@ -8,7 +8,7 @@ obj-$(CONFIG_INFINIBAND_USER_ACCESS) += ib_uverbs.o ib_ucm.o \ $(user_access-y) ib_core-y := packer.o ud_header.o verbs.o sysfs.o \ - device.o fmr_pool.o cache.o + device.o fmr_pool.o cache.o netlink.o ib_core-$(CONFIG_INFINIBAND_USER_MEM) += umem.o ib_mad-y := mad.o smi.o agent.o mad_rmpp.o diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c index 46a7a3febc12..4007f721d25d 100644 --- a/drivers/infiniband/core/device.c +++ b/drivers/infiniband/core/device.c @@ -38,6 +38,7 @@ #include #include #include +#include #include "core_priv.h" @@ -730,14 +731,23 @@ static int __init ib_core_init(void) goto err; } + ret = ibnl_init(); + if (ret) { + printk(KERN_WARNING "Couldn't init IB netlink interface\n"); + goto err_sysfs; + } + ret = ib_cache_setup(); if (ret) { printk(KERN_WARNING "Couldn't set up InfiniBand P_Key/GID cache\n"); - goto err_sysfs; + goto err_nl; } return 0; +err_nl: + ibnl_cleanup(); + err_sysfs: ib_sysfs_cleanup(); @@ -749,6 +759,7 @@ err: static void __exit ib_core_cleanup(void) { ib_cache_cleanup(); + ibnl_cleanup(); ib_sysfs_cleanup(); /* Make sure that any pending umem accounting work is done. */ destroy_workqueue(ib_wq); diff --git a/drivers/infiniband/core/netlink.c b/drivers/infiniband/core/netlink.c new file mode 100644 index 000000000000..4a5abaf0a25c --- /dev/null +++ b/drivers/infiniband/core/netlink.c @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2010 Voltaire Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#define pr_fmt(fmt) "%s:%s: " fmt, KBUILD_MODNAME, __func__ + +#include +#include +#include +#include + +struct ibnl_client { + struct list_head list; + int index; + int nops; + const struct ibnl_client_cbs *cb_table; +}; + +static DEFINE_MUTEX(ibnl_mutex); +static struct sock *nls; +static LIST_HEAD(client_list); + +int ibnl_add_client(int index, int nops, + const struct ibnl_client_cbs cb_table[]) +{ + struct ibnl_client *cur; + struct ibnl_client *nl_client; + + nl_client = kmalloc(sizeof *nl_client, GFP_KERNEL); + if (!nl_client) + return -ENOMEM; + + nl_client->index = index; + nl_client->nops = nops; + nl_client->cb_table = cb_table; + + mutex_lock(&ibnl_mutex); + + list_for_each_entry(cur, &client_list, list) { + if (cur->index == index) { + pr_warn("Client for %d already exists\n", index); + mutex_unlock(&ibnl_mutex); + kfree(nl_client); + return -EINVAL; + } + } + + list_add_tail(&nl_client->list, &client_list); + + mutex_unlock(&ibnl_mutex); + + return 0; +} +EXPORT_SYMBOL(ibnl_add_client); + +int ibnl_remove_client(int index) +{ + struct ibnl_client *cur, *next; + + mutex_lock(&ibnl_mutex); + list_for_each_entry_safe(cur, next, &client_list, list) { + if (cur->index == index) { + list_del(&(cur->list)); + mutex_unlock(&ibnl_mutex); + kfree(cur); + return 0; + } + } + pr_warn("Can't remove callback for client idx %d. Not found\n", index); + mutex_unlock(&ibnl_mutex); + + return -EINVAL; +} +EXPORT_SYMBOL(ibnl_remove_client); + +void *ibnl_put_msg(struct sk_buff *skb, struct nlmsghdr **nlh, int seq, + int len, int client, int op) +{ + unsigned char *prev_tail; + + prev_tail = skb_tail_pointer(skb); + *nlh = NLMSG_NEW(skb, 0, seq, RDMA_NL_GET_TYPE(client, op), + len, NLM_F_MULTI); + (*nlh)->nlmsg_len = skb_tail_pointer(skb) - prev_tail; + return NLMSG_DATA(*nlh); + +nlmsg_failure: + nlmsg_trim(skb, prev_tail); + return NULL; +} +EXPORT_SYMBOL(ibnl_put_msg); + +int ibnl_put_attr(struct sk_buff *skb, struct nlmsghdr *nlh, + int len, void *data, int type) +{ + unsigned char *prev_tail; + + prev_tail = skb_tail_pointer(skb); + NLA_PUT(skb, type, len, data); + nlh->nlmsg_len += skb_tail_pointer(skb) - prev_tail; + return 0; + +nla_put_failure: + nlmsg_trim(skb, prev_tail - nlh->nlmsg_len); + return -EMSGSIZE; +} +EXPORT_SYMBOL(ibnl_put_attr); + +static int ibnl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) +{ + struct ibnl_client *client; + int type = nlh->nlmsg_type; + int index = RDMA_NL_GET_CLIENT(type); + int op = RDMA_NL_GET_OP(type); + + list_for_each_entry(client, &client_list, list) { + if (client->index == index) { + if (op < 0 || op >= client->nops || + !client->cb_table[RDMA_NL_GET_OP(op)].dump) + return -EINVAL; + return netlink_dump_start(nls, skb, nlh, + client->cb_table[op].dump, + NULL); + } + } + + pr_info("Index %d wasn't found in client list\n", index); + return -EINVAL; +} + +static void ibnl_rcv(struct sk_buff *skb) +{ + mutex_lock(&ibnl_mutex); + netlink_rcv_skb(skb, &ibnl_rcv_msg); + mutex_unlock(&ibnl_mutex); +} + +int __init ibnl_init(void) +{ + nls = netlink_kernel_create(&init_net, NETLINK_RDMA, 0, ibnl_rcv, + NULL, THIS_MODULE); + if (!nls) { + pr_warn("Failed to create netlink socket\n"); + return -ENOMEM; + } + + return 0; +} + +void ibnl_cleanup(void) +{ + struct ibnl_client *cur, *next; + + mutex_lock(&ibnl_mutex); + list_for_each_entry_safe(cur, next, &client_list, list) { + list_del(&(cur->list)); + kfree(cur); + } + mutex_unlock(&ibnl_mutex); + + netlink_kernel_release(nls); +} diff --git a/drivers/infiniband/hw/qib/Kconfig b/drivers/infiniband/hw/qib/Kconfig index 7c03a70c55a2..8349f9c5064c 100644 --- a/drivers/infiniband/hw/qib/Kconfig +++ b/drivers/infiniband/hw/qib/Kconfig @@ -1,6 +1,6 @@ config INFINIBAND_QIB tristate "QLogic PCIe HCA support" - depends on 64BIT && NET + depends on 64BIT ---help--- This is a low-level driver for QLogic PCIe QLE InfiniBand host channel adapters. This driver does not support the QLogic diff --git a/include/linux/netlink.h b/include/linux/netlink.h index 4c4ac3f3ce5a..a9dd89552f9c 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -24,6 +24,7 @@ /* leave room for NETLINK_DM (DM Events) */ #define NETLINK_SCSITRANSPORT 18 /* SCSI Transports */ #define NETLINK_ECRYPTFS 19 +#define NETLINK_RDMA 20 #define MAX_LINKS 32 diff --git a/include/rdma/rdma_netlink.h b/include/rdma/rdma_netlink.h new file mode 100644 index 000000000000..c983a193cecf --- /dev/null +++ b/include/rdma/rdma_netlink.h @@ -0,0 +1,64 @@ +#ifndef _RDMA_NETLINK_H +#define _RDMA_NETLINK_H + +#define RDMA_NL_GET_CLIENT(type) ((type & (((1 << 6) - 1) << 10)) >> 10) +#define RDMA_NL_GET_OP(type) (type & ((1 << 10) - 1)) +#define RDMA_NL_GET_TYPE(client, op) ((client << 10) + op) + +#ifdef __KERNEL__ + +#include + +struct ibnl_client_cbs { + int (*dump)(struct sk_buff *skb, struct netlink_callback *nlcb); +}; + +int ibnl_init(void); +void ibnl_cleanup(void); + +/** + * Add a a client to the list of IB netlink exporters. + * @index: Index of the added client + * @nops: Number of supported ops by the added client. + * @cb_table: A table for op->callback + * + * Returns 0 on success or a negative error code. + */ +int ibnl_add_client(int index, int nops, + const struct ibnl_client_cbs cb_table[]); + +/** + * Remove a client from IB netlink. + * @index: Index of the removed IB client. + * + * Returns 0 on success or a negative error code. + */ +int ibnl_remove_client(int index); + +/** + * Put a new message in a supplied skb. + * @skb: The netlink skb. + * @nlh: Pointer to put the header of the new netlink message. + * @seq: The message sequence number. + * @len: The requested message length to allocate. + * @client: Calling IB netlink client. + * @op: message content op. + * Returns the allocated buffer on success and NULL on failure. + */ +void *ibnl_put_msg(struct sk_buff *skb, struct nlmsghdr **nlh, int seq, + int len, int client, int op); +/** + * Put a new attribute in a supplied skb. + * @skb: The netlink skb. + * @nlh: Header of the netlink message to append the attribute to. + * @len: The length of the attribute data. + * @data: The attribute data to put. + * @type: The attribute type. + * Returns the 0 and a negative error code on failure. + */ +int ibnl_put_attr(struct sk_buff *skb, struct nlmsghdr *nlh, + int len, void *data, int type); + +#endif /* __KERNEL__ */ + +#endif /* _RDMA_NETLINK_H */ -- cgit From 771949d03b4f5295f648f09141325fd478f6c7ce Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 20 May 2011 20:52:16 +0200 Subject: block: get rid of on-stack plugging debug checks We don't need them anymore, so kill: - REQ_ON_PLUG checks in various places - !rq_mergeable() check in plug merging Signed-off-by: Jens Axboe --- block/blk-core.c | 27 --------------------------- block/elevator.c | 4 ---- include/linux/blk_types.h | 2 -- 3 files changed, 33 deletions(-) (limited to 'include/linux') diff --git a/block/blk-core.c b/block/blk-core.c index 9e8e297374b9..7369eeeafe23 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -569,8 +569,6 @@ int blk_get_queue(struct request_queue *q) static inline void blk_free_request(struct request_queue *q, struct request *rq) { - BUG_ON(rq->cmd_flags & REQ_ON_PLUG); - if (rq->cmd_flags & REQ_ELVPRIV) elv_put_request(q, rq); mempool_free(rq, q->rq.rq_pool); @@ -1110,14 +1108,6 @@ static bool bio_attempt_back_merge(struct request_queue *q, struct request *req, { const int ff = bio->bi_rw & REQ_FAILFAST_MASK; - /* - * Debug stuff, kill later - */ - if (!rq_mergeable(req)) { - blk_dump_rq_flags(req, "back"); - return false; - } - if (!ll_back_merge_fn(q, req, bio)) return false; @@ -1141,14 +1131,6 @@ static bool bio_attempt_front_merge(struct request_queue *q, const int ff = bio->bi_rw & REQ_FAILFAST_MASK; sector_t sector; - /* - * Debug stuff, kill later - */ - if (!rq_mergeable(req)) { - blk_dump_rq_flags(req, "front"); - return false; - } - if (!ll_front_merge_fn(q, req, bio)) return false; @@ -1258,14 +1240,12 @@ static int __make_request(struct request_queue *q, struct bio *bio) el_ret = elv_merge(q, &req, bio); if (el_ret == ELEVATOR_BACK_MERGE) { - BUG_ON(req->cmd_flags & REQ_ON_PLUG); if (bio_attempt_back_merge(q, req, bio)) { if (!attempt_back_merge(q, req)) elv_merged_request(q, req, el_ret); goto out_unlock; } } else if (el_ret == ELEVATOR_FRONT_MERGE) { - BUG_ON(req->cmd_flags & REQ_ON_PLUG); if (bio_attempt_front_merge(q, req, bio)) { if (!attempt_front_merge(q, req)) elv_merged_request(q, req, el_ret); @@ -1320,10 +1300,6 @@ get_rq: if (__rq->q != q) plug->should_sort = 1; } - /* - * Debug flag, kill later - */ - req->cmd_flags |= REQ_ON_PLUG; list_add_tail(&req->queuelist, &plug->list); drive_stat_acct(req, 1); } else { @@ -2749,7 +2725,6 @@ void blk_flush_plug_list(struct blk_plug *plug, bool from_schedule) while (!list_empty(&list)) { rq = list_entry_rq(list.next); list_del_init(&rq->queuelist); - BUG_ON(!(rq->cmd_flags & REQ_ON_PLUG)); BUG_ON(!rq->q); if (rq->q != q) { /* @@ -2761,8 +2736,6 @@ void blk_flush_plug_list(struct blk_plug *plug, bool from_schedule) depth = 0; spin_lock(q->queue_lock); } - rq->cmd_flags &= ~REQ_ON_PLUG; - /* * rq is already accounted, so use raw insert */ diff --git a/block/elevator.c b/block/elevator.c index 2a0b653c90fd..b0b38ce0dcb6 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -416,8 +416,6 @@ void elv_dispatch_sort(struct request_queue *q, struct request *rq) struct list_head *entry; int stop_flags; - BUG_ON(rq->cmd_flags & REQ_ON_PLUG); - if (q->last_merge == rq) q->last_merge = NULL; @@ -656,8 +654,6 @@ void __elv_add_request(struct request_queue *q, struct request *rq, int where) rq->q = q; - BUG_ON(rq->cmd_flags & REQ_ON_PLUG); - if (rq->cmd_flags & REQ_SOFTBARRIER) { /* barriers are scheduling boundary, update end_sector */ if (rq->cmd_type == REQ_TYPE_FS || diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index be50d9e70a7d..2a7cea53ca0d 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h @@ -151,7 +151,6 @@ enum rq_flag_bits { __REQ_IO_STAT, /* account I/O stat */ __REQ_MIXED_MERGE, /* merge of different types, fail separately */ __REQ_SECURE, /* secure discard (used with __REQ_DISCARD) */ - __REQ_ON_PLUG, /* on plug list */ __REQ_NR_BITS, /* stops here */ }; @@ -192,6 +191,5 @@ enum rq_flag_bits { #define REQ_IO_STAT (1 << __REQ_IO_STAT) #define REQ_MIXED_MERGE (1 << __REQ_MIXED_MERGE) #define REQ_SECURE (1 << __REQ_SECURE) -#define REQ_ON_PLUG (1 << __REQ_ON_PLUG) #endif /* __LINUX_BLK_TYPES_H */ -- cgit From d974d905cbfc1039a73ba0c7eea3f4d4e13c0624 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Fri, 20 May 2011 15:48:17 +1000 Subject: spinlock_up.h: include asm/processor.h in for cpu_relax Commit e66eed651fd1 ("list: remove prefetching from regular list iterators") removed the include of prefetch.h from list.h and this was a path to including asm/processor.h. We need to include it excplicitly now. Fixes this build error on sparc32 (at least): In file included from include/linux/seqlock.h:29, from include/linux/time.h:8, from include/linux/timex.h:56, from include/linux/sched.h:57, from arch/sparc/kernel/asm-offsets.c:13: include/linux/spinlock.h: In function 'spin_unlock_wait': include/linux/spinlock.h:360: error: implicit declaration of function 'cpu_relax Signed-off-by: Stephen Rothwell Signed-off-by: Linus Torvalds --- include/linux/spinlock_up.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/spinlock_up.h b/include/linux/spinlock_up.h index b14f6a91e19f..a26e2fb604e6 100644 --- a/include/linux/spinlock_up.h +++ b/include/linux/spinlock_up.h @@ -5,6 +5,8 @@ # error "please don't include this file directly" #endif +#include /* for cpu_relax() */ + /* * include/linux/spinlock_up.h - UP-debug version of spinlocks. * -- cgit From b7281ca2a4b00044c60c25059f467d05772cdbe3 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Wed, 18 May 2011 10:51:48 +0100 Subject: ARM: 6904/1: MTD: Add integrator-flash feature to physmap In the process of moving platforms away from integrator-flash (aka armflash), add to physmap the few features that make armflash unique: - optionnal probing for the AFS partition type - init() and exit() methods, used by Integrator to control write access to the various onboard programmable components Signed-off-by: Marc Zyngier Acked-by: Catalin Marinas Acked-by: Artem Bityutskiy Acked-by: David Woodhouse Signed-off-by: Russell King --- drivers/mtd/maps/physmap.c | 16 +++++++++++++++- include/linux/mtd/physmap.h | 2 ++ 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c index 7522df4f71f1..49676b7a53a4 100644 --- a/drivers/mtd/maps/physmap.c +++ b/drivers/mtd/maps/physmap.c @@ -67,6 +67,10 @@ static int physmap_flash_remove(struct platform_device *dev) if (info->mtd[i] != NULL) map_destroy(info->mtd[i]); } + + if (physmap_data->exit) + physmap_data->exit(dev); + return 0; } @@ -77,7 +81,11 @@ static const char *rom_probe_types[] = { "map_rom", NULL }; #ifdef CONFIG_MTD_PARTITIONS -static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL }; +static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", +#ifdef CONFIG_MTD_AFS_PARTS + "afs", +#endif + NULL }; #endif static int physmap_flash_probe(struct platform_device *dev) @@ -100,6 +108,12 @@ static int physmap_flash_probe(struct platform_device *dev) goto err_out; } + if (physmap_data->init) { + err = physmap_data->init(dev); + if (err) + goto err_out; + } + platform_set_drvdata(dev, info); for (i = 0; i < dev->num_resources; i++) { diff --git a/include/linux/mtd/physmap.h b/include/linux/mtd/physmap.h index bcfd9f777454..d37cca05e62c 100644 --- a/include/linux/mtd/physmap.h +++ b/include/linux/mtd/physmap.h @@ -22,6 +22,8 @@ struct map_info; struct physmap_flash_data { unsigned int width; + int (*init)(struct platform_device *); + void (*exit)(struct platform_device *); void (*set_vpp)(struct map_info *, int); unsigned int nr_parts; unsigned int pfow_base; -- cgit From 667f390bee987d45351402e42008c52cdfb77d76 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Wed, 18 May 2011 10:51:55 +0100 Subject: ARM: 6910/1: MTD: physmap: let set_vpp() pass a platform_device instead of a map_info The set_vpp() method provided by physmap passes a map_info back to the platform code, which has little relevance as far as the platform is concerned (this parameter is completely unused). Instead, pass the platform_device, which can be used in the pismo driver to retrieve some important information in a nicer way, instead of the hack that was in place. The empty set_vpp function in board-at572d940hf_ek.c is left untouched, as the board/SoC is scheduled for removal. Cc: Andrew Victor Cc: Nicolas Ferre Acked-by: Jean-Christophe PLAGNIOL-VILLARD Cc: Philipp Zabel Cc: Eric Miao Cc: Ben Dooks Acked-by: Artem Bityutskiy Acked-by: David Woodhouse Signed-off-by: Marc Zyngier Signed-off-by: Russell King --- arch/arm/mach-integrator/integrator_ap.c | 2 +- arch/arm/mach-integrator/integrator_cp.c | 2 +- arch/arm/mach-omap1/flash.c | 2 +- arch/arm/mach-pxa/hx4700.c | 2 +- arch/arm/mach-pxa/magician.c | 2 +- arch/arm/mach-realview/core.c | 2 +- arch/arm/mach-s3c2410/nor-simtec.c | 2 +- arch/arm/mach-versatile/core.c | 2 +- arch/arm/mach-vexpress/v2m.c | 2 +- arch/arm/plat-omap/include/plat/flash.h | 2 +- drivers/mtd/maps/physmap.c | 20 ++++++++++++---- drivers/mtd/maps/pismo.c | 40 +++----------------------------- include/linux/mtd/physmap.h | 2 +- 13 files changed, 29 insertions(+), 53 deletions(-) (limited to 'include/linux') diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index 11bd49e8b663..2aa98ee41b8d 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -263,7 +263,7 @@ static void ap_flash_exit(struct platform_device *dev) } } -static void ap_flash_set_vpp(struct map_info *map, int on) +static void ap_flash_set_vpp(struct platform_device *pdev, int on) { void __iomem *reg = on ? SC_CTRLS : SC_CTRLC; diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index ec9628fe7109..b676b41d70e2 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -259,7 +259,7 @@ static void intcp_flash_exit(struct platform_device *dev) writel(val, INTCP_VA_CTRL_BASE + INTCP_FLASHPROG); } -static void intcp_flash_set_vpp(struct map_info *map, int on) +static void intcp_flash_set_vpp(struct platform_device *pdev, int on) { u32 val; diff --git a/arch/arm/mach-omap1/flash.c b/arch/arm/mach-omap1/flash.c index acd161666408..1749cb37dda0 100644 --- a/arch/arm/mach-omap1/flash.c +++ b/arch/arm/mach-omap1/flash.c @@ -13,7 +13,7 @@ #include #include -void omap1_set_vpp(struct map_info *map, int enable) +void omap1_set_vpp(struct platform_device *pdev, int enable) { static int count; u32 l; diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c index 9cdcca597924..f941a495a4a8 100644 --- a/arch/arm/mach-pxa/hx4700.c +++ b/arch/arm/mach-pxa/hx4700.c @@ -735,7 +735,7 @@ static struct platform_device bq24022 = { * StrataFlash */ -static void hx4700_set_vpp(struct map_info *map, int vpp) +static void hx4700_set_vpp(struct platform_device *pdev, int vpp) { gpio_set_value(GPIO91_HX4700_FLASH_VPEN, vpp); } diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c index 9984ef70bd79..e1920572948a 100644 --- a/arch/arm/mach-pxa/magician.c +++ b/arch/arm/mach-pxa/magician.c @@ -662,7 +662,7 @@ static struct pxaohci_platform_data magician_ohci_info = { * StrataFlash */ -static void magician_set_vpp(struct map_info *map, int vpp) +static void magician_set_vpp(struct platform_device *pdev, int vpp) { gpio_set_value(EGPIO_MAGICIAN_FLASH_VPP, vpp); } diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index d3f1dde70fc9..c8ec08886633 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c @@ -77,7 +77,7 @@ void __init realview_adjust_zones(unsigned long *size, unsigned long *hole) #define REALVIEW_FLASHCTRL (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_FLASH_OFFSET) -static void realview_flash_set_vpp(struct map_info *map, int on) +static void realview_flash_set_vpp(struct platform_device *pdev, int on) { u32 val; diff --git a/arch/arm/mach-s3c2410/nor-simtec.c b/arch/arm/mach-s3c2410/nor-simtec.c index 598d130633dc..ad9f750f1e55 100644 --- a/arch/arm/mach-s3c2410/nor-simtec.c +++ b/arch/arm/mach-s3c2410/nor-simtec.c @@ -32,7 +32,7 @@ #include "nor-simtec.h" -static void simtec_nor_vpp(struct map_info *map, int vpp) +static void simtec_nor_vpp(struct platform_device *pdev, int vpp) { unsigned int val; unsigned long flags; diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 06f406ad8edd..335d8250e364 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -190,7 +190,7 @@ void __init versatile_map_io(void) #define VERSATILE_FLASHCTRL (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_FLASH_OFFSET) -static void versatile_flash_set_vpp(struct map_info *map, int on) +static void versatile_flash_set_vpp(struct platform_device *pdev, int on) { u32 val; diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c index e3268152c834..f860314ef7f6 100644 --- a/arch/arm/mach-vexpress/v2m.c +++ b/arch/arm/mach-vexpress/v2m.c @@ -206,7 +206,7 @@ static struct platform_device v2m_usb_device = { .dev.platform_data = &v2m_usb_config, }; -static void v2m_flash_set_vpp(struct map_info *map, int on) +static void v2m_flash_set_vpp(struct platform_device *pdev, int on) { writel(on != 0, MMIO_P2V(V2M_SYS_FLASH)); } diff --git a/arch/arm/plat-omap/include/plat/flash.h b/arch/arm/plat-omap/include/plat/flash.h index 3e6327016b40..3083195123ea 100644 --- a/arch/arm/plat-omap/include/plat/flash.h +++ b/arch/arm/plat-omap/include/plat/flash.h @@ -11,6 +11,6 @@ #include -extern void omap1_set_vpp(struct map_info *map, int enable); +extern void omap1_set_vpp(struct platform_device *pdev, int enable); #endif diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c index 49676b7a53a4..1a9b94f0ee54 100644 --- a/drivers/mtd/maps/physmap.c +++ b/drivers/mtd/maps/physmap.c @@ -74,6 +74,18 @@ static int physmap_flash_remove(struct platform_device *dev) return 0; } +static void physmap_set_vpp(struct map_info *map, int state) +{ + struct platform_device *pdev; + struct physmap_flash_data *physmap_data; + + pdev = (struct platform_device *)map->map_priv_1; + physmap_data = pdev->dev.platform_data; + + if (physmap_data->set_vpp) + physmap_data->set_vpp(pdev, state); +} + static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", @@ -81,10 +93,7 @@ static const char *rom_probe_types[] = { "map_rom", NULL }; #ifdef CONFIG_MTD_PARTITIONS -static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", -#ifdef CONFIG_MTD_AFS_PARTS - "afs", -#endif +static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", "afs", NULL }; #endif @@ -134,8 +143,9 @@ static int physmap_flash_probe(struct platform_device *dev) info->map[i].phys = dev->resource[i].start; info->map[i].size = resource_size(&dev->resource[i]); info->map[i].bankwidth = physmap_data->width; - info->map[i].set_vpp = physmap_data->set_vpp; + info->map[i].set_vpp = physmap_set_vpp; info->map[i].pfow_base = physmap_data->pfow_base; + info->map[i].map_priv_1 = (unsigned long)dev; info->map[i].virt = devm_ioremap(&dev->dev, info->map[i].phys, info->map[i].size); diff --git a/drivers/mtd/maps/pismo.c b/drivers/mtd/maps/pismo.c index f4ce273e93fd..65bd1cd4d627 100644 --- a/drivers/mtd/maps/pismo.c +++ b/drivers/mtd/maps/pismo.c @@ -50,39 +50,13 @@ struct pismo_data { struct platform_device *dev[PISMO_NUM_CS]; }; -/* FIXME: set_vpp could do with a better calling convention */ -static struct pismo_data *vpp_pismo; -static DEFINE_MUTEX(pismo_mutex); - -static int pismo_setvpp_probe_fix(struct pismo_data *pismo) +static void pismo_set_vpp(struct platform_device *pdev, int on) { - mutex_lock(&pismo_mutex); - if (vpp_pismo) { - mutex_unlock(&pismo_mutex); - kfree(pismo); - return -EBUSY; - } - vpp_pismo = pismo; - mutex_unlock(&pismo_mutex); - return 0; -} - -static void pismo_setvpp_remove_fix(struct pismo_data *pismo) -{ - mutex_lock(&pismo_mutex); - if (vpp_pismo == pismo) - vpp_pismo = NULL; - mutex_unlock(&pismo_mutex); -} - -static void pismo_set_vpp(struct map_info *map, int on) -{ - struct pismo_data *pismo = vpp_pismo; + struct i2c_client *client = to_i2c_client(pdev->dev.parent); + struct pismo_data *pismo = i2c_get_clientdata(client); pismo->vpp(pismo->vpp_data, on); } -/* end of hack */ - static unsigned int __devinit pismo_width_to_bytes(unsigned int width) { @@ -231,9 +205,6 @@ static int __devexit pismo_remove(struct i2c_client *client) for (i = 0; i < ARRAY_SIZE(pismo->dev); i++) platform_device_unregister(pismo->dev[i]); - /* FIXME: set_vpp needs saner arguments */ - pismo_setvpp_remove_fix(pismo); - kfree(pismo); return 0; @@ -257,11 +228,6 @@ static int __devinit pismo_probe(struct i2c_client *client, if (!pismo) return -ENOMEM; - /* FIXME: set_vpp needs saner arguments */ - ret = pismo_setvpp_probe_fix(pismo); - if (ret) - return ret; - pismo->client = client; if (pdata) { pismo->vpp = pdata->set_vpp; diff --git a/include/linux/mtd/physmap.h b/include/linux/mtd/physmap.h index d37cca05e62c..49b959029417 100644 --- a/include/linux/mtd/physmap.h +++ b/include/linux/mtd/physmap.h @@ -24,7 +24,7 @@ struct physmap_flash_data { unsigned int width; int (*init)(struct platform_device *); void (*exit)(struct platform_device *); - void (*set_vpp)(struct map_info *, int); + void (*set_vpp)(struct platform_device *, int); unsigned int nr_parts; unsigned int pfow_base; char *probe_type; -- cgit From 94d56ffa0a9bf11dfb602dae9223089e09a8e050 Mon Sep 17 00:00:00 2001 From: Andreas Oberritter Date: Thu, 12 May 2011 18:11:06 -0300 Subject: [media] DVB: Add basic API support for DVB-T2 and bump minor version [steve@stevekerrison.com: Remove private definitions from cxd2820r that existed before API was defined] Signed-off-by: Andreas Oberritter Signed-off-by: Steve Kerrison Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-core/dvb_frontend.c | 13 +++++++++---- drivers/media/dvb/dvb-core/dvb_frontend.h | 3 +++ drivers/media/dvb/frontends/cxd2820r_priv.h | 12 ------------ include/linux/dvb/frontend.h | 20 ++++++++++++++++---- include/linux/dvb/version.h | 2 +- 5 files changed, 29 insertions(+), 21 deletions(-) (limited to 'include/linux') diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index 95c3fec6ae40..3639edce65e0 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -1148,10 +1148,9 @@ static void dtv_property_adv_params_sync(struct dvb_frontend *fe) break; } - if(c->delivery_system == SYS_ISDBT) { - /* Fake out a generic DVB-T request so we pass validation in the ioctl */ - p->frequency = c->frequency; - p->inversion = c->inversion; + /* Fake out a generic DVB-T request so we pass validation in the ioctl */ + if ((c->delivery_system == SYS_ISDBT) || + (c->delivery_system == SYS_DVBT2)) { p->u.ofdm.constellation = QAM_AUTO; p->u.ofdm.code_rate_HP = FEC_AUTO; p->u.ofdm.code_rate_LP = FEC_AUTO; @@ -1324,6 +1323,9 @@ static int dtv_property_process_get(struct dvb_frontend *fe, case DTV_ISDBS_TS_ID: tvp->u.data = fe->dtv_property_cache.isdbs_ts_id; break; + case DTV_DVBT2_PLP_ID: + tvp->u.data = fe->dtv_property_cache.dvbt2_plp_id; + break; default: return -EINVAL; } @@ -1479,6 +1481,9 @@ static int dtv_property_process_set(struct dvb_frontend *fe, case DTV_ISDBS_TS_ID: fe->dtv_property_cache.isdbs_ts_id = tvp->u.data; break; + case DTV_DVBT2_PLP_ID: + fe->dtv_property_cache.dvbt2_plp_id = tvp->u.data; + break; default: return -EINVAL; } diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h index 3b860504bf04..5590eb6eb408 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/drivers/media/dvb/dvb-core/dvb_frontend.h @@ -358,6 +358,9 @@ struct dtv_frontend_properties { /* ISDB-T specifics */ u32 isdbs_ts_id; + + /* DVB-T2 specifics */ + u32 dvbt2_plp_id; }; struct dvb_frontend { diff --git a/drivers/media/dvb/frontends/cxd2820r_priv.h b/drivers/media/dvb/frontends/cxd2820r_priv.h index d4e2e0b76c10..25adbeefa6d3 100644 --- a/drivers/media/dvb/frontends/cxd2820r_priv.h +++ b/drivers/media/dvb/frontends/cxd2820r_priv.h @@ -40,18 +40,6 @@ #undef warn #define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg) -/* - * FIXME: These are totally wrong and must be added properly to the API. - * Only temporary solution in order to get driver compile. - */ -#define SYS_DVBT2 SYS_DAB -#define TRANSMISSION_MODE_1K 0 -#define TRANSMISSION_MODE_16K 0 -#define TRANSMISSION_MODE_32K 0 -#define GUARD_INTERVAL_1_128 0 -#define GUARD_INTERVAL_19_128 0 -#define GUARD_INTERVAL_19_256 0 - struct reg_val_mask { u32 reg; u8 val; diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h index 493a2bf85f62..36a3ed63f571 100644 --- a/include/linux/dvb/frontend.h +++ b/include/linux/dvb/frontend.h @@ -175,14 +175,20 @@ typedef enum fe_transmit_mode { TRANSMISSION_MODE_2K, TRANSMISSION_MODE_8K, TRANSMISSION_MODE_AUTO, - TRANSMISSION_MODE_4K + TRANSMISSION_MODE_4K, + TRANSMISSION_MODE_1K, + TRANSMISSION_MODE_16K, + TRANSMISSION_MODE_32K, } fe_transmit_mode_t; typedef enum fe_bandwidth { BANDWIDTH_8_MHZ, BANDWIDTH_7_MHZ, BANDWIDTH_6_MHZ, - BANDWIDTH_AUTO + BANDWIDTH_AUTO, + BANDWIDTH_5_MHZ, + BANDWIDTH_10_MHZ, + BANDWIDTH_1_712_MHZ, } fe_bandwidth_t; @@ -191,7 +197,10 @@ typedef enum fe_guard_interval { GUARD_INTERVAL_1_16, GUARD_INTERVAL_1_8, GUARD_INTERVAL_1_4, - GUARD_INTERVAL_AUTO + GUARD_INTERVAL_AUTO, + GUARD_INTERVAL_1_128, + GUARD_INTERVAL_19_128, + GUARD_INTERVAL_19_256, } fe_guard_interval_t; @@ -305,7 +314,9 @@ struct dvb_frontend_event { #define DTV_ISDBS_TS_ID 42 -#define DTV_MAX_COMMAND DTV_ISDBS_TS_ID +#define DTV_DVBT2_PLP_ID 43 + +#define DTV_MAX_COMMAND DTV_DVBT2_PLP_ID typedef enum fe_pilot { PILOT_ON, @@ -337,6 +348,7 @@ typedef enum fe_delivery_system { SYS_DMBTH, SYS_CMMB, SYS_DAB, + SYS_DVBT2, } fe_delivery_system_t; struct dtv_cmds_h { diff --git a/include/linux/dvb/version.h b/include/linux/dvb/version.h index 5a7546c12688..1421cc84afaa 100644 --- a/include/linux/dvb/version.h +++ b/include/linux/dvb/version.h @@ -24,6 +24,6 @@ #define _DVBVERSION_H_ #define DVB_API_VERSION 5 -#define DVB_API_VERSION_MINOR 2 +#define DVB_API_VERSION_MINOR 3 #endif /*_DVBVERSION_H_*/ -- cgit From 3e0c2ab67e48f77c2da0a5c826aac397792a214e Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Fri, 20 May 2011 09:42:48 -0500 Subject: slub: Deal with hyperthetical case of PAGE_SIZE > 2M kmalloc_index() currently returns -1 if the PAGE_SIZE is larger than 2M which seems to cause some concern since the callers do not check for -1. Insert a BUG() and add a comment to the -1 explaining that the code cannot be reached. Signed-off-by: Christoph Lameter Signed-off-by: Pekka Enberg --- include/linux/slub_def.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h index ca0c076b2374..c8668d161dd8 100644 --- a/include/linux/slub_def.h +++ b/include/linux/slub_def.h @@ -177,7 +177,8 @@ static __always_inline int kmalloc_index(size_t size) if (size <= 4 * 1024) return 12; /* * The following is only needed to support architectures with a larger page - * size than 4k. + * size than 4k. We need to support 2 * PAGE_SIZE here. So for a 64k page + * size we would have to go up to 128k. */ if (size <= 8 * 1024) return 13; if (size <= 16 * 1024) return 14; @@ -188,7 +189,8 @@ static __always_inline int kmalloc_index(size_t size) if (size <= 512 * 1024) return 19; if (size <= 1024 * 1024) return 20; if (size <= 2 * 1024 * 1024) return 21; - return -1; + BUG(); + return -1; /* Will never be reached */ /* * What we really wanted to do and cannot do because of compiler issues is: -- cgit From 9f728f53dd70396f3183d2f0861022259471824b Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 12 May 2011 17:11:47 -0700 Subject: PCI/e1000e: Add and use pci_disable_link_state_locked() Need to use it in _e1000e_disable_aspm. This routine is used for error recovery, where the pci_bus_sem is already held, and we don't want pci_disable_link_state to try to take it again. So add a locked variant for use in cases like this. Found lock up: [ 2374.654557] kworker/32:1 D ffff881027f6b0f0 0 6075 2 0x00000000 [ 2374.654816] ffff88503f099a68 0000000000000046 ffff88503f098000 0000000000004000 [ 2374.654837] 00000000001d1ec0 ffff88503f099fd8 00000000001d1ec0 ffff88503f099fd8 [ 2374.654860] 0000000000004000 00000000001d1ec0 ffff88503dcc8000 ffff88503f090000 [ 2374.654880] Call Trace: [ 2374.654898] [] ? __lock_acquired+0x3a/0x224 [ 2374.654914] [] ? _raw_spin_unlock_irq+0x30/0x36 [ 2374.654925] [] ? trace_hardirqs_on_caller+0x1f/0x178 [ 2374.654936] [] rwsem_down_failed_common+0xd3/0x103 [ 2374.654945] [] ? __lock_contended+0x3a/0x2a2 [ 2374.654955] [] rwsem_down_read_failed+0x12/0x14 [ 2374.654967] [] call_rwsem_down_read_failed+0x14/0x30 [ 2374.654981] [] ? pci_disable_link_state+0x5f/0xf5 [ 2374.654990] [] ? down_read+0x7e/0x91 [ 2374.654999] [] ? pci_disable_link_state+0x5f/0xf5 [ 2374.655008] [] pci_disable_link_state+0x5f/0xf5 [ 2374.655024] [] e1000e_disable_aspm+0x55/0x5a [ 2374.655037] [] e1000_io_slot_reset+0x59/0xea [ 2374.655048] [] ? report_mmio_enabled+0x5d/0x5d [ 2374.655057] [] report_slot_reset+0x2e/0x5d [ 2374.655072] [] pci_walk_bus+0x8a/0xb7 [ 2374.655081] [] ? report_mmio_enabled+0x5d/0x5d [ 2374.655091] [] broadcast_error_message+0xa4/0xb2 [ 2374.655101] [] ? pci_bus_read_config_dword+0x72/0x80 [ 2374.655110] [] do_recovery+0x9e/0xf9 [ 2374.655120] [] handle_error_source+0x4c/0x51 [ 2374.655129] [] aer_isr_one_error+0x1e9/0x21a [ 2374.655138] [] aer_isr+0xc7/0xcc [ 2374.655147] [] ? aer_isr_one_error+0x21a/0x21a [ 2374.655159] [] process_one_work+0x237/0x3ec [ 2374.655168] [] ? process_one_work+0x1a8/0x3ec [ 2374.655178] [] worker_thread+0x17c/0x240 [ 2374.655186] [] ? trace_hardirqs_on+0xd/0xf [ 2374.655196] [] ? manage_workers+0xab/0xab [ 2374.655209] [] kthread+0xa0/0xa8 [ 2374.655223] [] kernel_thread_helper+0x4/0x10 [ 2374.655232] [] ? retint_restore_args+0xe/0xe [ 2374.655243] [] ? __init_kthread_worker+0x5b/0x5b [ 2374.655252] [] ? gs_change+0xb/0xb when aer happens, pci_walk_bus already have down_read(&pci_bus_sem)... then report_slot_reset ==> e1000_io_slot_reset ==> e1000e_disable_aspm ==> pci_disable_link_state... We can not use pci_disable_link_state, and it will try to hold pci_bus_sem again. Try to have __pci_disable_link_state that will not need to hold pci_bus_sem. -v2: change name to pci_disable_link_state_locked() according to Jesse. [jbarnes: make sure new function is exported for modules] Signed-off-by: Yinghai Lu Signed-off-by: Jesse Barnes --- drivers/net/e1000e/netdev.c | 2 +- drivers/pci/pcie/aspm.c | 19 ++++++++++++++++--- include/linux/pci-aspm.h | 1 + 3 files changed, 18 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 506a0a0043b3..5fb43f098f17 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -5347,7 +5347,7 @@ static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep, #ifdef CONFIG_PCIEASPM static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state) { - pci_disable_link_state(pdev, state); + pci_disable_link_state_locked(pdev, state); } #else static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state) diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 3eb667b24787..6892601fc76f 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -734,7 +734,7 @@ void pcie_aspm_powersave_config_link(struct pci_dev *pdev) * pci_disable_link_state - disable pci device's link state, so the link will * never enter specific states */ -void pci_disable_link_state(struct pci_dev *pdev, int state) +static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem) { struct pci_dev *parent = pdev->bus->self; struct pcie_link_state *link; @@ -747,7 +747,8 @@ void pci_disable_link_state(struct pci_dev *pdev, int state) if (!parent || !parent->link_state) return; - down_read(&pci_bus_sem); + if (sem) + down_read(&pci_bus_sem); mutex_lock(&aspm_lock); link = parent->link_state; if (state & PCIE_LINK_STATE_L0S) @@ -761,7 +762,19 @@ void pci_disable_link_state(struct pci_dev *pdev, int state) pcie_set_clkpm(link, 0); } mutex_unlock(&aspm_lock); - up_read(&pci_bus_sem); + if (sem) + up_read(&pci_bus_sem); +} + +void pci_disable_link_state_locked(struct pci_dev *pdev, int state) +{ + __pci_disable_link_state(pdev, state, false); +} +EXPORT_SYMBOL(pci_disable_link_state_locked); + +void pci_disable_link_state(struct pci_dev *pdev, int state) +{ + __pci_disable_link_state(pdev, state, true); } EXPORT_SYMBOL(pci_disable_link_state); diff --git a/include/linux/pci-aspm.h b/include/linux/pci-aspm.h index 67cb3ae38016..7cea7b6c1413 100644 --- a/include/linux/pci-aspm.h +++ b/include/linux/pci-aspm.h @@ -28,6 +28,7 @@ extern void pcie_aspm_exit_link_state(struct pci_dev *pdev); extern void pcie_aspm_pm_state_change(struct pci_dev *pdev); extern void pcie_aspm_powersave_config_link(struct pci_dev *pdev); extern void pci_disable_link_state(struct pci_dev *pdev, int state); +extern void pci_disable_link_state_locked(struct pci_dev *pdev, int state); extern void pcie_clear_aspm(void); extern void pcie_no_aspm(void); #else -- cgit From 24a4742f0be6226eb0106fbb17caf4d711d1ad43 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Tue, 10 May 2011 10:02:11 -0600 Subject: PCI: Track the size of each saved capability data area This will allow us to store and load it later. Signed-off-by: Alex Williamson Signed-off-by: Jesse Barnes --- drivers/pci/pci.c | 12 +++++++----- include/linux/pci.h | 11 ++++++++--- 2 files changed, 15 insertions(+), 8 deletions(-) (limited to 'include/linux') diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 53302cbdb94c..d6e5b8ea9194 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -830,7 +830,7 @@ static int pci_save_pcie_state(struct pci_dev *dev) dev_err(&dev->dev, "buffer not found in %s\n", __func__); return -ENOMEM; } - cap = (u16 *)&save_state->data[0]; + cap = (u16 *)&save_state->cap.data[0]; pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &flags); @@ -863,7 +863,7 @@ static void pci_restore_pcie_state(struct pci_dev *dev) pos = pci_find_capability(dev, PCI_CAP_ID_EXP); if (!save_state || pos <= 0) return; - cap = (u16 *)&save_state->data[0]; + cap = (u16 *)&save_state->cap.data[0]; pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &flags); @@ -899,7 +899,8 @@ static int pci_save_pcix_state(struct pci_dev *dev) return -ENOMEM; } - pci_read_config_word(dev, pos + PCI_X_CMD, (u16 *)save_state->data); + pci_read_config_word(dev, pos + PCI_X_CMD, + (u16 *)save_state->cap.data); return 0; } @@ -914,7 +915,7 @@ static void pci_restore_pcix_state(struct pci_dev *dev) pos = pci_find_capability(dev, PCI_CAP_ID_PCIX); if (!save_state || pos <= 0) return; - cap = (u16 *)&save_state->data[0]; + cap = (u16 *)&save_state->cap.data[0]; pci_write_config_word(dev, pos + PCI_X_CMD, cap[i++]); } @@ -1771,7 +1772,8 @@ static int pci_add_cap_save_buffer( if (!save_state) return -ENOMEM; - save_state->cap_nr = cap; + save_state->cap.cap_nr = cap; + save_state->cap.size = size; pci_add_saved_cap(dev, save_state); return 0; diff --git a/include/linux/pci.h b/include/linux/pci.h index df4d69b82144..61ef8f2f9b19 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -214,12 +214,17 @@ enum pci_bus_speed { PCI_SPEED_UNKNOWN = 0xff, }; -struct pci_cap_saved_state { - struct hlist_node next; +struct pci_cap_saved_data { char cap_nr; + unsigned int size; u32 data[0]; }; +struct pci_cap_saved_state { + struct hlist_node next; + struct pci_cap_saved_data cap; +}; + struct pcie_link_state; struct pci_vpd; struct pci_sriov; @@ -366,7 +371,7 @@ static inline struct pci_cap_saved_state *pci_find_saved_cap( struct hlist_node *pos; hlist_for_each_entry(tmp, pos, &pci_dev->saved_cap_space, next) { - if (tmp->cap_nr == cap) + if (tmp->cap.cap_nr == cap) return tmp; } return NULL; -- cgit From ffbdd3f7931fb7cb7e36d00d16303ec433be5145 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Tue, 10 May 2011 10:02:27 -0600 Subject: PCI: Add interfaces to store and load the device saved state For KVM device assignment, we'd like to save off the state of a device prior to passing it to the guest and restore it later. We also want to allow pci_reset_funciton() to be called while the device is owned by the guest. This however overwrites and invalidates the struct pci_dev buffers, so we can't just manually call save and restore. Add generic interfaces for the saved state to be stored and reloaded back into struct pci_dev at a later time. Signed-off-by: Alex Williamson Signed-off-by: Jesse Barnes --- drivers/pci/pci.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/pci.h | 4 +++ 2 files changed, 102 insertions(+) (limited to 'include/linux') diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index d6e5b8ea9194..22c9b27fdd8d 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -976,6 +976,104 @@ void pci_restore_state(struct pci_dev *dev) dev->state_saved = false; } +struct pci_saved_state { + u32 config_space[16]; + struct pci_cap_saved_data cap[0]; +}; + +/** + * pci_store_saved_state - Allocate and return an opaque struct containing + * the device saved state. + * @dev: PCI device that we're dealing with + * + * Rerturn NULL if no state or error. + */ +struct pci_saved_state *pci_store_saved_state(struct pci_dev *dev) +{ + struct pci_saved_state *state; + struct pci_cap_saved_state *tmp; + struct pci_cap_saved_data *cap; + struct hlist_node *pos; + size_t size; + + if (!dev->state_saved) + return NULL; + + size = sizeof(*state) + sizeof(struct pci_cap_saved_data); + + hlist_for_each_entry(tmp, pos, &dev->saved_cap_space, next) + size += sizeof(struct pci_cap_saved_data) + tmp->cap.size; + + state = kzalloc(size, GFP_KERNEL); + if (!state) + return NULL; + + memcpy(state->config_space, dev->saved_config_space, + sizeof(state->config_space)); + + cap = state->cap; + hlist_for_each_entry(tmp, pos, &dev->saved_cap_space, next) { + size_t len = sizeof(struct pci_cap_saved_data) + tmp->cap.size; + memcpy(cap, &tmp->cap, len); + cap = (struct pci_cap_saved_data *)((u8 *)cap + len); + } + /* Empty cap_save terminates list */ + + return state; +} +EXPORT_SYMBOL_GPL(pci_store_saved_state); + +/** + * pci_load_saved_state - Reload the provided save state into struct pci_dev. + * @dev: PCI device that we're dealing with + * @state: Saved state returned from pci_store_saved_state() + */ +int pci_load_saved_state(struct pci_dev *dev, struct pci_saved_state *state) +{ + struct pci_cap_saved_data *cap; + + dev->state_saved = false; + + if (!state) + return 0; + + memcpy(dev->saved_config_space, state->config_space, + sizeof(state->config_space)); + + cap = state->cap; + while (cap->size) { + struct pci_cap_saved_state *tmp; + + tmp = pci_find_saved_cap(dev, cap->cap_nr); + if (!tmp || tmp->cap.size != cap->size) + return -EINVAL; + + memcpy(tmp->cap.data, cap->data, tmp->cap.size); + cap = (struct pci_cap_saved_data *)((u8 *)cap + + sizeof(struct pci_cap_saved_data) + cap->size); + } + + dev->state_saved = true; + return 0; +} +EXPORT_SYMBOL_GPL(pci_load_saved_state); + +/** + * pci_load_and_free_saved_state - Reload the save state pointed to by state, + * and free the memory allocated for it. + * @dev: PCI device that we're dealing with + * @state: Pointer to saved state returned from pci_store_saved_state() + */ +int pci_load_and_free_saved_state(struct pci_dev *dev, + struct pci_saved_state **state) +{ + int ret = pci_load_saved_state(dev, *state); + kfree(*state); + *state = NULL; + return ret; +} +EXPORT_SYMBOL_GPL(pci_load_and_free_saved_state); + static int do_pci_enable_device(struct pci_dev *dev, int bars) { int err; diff --git a/include/linux/pci.h b/include/linux/pci.h index 61ef8f2f9b19..4604d1d5514d 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -812,6 +812,10 @@ size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size); /* Power management related routines */ int pci_save_state(struct pci_dev *dev); void pci_restore_state(struct pci_dev *dev); +struct pci_saved_state *pci_store_saved_state(struct pci_dev *dev); +int pci_load_saved_state(struct pci_dev *dev, struct pci_saved_state *state); +int pci_load_and_free_saved_state(struct pci_dev *dev, + struct pci_saved_state **state); int __pci_complete_power_transition(struct pci_dev *dev, pci_power_t state); int pci_set_power_state(struct pci_dev *dev, pci_power_t state); pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state); -- cgit From f8fcfd775523347afe460dc3a0f45d0479e784a2 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Tue, 10 May 2011 10:02:39 -0600 Subject: KVM: Use pci_store/load_saved_state() around VM device usage Store the device saved state so that we can reload the device back to the original state when it's unassigned. This has the benefit that the state survives across pci_reset_function() calls via the PCI sysfs reset interface while the VM is using the device. Signed-off-by: Alex Williamson Acked-by: Avi Kivity Signed-off-by: Jesse Barnes --- include/linux/kvm_host.h | 1 + virt/kvm/assigned-dev.c | 18 ++++++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index ab428552af8e..9272db03a3e5 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -513,6 +513,7 @@ struct kvm_assigned_dev_kernel { struct kvm *kvm; spinlock_t intx_lock; char irq_name[32]; + struct pci_saved_state *pci_saved_state; }; struct kvm_irq_mask_notifier { diff --git a/virt/kvm/assigned-dev.c b/virt/kvm/assigned-dev.c index ae72ae604c89..6cc4b97ec458 100644 --- a/virt/kvm/assigned-dev.c +++ b/virt/kvm/assigned-dev.c @@ -197,8 +197,13 @@ static void kvm_free_assigned_device(struct kvm *kvm, { kvm_free_assigned_irq(kvm, assigned_dev); - __pci_reset_function(assigned_dev->dev); - pci_restore_state(assigned_dev->dev); + pci_reset_function(assigned_dev->dev); + if (pci_load_and_free_saved_state(assigned_dev->dev, + &assigned_dev->pci_saved_state)) + printk(KERN_INFO "%s: Couldn't reload %s saved state\n", + __func__, dev_name(&assigned_dev->dev->dev)); + else + pci_restore_state(assigned_dev->dev); pci_release_regions(assigned_dev->dev); pci_disable_device(assigned_dev->dev); @@ -516,7 +521,10 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm, pci_reset_function(dev); pci_save_state(dev); - + match->pci_saved_state = pci_store_saved_state(dev); + if (!match->pci_saved_state) + printk(KERN_DEBUG "%s: Couldn't store %s saved state\n", + __func__, dev_name(&dev->dev)); match->assigned_dev_id = assigned_dev->assigned_dev_id; match->host_segnr = assigned_dev->segnr; match->host_busnr = assigned_dev->busnr; @@ -546,7 +554,9 @@ out: mutex_unlock(&kvm->lock); return r; out_list_del: - pci_restore_state(dev); + if (pci_load_and_free_saved_state(dev, &match->pci_saved_state)) + printk(KERN_INFO "%s: Couldn't reload %s saved state\n", + __func__, dev_name(&dev->dev)); list_del(&match->list); pci_release_regions(dev); out_disable: -- cgit From 5ce941ee4258b836cf818d2ac159d8cf3ebad648 Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Wed, 27 Apr 2011 17:24:21 -0500 Subject: KVM: PPC: booke: add sregs support Signed-off-by: Scott Wood Signed-off-by: Alexander Graf --- Documentation/kvm/api.txt | 6 +- arch/powerpc/include/asm/kvm.h | 184 ++++++++++++++++++++++++++++++++++++ arch/powerpc/include/asm/kvm_44x.h | 1 - arch/powerpc/include/asm/kvm_e500.h | 1 + arch/powerpc/include/asm/kvm_host.h | 3 + arch/powerpc/include/asm/kvm_ppc.h | 9 ++ arch/powerpc/kvm/44x.c | 10 ++ arch/powerpc/kvm/booke.c | 154 +++++++++++++++++++++++++++++- arch/powerpc/kvm/e500.c | 75 +++++++++++++++ arch/powerpc/kvm/e500_emulate.c | 5 +- arch/powerpc/kvm/e500_tlb.c | 8 ++ arch/powerpc/kvm/emulate.c | 13 ++- arch/powerpc/kvm/powerpc.c | 4 + include/linux/kvm.h | 1 + 14 files changed, 461 insertions(+), 13 deletions(-) (limited to 'include/linux') diff --git a/Documentation/kvm/api.txt b/Documentation/kvm/api.txt index 1b9eaa7e8856..f64c41f8ba61 100644 --- a/Documentation/kvm/api.txt +++ b/Documentation/kvm/api.txt @@ -261,7 +261,7 @@ See KVM_GET_REGS for the data structure. 4.13 KVM_GET_SREGS Capability: basic -Architectures: x86 +Architectures: x86, ppc Type: vcpu ioctl Parameters: struct kvm_sregs (out) Returns: 0 on success, -1 on error @@ -279,6 +279,8 @@ struct kvm_sregs { __u64 interrupt_bitmap[(KVM_NR_INTERRUPTS + 63) / 64]; }; +/* ppc -- see arch/powerpc/include/asm/kvm.h */ + interrupt_bitmap is a bitmap of pending external interrupts. At most one bit may be set. This interrupt has been acknowledged by the APIC but not yet injected into the cpu core. @@ -286,7 +288,7 @@ but not yet injected into the cpu core. 4.14 KVM_SET_SREGS Capability: basic -Architectures: x86 +Architectures: x86, ppc Type: vcpu ioctl Parameters: struct kvm_sregs (in) Returns: 0 on success, -1 on error diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/asm/kvm.h index 18ea6963ad77..d2ca5ed3877b 100644 --- a/arch/powerpc/include/asm/kvm.h +++ b/arch/powerpc/include/asm/kvm.h @@ -45,6 +45,114 @@ struct kvm_regs { __u64 gpr[32]; }; +#define KVM_SREGS_E_IMPL_NONE 0 +#define KVM_SREGS_E_IMPL_FSL 1 + +#define KVM_SREGS_E_FSL_PIDn (1 << 0) /* PID1/PID2 */ + +/* + * Feature bits indicate which sections of the sregs struct are valid, + * both in KVM_GET_SREGS and KVM_SET_SREGS. On KVM_SET_SREGS, registers + * corresponding to unset feature bits will not be modified. This allows + * restoring a checkpoint made without that feature, while keeping the + * default values of the new registers. + * + * KVM_SREGS_E_BASE contains: + * CSRR0/1 (refers to SRR2/3 on 40x) + * ESR + * DEAR + * MCSR + * TSR + * TCR + * DEC + * TB + * VRSAVE (USPRG0) + */ +#define KVM_SREGS_E_BASE (1 << 0) + +/* + * KVM_SREGS_E_ARCH206 contains: + * + * PIR + * MCSRR0/1 + * DECAR + * IVPR + */ +#define KVM_SREGS_E_ARCH206 (1 << 1) + +/* + * Contains EPCR, plus the upper half of 64-bit registers + * that are 32-bit on 32-bit implementations. + */ +#define KVM_SREGS_E_64 (1 << 2) + +#define KVM_SREGS_E_SPRG8 (1 << 3) +#define KVM_SREGS_E_MCIVPR (1 << 4) + +/* + * IVORs are used -- contains IVOR0-15, plus additional IVORs + * in combination with an appropriate feature bit. + */ +#define KVM_SREGS_E_IVOR (1 << 5) + +/* + * Contains MAS0-4, MAS6-7, TLBnCFG, MMUCFG. + * Also TLBnPS if MMUCFG[MAVN] = 1. + */ +#define KVM_SREGS_E_ARCH206_MMU (1 << 6) + +/* DBSR, DBCR, IAC, DAC, DVC */ +#define KVM_SREGS_E_DEBUG (1 << 7) + +/* Enhanced debug -- DSRR0/1, SPRG9 */ +#define KVM_SREGS_E_ED (1 << 8) + +/* Embedded Floating Point (SPE) -- IVOR32-34 if KVM_SREGS_E_IVOR */ +#define KVM_SREGS_E_SPE (1 << 9) + +/* External Proxy (EXP) -- EPR */ +#define KVM_SREGS_EXP (1 << 10) + +/* External PID (E.PD) -- EPSC/EPLC */ +#define KVM_SREGS_E_PD (1 << 11) + +/* Processor Control (E.PC) -- IVOR36-37 if KVM_SREGS_E_IVOR */ +#define KVM_SREGS_E_PC (1 << 12) + +/* Page table (E.PT) -- EPTCFG */ +#define KVM_SREGS_E_PT (1 << 13) + +/* Embedded Performance Monitor (E.PM) -- IVOR35 if KVM_SREGS_E_IVOR */ +#define KVM_SREGS_E_PM (1 << 14) + +/* + * Special updates: + * + * Some registers may change even while a vcpu is not running. + * To avoid losing these changes, by default these registers are + * not updated by KVM_SET_SREGS. To force an update, set the bit + * in u.e.update_special corresponding to the register to be updated. + * + * The update_special field is zero on return from KVM_GET_SREGS. + * + * When restoring a checkpoint, the caller can set update_special + * to 0xffffffff to ensure that everything is restored, even new features + * that the caller doesn't know about. + */ +#define KVM_SREGS_E_UPDATE_MCSR (1 << 0) +#define KVM_SREGS_E_UPDATE_TSR (1 << 1) +#define KVM_SREGS_E_UPDATE_DEC (1 << 2) +#define KVM_SREGS_E_UPDATE_DBSR (1 << 3) + +/* + * In KVM_SET_SREGS, reserved/pad fields must be left untouched from a + * previous KVM_GET_REGS. + * + * Unless otherwise indicated, setting any register with KVM_SET_SREGS + * directly sets its value. It does not trigger any special semantics such + * as write-one-to-clear. Calling KVM_SET_SREGS on an unmodified struct + * just received from KVM_GET_SREGS is always a no-op. + */ struct kvm_sregs { __u32 pvr; union { @@ -62,6 +170,82 @@ struct kvm_sregs { __u64 dbat[8]; } ppc32; } s; + struct { + union { + struct { /* KVM_SREGS_E_IMPL_FSL */ + __u32 features; /* KVM_SREGS_E_FSL_ */ + __u32 svr; + __u64 mcar; + __u32 hid0; + + /* KVM_SREGS_E_FSL_PIDn */ + __u32 pid1, pid2; + } fsl; + __u8 pad[256]; + } impl; + + __u32 features; /* KVM_SREGS_E_ */ + __u32 impl_id; /* KVM_SREGS_E_IMPL_ */ + __u32 update_special; /* KVM_SREGS_E_UPDATE_ */ + __u32 pir; /* read-only */ + __u64 sprg8; + __u64 sprg9; /* E.ED */ + __u64 csrr0; + __u64 dsrr0; /* E.ED */ + __u64 mcsrr0; + __u32 csrr1; + __u32 dsrr1; /* E.ED */ + __u32 mcsrr1; + __u32 esr; + __u64 dear; + __u64 ivpr; + __u64 mcivpr; + __u64 mcsr; /* KVM_SREGS_E_UPDATE_MCSR */ + + __u32 tsr; /* KVM_SREGS_E_UPDATE_TSR */ + __u32 tcr; + __u32 decar; + __u32 dec; /* KVM_SREGS_E_UPDATE_DEC */ + + /* + * Userspace can read TB directly, but the + * value reported here is consistent with "dec". + * + * Read-only. + */ + __u64 tb; + + __u32 dbsr; /* KVM_SREGS_E_UPDATE_DBSR */ + __u32 dbcr[3]; + __u32 iac[4]; + __u32 dac[2]; + __u32 dvc[2]; + __u8 num_iac; /* read-only */ + __u8 num_dac; /* read-only */ + __u8 num_dvc; /* read-only */ + __u8 pad; + + __u32 epr; /* EXP */ + __u32 vrsave; /* a.k.a. USPRG0 */ + __u32 epcr; /* KVM_SREGS_E_64 */ + + __u32 mas0; + __u32 mas1; + __u64 mas2; + __u64 mas7_3; + __u32 mas4; + __u32 mas6; + + __u32 ivor_low[16]; /* IVOR0-15 */ + __u32 ivor_high[18]; /* IVOR32+, plus room to expand */ + + __u32 mmucfg; /* read-only */ + __u32 eptcfg; /* E.PT, read-only */ + __u32 tlbcfg[4];/* read-only */ + __u32 tlbps[4]; /* read-only */ + + __u32 eplc, epsc; /* E.PD */ + } e; __u8 pad[1020]; } u; }; diff --git a/arch/powerpc/include/asm/kvm_44x.h b/arch/powerpc/include/asm/kvm_44x.h index d22d39942a92..a0e57618ff33 100644 --- a/arch/powerpc/include/asm/kvm_44x.h +++ b/arch/powerpc/include/asm/kvm_44x.h @@ -61,7 +61,6 @@ static inline struct kvmppc_vcpu_44x *to_44x(struct kvm_vcpu *vcpu) return container_of(vcpu, struct kvmppc_vcpu_44x, vcpu); } -void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 new_pid); void kvmppc_44x_tlb_put(struct kvm_vcpu *vcpu); void kvmppc_44x_tlb_load(struct kvm_vcpu *vcpu); diff --git a/arch/powerpc/include/asm/kvm_e500.h b/arch/powerpc/include/asm/kvm_e500.h index bb2a0890600f..7a2a565f88c4 100644 --- a/arch/powerpc/include/asm/kvm_e500.h +++ b/arch/powerpc/include/asm/kvm_e500.h @@ -59,6 +59,7 @@ struct kvmppc_vcpu_e500 { u32 hid1; u32 tlb0cfg; u32 tlb1cfg; + u64 mcar; struct kvm_vcpu vcpu; }; diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index a16804399165..186f150b9b89 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -233,6 +233,9 @@ struct kvm_vcpu_arch { ulong csrr1; ulong dsrr0; ulong dsrr1; + ulong mcsrr0; + ulong mcsrr1; + ulong mcsr; ulong esr; u32 dec; u32 decar; diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index ecb3bc74c344..9345238edecf 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -61,6 +61,7 @@ extern int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu); extern int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu); extern void kvmppc_emulate_dec(struct kvm_vcpu *vcpu); +extern u32 kvmppc_get_dec(struct kvm_vcpu *vcpu, u64 tb); /* Core-specific hooks */ @@ -142,4 +143,12 @@ static inline u32 kvmppc_set_field(u64 inst, int msb, int lsb, int value) return r; } +void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs); +int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs); + +void kvmppc_get_sregs_ivor(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs); +int kvmppc_set_sregs_ivor(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs); + +void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 pid); + #endif /* __POWERPC_KVM_PPC_H__ */ diff --git a/arch/powerpc/kvm/44x.c b/arch/powerpc/kvm/44x.c index 74d0e7421143..da3a1225c0ac 100644 --- a/arch/powerpc/kvm/44x.c +++ b/arch/powerpc/kvm/44x.c @@ -107,6 +107,16 @@ int kvmppc_core_vcpu_translate(struct kvm_vcpu *vcpu, return 0; } +void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) +{ + kvmppc_get_sregs_ivor(vcpu, sregs); +} + +int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) +{ + return kvmppc_set_sregs_ivor(vcpu, sregs); +} + struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) { struct kvmppc_vcpu_44x *vcpu_44x; diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index ef76acb455c3..8462b3a1c1c7 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -569,6 +569,7 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) kvmppc_set_msr(vcpu, regs->msr); vcpu->arch.shared->srr0 = regs->srr0; vcpu->arch.shared->srr1 = regs->srr1; + kvmppc_set_pid(vcpu, regs->pid); vcpu->arch.shared->sprg0 = regs->sprg0; vcpu->arch.shared->sprg1 = regs->sprg1; vcpu->arch.shared->sprg2 = regs->sprg2; @@ -584,16 +585,165 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) return 0; } +static void get_sregs_base(struct kvm_vcpu *vcpu, + struct kvm_sregs *sregs) +{ + u64 tb = get_tb(); + + sregs->u.e.features |= KVM_SREGS_E_BASE; + + sregs->u.e.csrr0 = vcpu->arch.csrr0; + sregs->u.e.csrr1 = vcpu->arch.csrr1; + sregs->u.e.mcsr = vcpu->arch.mcsr; + sregs->u.e.esr = vcpu->arch.esr; + sregs->u.e.dear = vcpu->arch.shared->dar; + sregs->u.e.tsr = vcpu->arch.tsr; + sregs->u.e.tcr = vcpu->arch.tcr; + sregs->u.e.dec = kvmppc_get_dec(vcpu, tb); + sregs->u.e.tb = tb; + sregs->u.e.vrsave = vcpu->arch.vrsave; +} + +static int set_sregs_base(struct kvm_vcpu *vcpu, + struct kvm_sregs *sregs) +{ + if (!(sregs->u.e.features & KVM_SREGS_E_BASE)) + return 0; + + vcpu->arch.csrr0 = sregs->u.e.csrr0; + vcpu->arch.csrr1 = sregs->u.e.csrr1; + vcpu->arch.mcsr = sregs->u.e.mcsr; + vcpu->arch.esr = sregs->u.e.esr; + vcpu->arch.shared->dar = sregs->u.e.dear; + vcpu->arch.vrsave = sregs->u.e.vrsave; + vcpu->arch.tcr = sregs->u.e.tcr; + + if (sregs->u.e.update_special & KVM_SREGS_E_UPDATE_DEC) + vcpu->arch.dec = sregs->u.e.dec; + + kvmppc_emulate_dec(vcpu); + + if (sregs->u.e.update_special & KVM_SREGS_E_UPDATE_TSR) { + /* + * FIXME: existing KVM timer handling is incomplete. + * TSR cannot be read by the guest, and its value in + * vcpu->arch is always zero. For now, just handle + * the case where the caller is trying to inject a + * decrementer interrupt. + */ + + if ((sregs->u.e.tsr & TSR_DIS) && + (vcpu->arch.tcr & TCR_DIE)) + kvmppc_core_queue_dec(vcpu); + } + + return 0; +} + +static void get_sregs_arch206(struct kvm_vcpu *vcpu, + struct kvm_sregs *sregs) +{ + sregs->u.e.features |= KVM_SREGS_E_ARCH206; + + sregs->u.e.pir = 0; + sregs->u.e.mcsrr0 = vcpu->arch.mcsrr0; + sregs->u.e.mcsrr1 = vcpu->arch.mcsrr1; + sregs->u.e.decar = vcpu->arch.decar; + sregs->u.e.ivpr = vcpu->arch.ivpr; +} + +static int set_sregs_arch206(struct kvm_vcpu *vcpu, + struct kvm_sregs *sregs) +{ + if (!(sregs->u.e.features & KVM_SREGS_E_ARCH206)) + return 0; + + if (sregs->u.e.pir != 0) + return -EINVAL; + + vcpu->arch.mcsrr0 = sregs->u.e.mcsrr0; + vcpu->arch.mcsrr1 = sregs->u.e.mcsrr1; + vcpu->arch.decar = sregs->u.e.decar; + vcpu->arch.ivpr = sregs->u.e.ivpr; + + return 0; +} + +void kvmppc_get_sregs_ivor(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) +{ + sregs->u.e.features |= KVM_SREGS_E_IVOR; + + sregs->u.e.ivor_low[0] = vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL]; + sregs->u.e.ivor_low[1] = vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK]; + sregs->u.e.ivor_low[2] = vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE]; + sregs->u.e.ivor_low[3] = vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE]; + sregs->u.e.ivor_low[4] = vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL]; + sregs->u.e.ivor_low[5] = vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT]; + sregs->u.e.ivor_low[6] = vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM]; + sregs->u.e.ivor_low[7] = vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL]; + sregs->u.e.ivor_low[8] = vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL]; + sregs->u.e.ivor_low[9] = vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL]; + sregs->u.e.ivor_low[10] = vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER]; + sregs->u.e.ivor_low[11] = vcpu->arch.ivor[BOOKE_IRQPRIO_FIT]; + sregs->u.e.ivor_low[12] = vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG]; + sregs->u.e.ivor_low[13] = vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS]; + sregs->u.e.ivor_low[14] = vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS]; + sregs->u.e.ivor_low[15] = vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG]; +} + +int kvmppc_set_sregs_ivor(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) +{ + if (!(sregs->u.e.features & KVM_SREGS_E_IVOR)) + return 0; + + vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL] = sregs->u.e.ivor_low[0]; + vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK] = sregs->u.e.ivor_low[1]; + vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE] = sregs->u.e.ivor_low[2]; + vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE] = sregs->u.e.ivor_low[3]; + vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL] = sregs->u.e.ivor_low[4]; + vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT] = sregs->u.e.ivor_low[5]; + vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM] = sregs->u.e.ivor_low[6]; + vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL] = sregs->u.e.ivor_low[7]; + vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL] = sregs->u.e.ivor_low[8]; + vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL] = sregs->u.e.ivor_low[9]; + vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER] = sregs->u.e.ivor_low[10]; + vcpu->arch.ivor[BOOKE_IRQPRIO_FIT] = sregs->u.e.ivor_low[11]; + vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG] = sregs->u.e.ivor_low[12]; + vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS] = sregs->u.e.ivor_low[13]; + vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS] = sregs->u.e.ivor_low[14]; + vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG] = sregs->u.e.ivor_low[15]; + + return 0; +} + int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) { - return -ENOTSUPP; + sregs->pvr = vcpu->arch.pvr; + + get_sregs_base(vcpu, sregs); + get_sregs_arch206(vcpu, sregs); + kvmppc_core_get_sregs(vcpu, sregs); + return 0; } int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) { - return -ENOTSUPP; + int ret; + + if (vcpu->arch.pvr != sregs->pvr) + return -EINVAL; + + ret = set_sregs_base(vcpu, sregs); + if (ret < 0) + return ret; + + ret = set_sregs_arch206(vcpu, sregs); + if (ret < 0) + return ret; + + return kvmppc_core_set_sregs(vcpu, sregs); } int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c index 0c1af1267843..318dbc61ba44 100644 --- a/arch/powerpc/kvm/e500.c +++ b/arch/powerpc/kvm/e500.c @@ -97,6 +97,81 @@ int kvmppc_core_vcpu_translate(struct kvm_vcpu *vcpu, return 0; } +void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) +{ + struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); + + sregs->u.e.features |= KVM_SREGS_E_ARCH206_MMU | KVM_SREGS_E_SPE | + KVM_SREGS_E_PM; + sregs->u.e.impl_id = KVM_SREGS_E_IMPL_FSL; + + sregs->u.e.impl.fsl.features = 0; + sregs->u.e.impl.fsl.svr = vcpu_e500->svr; + sregs->u.e.impl.fsl.hid0 = vcpu_e500->hid0; + sregs->u.e.impl.fsl.mcar = vcpu_e500->mcar; + + sregs->u.e.mas0 = vcpu_e500->mas0; + sregs->u.e.mas1 = vcpu_e500->mas1; + sregs->u.e.mas2 = vcpu_e500->mas2; + sregs->u.e.mas7_3 = ((u64)vcpu_e500->mas7 << 32) | vcpu_e500->mas3; + sregs->u.e.mas4 = vcpu_e500->mas4; + sregs->u.e.mas6 = vcpu_e500->mas6; + + sregs->u.e.mmucfg = mfspr(SPRN_MMUCFG); + sregs->u.e.tlbcfg[0] = vcpu_e500->tlb0cfg; + sregs->u.e.tlbcfg[1] = vcpu_e500->tlb1cfg; + sregs->u.e.tlbcfg[2] = 0; + sregs->u.e.tlbcfg[3] = 0; + + sregs->u.e.ivor_high[0] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL]; + sregs->u.e.ivor_high[1] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA]; + sregs->u.e.ivor_high[2] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND]; + sregs->u.e.ivor_high[3] = + vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR]; + + kvmppc_get_sregs_ivor(vcpu, sregs); +} + +int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) +{ + struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); + + if (sregs->u.e.impl_id == KVM_SREGS_E_IMPL_FSL) { + vcpu_e500->svr = sregs->u.e.impl.fsl.svr; + vcpu_e500->hid0 = sregs->u.e.impl.fsl.hid0; + vcpu_e500->mcar = sregs->u.e.impl.fsl.mcar; + } + + if (sregs->u.e.features & KVM_SREGS_E_ARCH206_MMU) { + vcpu_e500->mas0 = sregs->u.e.mas0; + vcpu_e500->mas1 = sregs->u.e.mas1; + vcpu_e500->mas2 = sregs->u.e.mas2; + vcpu_e500->mas7 = sregs->u.e.mas7_3 >> 32; + vcpu_e500->mas3 = (u32)sregs->u.e.mas7_3; + vcpu_e500->mas4 = sregs->u.e.mas4; + vcpu_e500->mas6 = sregs->u.e.mas6; + } + + if (!(sregs->u.e.features & KVM_SREGS_E_IVOR)) + return 0; + + if (sregs->u.e.features & KVM_SREGS_E_SPE) { + vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL] = + sregs->u.e.ivor_high[0]; + vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA] = + sregs->u.e.ivor_high[1]; + vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND] = + sregs->u.e.ivor_high[2]; + } + + if (sregs->u.e.features & KVM_SREGS_E_PM) { + vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR] = + sregs->u.e.ivor_high[3]; + } + + return kvmppc_set_sregs_ivor(vcpu, sregs); +} + struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) { struct kvmppc_vcpu_e500 *vcpu_e500; diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c index e2fb47f035a5..69cd665a0caf 100644 --- a/arch/powerpc/kvm/e500_emulate.c +++ b/arch/powerpc/kvm/e500_emulate.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved. + * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All rights reserved. * * Author: Yu Liu, * @@ -78,8 +78,7 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs) switch (sprn) { case SPRN_PID: - vcpu_e500->pid[0] = vcpu->arch.shadow_pid = - vcpu->arch.pid = spr_val; + kvmppc_set_pid(vcpu, spr_val); break; case SPRN_PID1: vcpu_e500->pid[1] = spr_val; break; diff --git a/arch/powerpc/kvm/e500_tlb.c b/arch/powerpc/kvm/e500_tlb.c index 56ac4523857d..b18fe353397d 100644 --- a/arch/powerpc/kvm/e500_tlb.c +++ b/arch/powerpc/kvm/e500_tlb.c @@ -675,6 +675,14 @@ int kvmppc_e500_tlb_search(struct kvm_vcpu *vcpu, return -1; } +void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 pid) +{ + struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); + + vcpu_e500->pid[0] = vcpu->arch.shadow_pid = + vcpu->arch.pid = pid; +} + void kvmppc_e500_tlb_setup(struct kvmppc_vcpu_e500 *vcpu_e500) { struct tlbe *tlbe; diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c index 8f7a3aa03c26..141dce3c6810 100644 --- a/arch/powerpc/kvm/emulate.c +++ b/arch/powerpc/kvm/emulate.c @@ -114,6 +114,12 @@ void kvmppc_emulate_dec(struct kvm_vcpu *vcpu) } } +u32 kvmppc_get_dec(struct kvm_vcpu *vcpu, u64 tb) +{ + u64 jd = tb - vcpu->arch.dec_jiffies; + return vcpu->arch.dec - jd; +} + /* XXX to do: * lhax * lhaux @@ -279,11 +285,8 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) case SPRN_DEC: { - u64 jd = get_tb() - vcpu->arch.dec_jiffies; - kvmppc_set_gpr(vcpu, rt, vcpu->arch.dec - jd); - pr_debug("mfDEC: %x - %llx = %lx\n", - vcpu->arch.dec, jd, - kvmppc_get_gpr(vcpu, rt)); + kvmppc_set_gpr(vcpu, rt, + kvmppc_get_dec(vcpu, get_tb())); break; } default: diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 9e6aa8bfd160..616dd516ca1f 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -175,7 +175,11 @@ int kvm_dev_ioctl_check_extension(long ext) int r; switch (ext) { +#ifdef CONFIG_BOOKE + case KVM_CAP_PPC_BOOKE_SREGS: +#else case KVM_CAP_PPC_SEGSTATE: +#endif case KVM_CAP_PPC_PAIRED_SINGLES: case KVM_CAP_PPC_UNSET_IRQ: case KVM_CAP_PPC_IRQ_LEVEL: diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 2f63ebeac639..55ef181521ff 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -543,6 +543,7 @@ struct kvm_ppc_pvinfo { #define KVM_CAP_ASYNC_PF 59 #define KVM_CAP_TSC_CONTROL 60 #define KVM_CAP_GET_TSC_KHZ 61 +#define KVM_CAP_PPC_BOOKE_SREGS 62 #ifdef KVM_CAP_IRQ_ROUTING -- cgit From 8fa2206821953a50a3a02ea33fcfb3ced2fd9997 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Wed, 4 May 2011 16:31:04 +0300 Subject: KVM: make guest mode entry to be rcu quiescent state KVM does not hold any references to rcu protected data when it switches CPU into a guest mode. In fact switching to a guest mode is very similar to exiting to userspase from rcu point of view. In addition CPU may stay in a guest mode for quite a long time (up to one time slice). Lets treat guest mode as quiescent state, just like we do with user-mode execution. Signed-off-by: Gleb Natapov Signed-off-by: Avi Kivity --- include/linux/kvm_host.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include/linux') diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 0bc3d372e3cb..b9c3299c6a55 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -591,8 +591,17 @@ static inline int kvm_deassign_device(struct kvm *kvm, static inline void kvm_guest_enter(void) { + BUG_ON(preemptible()); account_system_vtime(current); current->flags |= PF_VCPU; + /* KVM does not hold any references to rcu protected data when it + * switches CPU into a guest mode. In fact switching to a guest mode + * is very similar to exiting to userspase from rcu point of view. In + * addition CPU may stay in a guest mode for quite a long time (up to + * one time slice). Lets treat guest mode as quiescent state, just like + * we do with user-mode execution. + */ + rcu_virt_note_context_switch(smp_processor_id()); } static inline void kvm_guest_exit(void) -- cgit From 34ea646c9f8c18fd2e4332ff3b2b509f878c56f1 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Sun, 22 May 2011 18:55:10 +0200 Subject: net: add missing prefetch.h include Fixes build errors on s390 and probably other archs as well: In file included from net/ipv4/ip_forward.c:32:0: include/net/udp.h: In function 'udp_csum_outgoing': include/net/udp.h:141:2: error: implicit declaration of function 'prefetch' Signed-off-by: Heiko Carstens Signed-off-by: Linus Torvalds --- include/linux/skbuff.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 79aafbbf430a..827681540d6f 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -28,6 +28,7 @@ #include #include #include +#include #include /* Don't change this without changing skb_csum_unnecessary! */ -- cgit From 0fcbe742eaac14bd5032b369c09e9d94be9058ad Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 22 May 2011 20:35:29 -0400 Subject: net: Remove prefetches from SKB list handlers. Noticed by Linus. Signed-off-by: David S. Miller --- include/linux/skbuff.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 827681540d6f..09901fdd73ae 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -1783,7 +1783,7 @@ static inline int pskb_trim_rcsum(struct sk_buff *skb, unsigned int len) #define skb_queue_walk(queue, skb) \ for (skb = (queue)->next; \ - prefetch(skb->next), (skb != (struct sk_buff *)(queue)); \ + (skb != (struct sk_buff *)(queue)); \ skb = skb->next) #define skb_queue_walk_safe(queue, skb, tmp) \ @@ -1792,7 +1792,7 @@ static inline int pskb_trim_rcsum(struct sk_buff *skb, unsigned int len) skb = tmp, tmp = skb->next) #define skb_queue_walk_from(queue, skb) \ - for (; prefetch(skb->next), (skb != (struct sk_buff *)(queue)); \ + for (; (skb != (struct sk_buff *)(queue)); \ skb = skb->next) #define skb_queue_walk_from_safe(queue, skb, tmp) \ @@ -1802,7 +1802,7 @@ static inline int pskb_trim_rcsum(struct sk_buff *skb, unsigned int len) #define skb_queue_reverse_walk(queue, skb) \ for (skb = (queue)->prev; \ - prefetch(skb->prev), (skb != (struct sk_buff *)(queue)); \ + (skb != (struct sk_buff *)(queue)); \ skb = skb->prev) #define skb_queue_reverse_walk_safe(queue, skb, tmp) \ -- cgit From 67f11f4deda0818640decb19a28c537dbe5d429e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 22 May 2011 20:54:11 -0400 Subject: net: Remove linux/prefetch.h include from linux/skbuff.h No longer needed. Signed-off-by: David S. Miller --- include/linux/skbuff.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 09901fdd73ae..8cac356b77b2 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -28,7 +28,6 @@ #include #include #include -#include #include /* Don't change this without changing skb_csum_unnecessary! */ -- cgit From 8d8fc29d02a33e4bd5f4fa47823c1fd386346093 Mon Sep 17 00:00:00 2001 From: Amerigo Wang Date: Thu, 19 May 2011 21:39:10 +0000 Subject: netpoll: disable netpoll when enslave a device V3: rename NETDEV_ENSLAVE to NETDEV_JOIN Currently we do nothing when we enslave a net device which is running netconsole. Neil pointed out that we may get weird results in such case, so let's disable netpoll on the device being enslaved. I think it is too harsh to prevent the device being ensalved if it is running netconsole. By the way, this patch also removes the NETDEV_GOING_DOWN from netconsole netdev notifier, because netpoll will check if the device is running or not and we don't handle NETDEV_PRE_UP neither. This patch is based on net-next-2.6. Signed-off-by: WANG Cong Cc: Neil Horman Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 2 ++ drivers/net/netconsole.c | 26 +++++++++++++++++--------- include/linux/notifier.h | 1 + 3 files changed, 20 insertions(+), 9 deletions(-) (limited to 'include/linux') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 088fd845ffdf..f4960f516c39 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1640,6 +1640,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) } } + call_netdevice_notifiers(NETDEV_JOIN, slave_dev); + /* If this is the first slave, then we need to set the master's hardware * address to be the same as the slave's. */ if (is_zero_ether_addr(bond->dev->dev_addr)) diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index a83e101440fd..4190786de403 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -621,11 +621,10 @@ static int netconsole_netdev_event(struct notifier_block *this, bool stopped = false; if (!(event == NETDEV_CHANGENAME || event == NETDEV_UNREGISTER || - event == NETDEV_BONDING_DESLAVE || event == NETDEV_GOING_DOWN)) + event == NETDEV_BONDING_DESLAVE || event == NETDEV_JOIN)) goto done; spin_lock_irqsave(&target_list_lock, flags); -restart: list_for_each_entry(nt, &target_list, list) { netconsole_target_get(nt); if (nt->np.dev == dev) { @@ -633,6 +632,8 @@ restart: case NETDEV_CHANGENAME: strlcpy(nt->np.dev_name, dev->name, IFNAMSIZ); break; + case NETDEV_BONDING_DESLAVE: + case NETDEV_JOIN: case NETDEV_UNREGISTER: /* * rtnl_lock already held @@ -647,11 +648,7 @@ restart: dev_put(nt->np.dev); nt->np.dev = NULL; netconsole_target_put(nt); - goto restart; } - /* Fall through */ - case NETDEV_GOING_DOWN: - case NETDEV_BONDING_DESLAVE: nt->enabled = 0; stopped = true; break; @@ -660,10 +657,21 @@ restart: netconsole_target_put(nt); } spin_unlock_irqrestore(&target_list_lock, flags); - if (stopped && (event == NETDEV_UNREGISTER || event == NETDEV_BONDING_DESLAVE)) + if (stopped) { printk(KERN_INFO "netconsole: network logging stopped on " - "interface %s as it %s\n", dev->name, - event == NETDEV_UNREGISTER ? "unregistered" : "released slaves"); + "interface %s as it ", dev->name); + switch (event) { + case NETDEV_UNREGISTER: + printk(KERN_CONT "unregistered\n"); + break; + case NETDEV_BONDING_DESLAVE: + printk(KERN_CONT "released slaves\n"); + break; + case NETDEV_JOIN: + printk(KERN_CONT "is joining a master device\n"); + break; + } + } done: return NOTIFY_DONE; diff --git a/include/linux/notifier.h b/include/linux/notifier.h index 621dfa16acc0..a577762afbe7 100644 --- a/include/linux/notifier.h +++ b/include/linux/notifier.h @@ -211,6 +211,7 @@ static inline int notifier_to_errno(int ret) #define NETDEV_UNREGISTER_BATCH 0x0011 #define NETDEV_BONDING_DESLAVE 0x0012 #define NETDEV_NOTIFY_PEERS 0x0013 +#define NETDEV_JOIN 0x0014 #define SYS_DOWN 0x0001 /* Notify of system down */ #define SYS_RESTART SYS_DOWN -- cgit From daf9209bb2c8b07ca025eac82e3d175534086c77 Mon Sep 17 00:00:00 2001 From: Amerigo Wang Date: Thu, 19 May 2011 21:39:12 +0000 Subject: net: rename NETDEV_BONDING_DESLAVE to NETDEV_RELEASE s/NETDEV_BONDING_DESLAVE/NETDEV_RELEASE/ as Andy suggested. Signed-off-by: WANG Cong Cc: Andy Gospodarek Cc: Neil Horman Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 2 +- drivers/net/netconsole.c | 6 +++--- include/linux/notifier.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index f4960f516c39..6dc428461541 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1974,7 +1974,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) } block_netpoll_tx(); - netdev_bonding_change(bond_dev, NETDEV_BONDING_DESLAVE); + netdev_bonding_change(bond_dev, NETDEV_RELEASE); write_lock_bh(&bond->lock); slave = bond_get_slave_by_dev(bond, slave_dev); diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 4190786de403..dfc82720065a 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -621,7 +621,7 @@ static int netconsole_netdev_event(struct notifier_block *this, bool stopped = false; if (!(event == NETDEV_CHANGENAME || event == NETDEV_UNREGISTER || - event == NETDEV_BONDING_DESLAVE || event == NETDEV_JOIN)) + event == NETDEV_RELEASE || event == NETDEV_JOIN)) goto done; spin_lock_irqsave(&target_list_lock, flags); @@ -632,7 +632,7 @@ static int netconsole_netdev_event(struct notifier_block *this, case NETDEV_CHANGENAME: strlcpy(nt->np.dev_name, dev->name, IFNAMSIZ); break; - case NETDEV_BONDING_DESLAVE: + case NETDEV_RELEASE: case NETDEV_JOIN: case NETDEV_UNREGISTER: /* @@ -664,7 +664,7 @@ static int netconsole_netdev_event(struct notifier_block *this, case NETDEV_UNREGISTER: printk(KERN_CONT "unregistered\n"); break; - case NETDEV_BONDING_DESLAVE: + case NETDEV_RELEASE: printk(KERN_CONT "released slaves\n"); break; case NETDEV_JOIN: diff --git a/include/linux/notifier.h b/include/linux/notifier.h index a577762afbe7..c0688b0168b3 100644 --- a/include/linux/notifier.h +++ b/include/linux/notifier.h @@ -209,7 +209,7 @@ static inline int notifier_to_errno(int ret) #define NETDEV_POST_TYPE_CHANGE 0x000F #define NETDEV_POST_INIT 0x0010 #define NETDEV_UNREGISTER_BATCH 0x0011 -#define NETDEV_BONDING_DESLAVE 0x0012 +#define NETDEV_RELEASE 0x0012 #define NETDEV_NOTIFY_PEERS 0x0013 #define NETDEV_JOIN 0x0014 -- cgit From c4264f27e83968ddfe3f0cfe7a33adfb320e1e42 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sat, 21 May 2011 19:46:09 +0000 Subject: net: skb_trim explicitely check the linearity instead of data_len The purpose of the check on data_len is to check linearity, so use the inline helper for this. No overhead and more explicit. Signed-off-by: Emmanuel Grumbach Signed-off-by: David S. Miller --- include/linux/skbuff.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 8cac356b77b2..aeaad97e6815 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -1442,7 +1442,7 @@ extern int ___pskb_trim(struct sk_buff *skb, unsigned int len); static inline void __skb_trim(struct sk_buff *skb, unsigned int len) { - if (unlikely(skb->data_len)) { + if (unlikely(skb_is_nonlinear(skb))) { WARN_ON(1); return; } -- cgit From 792d4b5cb16b684958c2590f77688667ddec1f61 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Sun, 22 May 2011 07:08:11 +0000 Subject: net: filter: move forward declarations to avoid compile warnings Get rid of this compile warning: In file included from arch/s390/kernel/compat_linux.c:37:0: include/linux/filter.h:139:23: warning: 'struct sk_buff' declared inside parameter list Signed-off-by: Heiko Carstens Signed-off-by: David S. Miller --- include/linux/filter.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/filter.h b/include/linux/filter.h index 4609b85e559d..9ee3f9fb0b4a 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -131,6 +131,10 @@ struct sock_fprog { /* Required for SO_ATTACH_FILTER. */ #define SKF_LL_OFF (-0x200000) #ifdef __KERNEL__ + +struct sk_buff; +struct sock; + struct sk_filter { atomic_t refcnt; @@ -146,9 +150,6 @@ static inline unsigned int sk_filter_len(const struct sk_filter *fp) return fp->len * sizeof(struct sock_filter) + sizeof(*fp); } -struct sk_buff; -struct sock; - extern int sk_filter(struct sock *sk, struct sk_buff *skb); extern unsigned int sk_run_filter(const struct sk_buff *skb, const struct sock_filter *filter); -- cgit From a1e4891fd48d298870b704c6eb48cba0da5ed6b1 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 22 May 2011 16:51:43 -0700 Subject: Remove prefetch() from and "netlabel_addrlist.h" Commit e66eed651fd1 ("list: remove prefetching from regular list iterators") removed the include of prefetch.h from list.h. The skbuff list traversal still had them. Quoth David Miller: "Please just remove the prefetches. Those are modelled after list.h as I intend to eventually convert SKB list handling to "struct list_head" but we're not there yet. Therefore if we kill prefetches from list.h we should kill it from these things in skbuff.h too." Requested-by: David Miller Signed-off-by: Linus Torvalds --- include/linux/skbuff.h | 7 +++---- net/netlabel/netlabel_addrlist.h | 8 ++++---- 2 files changed, 7 insertions(+), 8 deletions(-) (limited to 'include/linux') diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 827681540d6f..16c9c091555d 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -28,7 +28,6 @@ #include #include #include -#include #include /* Don't change this without changing skb_csum_unnecessary! */ @@ -1783,7 +1782,7 @@ static inline int pskb_trim_rcsum(struct sk_buff *skb, unsigned int len) #define skb_queue_walk(queue, skb) \ for (skb = (queue)->next; \ - prefetch(skb->next), (skb != (struct sk_buff *)(queue)); \ + skb != (struct sk_buff *)(queue); \ skb = skb->next) #define skb_queue_walk_safe(queue, skb, tmp) \ @@ -1792,7 +1791,7 @@ static inline int pskb_trim_rcsum(struct sk_buff *skb, unsigned int len) skb = tmp, tmp = skb->next) #define skb_queue_walk_from(queue, skb) \ - for (; prefetch(skb->next), (skb != (struct sk_buff *)(queue)); \ + for (; skb != (struct sk_buff *)(queue); \ skb = skb->next) #define skb_queue_walk_from_safe(queue, skb, tmp) \ @@ -1802,7 +1801,7 @@ static inline int pskb_trim_rcsum(struct sk_buff *skb, unsigned int len) #define skb_queue_reverse_walk(queue, skb) \ for (skb = (queue)->prev; \ - prefetch(skb->prev), (skb != (struct sk_buff *)(queue)); \ + skb != (struct sk_buff *)(queue); \ skb = skb->prev) #define skb_queue_reverse_walk_safe(queue, skb, tmp) \ diff --git a/net/netlabel/netlabel_addrlist.h b/net/netlabel/netlabel_addrlist.h index 1c1c093cf279..2b9644e19de0 100644 --- a/net/netlabel/netlabel_addrlist.h +++ b/net/netlabel/netlabel_addrlist.h @@ -96,12 +96,12 @@ static inline struct netlbl_af4list *__af4list_valid_rcu(struct list_head *s, #define netlbl_af4list_foreach(iter, head) \ for (iter = __af4list_valid((head)->next, head); \ - prefetch(iter->list.next), &iter->list != (head); \ + &iter->list != (head); \ iter = __af4list_valid(iter->list.next, head)) #define netlbl_af4list_foreach_rcu(iter, head) \ for (iter = __af4list_valid_rcu((head)->next, head); \ - prefetch(iter->list.next), &iter->list != (head); \ + &iter->list != (head); \ iter = __af4list_valid_rcu(iter->list.next, head)) #define netlbl_af4list_foreach_safe(iter, tmp, head) \ @@ -163,12 +163,12 @@ static inline struct netlbl_af6list *__af6list_valid_rcu(struct list_head *s, #define netlbl_af6list_foreach(iter, head) \ for (iter = __af6list_valid((head)->next, head); \ - prefetch(iter->list.next), &iter->list != (head); \ + &iter->list != (head); \ iter = __af6list_valid(iter->list.next, head)) #define netlbl_af6list_foreach_rcu(iter, head) \ for (iter = __af6list_valid_rcu((head)->next, head); \ - prefetch(iter->list.next), &iter->list != (head); \ + &iter->list != (head); \ iter = __af6list_valid_rcu(iter->list.next, head)) #define netlbl_af6list_foreach_safe(iter, tmp, head) \ -- cgit From 2d42552d1c1659b014851cf449ad2fe458509128 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Mon, 23 May 2011 10:24:39 +0200 Subject: [S390] merge page_test_dirty and page_clear_dirty The page_clear_dirty primitive always sets the default storage key which resets the access control bits and the fetch protection bit. That will surprise a KVM guest that sets non-zero access control bits or the fetch protection bit. Merge page_test_dirty and page_clear_dirty back to a single function and only clear the dirty bit from the storage key. In addition move the function page_test_and_clear_dirty and page_test_and_clear_young to page.h where they belong. This requires to change the parameter from a struct page * to a page frame number. Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/page.h | 56 ++++++++++++++++++++++++++++++++++----- arch/s390/include/asm/pgtable.h | 58 +++++++---------------------------------- include/asm-generic/pgtable.h | 12 +++------ include/linux/page-flags.h | 2 +- mm/rmap.c | 11 +++----- 5 files changed, 68 insertions(+), 71 deletions(-) (limited to 'include/linux') diff --git a/arch/s390/include/asm/page.h b/arch/s390/include/asm/page.h index 3c987e9ec8d6..81ee2776088d 100644 --- a/arch/s390/include/asm/page.h +++ b/arch/s390/include/asm/page.h @@ -107,8 +107,8 @@ typedef pte_t *pgtable_t; #define __pgd(x) ((pgd_t) { (x) } ) #define __pgprot(x) ((pgprot_t) { (x) } ) -static inline void -page_set_storage_key(unsigned long addr, unsigned int skey, int mapped) +static inline void page_set_storage_key(unsigned long addr, + unsigned char skey, int mapped) { if (!mapped) asm volatile(".insn rrf,0xb22b0000,%0,%1,8,0" @@ -117,15 +117,59 @@ page_set_storage_key(unsigned long addr, unsigned int skey, int mapped) asm volatile("sske %0,%1" : : "d" (skey), "a" (addr)); } -static inline unsigned int -page_get_storage_key(unsigned long addr) +static inline unsigned char page_get_storage_key(unsigned long addr) { - unsigned int skey; + unsigned char skey; - asm volatile("iske %0,%1" : "=d" (skey) : "a" (addr), "0" (0)); + asm volatile("iske %0,%1" : "=d" (skey) : "a" (addr)); return skey; } +static inline int page_reset_referenced(unsigned long addr) +{ + unsigned int ipm; + + asm volatile( + " rrbe 0,%1\n" + " ipm %0\n" + : "=d" (ipm) : "a" (addr) : "cc"); + return !!(ipm & 0x20000000); +} + +/* Bits int the storage key */ +#define _PAGE_CHANGED 0x02 /* HW changed bit */ +#define _PAGE_REFERENCED 0x04 /* HW referenced bit */ +#define _PAGE_FP_BIT 0x08 /* HW fetch protection bit */ +#define _PAGE_ACC_BITS 0xf0 /* HW access control bits */ + +/* + * Test and clear dirty bit in storage key. + * We can't clear the changed bit atomically. This is a potential + * race against modification of the referenced bit. This function + * should therefore only be called if it is not mapped in any + * address space. + */ +#define __HAVE_ARCH_PAGE_TEST_AND_CLEAR_DIRTY +static inline int page_test_and_clear_dirty(unsigned long pfn, int mapped) +{ + unsigned char skey; + + skey = page_get_storage_key(pfn << PAGE_SHIFT); + if (!(skey & _PAGE_CHANGED)) + return 0; + page_set_storage_key(pfn << PAGE_SHIFT, skey & ~_PAGE_CHANGED, mapped); + return 1; +} + +/* + * Test and clear referenced bit in storage key. + */ +#define __HAVE_ARCH_PAGE_TEST_AND_CLEAR_YOUNG +static inline int page_test_and_clear_young(unsigned long pfn) +{ + return page_reset_referenced(pfn << PAGE_SHIFT); +} + struct page; void arch_free_page(struct page *page, int order); void arch_alloc_page(struct page *page, int order); diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 763620ec7925..4ca4dd2b329a 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -373,10 +373,6 @@ extern unsigned long VMALLOC_START; #define _ASCE_USER_BITS (_ASCE_SPACE_SWITCH | _ASCE_PRIVATE_SPACE | \ _ASCE_ALT_EVENT) -/* Bits int the storage key */ -#define _PAGE_CHANGED 0x02 /* HW changed bit */ -#define _PAGE_REFERENCED 0x04 /* HW referenced bit */ - /* * Page protection definitions. */ @@ -555,8 +551,6 @@ static inline void rcp_unlock(pte_t *ptep) #endif } -/* forward declaration for SetPageUptodate in page-flags.h*/ -static inline void page_clear_dirty(struct page *page, int mapped); #include static inline void ptep_rcp_copy(pte_t *ptep) @@ -566,7 +560,7 @@ static inline void ptep_rcp_copy(pte_t *ptep) unsigned int skey; unsigned long *pgste = (unsigned long *) (ptep + PTRS_PER_PTE); - skey = page_get_storage_key(page_to_phys(page)); + skey = page_get_storage_key(pte_val(*ptep) >> PAGE_SHIFT); if (skey & _PAGE_CHANGED) { set_bit_simple(RCP_GC_BIT, pgste); set_bit_simple(KVM_UD_BIT, pgste); @@ -760,6 +754,7 @@ static inline int kvm_s390_test_and_clear_page_dirty(struct mm_struct *mm, { int dirty; unsigned long *pgste; + unsigned long pfn; struct page *page; unsigned int skey; @@ -767,8 +762,9 @@ static inline int kvm_s390_test_and_clear_page_dirty(struct mm_struct *mm, return -EINVAL; rcp_lock(ptep); pgste = (unsigned long *) (ptep + PTRS_PER_PTE); - page = virt_to_page(pte_val(*ptep)); - skey = page_get_storage_key(page_to_phys(page)); + pfn = pte_val(*ptep) >> PAGE_SHIFT; + page = pfn_to_page(pfn); + skey = page_get_storage_key(pfn); if (skey & _PAGE_CHANGED) { set_bit_simple(RCP_GC_BIT, pgste); set_bit_simple(KVM_UD_BIT, pgste); @@ -779,7 +775,7 @@ static inline int kvm_s390_test_and_clear_page_dirty(struct mm_struct *mm, } dirty = test_and_clear_bit_simple(KVM_UD_BIT, pgste); if (skey & _PAGE_CHANGED) - page_clear_dirty(page, 1); + page_set_storage_key(pfn, skey & ~_PAGE_CHANGED, 1); rcp_unlock(ptep); return dirty; } @@ -790,16 +786,16 @@ static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) { #ifdef CONFIG_PGSTE - unsigned long physpage; + unsigned long pfn; int young; unsigned long *pgste; if (!vma->vm_mm->context.has_pgste) return 0; - physpage = pte_val(*ptep) & PAGE_MASK; + pfn = pte_val(*ptep) >> PAGE_SHIFT; pgste = (unsigned long *) (ptep + PTRS_PER_PTE); - young = ((page_get_storage_key(physpage) & _PAGE_REFERENCED) != 0); + young = ((page_get_storage_key(pfn) & _PAGE_REFERENCED) != 0); rcp_lock(ptep); if (young) set_bit_simple(RCP_GR_BIT, pgste); @@ -936,42 +932,6 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, __changed; \ }) -/* - * Test and clear dirty bit in storage key. - * We can't clear the changed bit atomically. This is a potential - * race against modification of the referenced bit. This function - * should therefore only be called if it is not mapped in any - * address space. - */ -#define __HAVE_ARCH_PAGE_TEST_DIRTY -static inline int page_test_dirty(struct page *page) -{ - return (page_get_storage_key(page_to_phys(page)) & _PAGE_CHANGED) != 0; -} - -#define __HAVE_ARCH_PAGE_CLEAR_DIRTY -static inline void page_clear_dirty(struct page *page, int mapped) -{ - page_set_storage_key(page_to_phys(page), PAGE_DEFAULT_KEY, mapped); -} - -/* - * Test and clear referenced bit in storage key. - */ -#define __HAVE_ARCH_PAGE_TEST_AND_CLEAR_YOUNG -static inline int page_test_and_clear_young(struct page *page) -{ - unsigned long physpage = page_to_phys(page); - int ccode; - - asm volatile( - " rrbe 0,%1\n" - " ipm %0\n" - " srl %0,28\n" - : "=d" (ccode) : "a" (physpage) : "cc" ); - return ccode & 2; -} - /* * Conversion functions: convert a page and protection to a page entry, * and a page entry and page directory to the page they refer to. diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h index b4bfe338ea0e..e9b8e5926bef 100644 --- a/include/asm-generic/pgtable.h +++ b/include/asm-generic/pgtable.h @@ -184,22 +184,18 @@ static inline int pmd_same(pmd_t pmd_a, pmd_t pmd_b) #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ #endif -#ifndef __HAVE_ARCH_PAGE_TEST_DIRTY -#define page_test_dirty(page) (0) +#ifndef __HAVE_ARCH_PAGE_TEST_AND_CLEAR_DIRTY +#define page_test_and_clear_dirty(pfn, mapped) (0) #endif -#ifndef __HAVE_ARCH_PAGE_CLEAR_DIRTY -#define page_clear_dirty(page, mapped) do { } while (0) -#endif - -#ifndef __HAVE_ARCH_PAGE_TEST_DIRTY +#ifndef __HAVE_ARCH_PAGE_TEST_AND_CLEAR_DIRTY #define pte_maybe_dirty(pte) pte_dirty(pte) #else #define pte_maybe_dirty(pte) (1) #endif #ifndef __HAVE_ARCH_PAGE_TEST_AND_CLEAR_YOUNG -#define page_test_and_clear_young(page) (0) +#define page_test_and_clear_young(pfn) (0) #endif #ifndef __HAVE_ARCH_PGD_OFFSET_GATE diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index 811183de1ef5..79a6700b7162 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h @@ -308,7 +308,7 @@ static inline void SetPageUptodate(struct page *page) { #ifdef CONFIG_S390 if (!test_and_set_bit(PG_uptodate, &page->flags)) - page_clear_dirty(page, 0); + page_set_storage_key(page_to_pfn(page), PAGE_DEFAULT_KEY, 0); #else /* * Memory barrier must be issued before setting the PG_uptodate bit, diff --git a/mm/rmap.c b/mm/rmap.c index 8da044a1db0f..522e4a93cadd 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -719,7 +719,7 @@ int page_referenced(struct page *page, unlock_page(page); } out: - if (page_test_and_clear_young(page)) + if (page_test_and_clear_young(page_to_pfn(page))) referenced++; return referenced; @@ -785,10 +785,8 @@ int page_mkclean(struct page *page) struct address_space *mapping = page_mapping(page); if (mapping) { ret = page_mkclean_file(mapping, page); - if (page_test_dirty(page)) { - page_clear_dirty(page, 1); + if (page_test_and_clear_dirty(page_to_pfn(page), 1)) ret = 1; - } } } @@ -981,10 +979,9 @@ void page_remove_rmap(struct page *page) * not if it's in swapcache - there might be another pte slot * containing the swap entry, but page not yet written to swap. */ - if ((!PageAnon(page) || PageSwapCache(page)) && page_test_dirty(page)) { - page_clear_dirty(page, 1); + if ((!PageAnon(page) || PageSwapCache(page)) && + page_test_and_clear_dirty(page_to_pfn(page), 1)) set_page_dirty(page); - } /* * Hugepages are not counted in NR_ANON_PAGES nor NR_FILE_MAPPED * and not charged by memcg for now. -- cgit From 586692a5a5fc5740c8a46abc0f2365495c2d7c5f Mon Sep 17 00:00:00 2001 From: Mandeep Singh Baines Date: Sun, 22 May 2011 22:10:22 -0700 Subject: watchdog: Disable watchdog when thresh is zero This restores the previous behavior of softlock_thresh. Currently, setting watchdog_thresh to zero causes the watchdog kthreads to consume a lot of CPU. In addition, the logic of proc_dowatchdog_thresh and proc_dowatchdog_enabled has been factored into proc_dowatchdog. Signed-off-by: Mandeep Singh Baines Cc: Marcin Slusarz Cc: Don Zickus Cc: Peter Zijlstra Cc: Frederic Weisbecker Link: http://lkml.kernel.org/r/1306127423-3347-3-git-send-email-msb@chromium.org Signed-off-by: Ingo Molnar LKML-Reference: <20110517071018.GE22305@elte.hu> --- include/linux/nmi.h | 5 +++-- include/linux/sched.h | 1 - kernel/sysctl.c | 12 ++++++++---- kernel/watchdog.c | 25 +++++++++---------------- 4 files changed, 20 insertions(+), 23 deletions(-) (limited to 'include/linux') diff --git a/include/linux/nmi.h b/include/linux/nmi.h index c536f8545f74..5317b8b2198f 100644 --- a/include/linux/nmi.h +++ b/include/linux/nmi.h @@ -47,9 +47,10 @@ static inline bool trigger_all_cpu_backtrace(void) int hw_nmi_is_cpu_stuck(struct pt_regs *); u64 hw_nmi_get_sample_period(void); extern int watchdog_enabled; +extern int watchdog_thresh; struct ctl_table; -extern int proc_dowatchdog_enabled(struct ctl_table *, int , - void __user *, size_t *, loff_t *); +extern int proc_dowatchdog(struct ctl_table *, int , + void __user *, size_t *, loff_t *); #endif #endif diff --git a/include/linux/sched.h b/include/linux/sched.h index 12211e1666e2..d8b2d0bec0d8 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -315,7 +315,6 @@ extern int proc_dowatchdog_thresh(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos); extern unsigned int softlockup_panic; -extern int softlockup_thresh; void lockup_detector_init(void); #else static inline void touch_softlockup_watchdog(void) diff --git a/kernel/sysctl.c b/kernel/sysctl.c index c0bb32414b17..3dd0c46fa3bb 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -730,14 +730,16 @@ static struct ctl_table kern_table[] = { .data = &watchdog_enabled, .maxlen = sizeof (int), .mode = 0644, - .proc_handler = proc_dowatchdog_enabled, + .proc_handler = proc_dowatchdog, + .extra1 = &zero, + .extra2 = &one, }, { .procname = "watchdog_thresh", - .data = &softlockup_thresh, + .data = &watchdog_thresh, .maxlen = sizeof(int), .mode = 0644, - .proc_handler = proc_dowatchdog_thresh, + .proc_handler = proc_dowatchdog, .extra1 = &neg_one, .extra2 = &sixty, }, @@ -755,7 +757,9 @@ static struct ctl_table kern_table[] = { .data = &watchdog_enabled, .maxlen = sizeof (int), .mode = 0644, - .proc_handler = proc_dowatchdog_enabled, + .proc_handler = proc_dowatchdog, + .extra1 = &zero, + .extra2 = &one, }, #endif #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86) diff --git a/kernel/watchdog.c b/kernel/watchdog.c index cf0e09f452e7..60301916f62e 100644 --- a/kernel/watchdog.c +++ b/kernel/watchdog.c @@ -28,7 +28,7 @@ #include int watchdog_enabled = 1; -int __read_mostly softlockup_thresh = 60; +int __read_mostly watchdog_thresh = 60; static DEFINE_PER_CPU(unsigned long, watchdog_touch_ts); static DEFINE_PER_CPU(struct task_struct *, softlockup_watchdog); @@ -105,12 +105,12 @@ static unsigned long get_timestamp(int this_cpu) static unsigned long get_sample_period(void) { /* - * convert softlockup_thresh from seconds to ns + * convert watchdog_thresh from seconds to ns * the divide by 5 is to give hrtimer 5 chances to * increment before the hardlockup detector generates * a warning */ - return softlockup_thresh * (NSEC_PER_SEC / 5); + return watchdog_thresh * (NSEC_PER_SEC / 5); } /* Commands for resetting the watchdog */ @@ -182,7 +182,7 @@ static int is_softlockup(unsigned long touch_ts) unsigned long now = get_timestamp(smp_processor_id()); /* Warn about unreasonable delays: */ - if (time_after(now, touch_ts + softlockup_thresh)) + if (time_after(now, touch_ts + watchdog_thresh)) return now - touch_ts; return 0; @@ -501,19 +501,19 @@ static void watchdog_disable_all_cpus(void) /* sysctl functions */ #ifdef CONFIG_SYSCTL /* - * proc handler for /proc/sys/kernel/nmi_watchdog + * proc handler for /proc/sys/kernel/nmi_watchdog,watchdog_thresh */ -int proc_dowatchdog_enabled(struct ctl_table *table, int write, - void __user *buffer, size_t *length, loff_t *ppos) +int proc_dowatchdog(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) { int ret; - ret = proc_dointvec(table, write, buffer, length, ppos); + ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); if (ret || !write) goto out; - if (watchdog_enabled) + if (watchdog_enabled && watchdog_thresh) watchdog_enable_all_cpus(); else watchdog_disable_all_cpus(); @@ -521,13 +521,6 @@ int proc_dowatchdog_enabled(struct ctl_table *table, int write, out: return ret; } - -int proc_dowatchdog_thresh(struct ctl_table *table, int write, - void __user *buffer, - size_t *lenp, loff_t *ppos) -{ - return proc_dointvec_minmax(table, write, buffer, lenp, ppos); -} #endif /* CONFIG_SYSCTL */ -- cgit From 4eec42f392043063d0f019640b4ccc2a45570002 Mon Sep 17 00:00:00 2001 From: Mandeep Singh Baines Date: Sun, 22 May 2011 22:10:23 -0700 Subject: watchdog: Change the default timeout and configure nmi watchdog period based on watchdog_thresh Before the conversion of the NMI watchdog to perf event, the watchdog timeout was 5 seconds. Now it is 60 seconds. For my particular application, netbooks, 5 seconds was a better timeout. With a short timeout, we catch faults earlier and are able to send back a panic. With a 60 second timeout, the user is unlikely to wait and will instead hit the power button, causing us to lose the panic info. This change configures the NMI period to watchdog_thresh and sets the softlockup_thresh to watchdog_thresh * 2. In addition, watchdog_thresh was reduced to 10 seconds as suggested by Ingo Molnar. Signed-off-by: Mandeep Singh Baines Cc: Marcin Slusarz Cc: Don Zickus Cc: Peter Zijlstra Cc: Frederic Weisbecker Link: http://lkml.kernel.org/r/1306127423-3347-4-git-send-email-msb@chromium.org Signed-off-by: Ingo Molnar LKML-Reference: <20110517071642.GF22305@elte.hu> --- arch/x86/kernel/apic/hw_nmi.c | 4 ++-- include/linux/nmi.h | 2 +- kernel/watchdog.c | 19 +++++++++++++++---- 3 files changed, 18 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/arch/x86/kernel/apic/hw_nmi.c b/arch/x86/kernel/apic/hw_nmi.c index 5260fe91bcb6..d5e57db0f7be 100644 --- a/arch/x86/kernel/apic/hw_nmi.c +++ b/arch/x86/kernel/apic/hw_nmi.c @@ -19,9 +19,9 @@ #include #ifdef CONFIG_HARDLOCKUP_DETECTOR -u64 hw_nmi_get_sample_period(void) +u64 hw_nmi_get_sample_period(int watchdog_thresh) { - return (u64)(cpu_khz) * 1000 * 60; + return (u64)(cpu_khz) * 1000 * watchdog_thresh; } #endif diff --git a/include/linux/nmi.h b/include/linux/nmi.h index 5317b8b2198f..2d304efc89df 100644 --- a/include/linux/nmi.h +++ b/include/linux/nmi.h @@ -45,7 +45,7 @@ static inline bool trigger_all_cpu_backtrace(void) #ifdef CONFIG_LOCKUP_DETECTOR int hw_nmi_is_cpu_stuck(struct pt_regs *); -u64 hw_nmi_get_sample_period(void); +u64 hw_nmi_get_sample_period(int watchdog_thresh); extern int watchdog_enabled; extern int watchdog_thresh; struct ctl_table; diff --git a/kernel/watchdog.c b/kernel/watchdog.c index 60301916f62e..6e63097fa73a 100644 --- a/kernel/watchdog.c +++ b/kernel/watchdog.c @@ -28,7 +28,7 @@ #include int watchdog_enabled = 1; -int __read_mostly watchdog_thresh = 60; +int __read_mostly watchdog_thresh = 10; static DEFINE_PER_CPU(unsigned long, watchdog_touch_ts); static DEFINE_PER_CPU(struct task_struct *, softlockup_watchdog); @@ -91,6 +91,17 @@ static int __init nosoftlockup_setup(char *str) __setup("nosoftlockup", nosoftlockup_setup); /* */ +/* + * Hard-lockup warnings should be triggered after just a few seconds. Soft- + * lockups can have false positives under extreme conditions. So we generally + * want a higher threshold for soft lockups than for hard lockups. So we couple + * the thresholds with a factor: we make the soft threshold twice the amount of + * time the hard threshold is. + */ +static int get_softlockup_thresh() +{ + return watchdog_thresh * 2; +} /* * Returns seconds, approximately. We don't need nanosecond @@ -110,7 +121,7 @@ static unsigned long get_sample_period(void) * increment before the hardlockup detector generates * a warning */ - return watchdog_thresh * (NSEC_PER_SEC / 5); + return get_softlockup_thresh() * (NSEC_PER_SEC / 5); } /* Commands for resetting the watchdog */ @@ -182,7 +193,7 @@ static int is_softlockup(unsigned long touch_ts) unsigned long now = get_timestamp(smp_processor_id()); /* Warn about unreasonable delays: */ - if (time_after(now, touch_ts + watchdog_thresh)) + if (time_after(now, touch_ts + get_softlockup_thresh())) return now - touch_ts; return 0; @@ -359,7 +370,7 @@ static int watchdog_nmi_enable(int cpu) /* Try to register using hardware perf events */ wd_attr = &wd_hw_attr; - wd_attr->sample_period = hw_nmi_get_sample_period(); + wd_attr->sample_period = hw_nmi_get_sample_period(watchdog_thresh); event = perf_event_create_kernel_counter(wd_attr, cpu, NULL, watchdog_overflow_callback); if (!IS_ERR(event)) { printk(KERN_INFO "NMI watchdog enabled, takes one hw-pmu counter.\n"); -- cgit From 9ec2690758a5467f24beb301cca5098078073bba Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 20 May 2011 16:18:50 +0200 Subject: timerfd: Manage cancelable timers in timerfd Peter is concerned about the extra scan of CLOCK_REALTIME_COS in the timer interrupt. Yes, I did not think about it, because the solution was so elegant. I didn't like the extra list in timerfd when it was proposed some time ago, but with a rcu based list the list walk it's less horrible than the original global lock, which was held over the list iteration. Requested-by: Peter Zijlstra Signed-off-by: Thomas Gleixner Reviewed-by: Peter Zijlstra --- fs/timerfd.c | 105 ++++++++++++++++++++++++++++++++++-------------- include/linux/hrtimer.h | 6 ++- include/linux/time.h | 6 --- include/linux/timerfd.h | 4 +- kernel/hrtimer.c | 94 +++++++++++++++---------------------------- 5 files changed, 113 insertions(+), 102 deletions(-) (limited to 'include/linux') diff --git a/fs/timerfd.c b/fs/timerfd.c index 7e14c9e7c4ee..f67acbdda5e8 100644 --- a/fs/timerfd.c +++ b/fs/timerfd.c @@ -22,6 +22,7 @@ #include #include #include +#include struct timerfd_ctx { struct hrtimer tmr; @@ -31,9 +32,14 @@ struct timerfd_ctx { u64 ticks; int expired; int clockid; + struct rcu_head rcu; + struct list_head clist; bool might_cancel; }; +static LIST_HEAD(cancel_list); +static DEFINE_SPINLOCK(cancel_lock); + /* * This gets called when the timer event triggers. We set the "expired" * flag, but we do not re-arm the timer (in case it's necessary, @@ -53,28 +59,69 @@ static enum hrtimer_restart timerfd_tmrproc(struct hrtimer *htmr) return HRTIMER_NORESTART; } -static ktime_t timerfd_get_remaining(struct timerfd_ctx *ctx) +/* + * Called when the clock was set to cancel the timers in the cancel + * list. + */ +void timerfd_clock_was_set(void) { - ktime_t remaining; + ktime_t moffs = ktime_get_monotonic_offset(); + struct timerfd_ctx *ctx; + unsigned long flags; - remaining = hrtimer_expires_remaining(&ctx->tmr); - return remaining.tv64 < 0 ? ktime_set(0, 0): remaining; + rcu_read_lock(); + list_for_each_entry_rcu(ctx, &cancel_list, clist) { + if (!ctx->might_cancel) + continue; + spin_lock_irqsave(&ctx->wqh.lock, flags); + if (ctx->moffs.tv64 != moffs.tv64) { + ctx->moffs.tv64 = KTIME_MAX; + wake_up_locked(&ctx->wqh); + } + spin_unlock_irqrestore(&ctx->wqh.lock, flags); + } + rcu_read_unlock(); } -static bool timerfd_canceled(struct timerfd_ctx *ctx) +static void timerfd_remove_cancel(struct timerfd_ctx *ctx) { - ktime_t moffs; + if (ctx->might_cancel) { + ctx->might_cancel = false; + spin_lock(&cancel_lock); + list_del_rcu(&ctx->clist); + spin_unlock(&cancel_lock); + } +} - if (!ctx->might_cancel) +static bool timerfd_canceled(struct timerfd_ctx *ctx) +{ + if (!ctx->might_cancel || ctx->moffs.tv64 != KTIME_MAX) return false; + ctx->moffs = ktime_get_monotonic_offset(); + return true; +} - moffs = ktime_get_monotonic_offset(); +static void timerfd_setup_cancel(struct timerfd_ctx *ctx, int flags) +{ + if (ctx->clockid == CLOCK_REALTIME && (flags & TFD_TIMER_ABSTIME) && + (flags & TFD_TIMER_CANCEL_ON_SET)) { + if (!ctx->might_cancel) { + ctx->might_cancel = true; + spin_lock(&cancel_lock); + list_add_rcu(&ctx->clist, &cancel_list); + spin_unlock(&cancel_lock); + } + } else if (ctx->might_cancel) { + timerfd_remove_cancel(ctx); + } +} - if (moffs.tv64 == ctx->moffs.tv64) - return false; +static ktime_t timerfd_get_remaining(struct timerfd_ctx *ctx) +{ + ktime_t remaining; - ctx->moffs = moffs; - return true; + remaining = hrtimer_expires_remaining(&ctx->tmr); + return remaining.tv64 < 0 ? ktime_set(0, 0): remaining; } static int timerfd_setup(struct timerfd_ctx *ctx, int flags, @@ -87,13 +134,6 @@ static int timerfd_setup(struct timerfd_ctx *ctx, int flags, htmode = (flags & TFD_TIMER_ABSTIME) ? HRTIMER_MODE_ABS: HRTIMER_MODE_REL; - ctx->might_cancel = false; - if (htmode == HRTIMER_MODE_ABS && ctx->clockid == CLOCK_REALTIME && - (flags & TFD_TIMER_CANCELON_SET)) { - clockid = CLOCK_REALTIME_COS; - ctx->might_cancel = true; - } - texp = timespec_to_ktime(ktmr->it_value); ctx->expired = 0; ctx->ticks = 0; @@ -113,8 +153,9 @@ static int timerfd_release(struct inode *inode, struct file *file) { struct timerfd_ctx *ctx = file->private_data; + timerfd_remove_cancel(ctx); hrtimer_cancel(&ctx->tmr); - kfree(ctx); + kfree_rcu(ctx, rcu); return 0; } @@ -149,20 +190,20 @@ static ssize_t timerfd_read(struct file *file, char __user *buf, size_t count, else res = wait_event_interruptible_locked_irq(ctx->wqh, ctx->ticks); + /* + * If clock has changed, we do not care about the + * ticks and we do not rearm the timer. Userspace must + * reevaluate anyway. + */ + if (timerfd_canceled(ctx)) { + ctx->ticks = 0; + ctx->expired = 0; + res = -ECANCELED; + } + if (ctx->ticks) { ticks = ctx->ticks; - /* - * If clock has changed, we do not care about the - * ticks and we do not rearm the timer. Userspace must - * reevaluate anyway. - */ - if (timerfd_canceled(ctx)) { - ticks = 0; - ctx->expired = 0; - res = -ECANCELED; - } - if (ctx->expired && ctx->tintv.tv64) { /* * If tintv.tv64 != 0, this is a periodic timer that @@ -258,6 +299,8 @@ SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags, return PTR_ERR(file); ctx = file->private_data; + timerfd_setup_cancel(ctx, flags); + /* * We need to stop the existing timer before reprogramming * it to the new values. diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index eda4ccde0730..925c8c01db7b 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -155,7 +155,6 @@ enum hrtimer_base_type { HRTIMER_BASE_REALTIME, HRTIMER_BASE_MONOTONIC, HRTIMER_BASE_BOOTTIME, - HRTIMER_BASE_REALTIME_COS, HRTIMER_MAX_CLOCK_BASES, }; @@ -306,6 +305,11 @@ static inline int hrtimer_is_hres_active(struct hrtimer *timer) #endif extern void clock_was_set(void); +#ifdef CONFIG_TIMERFD +extern void timerfd_clock_was_set(void); +#else +static inline void timerfd_clock_was_set(void) { } +#endif extern void hrtimers_resume(void); extern ktime_t ktime_get(void); diff --git a/include/linux/time.h b/include/linux/time.h index a9242773eb24..b3061782dec3 100644 --- a/include/linux/time.h +++ b/include/linux/time.h @@ -302,12 +302,6 @@ struct itimerval { * The IDs of various hardware clocks: */ #define CLOCK_SGI_CYCLE 10 - -#ifdef __KERNEL__ -/* This clock is not exposed to user space */ -#define CLOCK_REALTIME_COS 15 -#endif - #define MAX_CLOCKS 16 #define CLOCKS_MASK (CLOCK_REALTIME | CLOCK_MONOTONIC) #define CLOCKS_MONO CLOCK_MONOTONIC diff --git a/include/linux/timerfd.h b/include/linux/timerfd.h index e9571fc8f1a0..d3b57fa12225 100644 --- a/include/linux/timerfd.h +++ b/include/linux/timerfd.h @@ -19,7 +19,7 @@ * shared O_* flags. */ #define TFD_TIMER_ABSTIME (1 << 0) -#define TFD_TIMER_CANCELON_SET (1 << 1) +#define TFD_TIMER_CANCEL_ON_SET (1 << 1) #define TFD_CLOEXEC O_CLOEXEC #define TFD_NONBLOCK O_NONBLOCK @@ -27,6 +27,6 @@ /* Flags for timerfd_create. */ #define TFD_CREATE_FLAGS TFD_SHARED_FCNTL_FLAGS /* Flags for timerfd_settime. */ -#define TFD_SETTIME_FLAGS (TFD_TIMER_ABSTIME | TFD_TIMER_CANCELON_SET) +#define TFD_SETTIME_FLAGS (TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET) #endif /* _LINUX_TIMERFD_H */ diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index eabcbd781433..26dd32f9f6b2 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -78,11 +78,6 @@ DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) = .get_time = &ktime_get_boottime, .resolution = KTIME_LOW_RES, }, - { - .index = CLOCK_REALTIME_COS, - .get_time = &ktime_get_real, - .resolution = KTIME_LOW_RES, - }, } }; @@ -90,7 +85,6 @@ static const int hrtimer_clock_to_base_table[MAX_CLOCKS] = { [CLOCK_REALTIME] = HRTIMER_BASE_REALTIME, [CLOCK_MONOTONIC] = HRTIMER_BASE_MONOTONIC, [CLOCK_BOOTTIME] = HRTIMER_BASE_BOOTTIME, - [CLOCK_REALTIME_COS] = HRTIMER_BASE_REALTIME_COS, }; static inline int hrtimer_clockid_to_base(clockid_t clock_id) @@ -116,7 +110,6 @@ static void hrtimer_get_softirq_time(struct hrtimer_cpu_base *base) base->clock_base[HRTIMER_BASE_REALTIME].softirq_time = xtim; base->clock_base[HRTIMER_BASE_MONOTONIC].softirq_time = mono; base->clock_base[HRTIMER_BASE_BOOTTIME].softirq_time = boot; - base->clock_base[HRTIMER_BASE_REALTIME_COS].softirq_time = xtim; } /* @@ -486,8 +479,6 @@ static inline void debug_deactivate(struct hrtimer *timer) trace_hrtimer_cancel(timer); } -static void hrtimer_expire_cancelable(struct hrtimer_cpu_base *cpu_base); - /* High resolution timer related functions */ #ifdef CONFIG_HIGH_RES_TIMERS @@ -663,7 +654,33 @@ static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer, return 0; } -static void retrigger_next_event(void *arg); +/* + * Retrigger next event is called after clock was set + * + * Called with interrupts disabled via on_each_cpu() + */ +static void retrigger_next_event(void *arg) +{ + struct hrtimer_cpu_base *base = &__get_cpu_var(hrtimer_bases); + struct timespec realtime_offset, xtim, wtm, sleep; + + if (!hrtimer_hres_active()) + return; + + /* Optimized out for !HIGH_RES */ + get_xtime_and_monotonic_and_sleep_offset(&xtim, &wtm, &sleep); + set_normalized_timespec(&realtime_offset, -wtm.tv_sec, -wtm.tv_nsec); + + /* Adjust CLOCK_REALTIME offset */ + raw_spin_lock(&base->lock); + base->clock_base[HRTIMER_BASE_REALTIME].offset = + timespec_to_ktime(realtime_offset); + base->clock_base[HRTIMER_BASE_BOOTTIME].offset = + timespec_to_ktime(sleep); + + hrtimer_force_reprogram(base, 0); + raw_spin_unlock(&base->lock); +} /* * Switch to high resolution mode @@ -711,45 +728,10 @@ static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer, return 0; } static inline void hrtimer_init_hres(struct hrtimer_cpu_base *base) { } +static inline void retrigger_next_event(void *arg) { } #endif /* CONFIG_HIGH_RES_TIMERS */ -/* - * Retrigger next event is called after clock was set - * - * Called with interrupts disabled via on_each_cpu() - */ -static void retrigger_next_event(void *arg) -{ - struct hrtimer_cpu_base *base = &__get_cpu_var(hrtimer_bases); - struct timespec realtime_offset, xtim, wtm, sleep; - - if (!hrtimer_hres_active()) { - raw_spin_lock(&base->lock); - hrtimer_expire_cancelable(base); - raw_spin_unlock(&base->lock); - return; - } - - /* Optimized out for !HIGH_RES */ - get_xtime_and_monotonic_and_sleep_offset(&xtim, &wtm, &sleep); - set_normalized_timespec(&realtime_offset, -wtm.tv_sec, -wtm.tv_nsec); - - /* Adjust CLOCK_REALTIME offset */ - raw_spin_lock(&base->lock); - base->clock_base[HRTIMER_BASE_REALTIME].offset = - timespec_to_ktime(realtime_offset); - base->clock_base[HRTIMER_BASE_BOOTTIME].offset = - timespec_to_ktime(sleep); - base->clock_base[HRTIMER_BASE_REALTIME_COS].offset = - timespec_to_ktime(realtime_offset); - - hrtimer_expire_cancelable(base); - - hrtimer_force_reprogram(base, 0); - raw_spin_unlock(&base->lock); -} - /* * Clock realtime was set * @@ -763,8 +745,11 @@ static void retrigger_next_event(void *arg) */ void clock_was_set(void) { +#ifdef CONFIG_HIGHRES_TIMERS /* Retrigger the CPU local events everywhere */ on_each_cpu(retrigger_next_event, NULL, 1); +#endif + timerfd_clock_was_set(); } /* @@ -777,6 +762,7 @@ void hrtimers_resume(void) KERN_INFO "hrtimers_resume() called with IRQs enabled!"); retrigger_next_event(NULL); + timerfd_clock_was_set(); } static inline void timer_stats_hrtimer_set_start_info(struct hrtimer *timer) @@ -1240,22 +1226,6 @@ static void __run_hrtimer(struct hrtimer *timer, ktime_t *now) timer->state &= ~HRTIMER_STATE_CALLBACK; } -static void hrtimer_expire_cancelable(struct hrtimer_cpu_base *cpu_base) -{ - struct timerqueue_node *node; - struct hrtimer_clock_base *base; - ktime_t now = ktime_get_real(); - - base = &cpu_base->clock_base[HRTIMER_BASE_REALTIME_COS]; - - while ((node = timerqueue_getnext(&base->active))) { - struct hrtimer *timer; - - timer = container_of(node, struct hrtimer, node); - __run_hrtimer(timer, &now); - } -} - #ifdef CONFIG_HIGH_RES_TIMERS /* -- cgit From f24444b01bf6c51c300fd3ffc73423383d747882 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 20 May 2011 13:02:58 +0200 Subject: hrtimers: Make struct hrtimer_cpu_base layout less stupid In the HIGHRES=y case we access the members at the end of struct hrtimer_cpu_base first and then the one at the beginning. Move the hrtimer data to front, so we have linear progressing access. Signed-off-by: Thomas Gleixner Reviewed-by: Peter Zijlstra --- include/linux/hrtimer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 925c8c01db7b..cc5f5f51db10 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -174,7 +174,6 @@ enum hrtimer_base_type { */ struct hrtimer_cpu_base { raw_spinlock_t lock; - struct hrtimer_clock_base clock_base[HRTIMER_MAX_CLOCK_BASES]; #ifdef CONFIG_HIGH_RES_TIMERS ktime_t expires_next; int hres_active; @@ -184,6 +183,7 @@ struct hrtimer_cpu_base { unsigned long nr_hangs; ktime_t max_hang_time; #endif + struct hrtimer_clock_base clock_base[HRTIMER_MAX_CLOCK_BASES]; }; static inline void hrtimer_set_expires(struct hrtimer *timer, ktime_t time) -- cgit From ab8177bc53e8ae3a3ba6d200ce2c2dae263f7ee5 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 20 May 2011 13:05:15 +0200 Subject: hrtimers: Avoid touching inactive timer bases Instead of iterating over all possible timer bases avoid it by marking the active bases in the cpu base. Signed-off-by: Thomas Gleixner Reviewed-by: Peter Zijlstra --- include/linux/hrtimer.h | 7 +++++-- include/linux/thread_info.h | 2 +- kernel/hrtimer.c | 29 ++++++++++++++++++----------- kernel/posix-cpu-timers.c | 4 ++-- kernel/posix-timers.c | 2 +- kernel/time/alarmtimer.c | 4 ++-- 6 files changed, 29 insertions(+), 19 deletions(-) (limited to 'include/linux') diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index cc5f5f51db10..771c95802edc 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -143,7 +143,8 @@ struct hrtimer_sleeper { */ struct hrtimer_clock_base { struct hrtimer_cpu_base *cpu_base; - clockid_t index; + int index; + clockid_t clockid; struct timerqueue_head active; ktime_t resolution; ktime_t (*get_time)(void); @@ -162,7 +163,7 @@ enum hrtimer_base_type { * struct hrtimer_cpu_base - the per cpu clock bases * @lock: lock protecting the base and associated clock bases * and timers - * @clock_base: array of clock bases for this cpu + * @active_bases: Bitfield to mark bases with active timers * @expires_next: absolute time of the next event which was scheduled * via clock_set_next_event() * @hres_active: State of high resolution mode @@ -171,9 +172,11 @@ enum hrtimer_base_type { * @nr_retries: Total number of hrtimer interrupt retries * @nr_hangs: Total number of hrtimer interrupt hangs * @max_hang_time: Maximum time spent in hrtimer_interrupt + * @clock_base: array of clock bases for this cpu */ struct hrtimer_cpu_base { raw_spinlock_t lock; + unsigned long active_bases; #ifdef CONFIG_HIGH_RES_TIMERS ktime_t expires_next; int hres_active; diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h index 20fc303947d3..8d03f079688c 100644 --- a/include/linux/thread_info.h +++ b/include/linux/thread_info.h @@ -29,7 +29,7 @@ struct restart_block { } futex; /* For nanosleep */ struct { - clockid_t index; + clockid_t clockid; struct timespec __user *rmtp; #ifdef CONFIG_COMPAT struct compat_timespec __user *compat_rmtp; diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index 26dd32f9f6b2..1b08f6d67f12 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -64,17 +64,20 @@ DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) = .clock_base = { { - .index = CLOCK_REALTIME, + .index = HRTIMER_BASE_REALTIME, + .clockid = CLOCK_REALTIME, .get_time = &ktime_get_real, .resolution = KTIME_LOW_RES, }, { - .index = CLOCK_MONOTONIC, + .index = HRTIMER_BASE_MONOTONIC, + .clockid = CLOCK_MONOTONIC, .get_time = &ktime_get, .resolution = KTIME_LOW_RES, }, { - .index = CLOCK_BOOTTIME, + .index = HRTIMER_BASE_BOOTTIME, + .clockid = CLOCK_BOOTTIME, .get_time = &ktime_get_boottime, .resolution = KTIME_LOW_RES, }, @@ -196,7 +199,7 @@ switch_hrtimer_base(struct hrtimer *timer, struct hrtimer_clock_base *base, struct hrtimer_cpu_base *new_cpu_base; int this_cpu = smp_processor_id(); int cpu = hrtimer_get_target(this_cpu, pinned); - int basenum = hrtimer_clockid_to_base(base->index); + int basenum = base->index; again: new_cpu_base = &per_cpu(hrtimer_bases, cpu); @@ -857,6 +860,7 @@ static int enqueue_hrtimer(struct hrtimer *timer, debug_activate(timer); timerqueue_add(&base->active, &timer->node); + base->cpu_base->active_bases |= 1 << base->index; /* * HRTIMER_STATE_ENQUEUED is or'ed to the current state to preserve the @@ -898,6 +902,8 @@ static void __remove_hrtimer(struct hrtimer *timer, #endif } timerqueue_del(&base->active, &timer->node); + if (!timerqueue_getnext(&base->active)) + base->cpu_base->active_bases &= ~(1 << base->index); out: timer->state = newstate; } @@ -1235,7 +1241,6 @@ static void __run_hrtimer(struct hrtimer *timer, ktime_t *now) void hrtimer_interrupt(struct clock_event_device *dev) { struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases); - struct hrtimer_clock_base *base; ktime_t expires_next, now, entry_time, delta; int i, retries = 0; @@ -1257,12 +1262,15 @@ retry: */ cpu_base->expires_next.tv64 = KTIME_MAX; - base = cpu_base->clock_base; - for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) { - ktime_t basenow; + struct hrtimer_clock_base *base; struct timerqueue_node *node; + ktime_t basenow; + + if (!(cpu_base->active_bases & (1 << i))) + continue; + base = cpu_base->clock_base + i; basenow = ktime_add(now, base->offset); while ((node = timerqueue_getnext(&base->active))) { @@ -1295,7 +1303,6 @@ retry: __run_hrtimer(timer, &basenow); } - base++; } /* @@ -1526,7 +1533,7 @@ long __sched hrtimer_nanosleep_restart(struct restart_block *restart) struct timespec __user *rmtp; int ret = 0; - hrtimer_init_on_stack(&t.timer, restart->nanosleep.index, + hrtimer_init_on_stack(&t.timer, restart->nanosleep.clockid, HRTIMER_MODE_ABS); hrtimer_set_expires_tv64(&t.timer, restart->nanosleep.expires); @@ -1578,7 +1585,7 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp, restart = ¤t_thread_info()->restart_block; restart->fn = hrtimer_nanosleep_restart; - restart->nanosleep.index = t.timer.base->index; + restart->nanosleep.clockid = t.timer.base->clockid; restart->nanosleep.rmtp = rmtp; restart->nanosleep.expires = hrtimer_get_expires_tv64(&t.timer); diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c index 0791b13df7bf..58f405b581e7 100644 --- a/kernel/posix-cpu-timers.c +++ b/kernel/posix-cpu-timers.c @@ -1514,7 +1514,7 @@ static int posix_cpu_nsleep(const clockid_t which_clock, int flags, return -EFAULT; restart_block->fn = posix_cpu_nsleep_restart; - restart_block->nanosleep.index = which_clock; + restart_block->nanosleep.clockid = which_clock; restart_block->nanosleep.rmtp = rmtp; restart_block->nanosleep.expires = timespec_to_ns(rqtp); } @@ -1523,7 +1523,7 @@ static int posix_cpu_nsleep(const clockid_t which_clock, int flags, static long posix_cpu_nsleep_restart(struct restart_block *restart_block) { - clockid_t which_clock = restart_block->nanosleep.index; + clockid_t which_clock = restart_block->nanosleep.clockid; struct timespec t; struct itimerspec it; int error; diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c index e5498d7405c3..a1b5edf1bf92 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c @@ -1056,7 +1056,7 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, */ long clock_nanosleep_restart(struct restart_block *restart_block) { - clockid_t which_clock = restart_block->nanosleep.index; + clockid_t which_clock = restart_block->nanosleep.clockid; struct k_clock *kc = clockid_to_kclock(which_clock); if (WARN_ON_ONCE(!kc || !kc->nsleep_restart)) diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index c6027fe9a4e6..2d966244ea60 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -494,7 +494,7 @@ static int update_rmtp(ktime_t exp, enum alarmtimer_type type, */ static long __sched alarm_timer_nsleep_restart(struct restart_block *restart) { - enum alarmtimer_type type = restart->nanosleep.index; + enum alarmtimer_type type = restart->nanosleep.clockid; ktime_t exp; struct timespec __user *rmtp; struct alarm alarm; @@ -573,7 +573,7 @@ static int alarm_timer_nsleep(const clockid_t which_clock, int flags, restart = ¤t_thread_info()->restart_block; restart->fn = alarm_timer_nsleep_restart; - restart->nanosleep.index = type; + restart->nanosleep.clockid = type; restart->nanosleep.expires = exp.tv64; restart->nanosleep.rmtp = rmtp; ret = -ERESTART_RESTARTBLOCK; -- cgit From 68fa61c026057a39d6ccb850aa8785043afbee02 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 20 May 2011 23:14:04 +0200 Subject: hrtimers: Reorder clock bases The ordering of the clock bases is historical due to the CLOCK_REALTIME and CLOCK_MONOTONIC constants. Now the hrtimer bases have their own enumeration due to the gap between CLOCK_MONOTONIC and CLOCK_BOOTTIME. So we can be more clever as most timers end up on the CLOCK_MONOTONIC base due to the virtue of POSIX declaring that relative CLOCK_REALTIME timers are not affected by time changes. In desktop environments this is slowly changing as applications switch to absolute timers, but I've observed empty CLOCK_REALTIME bases often enough. There is no performance penalty or overhead when CLOCK_REALTIME timers are active, but in case they are not we don't skip over a full cache line. Signed-off-by: Thomas Gleixner Reviewed-by: Peter Zijlstra --- include/linux/hrtimer.h | 2 +- kernel/hrtimer.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 771c95802edc..51932e5acf7c 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -153,8 +153,8 @@ struct hrtimer_clock_base { }; enum hrtimer_base_type { - HRTIMER_BASE_REALTIME, HRTIMER_BASE_MONOTONIC, + HRTIMER_BASE_REALTIME, HRTIMER_BASE_BOOTTIME, HRTIMER_MAX_CLOCK_BASES, }; diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index 1b08f6d67f12..c541ee527ecb 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -63,18 +63,18 @@ DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) = .clock_base = { - { - .index = HRTIMER_BASE_REALTIME, - .clockid = CLOCK_REALTIME, - .get_time = &ktime_get_real, - .resolution = KTIME_LOW_RES, - }, { .index = HRTIMER_BASE_MONOTONIC, .clockid = CLOCK_MONOTONIC, .get_time = &ktime_get, .resolution = KTIME_LOW_RES, }, + { + .index = HRTIMER_BASE_REALTIME, + .clockid = CLOCK_REALTIME, + .get_time = &ktime_get_real, + .resolution = KTIME_LOW_RES, + }, { .index = HRTIMER_BASE_BOOTTIME, .clockid = CLOCK_BOOTTIME, -- cgit From 901025d2f3194b4868980c8ba80df4cc0aa1282c Mon Sep 17 00:00:00 2001 From: David Teigland Date: Wed, 2 Mar 2011 14:20:04 -0600 Subject: dlm: make plock operation killable Allow processes blocked on plock requests to be interrupted when they are killed. This leaves the problem of cleaning up the lock state in userspace. This has three parts: 1. Add a flag to unlock operations sent to userspace indicating the file is being closed. Userspace will then look for and clear any waiting plock operations that were abandoned by an interrupted process. 2. Queue an unlock-close operation (like in 1) to clean up userspace from an interrupted plock request. This is needed because the vfs will not send a cleanup-unlock if it sees no locks on the file, which it won't if the interrupted operation was the only one. 3. Do not use replies from userspace for unlock-close operations because they are unnecessary (they are just cleaning up for the process which did not make an unlock call). This also simplifies the new unlock-close generated from point 2. Signed-off-by: David Teigland --- fs/dlm/plock.c | 65 ++++++++++++++++++++++++++++++++++++++++++++--- include/linux/dlm_plock.h | 6 +++-- 2 files changed, 65 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/fs/dlm/plock.c b/fs/dlm/plock.c index 30d8b85febbf..e2b878004364 100644 --- a/fs/dlm/plock.c +++ b/fs/dlm/plock.c @@ -71,6 +71,36 @@ static void send_op(struct plock_op *op) wake_up(&send_wq); } +/* If a process was killed while waiting for the only plock on a file, + locks_remove_posix will not see any lock on the file so it won't + send an unlock-close to us to pass on to userspace to clean up the + abandoned waiter. So, we have to insert the unlock-close when the + lock call is interrupted. */ + +static void do_unlock_close(struct dlm_ls *ls, u64 number, + struct file *file, struct file_lock *fl) +{ + struct plock_op *op; + + op = kzalloc(sizeof(*op), GFP_NOFS); + if (!op) + return; + + op->info.optype = DLM_PLOCK_OP_UNLOCK; + op->info.pid = fl->fl_pid; + op->info.fsid = ls->ls_global_id; + op->info.number = number; + op->info.start = 0; + op->info.end = OFFSET_MAX; + if (fl->fl_lmops && fl->fl_lmops->fl_grant) + op->info.owner = (__u64) fl->fl_pid; + else + op->info.owner = (__u64)(long) fl->fl_owner; + + op->info.flags |= DLM_PLOCK_FL_CLOSE; + send_op(op); +} + int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file, int cmd, struct file_lock *fl) { @@ -114,9 +144,19 @@ int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file, send_op(op); - if (xop->callback == NULL) - wait_event(recv_wq, (op->done != 0)); - else { + if (xop->callback == NULL) { + rv = wait_event_killable(recv_wq, (op->done != 0)); + if (rv == -ERESTARTSYS) { + log_debug(ls, "dlm_posix_lock: wait killed %llx", + (unsigned long long)number); + spin_lock(&ops_lock); + list_del(&op->list); + spin_unlock(&ops_lock); + kfree(xop); + do_unlock_close(ls, number, file, fl); + goto out; + } + } else { rv = FILE_LOCK_DEFERRED; goto out; } @@ -233,6 +273,13 @@ int dlm_posix_unlock(dlm_lockspace_t *lockspace, u64 number, struct file *file, else op->info.owner = (__u64)(long) fl->fl_owner; + if (fl->fl_flags & FL_CLOSE) { + op->info.flags |= DLM_PLOCK_FL_CLOSE; + send_op(op); + rv = 0; + goto out; + } + send_op(op); wait_event(recv_wq, (op->done != 0)); @@ -334,7 +381,10 @@ static ssize_t dev_read(struct file *file, char __user *u, size_t count, spin_lock(&ops_lock); if (!list_empty(&send_list)) { op = list_entry(send_list.next, struct plock_op, list); - list_move(&op->list, &recv_list); + if (op->info.flags & DLM_PLOCK_FL_CLOSE) + list_del(&op->list); + else + list_move(&op->list, &recv_list); memcpy(&info, &op->info, sizeof(info)); } spin_unlock(&ops_lock); @@ -342,6 +392,13 @@ static ssize_t dev_read(struct file *file, char __user *u, size_t count, if (!op) return -EAGAIN; + /* there is no need to get a reply from userspace for unlocks + that were generated by the vfs cleaning up for a close + (the process did not make an unlock call). */ + + if (op->info.flags & DLM_PLOCK_FL_CLOSE) + kfree(op); + if (copy_to_user(u, &info, sizeof(info))) return -EFAULT; return sizeof(info); diff --git a/include/linux/dlm_plock.h b/include/linux/dlm_plock.h index 2dd21243104f..3b1cc1be419f 100644 --- a/include/linux/dlm_plock.h +++ b/include/linux/dlm_plock.h @@ -14,7 +14,7 @@ #define DLM_PLOCK_MISC_NAME "dlm_plock" #define DLM_PLOCK_VERSION_MAJOR 1 -#define DLM_PLOCK_VERSION_MINOR 1 +#define DLM_PLOCK_VERSION_MINOR 2 #define DLM_PLOCK_VERSION_PATCH 0 enum { @@ -23,12 +23,14 @@ enum { DLM_PLOCK_OP_GET, }; +#define DLM_PLOCK_FL_CLOSE 1 + struct dlm_plock_info { __u32 version[3]; __u8 optype; __u8 ex; __u8 wait; - __u8 pad; + __u8 flags; __u32 pid; __s32 nodeid; __s32 rv; -- cgit From 442c8176d2efa468577738e3a99a6e051f6e8e55 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 8 May 2011 14:06:52 +0100 Subject: clocksource: add common mmio clocksource Add a generic mmio clocksource, covering both 32-bit and 16-bit register access sizes, for up or down counters. This can be used to easily create clocksources for simple counter-based implementations. Cc: Alessandro Rubini Cc: Colin Cross Cc: Eric Miao Cc: Erik Gilling Acked-by: "Hans J. Koch" Cc: Imre Kaloz Cc: Krzysztof Halasa Cc: Kukjin Kim Cc: Lennert Buytenhek Cc: Linus Walleij Cc: linux-omap@vger.kernel.org Acked-by: Nicolas Pitre Cc: Olof Johansson Tested-by: Sascha Hauer Reviewed-by: Thomas Gleixner Tested-by: Tony Lindgren Reviewed-by: Viresh Kumar Cc: Wan ZongShun Signed-off-by: Russell King --- drivers/clocksource/Kconfig | 3 ++ drivers/clocksource/Makefile | 1 + drivers/clocksource/mmio.c | 73 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/clocksource.h | 8 +++++ 4 files changed, 85 insertions(+) create mode 100644 drivers/clocksource/mmio.c (limited to 'include/linux') diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 110aeeb52f9a..96c921910469 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -1,2 +1,5 @@ config CLKSRC_I8253 bool + +config CLKSRC_MMIO + bool diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index cfb6383b543a..b995942a5060 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -7,3 +7,4 @@ obj-$(CONFIG_SH_TIMER_CMT) += sh_cmt.o obj-$(CONFIG_SH_TIMER_MTU2) += sh_mtu2.o obj-$(CONFIG_SH_TIMER_TMU) += sh_tmu.o obj-$(CONFIG_CLKSRC_I8253) += i8253.o +obj-$(CONFIG_CLKSRC_MMIO) += mmio.o diff --git a/drivers/clocksource/mmio.c b/drivers/clocksource/mmio.c new file mode 100644 index 000000000000..c0e25125a55e --- /dev/null +++ b/drivers/clocksource/mmio.c @@ -0,0 +1,73 @@ +/* + * Generic MMIO clocksource support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include + +struct clocksource_mmio { + void __iomem *reg; + struct clocksource clksrc; +}; + +static inline struct clocksource_mmio *to_mmio_clksrc(struct clocksource *c) +{ + return container_of(c, struct clocksource_mmio, clksrc); +} + +cycle_t clocksource_mmio_readl_up(struct clocksource *c) +{ + return readl_relaxed(to_mmio_clksrc(c)->reg); +} + +cycle_t clocksource_mmio_readl_down(struct clocksource *c) +{ + return ~readl_relaxed(to_mmio_clksrc(c)->reg); +} + +cycle_t clocksource_mmio_readw_up(struct clocksource *c) +{ + return readw_relaxed(to_mmio_clksrc(c)->reg); +} + +cycle_t clocksource_mmio_readw_down(struct clocksource *c) +{ + return ~(unsigned)readw_relaxed(to_mmio_clksrc(c)->reg); +} + +/** + * clocksource_mmio_init - Initialize a simple mmio based clocksource + * @base: Virtual address of the clock readout register + * @name: Name of the clocksource + * @hz: Frequency of the clocksource in Hz + * @rating: Rating of the clocksource + * @bits: Number of valid bits + * @read: One of clocksource_mmio_read*() above + */ +int __init clocksource_mmio_init(void __iomem *base, const char *name, + unsigned long hz, int rating, unsigned bits, + cycle_t (*read)(struct clocksource *)) +{ + struct clocksource_mmio *cs; + + if (bits > 32 || bits < 16) + return -EINVAL; + + cs = kzalloc(sizeof(struct clocksource_mmio), GFP_KERNEL); + if (!cs) + return -ENOMEM; + + cs->reg = base; + cs->clksrc.name = name; + cs->clksrc.rating = rating; + cs->clksrc.read = read; + cs->clksrc.mask = CLOCKSOURCE_MASK(bits); + cs->clksrc.flags = CLOCK_SOURCE_IS_CONTINUOUS; + + return clocksource_register_hz(&cs->clksrc, hz); +} diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h index c918fbd33ee5..d4646b48dc4a 100644 --- a/include/linux/clocksource.h +++ b/include/linux/clocksource.h @@ -337,6 +337,14 @@ static inline void update_vsyscall_tz(void) extern void timekeeping_notify(struct clocksource *clock); +extern cycle_t clocksource_mmio_readl_up(struct clocksource *); +extern cycle_t clocksource_mmio_readl_down(struct clocksource *); +extern cycle_t clocksource_mmio_readw_up(struct clocksource *); +extern cycle_t clocksource_mmio_readw_down(struct clocksource *); + +extern int clocksource_mmio_init(void __iomem *, const char *, + unsigned long, int, unsigned, cycle_t (*)(struct clocksource *)); + extern int clocksource_i8253_init(void); #endif /* _LINUX_CLOCKSOURCE_H */ -- cgit From d94ba80ebbea17f036cecb104398fbcd788aa742 Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Fri, 22 Apr 2011 12:03:08 +0200 Subject: ptp: Added a brand new class driver for ptp clocks. This patch adds an infrastructure for hardware clocks that implement IEEE 1588, the Precision Time Protocol (PTP). A class driver offers a registration method to particular hardware clock drivers. Each clock is presented as a standard POSIX clock. The ancillary clock features are exposed in two different ways, via the sysfs and by a character device. Signed-off-by: Richard Cochran Acked-by: Arnd Bergmann Acked-by: David S. Miller Signed-off-by: John Stultz --- Documentation/ABI/testing/sysfs-ptp | 98 ++++++++++ Documentation/ptp/ptp.txt | 89 +++++++++ Documentation/ptp/testptp.c | 381 ++++++++++++++++++++++++++++++++++++ Documentation/ptp/testptp.mk | 33 ++++ drivers/Kconfig | 2 + drivers/Makefile | 1 + drivers/ptp/Kconfig | 30 +++ drivers/ptp/Makefile | 6 + drivers/ptp/ptp_chardev.c | 159 +++++++++++++++ drivers/ptp/ptp_clock.c | 343 ++++++++++++++++++++++++++++++++ drivers/ptp/ptp_private.h | 92 +++++++++ drivers/ptp/ptp_sysfs.c | 230 ++++++++++++++++++++++ include/linux/Kbuild | 1 + include/linux/ptp_classify.h | 7 + include/linux/ptp_clock.h | 84 ++++++++ include/linux/ptp_clock_kernel.h | 139 +++++++++++++ 16 files changed, 1695 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-ptp create mode 100644 Documentation/ptp/ptp.txt create mode 100644 Documentation/ptp/testptp.c create mode 100644 Documentation/ptp/testptp.mk create mode 100644 drivers/ptp/Kconfig create mode 100644 drivers/ptp/Makefile create mode 100644 drivers/ptp/ptp_chardev.c create mode 100644 drivers/ptp/ptp_clock.c create mode 100644 drivers/ptp/ptp_private.h create mode 100644 drivers/ptp/ptp_sysfs.c create mode 100644 include/linux/ptp_clock.h create mode 100644 include/linux/ptp_clock_kernel.h (limited to 'include/linux') diff --git a/Documentation/ABI/testing/sysfs-ptp b/Documentation/ABI/testing/sysfs-ptp new file mode 100644 index 000000000000..d40d2b550502 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-ptp @@ -0,0 +1,98 @@ +What: /sys/class/ptp/ +Date: September 2010 +Contact: Richard Cochran +Description: + This directory contains files and directories + providing a standardized interface to the ancillary + features of PTP hardware clocks. + +What: /sys/class/ptp/ptpN/ +Date: September 2010 +Contact: Richard Cochran +Description: + This directory contains the attributes of the Nth PTP + hardware clock registered into the PTP class driver + subsystem. + +What: /sys/class/ptp/ptpN/clock_name +Date: September 2010 +Contact: Richard Cochran +Description: + This file contains the name of the PTP hardware clock + as a human readable string. + +What: /sys/class/ptp/ptpN/max_adjustment +Date: September 2010 +Contact: Richard Cochran +Description: + This file contains the PTP hardware clock's maximum + frequency adjustment value (a positive integer) in + parts per billion. + +What: /sys/class/ptp/ptpN/n_alarms +Date: September 2010 +Contact: Richard Cochran +Description: + This file contains the number of periodic or one shot + alarms offer by the PTP hardware clock. + +What: /sys/class/ptp/ptpN/n_external_timestamps +Date: September 2010 +Contact: Richard Cochran +Description: + This file contains the number of external timestamp + channels offered by the PTP hardware clock. + +What: /sys/class/ptp/ptpN/n_periodic_outputs +Date: September 2010 +Contact: Richard Cochran +Description: + This file contains the number of programmable periodic + output channels offered by the PTP hardware clock. + +What: /sys/class/ptp/ptpN/pps_avaiable +Date: September 2010 +Contact: Richard Cochran +Description: + This file indicates whether the PTP hardware clock + supports a Pulse Per Second to the host CPU. Reading + "1" means that the PPS is supported, while "0" means + not supported. + +What: /sys/class/ptp/ptpN/extts_enable +Date: September 2010 +Contact: Richard Cochran +Description: + This write-only file enables or disables external + timestamps. To enable external timestamps, write the + channel index followed by a "1" into the file. + To disable external timestamps, write the channel + index followed by a "0" into the file. + +What: /sys/class/ptp/ptpN/fifo +Date: September 2010 +Contact: Richard Cochran +Description: + This file provides timestamps on external events, in + the form of three integers: channel index, seconds, + and nanoseconds. + +What: /sys/class/ptp/ptpN/period +Date: September 2010 +Contact: Richard Cochran +Description: + This write-only file enables or disables periodic + outputs. To enable a periodic output, write five + integers into the file: channel index, start time + seconds, start time nanoseconds, period seconds, and + period nanoseconds. To disable a periodic output, set + all the seconds and nanoseconds values to zero. + +What: /sys/class/ptp/ptpN/pps_enable +Date: September 2010 +Contact: Richard Cochran +Description: + This write-only file enables or disables delivery of + PPS events to the Linux PPS subsystem. To enable PPS + events, write a "1" into the file. To disable events, + write a "0" into the file. diff --git a/Documentation/ptp/ptp.txt b/Documentation/ptp/ptp.txt new file mode 100644 index 000000000000..ae8fef86b832 --- /dev/null +++ b/Documentation/ptp/ptp.txt @@ -0,0 +1,89 @@ + +* PTP hardware clock infrastructure for Linux + + This patch set introduces support for IEEE 1588 PTP clocks in + Linux. Together with the SO_TIMESTAMPING socket options, this + presents a standardized method for developing PTP user space + programs, synchronizing Linux with external clocks, and using the + ancillary features of PTP hardware clocks. + + A new class driver exports a kernel interface for specific clock + drivers and a user space interface. The infrastructure supports a + complete set of PTP hardware clock functionality. + + + Basic clock operations + - Set time + - Get time + - Shift the clock by a given offset atomically + - Adjust clock frequency + + + Ancillary clock features + - One short or periodic alarms, with signal delivery to user program + - Time stamp external events + - Period output signals configurable from user space + - Synchronization of the Linux system time via the PPS subsystem + +** PTP hardware clock kernel API + + A PTP clock driver registers itself with the class driver. The + class driver handles all of the dealings with user space. The + author of a clock driver need only implement the details of + programming the clock hardware. The clock driver notifies the class + driver of asynchronous events (alarms and external time stamps) via + a simple message passing interface. + + The class driver supports multiple PTP clock drivers. In normal use + cases, only one PTP clock is needed. However, for testing and + development, it can be useful to have more than one clock in a + single system, in order to allow performance comparisons. + +** PTP hardware clock user space API + + The class driver also creates a character device for each + registered clock. User space can use an open file descriptor from + the character device as a POSIX clock id and may call + clock_gettime, clock_settime, and clock_adjtime. These calls + implement the basic clock operations. + + User space programs may control the clock using standardized + ioctls. A program may query, enable, configure, and disable the + ancillary clock features. User space can receive time stamped + events via blocking read() and poll(). One shot and periodic + signals may be configured via the POSIX timer_settime() system + call. + +** Writing clock drivers + + Clock drivers include include/linux/ptp_clock_kernel.h and register + themselves by presenting a 'struct ptp_clock_info' to the + registration method. Clock drivers must implement all of the + functions in the interface. If a clock does not offer a particular + ancillary feature, then the driver should just return -EOPNOTSUPP + from those functions. + + Drivers must ensure that all of the methods in interface are + reentrant. Since most hardware implementations treat the time value + as a 64 bit integer accessed as two 32 bit registers, drivers + should use spin_lock_irqsave/spin_unlock_irqrestore to protect + against concurrent access. This locking cannot be accomplished in + class driver, since the lock may also be needed by the clock + driver's interrupt service routine. + +** Supported hardware + + + Freescale eTSEC gianfar + - 2 Time stamp external triggers, programmable polarity (opt. interrupt) + - 2 Alarm registers (optional interrupt) + - 3 Periodic signals (optional interrupt) + + + National DP83640 + - 6 GPIOs programmable as inputs or outputs + - 6 GPIOs with dedicated functions (LED/JTAG/clock) can also be + used as general inputs or outputs + - GPIO inputs can time stamp external triggers + - GPIO outputs can produce periodic signals + - 1 interrupt pin + + + Intel IXP465 + - Auxiliary Slave/Master Mode Snapshot (optional interrupt) + - Target Time (optional interrupt) diff --git a/Documentation/ptp/testptp.c b/Documentation/ptp/testptp.c new file mode 100644 index 000000000000..f59ded066108 --- /dev/null +++ b/Documentation/ptp/testptp.c @@ -0,0 +1,381 @@ +/* + * PTP 1588 clock support - User space test program + * + * Copyright (C) 2010 OMICRON electronics GmbH + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define DEVICE "/dev/ptp0" + +#ifndef ADJ_SETOFFSET +#define ADJ_SETOFFSET 0x0100 +#endif + +#ifndef CLOCK_INVALID +#define CLOCK_INVALID -1 +#endif + +/* When glibc offers the syscall, this will go away. */ +#include +static int clock_adjtime(clockid_t id, struct timex *tx) +{ + return syscall(__NR_clock_adjtime, id, tx); +} + +static clockid_t get_clockid(int fd) +{ +#define CLOCKFD 3 +#define FD_TO_CLOCKID(fd) ((~(clockid_t) (fd) << 3) | CLOCKFD) + + return FD_TO_CLOCKID(fd); +} + +static void handle_alarm(int s) +{ + printf("received signal %d\n", s); +} + +static int install_handler(int signum, void (*handler)(int)) +{ + struct sigaction action; + sigset_t mask; + + /* Unblock the signal. */ + sigemptyset(&mask); + sigaddset(&mask, signum); + sigprocmask(SIG_UNBLOCK, &mask, NULL); + + /* Install the signal handler. */ + action.sa_handler = handler; + action.sa_flags = 0; + sigemptyset(&action.sa_mask); + sigaction(signum, &action, NULL); + + return 0; +} + +static long ppb_to_scaled_ppm(int ppb) +{ + /* + * The 'freq' field in the 'struct timex' is in parts per + * million, but with a 16 bit binary fractional field. + * Instead of calculating either one of + * + * scaled_ppm = (ppb / 1000) << 16 [1] + * scaled_ppm = (ppb << 16) / 1000 [2] + * + * we simply use double precision math, in order to avoid the + * truncation in [1] and the possible overflow in [2]. + */ + return (long) (ppb * 65.536); +} + +static void usage(char *progname) +{ + fprintf(stderr, + "usage: %s [options]\n" + " -a val request a one-shot alarm after 'val' seconds\n" + " -A val request a periodic alarm every 'val' seconds\n" + " -c query the ptp clock's capabilities\n" + " -d name device to open\n" + " -e val read 'val' external time stamp events\n" + " -f val adjust the ptp clock frequency by 'val' ppb\n" + " -g get the ptp clock time\n" + " -h prints this message\n" + " -p val enable output with a period of 'val' nanoseconds\n" + " -P val enable or disable (val=1|0) the system clock PPS\n" + " -s set the ptp clock time from the system time\n" + " -S set the system time from the ptp clock time\n" + " -t val shift the ptp clock time by 'val' seconds\n", + progname); +} + +int main(int argc, char *argv[]) +{ + struct ptp_clock_caps caps; + struct ptp_extts_event event; + struct ptp_extts_request extts_request; + struct ptp_perout_request perout_request; + struct timespec ts; + struct timex tx; + + static timer_t timerid; + struct itimerspec timeout; + struct sigevent sigevent; + + char *progname; + int c, cnt, fd; + + char *device = DEVICE; + clockid_t clkid; + int adjfreq = 0x7fffffff; + int adjtime = 0; + int capabilities = 0; + int extts = 0; + int gettime = 0; + int oneshot = 0; + int periodic = 0; + int perout = -1; + int pps = -1; + int settime = 0; + + progname = strrchr(argv[0], '/'); + progname = progname ? 1+progname : argv[0]; + while (EOF != (c = getopt(argc, argv, "a:A:cd:e:f:ghp:P:sSt:v"))) { + switch (c) { + case 'a': + oneshot = atoi(optarg); + break; + case 'A': + periodic = atoi(optarg); + break; + case 'c': + capabilities = 1; + break; + case 'd': + device = optarg; + break; + case 'e': + extts = atoi(optarg); + break; + case 'f': + adjfreq = atoi(optarg); + break; + case 'g': + gettime = 1; + break; + case 'p': + perout = atoi(optarg); + break; + case 'P': + pps = atoi(optarg); + break; + case 's': + settime = 1; + break; + case 'S': + settime = 2; + break; + case 't': + adjtime = atoi(optarg); + break; + case 'h': + usage(progname); + return 0; + case '?': + default: + usage(progname); + return -1; + } + } + + fd = open(device, O_RDWR); + if (fd < 0) { + fprintf(stderr, "opening %s: %s\n", device, strerror(errno)); + return -1; + } + + clkid = get_clockid(fd); + if (CLOCK_INVALID == clkid) { + fprintf(stderr, "failed to read clock id\n"); + return -1; + } + + if (capabilities) { + if (ioctl(fd, PTP_CLOCK_GETCAPS, &caps)) { + perror("PTP_CLOCK_GETCAPS"); + } else { + printf("capabilities:\n" + " %d maximum frequency adjustment (ppb)\n" + " %d programmable alarms\n" + " %d external time stamp channels\n" + " %d programmable periodic signals\n" + " %d pulse per second\n", + caps.max_adj, + caps.n_alarm, + caps.n_ext_ts, + caps.n_per_out, + caps.pps); + } + } + + if (0x7fffffff != adjfreq) { + memset(&tx, 0, sizeof(tx)); + tx.modes = ADJ_FREQUENCY; + tx.freq = ppb_to_scaled_ppm(adjfreq); + if (clock_adjtime(clkid, &tx)) { + perror("clock_adjtime"); + } else { + puts("frequency adjustment okay"); + } + } + + if (adjtime) { + memset(&tx, 0, sizeof(tx)); + tx.modes = ADJ_SETOFFSET; + tx.time.tv_sec = adjtime; + tx.time.tv_usec = 0; + if (clock_adjtime(clkid, &tx) < 0) { + perror("clock_adjtime"); + } else { + puts("time shift okay"); + } + } + + if (gettime) { + if (clock_gettime(clkid, &ts)) { + perror("clock_gettime"); + } else { + printf("clock time: %ld.%09ld or %s", + ts.tv_sec, ts.tv_nsec, ctime(&ts.tv_sec)); + } + } + + if (settime == 1) { + clock_gettime(CLOCK_REALTIME, &ts); + if (clock_settime(clkid, &ts)) { + perror("clock_settime"); + } else { + puts("set time okay"); + } + } + + if (settime == 2) { + clock_gettime(clkid, &ts); + if (clock_settime(CLOCK_REALTIME, &ts)) { + perror("clock_settime"); + } else { + puts("set time okay"); + } + } + + if (extts) { + memset(&extts_request, 0, sizeof(extts_request)); + extts_request.index = 0; + extts_request.flags = PTP_ENABLE_FEATURE; + if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) { + perror("PTP_EXTTS_REQUEST"); + extts = 0; + } else { + puts("external time stamp request okay"); + } + for (; extts; extts--) { + cnt = read(fd, &event, sizeof(event)); + if (cnt != sizeof(event)) { + perror("read"); + break; + } + printf("event index %u at %lld.%09u\n", event.index, + event.t.sec, event.t.nsec); + fflush(stdout); + } + /* Disable the feature again. */ + extts_request.flags = 0; + if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) { + perror("PTP_EXTTS_REQUEST"); + } + } + + if (oneshot) { + install_handler(SIGALRM, handle_alarm); + /* Create a timer. */ + sigevent.sigev_notify = SIGEV_SIGNAL; + sigevent.sigev_signo = SIGALRM; + if (timer_create(clkid, &sigevent, &timerid)) { + perror("timer_create"); + return -1; + } + /* Start the timer. */ + memset(&timeout, 0, sizeof(timeout)); + timeout.it_value.tv_sec = oneshot; + if (timer_settime(timerid, 0, &timeout, NULL)) { + perror("timer_settime"); + return -1; + } + pause(); + timer_delete(timerid); + } + + if (periodic) { + install_handler(SIGALRM, handle_alarm); + /* Create a timer. */ + sigevent.sigev_notify = SIGEV_SIGNAL; + sigevent.sigev_signo = SIGALRM; + if (timer_create(clkid, &sigevent, &timerid)) { + perror("timer_create"); + return -1; + } + /* Start the timer. */ + memset(&timeout, 0, sizeof(timeout)); + timeout.it_interval.tv_sec = periodic; + timeout.it_value.tv_sec = periodic; + if (timer_settime(timerid, 0, &timeout, NULL)) { + perror("timer_settime"); + return -1; + } + while (1) { + pause(); + } + timer_delete(timerid); + } + + if (perout >= 0) { + if (clock_gettime(clkid, &ts)) { + perror("clock_gettime"); + return -1; + } + memset(&perout_request, 0, sizeof(perout_request)); + perout_request.index = 0; + perout_request.start.sec = ts.tv_sec + 2; + perout_request.start.nsec = 0; + perout_request.period.sec = 0; + perout_request.period.nsec = perout; + if (ioctl(fd, PTP_PEROUT_REQUEST, &perout_request)) { + perror("PTP_PEROUT_REQUEST"); + } else { + puts("periodic output request okay"); + } + } + + if (pps != -1) { + int enable = pps ? 1 : 0; + if (ioctl(fd, PTP_ENABLE_PPS, enable)) { + perror("PTP_ENABLE_PPS"); + } else { + puts("pps for system time request okay"); + } + } + + close(fd); + return 0; +} diff --git a/Documentation/ptp/testptp.mk b/Documentation/ptp/testptp.mk new file mode 100644 index 000000000000..4ef2d9755421 --- /dev/null +++ b/Documentation/ptp/testptp.mk @@ -0,0 +1,33 @@ +# PTP 1588 clock support - User space test program +# +# Copyright (C) 2010 OMICRON electronics GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +CC = $(CROSS_COMPILE)gcc +INC = -I$(KBUILD_OUTPUT)/usr/include +CFLAGS = -Wall $(INC) +LDLIBS = -lrt +PROGS = testptp + +all: $(PROGS) + +testptp: testptp.o + +clean: + rm -f testptp.o + +distclean: clean + rm -f $(PROGS) diff --git a/drivers/Kconfig b/drivers/Kconfig index 61631edfecc2..3bb154d8c8cc 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -54,6 +54,8 @@ source "drivers/spi/Kconfig" source "drivers/pps/Kconfig" +source "drivers/ptp/Kconfig" + source "drivers/gpio/Kconfig" source "drivers/w1/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index a29527f4ded6..3c2960128a7f 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -76,6 +76,7 @@ obj-$(CONFIG_I2O) += message/ obj-$(CONFIG_RTC_LIB) += rtc/ obj-y += i2c/ media/ obj-$(CONFIG_PPS) += pps/ +obj-$(CONFIG_PTP_1588_CLOCK) += ptp/ obj-$(CONFIG_W1) += w1/ obj-$(CONFIG_POWER_SUPPLY) += power/ obj-$(CONFIG_HWMON) += hwmon/ diff --git a/drivers/ptp/Kconfig b/drivers/ptp/Kconfig new file mode 100644 index 000000000000..70d4bb1cbdab --- /dev/null +++ b/drivers/ptp/Kconfig @@ -0,0 +1,30 @@ +# +# PTP clock support configuration +# + +menu "PTP clock support" + +comment "Enable Device Drivers -> PPS to see the PTP clock options." + depends on PPS=n + +config PTP_1588_CLOCK + tristate "PTP clock support" + depends on EXPERIMENTAL + depends on PPS + help + The IEEE 1588 standard defines a method to precisely + synchronize distributed clocks over Ethernet networks. The + standard defines a Precision Time Protocol (PTP), which can + be used to achieve synchronization within a few dozen + microseconds. In addition, with the help of special hardware + time stamping units, it can be possible to achieve + synchronization to within a few hundred nanoseconds. + + This driver adds support for PTP clocks as character + devices. If you want to use a PTP clock, then you should + also enable at least one clock driver as well. + + To compile this driver as a module, choose M here: the module + will be called ptp. + +endmenu diff --git a/drivers/ptp/Makefile b/drivers/ptp/Makefile new file mode 100644 index 000000000000..480e2afdc999 --- /dev/null +++ b/drivers/ptp/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for PTP 1588 clock support. +# + +ptp-y := ptp_clock.o ptp_chardev.o ptp_sysfs.o +obj-$(CONFIG_PTP_1588_CLOCK) += ptp.o diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c new file mode 100644 index 000000000000..a8d03aeb4051 --- /dev/null +++ b/drivers/ptp/ptp_chardev.c @@ -0,0 +1,159 @@ +/* + * PTP 1588 clock support - character device implementation. + * + * Copyright (C) 2010 OMICRON electronics GmbH + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include + +#include "ptp_private.h" + +int ptp_open(struct posix_clock *pc, fmode_t fmode) +{ + return 0; +} + +long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg) +{ + struct ptp_clock_caps caps; + struct ptp_clock_request req; + struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); + struct ptp_clock_info *ops = ptp->info; + int enable, err = 0; + + switch (cmd) { + + case PTP_CLOCK_GETCAPS: + memset(&caps, 0, sizeof(caps)); + caps.max_adj = ptp->info->max_adj; + caps.n_alarm = ptp->info->n_alarm; + caps.n_ext_ts = ptp->info->n_ext_ts; + caps.n_per_out = ptp->info->n_per_out; + caps.pps = ptp->info->pps; + err = copy_to_user((void __user *)arg, &caps, sizeof(caps)); + break; + + case PTP_EXTTS_REQUEST: + if (copy_from_user(&req.extts, (void __user *)arg, + sizeof(req.extts))) { + err = -EFAULT; + break; + } + if (req.extts.index >= ops->n_ext_ts) { + err = -EINVAL; + break; + } + req.type = PTP_CLK_REQ_EXTTS; + enable = req.extts.flags & PTP_ENABLE_FEATURE ? 1 : 0; + err = ops->enable(ops, &req, enable); + break; + + case PTP_PEROUT_REQUEST: + if (copy_from_user(&req.perout, (void __user *)arg, + sizeof(req.perout))) { + err = -EFAULT; + break; + } + if (req.perout.index >= ops->n_per_out) { + err = -EINVAL; + break; + } + req.type = PTP_CLK_REQ_PEROUT; + enable = req.perout.period.sec || req.perout.period.nsec; + err = ops->enable(ops, &req, enable); + break; + + case PTP_ENABLE_PPS: + if (!capable(CAP_SYS_TIME)) + return -EPERM; + req.type = PTP_CLK_REQ_PPS; + enable = arg ? 1 : 0; + err = ops->enable(ops, &req, enable); + break; + + default: + err = -ENOTTY; + break; + } + return err; +} + +unsigned int ptp_poll(struct posix_clock *pc, struct file *fp, poll_table *wait) +{ + struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); + + poll_wait(fp, &ptp->tsev_wq, wait); + + return queue_cnt(&ptp->tsevq) ? POLLIN : 0; +} + +ssize_t ptp_read(struct posix_clock *pc, + uint rdflags, char __user *buf, size_t cnt) +{ + struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); + struct timestamp_event_queue *queue = &ptp->tsevq; + struct ptp_extts_event event[PTP_BUF_TIMESTAMPS]; + unsigned long flags; + size_t qcnt, i; + + if (cnt % sizeof(struct ptp_extts_event) != 0) + return -EINVAL; + + if (cnt > sizeof(event)) + cnt = sizeof(event); + + cnt = cnt / sizeof(struct ptp_extts_event); + + if (mutex_lock_interruptible(&ptp->tsevq_mux)) + return -ERESTARTSYS; + + if (wait_event_interruptible(ptp->tsev_wq, + ptp->defunct || queue_cnt(queue))) { + mutex_unlock(&ptp->tsevq_mux); + return -ERESTARTSYS; + } + + if (ptp->defunct) + return -ENODEV; + + spin_lock_irqsave(&queue->lock, flags); + + qcnt = queue_cnt(queue); + + if (cnt > qcnt) + cnt = qcnt; + + for (i = 0; i < cnt; i++) { + event[i] = queue->buf[queue->head]; + queue->head = (queue->head + 1) % PTP_MAX_TIMESTAMPS; + } + + spin_unlock_irqrestore(&queue->lock, flags); + + cnt = cnt * sizeof(struct ptp_extts_event); + + mutex_unlock(&ptp->tsevq_mux); + + if (copy_to_user(buf, event, cnt)) { + mutex_unlock(&ptp->tsevq_mux); + return -EFAULT; + } + + return cnt; +} diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c new file mode 100644 index 000000000000..cf3f9997546d --- /dev/null +++ b/drivers/ptp/ptp_clock.c @@ -0,0 +1,343 @@ +/* + * PTP 1588 clock support + * + * Copyright (C) 2010 OMICRON electronics GmbH + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ptp_private.h" + +#define PTP_MAX_ALARMS 4 +#define PTP_MAX_CLOCKS 8 +#define PTP_PPS_DEFAULTS (PPS_CAPTUREASSERT | PPS_OFFSETASSERT) +#define PTP_PPS_EVENT PPS_CAPTUREASSERT +#define PTP_PPS_MODE (PTP_PPS_DEFAULTS | PPS_CANWAIT | PPS_TSFMT_TSPEC) + +/* private globals */ + +static dev_t ptp_devt; +static struct class *ptp_class; + +static DECLARE_BITMAP(ptp_clocks_map, PTP_MAX_CLOCKS); +static DEFINE_MUTEX(ptp_clocks_mutex); /* protects 'ptp_clocks_map' */ + +/* time stamp event queue operations */ + +static inline int queue_free(struct timestamp_event_queue *q) +{ + return PTP_MAX_TIMESTAMPS - queue_cnt(q) - 1; +} + +static void enqueue_external_timestamp(struct timestamp_event_queue *queue, + struct ptp_clock_event *src) +{ + struct ptp_extts_event *dst; + unsigned long flags; + s64 seconds; + u32 remainder; + + seconds = div_u64_rem(src->timestamp, 1000000000, &remainder); + + spin_lock_irqsave(&queue->lock, flags); + + dst = &queue->buf[queue->tail]; + dst->index = src->index; + dst->t.sec = seconds; + dst->t.nsec = remainder; + + if (!queue_free(queue)) + queue->head = (queue->head + 1) % PTP_MAX_TIMESTAMPS; + + queue->tail = (queue->tail + 1) % PTP_MAX_TIMESTAMPS; + + spin_unlock_irqrestore(&queue->lock, flags); +} + +static s32 scaled_ppm_to_ppb(long ppm) +{ + /* + * The 'freq' field in the 'struct timex' is in parts per + * million, but with a 16 bit binary fractional field. + * + * We want to calculate + * + * ppb = scaled_ppm * 1000 / 2^16 + * + * which simplifies to + * + * ppb = scaled_ppm * 125 / 2^13 + */ + s64 ppb = 1 + ppm; + ppb *= 125; + ppb >>= 13; + return (s32) ppb; +} + +/* posix clock implementation */ + +static int ptp_clock_getres(struct posix_clock *pc, struct timespec *tp) +{ + return 1; /* always round timer functions to one nanosecond */ +} + +static int ptp_clock_settime(struct posix_clock *pc, const struct timespec *tp) +{ + struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); + return ptp->info->settime(ptp->info, tp); +} + +static int ptp_clock_gettime(struct posix_clock *pc, struct timespec *tp) +{ + struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); + return ptp->info->gettime(ptp->info, tp); +} + +static int ptp_clock_adjtime(struct posix_clock *pc, struct timex *tx) +{ + struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); + struct ptp_clock_info *ops; + int err = -EOPNOTSUPP; + + ops = ptp->info; + + if (tx->modes & ADJ_SETOFFSET) { + struct timespec ts; + ktime_t kt; + s64 delta; + + ts.tv_sec = tx->time.tv_sec; + ts.tv_nsec = tx->time.tv_usec; + + if (!(tx->modes & ADJ_NANO)) + ts.tv_nsec *= 1000; + + if ((unsigned long) ts.tv_nsec >= NSEC_PER_SEC) + return -EINVAL; + + kt = timespec_to_ktime(ts); + delta = ktime_to_ns(kt); + err = ops->adjtime(ops, delta); + + } else if (tx->modes & ADJ_FREQUENCY) { + + err = ops->adjfreq(ops, scaled_ppm_to_ppb(tx->freq)); + } + + return err; +} + +static struct posix_clock_operations ptp_clock_ops = { + .owner = THIS_MODULE, + .clock_adjtime = ptp_clock_adjtime, + .clock_gettime = ptp_clock_gettime, + .clock_getres = ptp_clock_getres, + .clock_settime = ptp_clock_settime, + .ioctl = ptp_ioctl, + .open = ptp_open, + .poll = ptp_poll, + .read = ptp_read, +}; + +static void delete_ptp_clock(struct posix_clock *pc) +{ + struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); + + mutex_destroy(&ptp->tsevq_mux); + + /* Remove the clock from the bit map. */ + mutex_lock(&ptp_clocks_mutex); + clear_bit(ptp->index, ptp_clocks_map); + mutex_unlock(&ptp_clocks_mutex); + + kfree(ptp); +} + +/* public interface */ + +struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info) +{ + struct ptp_clock *ptp; + int err = 0, index, major = MAJOR(ptp_devt); + + if (info->n_alarm > PTP_MAX_ALARMS) + return ERR_PTR(-EINVAL); + + /* Find a free clock slot and reserve it. */ + err = -EBUSY; + mutex_lock(&ptp_clocks_mutex); + index = find_first_zero_bit(ptp_clocks_map, PTP_MAX_CLOCKS); + if (index < PTP_MAX_CLOCKS) + set_bit(index, ptp_clocks_map); + else + goto no_slot; + + /* Initialize a clock structure. */ + err = -ENOMEM; + ptp = kzalloc(sizeof(struct ptp_clock), GFP_KERNEL); + if (ptp == NULL) + goto no_memory; + + ptp->clock.ops = ptp_clock_ops; + ptp->clock.release = delete_ptp_clock; + ptp->info = info; + ptp->devid = MKDEV(major, index); + ptp->index = index; + spin_lock_init(&ptp->tsevq.lock); + mutex_init(&ptp->tsevq_mux); + init_waitqueue_head(&ptp->tsev_wq); + + /* Create a new device in our class. */ + ptp->dev = device_create(ptp_class, NULL, ptp->devid, ptp, + "ptp%d", ptp->index); + if (IS_ERR(ptp->dev)) + goto no_device; + + dev_set_drvdata(ptp->dev, ptp); + + err = ptp_populate_sysfs(ptp); + if (err) + goto no_sysfs; + + /* Register a new PPS source. */ + if (info->pps) { + struct pps_source_info pps; + memset(&pps, 0, sizeof(pps)); + snprintf(pps.name, PPS_MAX_NAME_LEN, "ptp%d", index); + pps.mode = PTP_PPS_MODE; + pps.owner = info->owner; + ptp->pps_source = pps_register_source(&pps, PTP_PPS_DEFAULTS); + if (!ptp->pps_source) { + pr_err("failed to register pps source\n"); + goto no_pps; + } + } + + /* Create a posix clock. */ + err = posix_clock_register(&ptp->clock, ptp->devid); + if (err) { + pr_err("failed to create posix clock\n"); + goto no_clock; + } + + mutex_unlock(&ptp_clocks_mutex); + return ptp; + +no_clock: + if (ptp->pps_source) + pps_unregister_source(ptp->pps_source); +no_pps: + ptp_cleanup_sysfs(ptp); +no_sysfs: + device_destroy(ptp_class, ptp->devid); +no_device: + mutex_destroy(&ptp->tsevq_mux); + kfree(ptp); +no_memory: + clear_bit(index, ptp_clocks_map); +no_slot: + mutex_unlock(&ptp_clocks_mutex); + return ERR_PTR(err); +} +EXPORT_SYMBOL(ptp_clock_register); + +int ptp_clock_unregister(struct ptp_clock *ptp) +{ + ptp->defunct = 1; + wake_up_interruptible(&ptp->tsev_wq); + + /* Release the clock's resources. */ + if (ptp->pps_source) + pps_unregister_source(ptp->pps_source); + ptp_cleanup_sysfs(ptp); + device_destroy(ptp_class, ptp->devid); + + posix_clock_unregister(&ptp->clock); + return 0; +} +EXPORT_SYMBOL(ptp_clock_unregister); + +void ptp_clock_event(struct ptp_clock *ptp, struct ptp_clock_event *event) +{ + struct pps_event_time evt; + + switch (event->type) { + + case PTP_CLOCK_ALARM: + break; + + case PTP_CLOCK_EXTTS: + enqueue_external_timestamp(&ptp->tsevq, event); + wake_up_interruptible(&ptp->tsev_wq); + break; + + case PTP_CLOCK_PPS: + pps_get_ts(&evt); + pps_event(ptp->pps_source, &evt, PTP_PPS_EVENT, NULL); + break; + } +} +EXPORT_SYMBOL(ptp_clock_event); + +/* module operations */ + +static void __exit ptp_exit(void) +{ + class_destroy(ptp_class); + unregister_chrdev_region(ptp_devt, PTP_MAX_CLOCKS); +} + +static int __init ptp_init(void) +{ + int err; + + ptp_class = class_create(THIS_MODULE, "ptp"); + if (IS_ERR(ptp_class)) { + pr_err("ptp: failed to allocate class\n"); + return PTR_ERR(ptp_class); + } + + err = alloc_chrdev_region(&ptp_devt, 0, PTP_MAX_CLOCKS, "ptp"); + if (err < 0) { + pr_err("ptp: failed to allocate device region\n"); + goto no_region; + } + + ptp_class->dev_attrs = ptp_dev_attrs; + pr_info("PTP clock support registered\n"); + return 0; + +no_region: + class_destroy(ptp_class); + return err; +} + +subsys_initcall(ptp_init); +module_exit(ptp_exit); + +MODULE_AUTHOR("Richard Cochran "); +MODULE_DESCRIPTION("PTP clocks support"); +MODULE_LICENSE("GPL"); diff --git a/drivers/ptp/ptp_private.h b/drivers/ptp/ptp_private.h new file mode 100644 index 000000000000..4d5b5082c3b1 --- /dev/null +++ b/drivers/ptp/ptp_private.h @@ -0,0 +1,92 @@ +/* + * PTP 1588 clock support - private declarations for the core module. + * + * Copyright (C) 2010 OMICRON electronics GmbH + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#ifndef _PTP_PRIVATE_H_ +#define _PTP_PRIVATE_H_ + +#include +#include +#include +#include +#include +#include +#include + +#define PTP_MAX_TIMESTAMPS 128 +#define PTP_BUF_TIMESTAMPS 30 + +struct timestamp_event_queue { + struct ptp_extts_event buf[PTP_MAX_TIMESTAMPS]; + int head; + int tail; + spinlock_t lock; +}; + +struct ptp_clock { + struct posix_clock clock; + struct device *dev; + struct ptp_clock_info *info; + dev_t devid; + int index; /* index into clocks.map */ + struct pps_device *pps_source; + struct timestamp_event_queue tsevq; /* simple fifo for time stamps */ + struct mutex tsevq_mux; /* one process at a time reading the fifo */ + wait_queue_head_t tsev_wq; + int defunct; /* tells readers to go away when clock is being removed */ +}; + +/* + * The function queue_cnt() is safe for readers to call without + * holding q->lock. Readers use this function to verify that the queue + * is nonempty before proceeding with a dequeue operation. The fact + * that a writer might concurrently increment the tail does not + * matter, since the queue remains nonempty nonetheless. + */ +static inline int queue_cnt(struct timestamp_event_queue *q) +{ + int cnt = q->tail - q->head; + return cnt < 0 ? PTP_MAX_TIMESTAMPS + cnt : cnt; +} + +/* + * see ptp_chardev.c + */ + +long ptp_ioctl(struct posix_clock *pc, + unsigned int cmd, unsigned long arg); + +int ptp_open(struct posix_clock *pc, fmode_t fmode); + +ssize_t ptp_read(struct posix_clock *pc, + uint flags, char __user *buf, size_t cnt); + +uint ptp_poll(struct posix_clock *pc, + struct file *fp, poll_table *wait); + +/* + * see ptp_sysfs.c + */ + +extern struct device_attribute ptp_dev_attrs[]; + +int ptp_cleanup_sysfs(struct ptp_clock *ptp); + +int ptp_populate_sysfs(struct ptp_clock *ptp); + +#endif diff --git a/drivers/ptp/ptp_sysfs.c b/drivers/ptp/ptp_sysfs.c new file mode 100644 index 000000000000..2f93926ac976 --- /dev/null +++ b/drivers/ptp/ptp_sysfs.c @@ -0,0 +1,230 @@ +/* + * PTP 1588 clock support - sysfs interface. + * + * Copyright (C) 2010 OMICRON electronics GmbH + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include + +#include "ptp_private.h" + +static ssize_t clock_name_show(struct device *dev, + struct device_attribute *attr, char *page) +{ + struct ptp_clock *ptp = dev_get_drvdata(dev); + return snprintf(page, PAGE_SIZE-1, "%s\n", ptp->info->name); +} + +#define PTP_SHOW_INT(name) \ +static ssize_t name##_show(struct device *dev, \ + struct device_attribute *attr, char *page) \ +{ \ + struct ptp_clock *ptp = dev_get_drvdata(dev); \ + return snprintf(page, PAGE_SIZE-1, "%d\n", ptp->info->name); \ +} + +PTP_SHOW_INT(max_adj); +PTP_SHOW_INT(n_alarm); +PTP_SHOW_INT(n_ext_ts); +PTP_SHOW_INT(n_per_out); +PTP_SHOW_INT(pps); + +#define PTP_RO_ATTR(_var, _name) { \ + .attr = { .name = __stringify(_name), .mode = 0444 }, \ + .show = _var##_show, \ +} + +struct device_attribute ptp_dev_attrs[] = { + PTP_RO_ATTR(clock_name, clock_name), + PTP_RO_ATTR(max_adj, max_adjustment), + PTP_RO_ATTR(n_alarm, n_alarms), + PTP_RO_ATTR(n_ext_ts, n_external_timestamps), + PTP_RO_ATTR(n_per_out, n_periodic_outputs), + PTP_RO_ATTR(pps, pps_available), + __ATTR_NULL, +}; + +static ssize_t extts_enable_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ptp_clock *ptp = dev_get_drvdata(dev); + struct ptp_clock_info *ops = ptp->info; + struct ptp_clock_request req = { .type = PTP_CLK_REQ_EXTTS }; + int cnt, enable; + int err = -EINVAL; + + cnt = sscanf(buf, "%u %d", &req.extts.index, &enable); + if (cnt != 2) + goto out; + if (req.extts.index >= ops->n_ext_ts) + goto out; + + err = ops->enable(ops, &req, enable ? 1 : 0); + if (err) + goto out; + + return count; +out: + return err; +} + +static ssize_t extts_fifo_show(struct device *dev, + struct device_attribute *attr, char *page) +{ + struct ptp_clock *ptp = dev_get_drvdata(dev); + struct timestamp_event_queue *queue = &ptp->tsevq; + struct ptp_extts_event event; + unsigned long flags; + size_t qcnt; + int cnt = 0; + + memset(&event, 0, sizeof(event)); + + if (mutex_lock_interruptible(&ptp->tsevq_mux)) + return -ERESTARTSYS; + + spin_lock_irqsave(&queue->lock, flags); + qcnt = queue_cnt(queue); + if (qcnt) { + event = queue->buf[queue->head]; + queue->head = (queue->head + 1) % PTP_MAX_TIMESTAMPS; + } + spin_unlock_irqrestore(&queue->lock, flags); + + if (!qcnt) + goto out; + + cnt = snprintf(page, PAGE_SIZE, "%u %lld %u\n", + event.index, event.t.sec, event.t.nsec); +out: + mutex_unlock(&ptp->tsevq_mux); + return cnt; +} + +static ssize_t period_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ptp_clock *ptp = dev_get_drvdata(dev); + struct ptp_clock_info *ops = ptp->info; + struct ptp_clock_request req = { .type = PTP_CLK_REQ_PEROUT }; + int cnt, enable, err = -EINVAL; + + cnt = sscanf(buf, "%u %lld %u %lld %u", &req.perout.index, + &req.perout.start.sec, &req.perout.start.nsec, + &req.perout.period.sec, &req.perout.period.nsec); + if (cnt != 5) + goto out; + if (req.perout.index >= ops->n_per_out) + goto out; + + enable = req.perout.period.sec || req.perout.period.nsec; + err = ops->enable(ops, &req, enable); + if (err) + goto out; + + return count; +out: + return err; +} + +static ssize_t pps_enable_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ptp_clock *ptp = dev_get_drvdata(dev); + struct ptp_clock_info *ops = ptp->info; + struct ptp_clock_request req = { .type = PTP_CLK_REQ_PPS }; + int cnt, enable; + int err = -EINVAL; + + if (!capable(CAP_SYS_TIME)) + return -EPERM; + + cnt = sscanf(buf, "%d", &enable); + if (cnt != 1) + goto out; + + err = ops->enable(ops, &req, enable ? 1 : 0); + if (err) + goto out; + + return count; +out: + return err; +} + +static DEVICE_ATTR(extts_enable, 0220, NULL, extts_enable_store); +static DEVICE_ATTR(fifo, 0444, extts_fifo_show, NULL); +static DEVICE_ATTR(period, 0220, NULL, period_store); +static DEVICE_ATTR(pps_enable, 0220, NULL, pps_enable_store); + +int ptp_cleanup_sysfs(struct ptp_clock *ptp) +{ + struct device *dev = ptp->dev; + struct ptp_clock_info *info = ptp->info; + + if (info->n_ext_ts) { + device_remove_file(dev, &dev_attr_extts_enable); + device_remove_file(dev, &dev_attr_fifo); + } + if (info->n_per_out) + device_remove_file(dev, &dev_attr_period); + + if (info->pps) + device_remove_file(dev, &dev_attr_pps_enable); + + return 0; +} + +int ptp_populate_sysfs(struct ptp_clock *ptp) +{ + struct device *dev = ptp->dev; + struct ptp_clock_info *info = ptp->info; + int err; + + if (info->n_ext_ts) { + err = device_create_file(dev, &dev_attr_extts_enable); + if (err) + goto out1; + err = device_create_file(dev, &dev_attr_fifo); + if (err) + goto out2; + } + if (info->n_per_out) { + err = device_create_file(dev, &dev_attr_period); + if (err) + goto out3; + } + if (info->pps) { + err = device_create_file(dev, &dev_attr_pps_enable); + if (err) + goto out4; + } + return 0; +out4: + if (info->n_per_out) + device_remove_file(dev, &dev_attr_period); +out3: + if (info->n_ext_ts) + device_remove_file(dev, &dev_attr_fifo); +out2: + if (info->n_ext_ts) + device_remove_file(dev, &dev_attr_extts_enable); +out1: + return err; +} diff --git a/include/linux/Kbuild b/include/linux/Kbuild index 75cf611641e6..4585836ba664 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild @@ -302,6 +302,7 @@ header-y += ppp-comp.h header-y += ppp_defs.h header-y += pps.h header-y += prctl.h +header-y += ptp_clock.h header-y += ptrace.h header-y += qnx4_fs.h header-y += qnxtypes.h diff --git a/include/linux/ptp_classify.h b/include/linux/ptp_classify.h index 943a85ab0020..e07e2742a865 100644 --- a/include/linux/ptp_classify.h +++ b/include/linux/ptp_classify.h @@ -25,6 +25,7 @@ #include #include +#include #include #ifdef __KERNEL__ #include @@ -58,6 +59,12 @@ #define OFF_NEXT 6 #define OFF_UDP_DST 2 +#define OFF_PTP_SOURCE_UUID 22 /* PTPv1 only */ +#define OFF_PTP_SEQUENCE_ID 30 +#define OFF_PTP_CONTROL 32 /* PTPv1 only */ + +#define IPV4_HLEN(data) (((struct iphdr *)(data + OFF_IHL))->ihl << 2) + #define IP6_HLEN 40 #define UDP_HLEN 8 diff --git a/include/linux/ptp_clock.h b/include/linux/ptp_clock.h new file mode 100644 index 000000000000..94e981f810a2 --- /dev/null +++ b/include/linux/ptp_clock.h @@ -0,0 +1,84 @@ +/* + * PTP 1588 clock support - user space interface + * + * Copyright (C) 2010 OMICRON electronics GmbH + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _PTP_CLOCK_H_ +#define _PTP_CLOCK_H_ + +#include +#include + +/* PTP_xxx bits, for the flags field within the request structures. */ +#define PTP_ENABLE_FEATURE (1<<0) +#define PTP_RISING_EDGE (1<<1) +#define PTP_FALLING_EDGE (1<<2) + +/* + * struct ptp_clock_time - represents a time value + * + * The sign of the seconds field applies to the whole value. The + * nanoseconds field is always unsigned. The reserved field is + * included for sub-nanosecond resolution, should the demand for + * this ever appear. + * + */ +struct ptp_clock_time { + __s64 sec; /* seconds */ + __u32 nsec; /* nanoseconds */ + __u32 reserved; +}; + +struct ptp_clock_caps { + int max_adj; /* Maximum frequency adjustment in parts per billon. */ + int n_alarm; /* Number of programmable alarms. */ + int n_ext_ts; /* Number of external time stamp channels. */ + int n_per_out; /* Number of programmable periodic signals. */ + int pps; /* Whether the clock supports a PPS callback. */ + int rsv[15]; /* Reserved for future use. */ +}; + +struct ptp_extts_request { + unsigned int index; /* Which channel to configure. */ + unsigned int flags; /* Bit field for PTP_xxx flags. */ + unsigned int rsv[2]; /* Reserved for future use. */ +}; + +struct ptp_perout_request { + struct ptp_clock_time start; /* Absolute start time. */ + struct ptp_clock_time period; /* Desired period, zero means disable. */ + unsigned int index; /* Which channel to configure. */ + unsigned int flags; /* Reserved for future use. */ + unsigned int rsv[4]; /* Reserved for future use. */ +}; + +#define PTP_CLK_MAGIC '=' + +#define PTP_CLOCK_GETCAPS _IOR(PTP_CLK_MAGIC, 1, struct ptp_clock_caps) +#define PTP_EXTTS_REQUEST _IOW(PTP_CLK_MAGIC, 2, struct ptp_extts_request) +#define PTP_PEROUT_REQUEST _IOW(PTP_CLK_MAGIC, 3, struct ptp_perout_request) +#define PTP_ENABLE_PPS _IOW(PTP_CLK_MAGIC, 4, int) + +struct ptp_extts_event { + struct ptp_clock_time t; /* Time event occured. */ + unsigned int index; /* Which channel produced the event. */ + unsigned int flags; /* Reserved for future use. */ + unsigned int rsv[2]; /* Reserved for future use. */ +}; + +#endif diff --git a/include/linux/ptp_clock_kernel.h b/include/linux/ptp_clock_kernel.h new file mode 100644 index 000000000000..dd2e44fba63e --- /dev/null +++ b/include/linux/ptp_clock_kernel.h @@ -0,0 +1,139 @@ +/* + * PTP 1588 clock support + * + * Copyright (C) 2010 OMICRON electronics GmbH + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _PTP_CLOCK_KERNEL_H_ +#define _PTP_CLOCK_KERNEL_H_ + +#include + + +struct ptp_clock_request { + enum { + PTP_CLK_REQ_EXTTS, + PTP_CLK_REQ_PEROUT, + PTP_CLK_REQ_PPS, + } type; + union { + struct ptp_extts_request extts; + struct ptp_perout_request perout; + }; +}; + +/** + * struct ptp_clock_info - decribes a PTP hardware clock + * + * @owner: The clock driver should set to THIS_MODULE. + * @name: A short name to identify the clock. + * @max_adj: The maximum possible frequency adjustment, in parts per billon. + * @n_alarm: The number of programmable alarms. + * @n_ext_ts: The number of external time stamp channels. + * @n_per_out: The number of programmable periodic signals. + * @pps: Indicates whether the clock supports a PPS callback. + * + * clock operations + * + * @adjfreq: Adjusts the frequency of the hardware clock. + * parameter delta: Desired period change in parts per billion. + * + * @adjtime: Shifts the time of the hardware clock. + * parameter delta: Desired change in nanoseconds. + * + * @gettime: Reads the current time from the hardware clock. + * parameter ts: Holds the result. + * + * @settime: Set the current time on the hardware clock. + * parameter ts: Time value to set. + * + * @enable: Request driver to enable or disable an ancillary feature. + * parameter request: Desired resource to enable or disable. + * parameter on: Caller passes one to enable or zero to disable. + * + * Drivers should embed their ptp_clock_info within a private + * structure, obtaining a reference to it using container_of(). + * + * The callbacks must all return zero on success, non-zero otherwise. + */ + +struct ptp_clock_info { + struct module *owner; + char name[16]; + s32 max_adj; + int n_alarm; + int n_ext_ts; + int n_per_out; + int pps; + int (*adjfreq)(struct ptp_clock_info *ptp, s32 delta); + int (*adjtime)(struct ptp_clock_info *ptp, s64 delta); + int (*gettime)(struct ptp_clock_info *ptp, struct timespec *ts); + int (*settime)(struct ptp_clock_info *ptp, const struct timespec *ts); + int (*enable)(struct ptp_clock_info *ptp, + struct ptp_clock_request *request, int on); +}; + +struct ptp_clock; + +/** + * ptp_clock_register() - register a PTP hardware clock driver + * + * @info: Structure describing the new clock. + */ + +extern struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info); + +/** + * ptp_clock_unregister() - unregister a PTP hardware clock driver + * + * @ptp: The clock to remove from service. + */ + +extern int ptp_clock_unregister(struct ptp_clock *ptp); + + +enum ptp_clock_events { + PTP_CLOCK_ALARM, + PTP_CLOCK_EXTTS, + PTP_CLOCK_PPS, +}; + +/** + * struct ptp_clock_event - decribes a PTP hardware clock event + * + * @type: One of the ptp_clock_events enumeration values. + * @index: Identifies the source of the event. + * @timestamp: When the event occured. + */ + +struct ptp_clock_event { + int type; + int index; + u64 timestamp; +}; + +/** + * ptp_clock_event() - notify the PTP layer about an event + * + * @ptp: The clock obtained from ptp_clock_register(). + * @event: Message structure describing the event. + */ + +extern void ptp_clock_event(struct ptp_clock *ptp, + struct ptp_clock_event *event); + +#endif -- cgit From 600942e0fdb7ed1565d056d7305c46c7c0544a3e Mon Sep 17 00:00:00 2001 From: Lars Ellenberg Date: Thu, 27 Jan 2011 15:24:58 +0100 Subject: lru_cache.h: fix comments referring to ts_ instead of lc_ For some time we contemplated calling the "struct lru_cache" a "struct tracked_set", and some comments kept the ts_ prefix. Fix those to match the member field names. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- include/linux/lru_cache.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/lru_cache.h b/include/linux/lru_cache.h index 6a4fab7c6e09..7a71ffad037c 100644 --- a/include/linux/lru_cache.h +++ b/include/linux/lru_cache.h @@ -139,9 +139,9 @@ write intent log information, three of which are mentioned here. * .list is on one of three lists: * in_use: currently in use (refcnt > 0, lc_number != LC_FREE) * lru: unused but ready to be reused or recycled - * (ts_refcnt == 0, lc_number != LC_FREE), + * (lc_refcnt == 0, lc_number != LC_FREE), * free: unused but ready to be recycled - * (ts_refcnt == 0, lc_number == LC_FREE), + * (lc_refcnt == 0, lc_number == LC_FREE), * * an element is said to be "in the active set", * if either on "in_use" or "lru", i.e. lc_number != LC_FREE. @@ -160,8 +160,8 @@ struct lc_element { struct hlist_node colision; struct list_head list; /* LRU list or free list */ unsigned refcnt; - /* back "pointer" into ts_cache->element[index], - * for paranoia, and for "ts_element_to_index" */ + /* back "pointer" into lc_cache->element[index], + * for paranoia, and for "lc_element_to_index" */ unsigned lc_index; /* if we want to track a larger set of objects, * it needs to become arch independend u64 */ @@ -190,8 +190,8 @@ struct lru_cache { /* Arbitrary limit on maximum tracked objects. Practical limit is much * lower due to allocation failures, probably. For typical use cases, * nr_elements should be a few thousand at most. - * This also limits the maximum value of ts_element.ts_index, allowing the - * 8 high bits of .ts_index to be overloaded with flags in the future. */ + * This also limits the maximum value of lc_element.lc_index, allowing the + * 8 high bits of .lc_index to be overloaded with flags in the future. */ #define LC_MAX_ACTIVE (1<<24) /* statistics */ -- cgit From 9a0d9d0389ef769e4b01abf50fcc11407706270b Mon Sep 17 00:00:00 2001 From: Lars Ellenberg Date: Mon, 2 May 2011 11:51:31 +0200 Subject: drbd: fix schedule in atomic An administrative detach used to request a state change directly to D_DISKLESS, first suspending IO to avoid the last put_ldev() occuring from an endio handler, potentially in irq context. This is not enough on the receiving side (typically secondary), we may miss some peer_req on the way to local disk, which then may do the last put_ldev() from their drbd_peer_request_endio(). This patch makes the detach always go through the intermediate D_FAILED state. We may consider to rename it D_DETACHING. Alternative approach would be to create yet an other work item to be scheduled on the worker, do the destructor work from there, and get the timing right. manually picked commit 564040f from the drbd 8.4 branch. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_int.h | 4 ++++ drivers/block/drbd/drbd_nl.c | 14 +++++++++++--- include/linux/drbd.h | 2 +- 3 files changed, 16 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 8aa10391115b..a74d3ee04ba8 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -2157,6 +2157,10 @@ static inline int get_net_conf(struct drbd_conf *mdev) static inline void put_ldev(struct drbd_conf *mdev) { int i = atomic_dec_return(&mdev->local_cnt); + + /* This may be called from some endio handler, + * so we must not sleep here. */ + __release(local); D_ASSERT(i >= 0); if (i == 0) { diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 7c64ec042124..13569635b922 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -1334,11 +1334,19 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp static int drbd_nl_detach(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, struct drbd_nl_cfg_reply *reply) { + enum drbd_ret_code retcode; + int ret; drbd_suspend_io(mdev); /* so no-one is stuck in drbd_al_begin_io */ - reply->ret_code = drbd_request_state(mdev, NS(disk, D_DISKLESS)); - if (mdev->state.disk == D_DISKLESS) - wait_event(mdev->misc_wait, !atomic_read(&mdev->local_cnt)); + retcode = drbd_request_state(mdev, NS(disk, D_FAILED)); + /* D_FAILED will transition to DISKLESS. */ + ret = wait_event_interruptible(mdev->misc_wait, + mdev->state.disk != D_FAILED); drbd_resume_io(mdev); + if (retcode == SS_IS_DISKLESS) + retcode = SS_NOTHING_TO_DO; + if (ret) + retcode = ERR_INTR; + reply->ret_code = retcode; return 0; } diff --git a/include/linux/drbd.h b/include/linux/drbd.h index cec467f5d676..c86283b4fbab 100644 --- a/include/linux/drbd.h +++ b/include/linux/drbd.h @@ -53,7 +53,7 @@ extern const char *drbd_buildtag(void); -#define REL_VERSION "8.3.10" +#define REL_VERSION "8.3.11" #define API_VERSION 88 #define PRO_VERSION_MIN 86 #define PRO_VERSION_MAX 96 -- cgit From 24c4830c8ec3cbc904d84c213126a35f41a4e455 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 21 May 2011 18:32:29 +0200 Subject: drbd: Fix spelling Found these with the help of ispell -l. Signed-off-by: Bart Van Assche Signed-off-by: Lars Ellenberg Signed-off-by: Philipp Reisner --- drivers/block/drbd/drbd_actlog.c | 2 +- drivers/block/drbd/drbd_bitmap.c | 6 +++--- drivers/block/drbd/drbd_int.h | 6 +++--- drivers/block/drbd/drbd_main.c | 4 ++-- drivers/block/drbd/drbd_nl.c | 6 +++--- drivers/block/drbd/drbd_receiver.c | 30 +++++++++++++++--------------- drivers/block/drbd/drbd_req.c | 18 +++++++++--------- drivers/block/drbd/drbd_req.h | 4 ++-- drivers/block/drbd/drbd_worker.c | 4 ++-- include/linux/drbd.h | 8 ++++---- include/linux/drbd_tag_magic.h | 2 +- 11 files changed, 45 insertions(+), 45 deletions(-) (limited to 'include/linux') diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c index c6828b68d77b..09ef9a878ef0 100644 --- a/drivers/block/drbd/drbd_actlog.c +++ b/drivers/block/drbd/drbd_actlog.c @@ -28,7 +28,7 @@ #include "drbd_int.h" #include "drbd_wrappers.h" -/* We maintain a trivial check sum in our on disk activity log. +/* We maintain a trivial checksum in our on disk activity log. * With that we can ensure correct operation even when the storage * device might do a partial (last) sector write while losing power. */ diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c index 76210ba401ac..f440a02dfdb1 100644 --- a/drivers/block/drbd/drbd_bitmap.c +++ b/drivers/block/drbd/drbd_bitmap.c @@ -74,7 +74,7 @@ * as we are "attached" to a local disk, which at 32 GiB for 1PiB storage * seems excessive. * - * We plan to reduce the amount of in-core bitmap pages by pageing them in + * We plan to reduce the amount of in-core bitmap pages by paging them in * and out against their on-disk location as necessary, but need to make * sure we don't cause too much meta data IO, and must not deadlock in * tight memory situations. This needs some more work. @@ -200,7 +200,7 @@ void drbd_bm_unlock(struct drbd_conf *mdev) * we if bits have been cleared since last IO. */ #define BM_PAGE_LAZY_WRITEOUT 28 -/* store_page_idx uses non-atomic assingment. It is only used directly after +/* store_page_idx uses non-atomic assignment. It is only used directly after * allocating the page. All other bm_set_page_* and bm_clear_page_* need to * use atomic bit manipulation, as set_out_of_sync (and therefore bitmap * changes) may happen from various contexts, and wait_on_bit/wake_up_bit @@ -318,7 +318,7 @@ static void bm_unmap(unsigned long *p_addr) /* word offset from start of bitmap to word number _in_page_ * modulo longs per page #define MLPP(X) ((X) % (PAGE_SIZE/sizeof(long)) - hm, well, Philipp thinks gcc might not optimze the % into & (... - 1) + hm, well, Philipp thinks gcc might not optimize the % into & (... - 1) so do it explicitly: */ #define MLPP(X) ((X) & ((PAGE_SIZE/sizeof(long))-1)) diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index a74d3ee04ba8..7952eb90d17f 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -699,7 +699,7 @@ struct drbd_request { * see drbd_endio_pri(). */ struct bio *private_bio; - struct hlist_node colision; + struct hlist_node collision; sector_t sector; unsigned int size; unsigned int epoch; /* barrier_nr */ @@ -765,7 +765,7 @@ struct digest_info { struct drbd_epoch_entry { struct drbd_work w; - struct hlist_node colision; + struct hlist_node collision; struct drbd_epoch *epoch; /* for writes */ struct drbd_conf *mdev; struct page *pages; @@ -1520,7 +1520,7 @@ extern void drbd_resume_io(struct drbd_conf *mdev); extern char *ppsize(char *buf, unsigned long long size); extern sector_t drbd_new_dev_size(struct drbd_conf *, struct drbd_backing_dev *, int); enum determine_dev_size { dev_size_error = -1, unchanged = 0, shrunk = 1, grew = 2 }; -extern enum determine_dev_size drbd_determin_dev_size(struct drbd_conf *, enum dds_flags) __must_hold(local); +extern enum determine_dev_size drbd_determine_dev_size(struct drbd_conf *, enum dds_flags) __must_hold(local); extern void resync_after_online_grow(struct drbd_conf *); extern void drbd_reconsider_max_bio_size(struct drbd_conf *mdev); extern enum drbd_state_rv drbd_set_role(struct drbd_conf *mdev, diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index cfeb13b5a216..0358e55356c8 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -2732,7 +2732,7 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req) /* double check digest, sometimes buffers have been modified in flight. */ if (dgs > 0 && dgs <= 64) { - /* 64 byte, 512 bit, is the larges digest size + /* 64 byte, 512 bit, is the largest digest size * currently supported in kernel crypto. */ unsigned char digest[64]; drbd_csum_bio(mdev, mdev->integrity_w_tfm, req->master_bio, digest); @@ -3287,7 +3287,7 @@ static void drbd_delete_device(unsigned int minor) drbd_release_ee_lists(mdev); - /* should be free'd on disconnect? */ + /* should be freed on disconnect? */ kfree(mdev->ee_hash); /* mdev->ee_hash_s = 0; diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 13569635b922..259ca0b20961 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -596,7 +596,7 @@ void drbd_resume_io(struct drbd_conf *mdev) * Returns 0 on success, negative return values indicate errors. * You should call drbd_md_sync() after calling this function. */ -enum determine_dev_size drbd_determin_dev_size(struct drbd_conf *mdev, enum dds_flags flags) __must_hold(local) +enum determine_dev_size drbd_determine_dev_size(struct drbd_conf *mdev, enum dds_flags flags) __must_hold(local) { sector_t prev_first_sect, prev_size; /* previous meta location */ sector_t la_size; @@ -1205,7 +1205,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp !drbd_md_test_flag(mdev->ldev, MDF_CONNECTED_IND)) set_bit(USE_DEGR_WFC_T, &mdev->flags); - dd = drbd_determin_dev_size(mdev, 0); + dd = drbd_determine_dev_size(mdev, 0); if (dd == dev_size_error) { retcode = ERR_NOMEM_BITMAP; goto force_diskless_dec; @@ -1719,7 +1719,7 @@ static int drbd_nl_resize(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, mdev->ldev->dc.disk_size = (sector_t)rs.resize_size; ddsf = (rs.resize_force ? DDSF_FORCED : 0) | (rs.no_resync ? DDSF_NO_RESYNC : 0); - dd = drbd_determin_dev_size(mdev, ddsf); + dd = drbd_determine_dev_size(mdev, ddsf); drbd_md_sync(mdev); put_ldev(mdev); if (dd == dev_size_error) { diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 6ea0a4b51ece..d9f2109fd9e6 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -333,7 +333,7 @@ struct drbd_epoch_entry *drbd_alloc_ee(struct drbd_conf *mdev, if (!page) goto fail; - INIT_HLIST_NODE(&e->colision); + INIT_HLIST_NODE(&e->collision); e->epoch = NULL; e->mdev = mdev; e->pages = page; @@ -356,7 +356,7 @@ void drbd_free_some_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e, int i kfree(e->digest); drbd_pp_free(mdev, e->pages, is_net); D_ASSERT(atomic_read(&e->pending_bios) == 0); - D_ASSERT(hlist_unhashed(&e->colision)); + D_ASSERT(hlist_unhashed(&e->collision)); mempool_free(e, drbd_ee_mempool); } @@ -1413,7 +1413,7 @@ static int e_end_resync_block(struct drbd_conf *mdev, struct drbd_work *w, int u sector_t sector = e->sector; int ok; - D_ASSERT(hlist_unhashed(&e->colision)); + D_ASSERT(hlist_unhashed(&e->collision)); if (likely((e->flags & EE_WAS_ERROR) == 0)) { drbd_set_in_sync(mdev, sector, e->size); @@ -1482,7 +1482,7 @@ static int receive_DataReply(struct drbd_conf *mdev, enum drbd_packets cmd, unsi return false; } - /* hlist_del(&req->colision) is done in _req_may_be_done, to avoid + /* hlist_del(&req->collision) is done in _req_may_be_done, to avoid * special casing it there for the various failure cases. * still no race with drbd_fail_pending_reads */ ok = recv_dless_read(mdev, req, sector, data_size); @@ -1553,11 +1553,11 @@ static int e_end_block(struct drbd_conf *mdev, struct drbd_work *w, int cancel) * P_WRITE_ACK / P_NEG_ACK, to get the sequence number right. */ if (mdev->net_conf->two_primaries) { spin_lock_irq(&mdev->req_lock); - D_ASSERT(!hlist_unhashed(&e->colision)); - hlist_del_init(&e->colision); + D_ASSERT(!hlist_unhashed(&e->collision)); + hlist_del_init(&e->collision); spin_unlock_irq(&mdev->req_lock); } else { - D_ASSERT(hlist_unhashed(&e->colision)); + D_ASSERT(hlist_unhashed(&e->collision)); } drbd_may_finish_epoch(mdev, e->epoch, EV_PUT + (cancel ? EV_CLEANUP : 0)); @@ -1574,8 +1574,8 @@ static int e_send_discard_ack(struct drbd_conf *mdev, struct drbd_work *w, int u ok = drbd_send_ack(mdev, P_DISCARD_ACK, e); spin_lock_irq(&mdev->req_lock); - D_ASSERT(!hlist_unhashed(&e->colision)); - hlist_del_init(&e->colision); + D_ASSERT(!hlist_unhashed(&e->collision)); + hlist_del_init(&e->collision); spin_unlock_irq(&mdev->req_lock); dec_unacked(mdev); @@ -1750,7 +1750,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned spin_lock_irq(&mdev->req_lock); - hlist_add_head(&e->colision, ee_hash_slot(mdev, sector)); + hlist_add_head(&e->collision, ee_hash_slot(mdev, sector)); #define OVERLAPS overlaps(i->sector, i->size, sector, size) slot = tl_hash_slot(mdev, sector); @@ -1760,7 +1760,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int have_conflict = 0; prepare_to_wait(&mdev->misc_wait, &wait, TASK_INTERRUPTIBLE); - hlist_for_each_entry(i, n, slot, colision) { + hlist_for_each_entry(i, n, slot, collision) { if (OVERLAPS) { /* only ALERT on first iteration, * we may be woken up early... */ @@ -1799,7 +1799,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned } if (signal_pending(current)) { - hlist_del_init(&e->colision); + hlist_del_init(&e->collision); spin_unlock_irq(&mdev->req_lock); @@ -1857,7 +1857,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned dev_err(DEV, "submit failed, triggering re-connect\n"); spin_lock_irq(&mdev->req_lock); list_del(&e->w.list); - hlist_del_init(&e->colision); + hlist_del_init(&e->collision); spin_unlock_irq(&mdev->req_lock); if (e->flags & EE_CALL_AL_COMPLETE_IO) drbd_al_complete_io(mdev, e->sector); @@ -2988,7 +2988,7 @@ static int receive_sizes(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned ddsf = be16_to_cpu(p->dds_flags); if (get_ldev(mdev)) { - dd = drbd_determin_dev_size(mdev, ddsf); + dd = drbd_determine_dev_size(mdev, ddsf); put_ldev(mdev); if (dd == dev_size_error) return false; @@ -4261,7 +4261,7 @@ static struct drbd_request *_ack_id_to_req(struct drbd_conf *mdev, struct hlist_node *n; struct drbd_request *req; - hlist_for_each_entry(req, n, slot, colision) { + hlist_for_each_entry(req, n, slot, collision) { if ((unsigned long)req == (unsigned long)id) { if (req->sector != sector) { dev_err(DEV, "_ack_id_to_req: found req %p but it has " diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index 14645bd40092..3424d675b769 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c @@ -163,7 +163,7 @@ static void _about_to_complete_local_write(struct drbd_conf *mdev, * they must have been failed on the spot */ #define OVERLAPS overlaps(sector, size, i->sector, i->size) slot = tl_hash_slot(mdev, sector); - hlist_for_each_entry(i, n, slot, colision) { + hlist_for_each_entry(i, n, slot, collision) { if (OVERLAPS) { dev_alert(DEV, "LOGIC BUG: completed: %p %llus +%u; " "other: %p %llus +%u\n", @@ -187,7 +187,7 @@ static void _about_to_complete_local_write(struct drbd_conf *mdev, #undef OVERLAPS #define OVERLAPS overlaps(sector, size, e->sector, e->size) slot = ee_hash_slot(mdev, req->sector); - hlist_for_each_entry(e, n, slot, colision) { + hlist_for_each_entry(e, n, slot, collision) { if (OVERLAPS) { wake_up(&mdev->misc_wait); break; @@ -260,8 +260,8 @@ void _req_may_be_done(struct drbd_request *req, struct bio_and_error *m) /* remove the request from the conflict detection * respective block_id verification hash */ - if (!hlist_unhashed(&req->colision)) - hlist_del(&req->colision); + if (!hlist_unhashed(&req->collision)) + hlist_del(&req->collision); else D_ASSERT((s & (RQ_NET_MASK & ~RQ_NET_DONE)) == 0); @@ -329,7 +329,7 @@ static int _req_conflicts(struct drbd_request *req) struct hlist_node *n; struct hlist_head *slot; - D_ASSERT(hlist_unhashed(&req->colision)); + D_ASSERT(hlist_unhashed(&req->collision)); if (!get_net_conf(mdev)) return 0; @@ -341,7 +341,7 @@ static int _req_conflicts(struct drbd_request *req) #define OVERLAPS overlaps(i->sector, i->size, sector, size) slot = tl_hash_slot(mdev, sector); - hlist_for_each_entry(i, n, slot, colision) { + hlist_for_each_entry(i, n, slot, collision) { if (OVERLAPS) { dev_alert(DEV, "%s[%u] Concurrent local write detected! " "[DISCARD L] new: %llus +%u; " @@ -359,7 +359,7 @@ static int _req_conflicts(struct drbd_request *req) #undef OVERLAPS #define OVERLAPS overlaps(e->sector, e->size, sector, size) slot = ee_hash_slot(mdev, sector); - hlist_for_each_entry(e, n, slot, colision) { + hlist_for_each_entry(e, n, slot, collision) { if (OVERLAPS) { dev_alert(DEV, "%s[%u] Concurrent remote write detected!" " [DISCARD L] new: %llus +%u; " @@ -491,7 +491,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, /* so we can verify the handle in the answer packet * corresponding hlist_del is in _req_may_be_done() */ - hlist_add_head(&req->colision, ar_hash_slot(mdev, req->sector)); + hlist_add_head(&req->collision, ar_hash_slot(mdev, req->sector)); set_bit(UNPLUG_REMOTE, &mdev->flags); @@ -507,7 +507,7 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, /* assert something? */ /* from drbd_make_request_common only */ - hlist_add_head(&req->colision, tl_hash_slot(mdev, req->sector)); + hlist_add_head(&req->collision, tl_hash_slot(mdev, req->sector)); /* corresponding hlist_del is in _req_may_be_done() */ /* NOTE diff --git a/drivers/block/drbd/drbd_req.h b/drivers/block/drbd/drbd_req.h index 32e2c3e6a813..281342dca2c8 100644 --- a/drivers/block/drbd/drbd_req.h +++ b/drivers/block/drbd/drbd_req.h @@ -256,7 +256,7 @@ static inline struct drbd_request *_ar_id_to_req(struct drbd_conf *mdev, struct hlist_node *n; struct drbd_request *req; - hlist_for_each_entry(req, n, slot, colision) { + hlist_for_each_entry(req, n, slot, collision) { if ((unsigned long)req == (unsigned long)id) { D_ASSERT(req->sector == sector); return req; @@ -291,7 +291,7 @@ static inline struct drbd_request *drbd_req_new(struct drbd_conf *mdev, req->epoch = 0; req->sector = bio_src->bi_sector; req->size = bio_src->bi_size; - INIT_HLIST_NODE(&req->colision); + INIT_HLIST_NODE(&req->collision); INIT_LIST_HEAD(&req->tl_requests); INIT_LIST_HEAD(&req->w.list); } diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index b5e53695fd7e..4d76b06b6b20 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c @@ -126,7 +126,7 @@ static void drbd_endio_write_sec_final(struct drbd_epoch_entry *e) __releases(lo list_del(&e->w.list); /* has been on active_ee or sync_ee */ list_add_tail(&e->w.list, &mdev->done_ee); - /* No hlist_del_init(&e->colision) here, we did not send the Ack yet, + /* No hlist_del_init(&e->collision) here, we did not send the Ack yet, * neither did we wake possibly waiting conflicting requests. * done from "drbd_process_done_ee" within the appropriate w.cb * (e_end_block/e_end_resync_block) or from _drbd_clear_done_ee */ @@ -840,7 +840,7 @@ int drbd_resync_finished(struct drbd_conf *mdev) const int ratio = (t == 0) ? 0 : (t < 100000) ? ((s*100)/t) : (s/(t/100)); - dev_info(DEV, "%u %% had equal check sums, eliminated: %luK; " + dev_info(DEV, "%u %% had equal checksums, eliminated: %luK; " "transferred %luK total %luK\n", ratio, Bit2KB(mdev->rs_same_csum), diff --git a/include/linux/drbd.h b/include/linux/drbd.h index c86283b4fbab..9e5f5607eba3 100644 --- a/include/linux/drbd.h +++ b/include/linux/drbd.h @@ -38,7 +38,7 @@ /* Although the Linux source code makes a difference between generic endianness and the bitfields' endianness, there is no - architecture as of Linux-2.6.24-rc4 where the bitfileds' endianness + architecture as of Linux-2.6.24-rc4 where the bitfields' endianness does not match the generic endianness. */ #if __BYTE_ORDER == __LITTLE_ENDIAN @@ -195,7 +195,7 @@ enum drbd_conns { C_WF_REPORT_PARAMS, /* we have a socket */ C_CONNECTED, /* we have introduced each other */ C_STARTING_SYNC_S, /* starting full sync by admin request. */ - C_STARTING_SYNC_T, /* stariing full sync by admin request. */ + C_STARTING_SYNC_T, /* starting full sync by admin request. */ C_WF_BITMAP_S, C_WF_BITMAP_T, C_WF_SYNC_UUID, @@ -236,7 +236,7 @@ union drbd_state { * pointed out by Maxim Uvarov q * even though we transmit as "cpu_to_be32(state)", * the offsets of the bitfields still need to be swapped - * on different endianess. + * on different endianness. */ struct { #if defined(__LITTLE_ENDIAN_BITFIELD) @@ -266,7 +266,7 @@ union drbd_state { unsigned peer:2 ; /* 3/4 primary/secondary/unknown */ unsigned role:2 ; /* 3/4 primary/secondary/unknown */ #else -# error "this endianess is not supported" +# error "this endianness is not supported" #endif }; unsigned int i; diff --git a/include/linux/drbd_tag_magic.h b/include/linux/drbd_tag_magic.h index f14a165e82dc..069543190516 100644 --- a/include/linux/drbd_tag_magic.h +++ b/include/linux/drbd_tag_magic.h @@ -30,7 +30,7 @@ enum packet_types { int tag_and_len ## member; #include "linux/drbd_nl.h" -/* declate tag-list-sizes */ +/* declare tag-list-sizes */ static const int tag_list_sizes[] = { #define NL_PACKET(name, number, fields) 2 fields , #define NL_INTEGER(pn, pr, member) + 4 + 4 -- cgit From 8af088710d1eb3c980e0ef3779c8d47f3f217b48 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 24 May 2011 11:12:58 +0200 Subject: posix-timers: RCU conversion Ben Nagy reported a scalability problem with KVM/QEMU that hit very hard a single spinlock (idr_lock) in posix-timers code, on its 48 core machine. Even on a 16 cpu machine (2x4x2), a single test can show 98% of cpu time used in ticket_spin_lock, from lock_timer Ref: http://www.spinics.net/lists/kvm/msg51526.html Switching to RCU is quite easy, IDR being already RCU ready. idr_lock should be locked only for an insert/delete, not a lookup. Benchmark on a 2x4x2 machine, 16 processes calling timer_gettime(). Before : real 1m18.669s user 0m1.346s sys 1m17.180s After : real 0m3.296s user 0m1.366s sys 0m1.926s Reported-by: Ben Nagy Signed-off-by: Eric Dumazet Tested-by: Ben Nagy Cc: Oleg Nesterov Cc: Avi Kivity Cc: John Stultz Cc: Richard Cochran Cc: Paul E. McKenney Cc: Andrew Morton Signed-off-by: Thomas Gleixner --- include/linux/posix-timers.h | 1 + kernel/posix-timers.c | 25 ++++++++++++++----------- 2 files changed, 15 insertions(+), 11 deletions(-) (limited to 'include/linux') diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h index 808227d40a64..959c14132f46 100644 --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -82,6 +82,7 @@ struct k_itimer { unsigned long expires; } mmtimer; struct alarm alarmtimer; + struct rcu_head rcu; } it; }; diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c index a1b5edf1bf92..4556182527f3 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c @@ -491,6 +491,13 @@ static struct k_itimer * alloc_posix_timer(void) return tmr; } +static void k_itimer_rcu_free(struct rcu_head *head) +{ + struct k_itimer *tmr = container_of(head, struct k_itimer, it.rcu); + + kmem_cache_free(posix_timers_cache, tmr); +} + #define IT_ID_SET 1 #define IT_ID_NOT_SET 0 static void release_posix_timer(struct k_itimer *tmr, int it_id_set) @@ -503,7 +510,7 @@ static void release_posix_timer(struct k_itimer *tmr, int it_id_set) } put_pid(tmr->it_pid); sigqueue_free(tmr->sigq); - kmem_cache_free(posix_timers_cache, tmr); + call_rcu(&tmr->it.rcu, k_itimer_rcu_free); } static struct k_clock *clockid_to_kclock(const clockid_t id) @@ -631,22 +638,18 @@ out: static struct k_itimer *__lock_timer(timer_t timer_id, unsigned long *flags) { struct k_itimer *timr; - /* - * Watch out here. We do a irqsave on the idr_lock and pass the - * flags part over to the timer lock. Must not let interrupts in - * while we are moving the lock. - */ - spin_lock_irqsave(&idr_lock, *flags); + + rcu_read_lock(); timr = idr_find(&posix_timers_id, (int)timer_id); if (timr) { - spin_lock(&timr->it_lock); + spin_lock_irqsave(&timr->it_lock, *flags); if (timr->it_signal == current->signal) { - spin_unlock(&idr_lock); + rcu_read_unlock(); return timr; } - spin_unlock(&timr->it_lock); + spin_unlock_irqrestore(&timr->it_lock, *flags); } - spin_unlock_irqrestore(&idr_lock, *flags); + rcu_read_unlock(); return NULL; } -- cgit From 1b4ac2a935aaf194241a2f4165d6407ba9650e1a Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Tue, 24 May 2011 00:18:05 +0200 Subject: x86: Get rid of asmregparm As UML does no longer need asmregparm we can remove it. Signed-off-by: Richard Weinberger Cc: namhyung@gmail.com Cc: davem@davemloft.net Cc: fweisbec@gmail.com Cc: dhowells@redhat.com Link: http://lkml.kernel.org/r/%3C1306189085-29896-1-git-send-email-richard%40nod.at%3E Signed-off-by: Thomas Gleixner --- arch/x86/include/asm/linkage.h | 5 ----- arch/x86/kernel/ptrace.c | 4 ++-- include/linux/linkage.h | 4 ---- 3 files changed, 2 insertions(+), 11 deletions(-) (limited to 'include/linux') diff --git a/arch/x86/include/asm/linkage.h b/arch/x86/include/asm/linkage.h index 12d55e773eb6..48142971b25d 100644 --- a/arch/x86/include/asm/linkage.h +++ b/arch/x86/include/asm/linkage.h @@ -8,11 +8,6 @@ #ifdef CONFIG_X86_32 #define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0))) -/* - * For 32-bit UML - mark functions implemented in assembly that use - * regparm input parameters: - */ -#define asmregparm __attribute__((regparm(3))) /* * Make sure the compiler doesn't do anything stupid with the diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index f65e5b521dbd..807c2a2b80f1 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -1363,7 +1363,7 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, * We must return the syscall number to actually look up in the table. * This can be -1L to skip running any syscall at all. */ -asmregparm long syscall_trace_enter(struct pt_regs *regs) +long syscall_trace_enter(struct pt_regs *regs) { long ret = 0; @@ -1408,7 +1408,7 @@ asmregparm long syscall_trace_enter(struct pt_regs *regs) return ret ?: regs->orig_ax; } -asmregparm void syscall_trace_leave(struct pt_regs *regs) +void syscall_trace_leave(struct pt_regs *regs) { bool step; diff --git a/include/linux/linkage.h b/include/linux/linkage.h index 7135ebc8428c..3f46aedea42f 100644 --- a/include/linux/linkage.h +++ b/include/linux/linkage.h @@ -14,10 +14,6 @@ #define asmlinkage CPP_ASMLINKAGE #endif -#ifndef asmregparm -# define asmregparm -#endif - #define __page_aligned_data __section(.data..page_aligned) __aligned(PAGE_SIZE) #define __page_aligned_bss __section(.bss..page_aligned) __aligned(PAGE_SIZE) -- cgit From 45e9683e87b69328175df3a9e42039b9892ca47e Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 24 May 2011 13:28:54 +1000 Subject: compat: include aio_abi.h for aio_context_t fixes this build error on sparc64 (at least): In file included from arch/sparc/include/asm/siginfo.h:19, from include/linux/signal.h:5, from include/linux/sched.h:73, from arch/sparc/kernel/asm-offsets.c:13: include/linux/compat.h:401: error: expected ')' before 'ctx_id' include/linux/compat.h:406: error: expected ')' before 'ctx_id' Signed-off-by: Stephen Rothwell Signed-off-by: Chris Metcalf --- include/linux/compat.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/compat.h b/include/linux/compat.h index 644e1a4692b1..ddcb7db38e67 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -13,6 +13,7 @@ #include #include #include +#include /* for aio_context_t */ #include #include -- cgit From c4dbe54ed7296ac3249c415d512dd6d649f66f4b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 24 May 2011 14:08:08 +0200 Subject: seqlock: Get rid of SEQLOCK_UNLOCKED All static seqlock should be initialized with the lockdep friendly __SEQLOCK_UNLOCKED() macro. Remove legacy SEQLOCK_UNLOCKED() macro. Signed-off-by: Eric Dumazet Cc: David Miller Link: http://lkml.kernel.org/r/%3C1306238888.3026.31.camel%40edumazet-laptop%3E Signed-off-by: Thomas Gleixner --- arch/ia64/kernel/time.c | 2 +- arch/x86/kernel/vsyscall_64.c | 2 +- include/linux/seqlock.h | 3 --- net/ipv4/inet_connection_sock.c | 2 +- 4 files changed, 3 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index 04440cc09b40..85118dfe9bb5 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c @@ -36,7 +36,7 @@ static cycle_t itc_get_cycles(struct clocksource *cs); struct fsyscall_gtod_data_t fsyscall_gtod_data = { - .lock = SEQLOCK_UNLOCKED, + .lock = __SEQLOCK_UNLOCKED(fsyscall_gtod_data.lock), }; struct itc_jitter_data_t itc_jitter_data; diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c index dcbb28c4b694..59be48d0d75c 100644 --- a/arch/x86/kernel/vsyscall_64.c +++ b/arch/x86/kernel/vsyscall_64.c @@ -59,7 +59,7 @@ int __vgetcpu_mode __section_vgetcpu_mode; struct vsyscall_gtod_data __vsyscall_gtod_data __section_vsyscall_gtod_data = { - .lock = SEQLOCK_UNLOCKED, + .lock = __SEQLOCK_UNLOCKED(__vsyscall_gtod_data.lock), .sysctl_enabled = 1, }; diff --git a/include/linux/seqlock.h b/include/linux/seqlock.h index 06d69648fc86..e9811892844f 100644 --- a/include/linux/seqlock.h +++ b/include/linux/seqlock.h @@ -41,9 +41,6 @@ typedef struct { #define __SEQLOCK_UNLOCKED(lockname) \ { 0, __SPIN_LOCK_UNLOCKED(lockname) } -#define SEQLOCK_UNLOCKED \ - __SEQLOCK_UNLOCKED(old_style_seqlock_init) - #define seqlock_init(x) \ do { \ (x)->sequence = 0; \ diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 61fac4cabc78..c14d88ad348d 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c @@ -33,7 +33,7 @@ EXPORT_SYMBOL(inet_csk_timer_bug_msg); * This struct holds the first and last local port number. */ struct local_ports sysctl_local_ports __read_mostly = { - .lock = SEQLOCK_UNLOCKED, + .lock = __SEQLOCK_UNLOCKED(sysctl_local_ports.lock), .range = { 32768, 61000 }, }; -- cgit From 81be12c8179c1c397d3f179cdd9b3f7146cf47f1 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 24 May 2011 11:52:40 -0400 Subject: jbd2: fix sending of data flush on journal commit In data=ordered mode, it's theoretically possible (however rare) that an inode is filed to transaction's t_inode_list and a flusher thread writes all the data and inode is reclaimed before the transaction starts to commit. In such a case, we could erroneously omit sending a flush to file system device when it is different from the journal device (because data can still be in disk cache only). Fix the problem by setting a flag in a transaction when some inode is added to it and then send disk flush in the commit code when the flag is set. Signed-off-by: Jan Kara Signed-off-by: "Theodore Ts'o" --- fs/jbd2/commit.c | 3 +-- fs/jbd2/transaction.c | 7 +++++++ include/linux/jbd2.h | 4 +++- 3 files changed, 11 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 78c299218681..2d5095ecc25f 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c @@ -219,7 +219,6 @@ static int journal_submit_data_buffers(journal_t *journal, ret = err; spin_lock(&journal->j_list_lock); J_ASSERT(jinode->i_transaction == commit_transaction); - commit_transaction->t_flushed_data_blocks = 1; clear_bit(__JI_COMMIT_RUNNING, &jinode->i_flags); smp_mb__after_clear_bit(); wake_up_bit(&jinode->i_flags, __JI_COMMIT_RUNNING); @@ -683,7 +682,7 @@ start_journal_io: * then we must flush the file system device before we issue * the commit record */ - if (commit_transaction->t_flushed_data_blocks && + if (commit_transaction->t_need_data_flush && (journal->j_fs_dev != journal->j_dev) && (journal->j_flags & JBD2_BARRIER)) blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL); diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 85a055ef93fe..20065c9f2479 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c @@ -2147,6 +2147,13 @@ int jbd2_journal_file_inode(handle_t *handle, struct jbd2_inode *jinode) jinode->i_next_transaction == transaction) goto done; + /* + * We only ever set this variable to 1 so the test is safe. Since + * t_need_data_flush is likely to be set, we do the test to save some + * cacheline bouncing + */ + if (!transaction->t_need_data_flush) + transaction->t_need_data_flush = 1; /* On some different transaction's list - should be * the committing one */ if (jinode->i_transaction) { diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index a32dcaec04e1..4d57955061f4 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h @@ -658,7 +658,9 @@ struct transaction_s * waiting for it to finish. */ unsigned int t_synchronous_commit:1; - unsigned int t_flushed_data_blocks:1; + + /* Disk flush needs to be sent to fs partition [no locking] */ + int t_need_data_flush; /* * For use by the filesystem to store fs-specific data -- cgit From bbd2be36910728f485ac78ea36e0f4f5a38e691e Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 24 May 2011 11:59:18 -0400 Subject: jbd2: Add function jbd2_trans_will_send_data_barrier() Provide a function which returns whether a transaction with given tid will send a flush to the filesystem device. The function will be used by ext4 to detect whether fsync needs to send a separate flush or not. Signed-off-by: Jan Kara Signed-off-by: "Theodore Ts'o" --- fs/jbd2/commit.c | 10 +++++++++- fs/jbd2/journal.c | 41 +++++++++++++++++++++++++++++++++++++++++ include/linux/jbd2.h | 4 +++- 3 files changed, 53 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 2d5095ecc25f..5b506e53c70b 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c @@ -677,6 +677,10 @@ start_journal_io: err = 0; } + write_lock(&journal->j_state_lock); + J_ASSERT(commit_transaction->t_state == T_COMMIT); + commit_transaction->t_state = T_COMMIT_DFLUSH; + write_unlock(&journal->j_state_lock); /* * If the journal is not located on the file system device, * then we must flush the file system device before we issue @@ -804,6 +808,10 @@ wait_for_iobuf: jbd2_journal_abort(journal, err); jbd_debug(3, "JBD: commit phase 5\n"); + write_lock(&journal->j_state_lock); + J_ASSERT(commit_transaction->t_state == T_COMMIT_DFLUSH); + commit_transaction->t_state = T_COMMIT_JFLUSH; + write_unlock(&journal->j_state_lock); if (!JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) { @@ -959,7 +967,7 @@ restart_loop: jbd_debug(3, "JBD: commit phase 7\n"); - J_ASSERT(commit_transaction->t_state == T_COMMIT); + J_ASSERT(commit_transaction->t_state == T_COMMIT_JFLUSH); commit_transaction->t_start = jiffies; stats.run.rs_logging = jbd2_time_diff(stats.run.rs_logging, diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index cd2d341f602e..9a7826990304 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -587,6 +587,47 @@ int jbd2_journal_start_commit(journal_t *journal, tid_t *ptid) return ret; } +/* + * Return 1 if a given transaction has not yet sent barrier request + * connected with a transaction commit. If 0 is returned, transaction + * may or may not have sent the barrier. Used to avoid sending barrier + * twice in common cases. + */ +int jbd2_trans_will_send_data_barrier(journal_t *journal, tid_t tid) +{ + int ret = 0; + transaction_t *commit_trans; + + if (!(journal->j_flags & JBD2_BARRIER)) + return 0; + read_lock(&journal->j_state_lock); + /* Transaction already committed? */ + if (tid_geq(journal->j_commit_sequence, tid)) + goto out; + commit_trans = journal->j_committing_transaction; + if (!commit_trans || commit_trans->t_tid != tid) { + ret = 1; + goto out; + } + /* + * Transaction is being committed and we already proceeded to + * submitting a flush to fs partition? + */ + if (journal->j_fs_dev != journal->j_dev) { + if (!commit_trans->t_need_data_flush || + commit_trans->t_state >= T_COMMIT_DFLUSH) + goto out; + } else { + if (commit_trans->t_state >= T_COMMIT_JFLUSH) + goto out; + } + ret = 1; +out: + read_unlock(&journal->j_state_lock); + return ret; +} +EXPORT_SYMBOL(jbd2_trans_will_send_data_barrier); + /* * Wait for a specified commit to complete. * The caller may not hold the journal lock. diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index 4d57955061f4..4ecb7b16b278 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h @@ -529,9 +529,10 @@ struct transaction_s enum { T_RUNNING, T_LOCKED, - T_RUNDOWN, T_FLUSH, T_COMMIT, + T_COMMIT_DFLUSH, + T_COMMIT_JFLUSH, T_FINISHED } t_state; @@ -1230,6 +1231,7 @@ int jbd2_journal_start_commit(journal_t *journal, tid_t *tid); int jbd2_journal_force_commit_nested(journal_t *journal); int jbd2_log_wait_commit(journal_t *journal, tid_t tid); int jbd2_log_do_checkpoint(journal_t *journal); +int jbd2_trans_will_send_data_barrier(journal_t *journal, tid_t tid); void __jbd2_log_wait_for_space(journal_t *journal); extern void __jbd2_journal_drop_transaction(journal_t *, transaction_t *); -- cgit From 3c454cf21645bc96668e286f6352ac2c4c895fa2 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 6 Apr 2011 09:31:40 -0700 Subject: ceph: use LOOKUPINO to make unconnected nfs fh more reliable If we are unable to locate an inode by ino, ask the MDS using the new LOOKUPINO command. Signed-off-by: Sage Weil --- fs/ceph/export.c | 19 +++++++++++++++++-- include/linux/ceph/ceph_fs.h | 1 + 2 files changed, 18 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/fs/ceph/export.c b/fs/ceph/export.c index e41056174bf8..f1828af09912 100644 --- a/fs/ceph/export.c +++ b/fs/ceph/export.c @@ -86,6 +86,7 @@ static int ceph_encode_fh(struct dentry *dentry, u32 *rawfh, int *max_len, static struct dentry *__fh_to_dentry(struct super_block *sb, struct ceph_nfs_fh *fh) { + struct ceph_mds_client *mdsc = ceph_sb_to_client(sb)->mdsc; struct inode *inode; struct dentry *dentry; struct ceph_vino vino; @@ -95,8 +96,22 @@ static struct dentry *__fh_to_dentry(struct super_block *sb, vino.ino = fh->ino; vino.snap = CEPH_NOSNAP; inode = ceph_find_inode(sb, vino); - if (!inode) - return ERR_PTR(-ESTALE); + if (!inode) { + struct ceph_mds_request *req; + + req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LOOKUPINO, + USE_ANY_MDS); + if (IS_ERR(req)) + return ERR_CAST(req); + + req->r_ino1 = vino; + req->r_num_caps = 1; + err = ceph_mdsc_do_request(mdsc, NULL, req); + ceph_mdsc_put_request(req); + inode = ceph_find_inode(sb, vino); + if (!inode) + return ERR_PTR(-ESTALE); + } dentry = d_obtain_alias(inode); if (IS_ERR(dentry)) { diff --git a/include/linux/ceph/ceph_fs.h b/include/linux/ceph/ceph_fs.h index b8e995fbd867..b8c60694b2b0 100644 --- a/include/linux/ceph/ceph_fs.h +++ b/include/linux/ceph/ceph_fs.h @@ -313,6 +313,7 @@ enum { CEPH_MDS_OP_GETATTR = 0x00101, CEPH_MDS_OP_LOOKUPHASH = 0x00102, CEPH_MDS_OP_LOOKUPPARENT = 0x00103, + CEPH_MDS_OP_LOOKUPINO = 0x00104, CEPH_MDS_OP_SETXATTR = 0x01105, CEPH_MDS_OP_RMXATTR = 0x01106, -- cgit From 650c2a2145981696c414be1d540a32447d0e353e Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sun, 15 May 2011 22:53:56 +0200 Subject: mach-ux500: move the DB8500 PRCMU driver to MFD We have decided that this function arbiter fits better in the MFD subsystem. Since we need to concatenate the split header files we move it basically like this: mv mach-ux500/prcmu-db8500.c drivers/mfd/db8500-prcmu.c mv mach-ux500/include/mach/prcmu-defs.h include/linux/mfd/db8500-prcmu.h mv mach-ux500/include/mach/prcmu-regs.h drivers/mfd/db8500-prcmu-regs.h mach-ux500/include/mach/prcmu.h >> include/linux/mfd/db8500-prcmu.h rm arch/arm/mach-ux500/include/mach/prcmu.h Then we update different #include statements and Makefile orders etc to make the PRCMU driver compile, link and boot in the new place without really changing any code. Acked-by: Samuel Ortiz Signed-off-by: Linus Walleij --- arch/arm/mach-ux500/Kconfig | 1 + arch/arm/mach-ux500/Makefile | 2 +- arch/arm/mach-ux500/cpu.c | 2 +- arch/arm/mach-ux500/cpufreq.c | 3 +- arch/arm/mach-ux500/include/mach/prcmu-defs.h | 30 -- arch/arm/mach-ux500/include/mach/prcmu-regs.h | 94 ------ arch/arm/mach-ux500/include/mach/prcmu.h | 28 -- arch/arm/mach-ux500/prcmu-db8500.c | 394 ------------------------- drivers/mfd/Kconfig | 12 +- drivers/mfd/Makefile | 4 +- drivers/mfd/ab8500-i2c.c | 3 +- drivers/mfd/db8500-prcmu-regs.h | 94 ++++++ drivers/mfd/db8500-prcmu.c | 395 ++++++++++++++++++++++++++ include/linux/mfd/db8500-prcmu.h | 58 ++++ 14 files changed, 566 insertions(+), 554 deletions(-) delete mode 100644 arch/arm/mach-ux500/include/mach/prcmu-defs.h delete mode 100644 arch/arm/mach-ux500/include/mach/prcmu-regs.h delete mode 100644 arch/arm/mach-ux500/include/mach/prcmu.h delete mode 100644 arch/arm/mach-ux500/prcmu-db8500.c create mode 100644 drivers/mfd/db8500-prcmu-regs.h create mode 100644 drivers/mfd/db8500-prcmu.c create mode 100644 include/linux/mfd/db8500-prcmu.h (limited to 'include/linux') diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index 58626013aa32..8071d2746f70 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig @@ -15,6 +15,7 @@ config UX500_SOC_DB5500 config UX500_SOC_DB8500 bool "DB8500" + select MFD_DB8500_PRCMU endmenu diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile index 2a08a10e09da..7a1d43e04f97 100644 --- a/arch/arm/mach-ux500/Makefile +++ b/arch/arm/mach-ux500/Makefile @@ -5,7 +5,7 @@ obj-y := clock.o cpu.o devices.o devices-common.o \ id.o usb.o obj-$(CONFIG_UX500_SOC_DB5500) += cpu-db5500.o dma-db5500.o -obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o prcmu-db8500.o +obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o obj-$(CONFIG_MACH_U8500) += board-mop500.o board-mop500-sdi.o \ board-mop500-regulators.o \ board-mop500-uib.o board-mop500-stuib.o \ diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c index 0190e0e68b4d..11360f734cec 100644 --- a/arch/arm/mach-ux500/cpu.c +++ b/arch/arm/mach-ux500/cpu.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -19,7 +20,6 @@ #include #include #include -#include #include "clock.h" diff --git a/arch/arm/mach-ux500/cpufreq.c b/arch/arm/mach-ux500/cpufreq.c index 5c5b747f134d..d196939fcdb9 100644 --- a/arch/arm/mach-ux500/cpufreq.c +++ b/arch/arm/mach-ux500/cpufreq.c @@ -17,10 +17,9 @@ #include #include #include +#include #include -#include -#include #define DRIVER_NAME "cpufreq-u8500" #define CPUFREQ_NAME "u8500" diff --git a/arch/arm/mach-ux500/include/mach/prcmu-defs.h b/arch/arm/mach-ux500/include/mach/prcmu-defs.h deleted file mode 100644 index 848ba64b561f..000000000000 --- a/arch/arm/mach-ux500/include/mach/prcmu-defs.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) STMicroelectronics 2009 - * Copyright (C) ST-Ericsson SA 2010 - * - * Author: Sundar Iyer - * Author: Martin Persson - * - * License Terms: GNU General Public License v2 - * - * PRCM Unit definitions - */ - -#ifndef __MACH_PRCMU_DEFS_H -#define __MACH_PRCMU_DEFS_H - -enum prcmu_cpu_opp { - CPU_OPP_INIT = 0x00, - CPU_OPP_NO_CHANGE = 0x01, - CPU_OPP_100 = 0x02, - CPU_OPP_50 = 0x03, - CPU_OPP_MAX = 0x04, - CPU_OPP_EXT_CLK = 0x07 -}; -enum prcmu_ape_opp { - APE_OPP_NO_CHANGE = 0x00, - APE_OPP_100 = 0x02, - APE_OPP_50 = 0x03, -}; - -#endif /* __MACH_PRCMU_DEFS_H */ diff --git a/arch/arm/mach-ux500/include/mach/prcmu-regs.h b/arch/arm/mach-ux500/include/mach/prcmu-regs.h deleted file mode 100644 index c1226da19bfb..000000000000 --- a/arch/arm/mach-ux500/include/mach/prcmu-regs.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) STMicroelectronics 2009 - * Copyright (C) ST-Ericsson SA 2010 - * - * Author: Kumar Sanghvi - * Author: Sundar Iyer - * - * License Terms: GNU General Public License v2 - * - * PRCM Unit registers - */ - -#ifndef __MACH_PRCMU_REGS_H -#define __MACH_PRCMU_REGS_H - -#include - -#define PRCM_ARM_PLLDIVPS (_PRCMU_BASE + 0x118) -#define PRCM_ARM_CHGCLKREQ (_PRCMU_BASE + 0x114) -#define PRCM_PLLARM_ENABLE (_PRCMU_BASE + 0x98) -#define PRCM_ARMCLKFIX_MGT (_PRCMU_BASE + 0x0) -#define PRCM_A9_RESETN_CLR (_PRCMU_BASE + 0x1f4) -#define PRCM_A9_RESETN_SET (_PRCMU_BASE + 0x1f0) -#define PRCM_ARM_LS_CLAMP (_PRCMU_BASE + 0x30c) -#define PRCM_SRAM_A9 (_PRCMU_BASE + 0x308) - -/* ARM WFI Standby signal register */ -#define PRCM_ARM_WFI_STANDBY (_PRCMU_BASE + 0x130) -#define PRCMU_IOCR (_PRCMU_BASE + 0x310) - -/* CPU mailbox registers */ -#define PRCM_MBOX_CPU_VAL (_PRCMU_BASE + 0x0fc) -#define PRCM_MBOX_CPU_SET (_PRCMU_BASE + 0x100) -#define PRCM_MBOX_CPU_CLR (_PRCMU_BASE + 0x104) - -/* Dual A9 core interrupt management unit registers */ -#define PRCM_A9_MASK_REQ (_PRCMU_BASE + 0x328) -#define PRCM_A9_MASK_ACK (_PRCMU_BASE + 0x32c) -#define PRCM_ARMITMSK31TO0 (_PRCMU_BASE + 0x11c) -#define PRCM_ARMITMSK63TO32 (_PRCMU_BASE + 0x120) -#define PRCM_ARMITMSK95TO64 (_PRCMU_BASE + 0x124) -#define PRCM_ARMITMSK127TO96 (_PRCMU_BASE + 0x128) -#define PRCM_POWER_STATE_VAL (_PRCMU_BASE + 0x25C) -#define PRCM_ARMITVAL31TO0 (_PRCMU_BASE + 0x260) -#define PRCM_ARMITVAL63TO32 (_PRCMU_BASE + 0x264) -#define PRCM_ARMITVAL95TO64 (_PRCMU_BASE + 0x268) -#define PRCM_ARMITVAL127TO96 (_PRCMU_BASE + 0x26C) - -#define PRCM_HOSTACCESS_REQ (_PRCMU_BASE + 0x334) -#define ARM_WAKEUP_MODEM 0x1 - -#define PRCM_ARM_IT1_CLEAR (_PRCMU_BASE + 0x48C) -#define PRCM_ARM_IT1_VAL (_PRCMU_BASE + 0x494) -#define PRCM_HOLD_EVT (_PRCMU_BASE + 0x174) - -#define PRCM_ITSTATUS0 (_PRCMU_BASE + 0x148) -#define PRCM_ITSTATUS1 (_PRCMU_BASE + 0x150) -#define PRCM_ITSTATUS2 (_PRCMU_BASE + 0x158) -#define PRCM_ITSTATUS3 (_PRCMU_BASE + 0x160) -#define PRCM_ITSTATUS4 (_PRCMU_BASE + 0x168) -#define PRCM_ITSTATUS5 (_PRCMU_BASE + 0x484) -#define PRCM_ITCLEAR5 (_PRCMU_BASE + 0x488) -#define PRCM_ARMIT_MASKXP70_IT (_PRCMU_BASE + 0x1018) - -/* System reset register */ -#define PRCM_APE_SOFTRST (_PRCMU_BASE + 0x228) - -/* Level shifter and clamp control registers */ -#define PRCM_MMIP_LS_CLAMP_SET (_PRCMU_BASE + 0x420) -#define PRCM_MMIP_LS_CLAMP_CLR (_PRCMU_BASE + 0x424) - -/* PRCMU clock/PLL/reset registers */ -#define PRCM_PLLDSI_FREQ (_PRCMU_BASE + 0x500) -#define PRCM_PLLDSI_ENABLE (_PRCMU_BASE + 0x504) -#define PRCM_LCDCLK_MGT (_PRCMU_BASE + 0x044) -#define PRCM_MCDECLK_MGT (_PRCMU_BASE + 0x064) -#define PRCM_HDMICLK_MGT (_PRCMU_BASE + 0x058) -#define PRCM_TVCLK_MGT (_PRCMU_BASE + 0x07c) -#define PRCM_DSI_PLLOUT_SEL (_PRCMU_BASE + 0x530) -#define PRCM_DSITVCLK_DIV (_PRCMU_BASE + 0x52C) -#define PRCM_APE_RESETN_SET (_PRCMU_BASE + 0x1E4) -#define PRCM_APE_RESETN_CLR (_PRCMU_BASE + 0x1E8) - -/* ePOD and memory power signal control registers */ -#define PRCM_EPOD_C_SET (_PRCMU_BASE + 0x410) -#define PRCM_SRAM_LS_SLEEP (_PRCMU_BASE + 0x304) - -/* Debug power control unit registers */ -#define PRCM_POWER_STATE_SET (_PRCMU_BASE + 0x254) - -/* Miscellaneous unit registers */ -#define PRCM_DSI_SW_RESET (_PRCMU_BASE + 0x324) - -#endif /* __MACH_PRCMU_REGS_H */ diff --git a/arch/arm/mach-ux500/include/mach/prcmu.h b/arch/arm/mach-ux500/include/mach/prcmu.h deleted file mode 100644 index c49e456162ef..000000000000 --- a/arch/arm/mach-ux500/include/mach/prcmu.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) STMicroelectronics 2009 - * Copyright (C) ST-Ericsson SA 2010 - * - * Author: Kumar Sanghvi - * Author: Sundar Iyer - * Author: Mattias Nilsson - * - * License Terms: GNU General Public License v2 - * - * PRCM Unit f/w API - */ -#ifndef __MACH_PRCMU_H -#define __MACH_PRCMU_H -#include - -void __init prcmu_early_init(void); -int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size); -int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size); -int prcmu_set_ape_opp(enum prcmu_ape_opp opp); -int prcmu_set_cpu_opp(enum prcmu_cpu_opp opp); -int prcmu_set_ape_cpu_opps(enum prcmu_ape_opp ape_opp, - enum prcmu_cpu_opp cpu_opp); -int prcmu_get_ape_opp(void); -int prcmu_get_cpu_opp(void); -bool prcmu_has_arm_maxopp(void); - -#endif /* __MACH_PRCMU_H */ diff --git a/arch/arm/mach-ux500/prcmu-db8500.c b/arch/arm/mach-ux500/prcmu-db8500.c deleted file mode 100644 index c522d26ef348..000000000000 --- a/arch/arm/mach-ux500/prcmu-db8500.c +++ /dev/null @@ -1,394 +0,0 @@ -/* - * Copyright (C) STMicroelectronics 2009 - * Copyright (C) ST-Ericsson SA 2010 - * - * License Terms: GNU General Public License v2 - * Author: Kumar Sanghvi - * Author: Sundar Iyer - * Author: Mattias Nilsson - * - * U8500 PRCM Unit interface driver - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -/* Global var to runtime determine TCDM base for v2 or v1 */ -static __iomem void *tcdm_base; - -#define _MBOX_HEADER (tcdm_base + 0xFE8) -#define MBOX_HEADER_REQ_MB0 (_MBOX_HEADER + 0x0) - -#define REQ_MB1 (tcdm_base + 0xFD0) -#define REQ_MB5 (tcdm_base + 0xE44) - -#define REQ_MB1_ARMOPP (REQ_MB1 + 0x0) -#define REQ_MB1_APEOPP (REQ_MB1 + 0x1) -#define REQ_MB1_BOOSTOPP (REQ_MB1 + 0x2) - -#define ACK_MB1 (tcdm_base + 0xE04) -#define ACK_MB5 (tcdm_base + 0xDF4) - -#define ACK_MB1_CURR_ARMOPP (ACK_MB1 + 0x0) -#define ACK_MB1_CURR_APEOPP (ACK_MB1 + 0x1) - -#define REQ_MB5_I2C_SLAVE_OP (REQ_MB5) -#define REQ_MB5_I2C_HW_BITS (REQ_MB5 + 1) -#define REQ_MB5_I2C_REG (REQ_MB5 + 2) -#define REQ_MB5_I2C_VAL (REQ_MB5 + 3) - -#define ACK_MB5_I2C_STATUS (ACK_MB5 + 1) -#define ACK_MB5_I2C_VAL (ACK_MB5 + 3) - -#define PRCM_AVS_VARM_MAX_OPP (tcdm_base + 0x2E4) -#define PRCM_AVS_ISMODEENABLE 7 -#define PRCM_AVS_ISMODEENABLE_MASK (1 << PRCM_AVS_ISMODEENABLE) - -#define I2C_WRITE(slave) \ - (((slave) << 1) | (cpu_is_u8500v2() ? BIT(6) : 0)) -#define I2C_READ(slave) \ - (((slave) << 1) | (cpu_is_u8500v2() ? BIT(6) : 0) | BIT(0)) -#define I2C_STOP_EN BIT(3) - -enum mb1_h { - MB1H_ARM_OPP = 1, - MB1H_APE_OPP, - MB1H_ARM_APE_OPP, -}; - -static struct { - struct mutex lock; - struct completion work; - struct { - u8 arm_opp; - u8 ape_opp; - u8 arm_status; - u8 ape_status; - } ack; -} mb1_transfer; - -enum ack_mb5_status { - I2C_WR_OK = 0x01, - I2C_RD_OK = 0x02, -}; - -#define MBOX_BIT BIT -#define NUM_MBOX 8 - -static struct { - struct mutex lock; - struct completion work; - bool failed; - struct { - u8 status; - u8 value; - } ack; -} mb5_transfer; - -/** - * prcmu_abb_read() - Read register value(s) from the ABB. - * @slave: The I2C slave address. - * @reg: The (start) register address. - * @value: The read out value(s). - * @size: The number of registers to read. - * - * Reads register value(s) from the ABB. - * @size has to be 1 for the current firmware version. - */ -int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size) -{ - int r; - - if (size != 1) - return -EINVAL; - - r = mutex_lock_interruptible(&mb5_transfer.lock); - if (r) - return r; - - while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5)) - cpu_relax(); - - writeb(I2C_READ(slave), REQ_MB5_I2C_SLAVE_OP); - writeb(I2C_STOP_EN, REQ_MB5_I2C_HW_BITS); - writeb(reg, REQ_MB5_I2C_REG); - - writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET); - if (!wait_for_completion_timeout(&mb5_transfer.work, - msecs_to_jiffies(500))) { - pr_err("prcmu: prcmu_abb_read timed out.\n"); - r = -EIO; - goto unlock_and_return; - } - r = ((mb5_transfer.ack.status == I2C_RD_OK) ? 0 : -EIO); - if (!r) - *value = mb5_transfer.ack.value; - -unlock_and_return: - mutex_unlock(&mb5_transfer.lock); - return r; -} -EXPORT_SYMBOL(prcmu_abb_read); - -/** - * prcmu_abb_write() - Write register value(s) to the ABB. - * @slave: The I2C slave address. - * @reg: The (start) register address. - * @value: The value(s) to write. - * @size: The number of registers to write. - * - * Reads register value(s) from the ABB. - * @size has to be 1 for the current firmware version. - */ -int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size) -{ - int r; - - if (size != 1) - return -EINVAL; - - r = mutex_lock_interruptible(&mb5_transfer.lock); - if (r) - return r; - - - while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5)) - cpu_relax(); - - writeb(I2C_WRITE(slave), REQ_MB5_I2C_SLAVE_OP); - writeb(I2C_STOP_EN, REQ_MB5_I2C_HW_BITS); - writeb(reg, REQ_MB5_I2C_REG); - writeb(*value, REQ_MB5_I2C_VAL); - - writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET); - if (!wait_for_completion_timeout(&mb5_transfer.work, - msecs_to_jiffies(500))) { - pr_err("prcmu: prcmu_abb_write timed out.\n"); - r = -EIO; - goto unlock_and_return; - } - r = ((mb5_transfer.ack.status == I2C_WR_OK) ? 0 : -EIO); - -unlock_and_return: - mutex_unlock(&mb5_transfer.lock); - return r; -} -EXPORT_SYMBOL(prcmu_abb_write); - -static int set_ape_cpu_opps(u8 header, enum prcmu_ape_opp ape_opp, - enum prcmu_cpu_opp cpu_opp) -{ - bool do_ape; - bool do_arm; - int err = 0; - - do_ape = ((header == MB1H_APE_OPP) || (header == MB1H_ARM_APE_OPP)); - do_arm = ((header == MB1H_ARM_OPP) || (header == MB1H_ARM_APE_OPP)); - - mutex_lock(&mb1_transfer.lock); - - while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(1)) - cpu_relax(); - - writeb(0, MBOX_HEADER_REQ_MB0); - writeb(cpu_opp, REQ_MB1_ARMOPP); - writeb(ape_opp, REQ_MB1_APEOPP); - writeb(0, REQ_MB1_BOOSTOPP); - writel(MBOX_BIT(1), PRCM_MBOX_CPU_SET); - wait_for_completion(&mb1_transfer.work); - if ((do_ape) && (mb1_transfer.ack.ape_status != 0)) - err = -EIO; - if ((do_arm) && (mb1_transfer.ack.arm_status != 0)) - err = -EIO; - - mutex_unlock(&mb1_transfer.lock); - - return err; -} - -/** - * prcmu_set_ape_opp() - Set the OPP of the APE. - * @opp: The OPP to set. - * - * This function sets the OPP of the APE. - */ -int prcmu_set_ape_opp(enum prcmu_ape_opp opp) -{ - return set_ape_cpu_opps(MB1H_APE_OPP, opp, APE_OPP_NO_CHANGE); -} -EXPORT_SYMBOL(prcmu_set_ape_opp); - -/** - * prcmu_set_cpu_opp() - Set the OPP of the CPU. - * @opp: The OPP to set. - * - * This function sets the OPP of the CPU. - */ -int prcmu_set_cpu_opp(enum prcmu_cpu_opp opp) -{ - return set_ape_cpu_opps(MB1H_ARM_OPP, CPU_OPP_NO_CHANGE, opp); -} -EXPORT_SYMBOL(prcmu_set_cpu_opp); - -/** - * prcmu_set_ape_cpu_opps() - Set the OPPs of the APE and the CPU. - * @ape_opp: The APE OPP to set. - * @cpu_opp: The CPU OPP to set. - * - * This function sets the OPPs of the APE and the CPU. - */ -int prcmu_set_ape_cpu_opps(enum prcmu_ape_opp ape_opp, - enum prcmu_cpu_opp cpu_opp) -{ - return set_ape_cpu_opps(MB1H_ARM_APE_OPP, ape_opp, cpu_opp); -} -EXPORT_SYMBOL(prcmu_set_ape_cpu_opps); - -/** - * prcmu_get_ape_opp() - Get the OPP of the APE. - * - * This function gets the OPP of the APE. - */ -enum prcmu_ape_opp prcmu_get_ape_opp(void) -{ - return readb(ACK_MB1_CURR_APEOPP); -} -EXPORT_SYMBOL(prcmu_get_ape_opp); - -/** - * prcmu_get_cpu_opp() - Get the OPP of the CPU. - * - * This function gets the OPP of the CPU. The OPP is specified in %%. - * PRCMU_OPP_EXT is a special OPP value, not specified in %%. - */ -int prcmu_get_cpu_opp(void) -{ - return readb(ACK_MB1_CURR_ARMOPP); -} -EXPORT_SYMBOL(prcmu_get_cpu_opp); - -bool prcmu_has_arm_maxopp(void) -{ - return (readb(PRCM_AVS_VARM_MAX_OPP) & PRCM_AVS_ISMODEENABLE_MASK) - == PRCM_AVS_ISMODEENABLE_MASK; -} - -static void read_mailbox_0(void) -{ - writel(MBOX_BIT(0), PRCM_ARM_IT1_CLEAR); -} - -static void read_mailbox_1(void) -{ - mb1_transfer.ack.arm_opp = readb(ACK_MB1_CURR_ARMOPP); - mb1_transfer.ack.ape_opp = readb(ACK_MB1_CURR_APEOPP); - complete(&mb1_transfer.work); - writel(MBOX_BIT(1), PRCM_ARM_IT1_CLEAR); -} - -static void read_mailbox_2(void) -{ - writel(MBOX_BIT(2), PRCM_ARM_IT1_CLEAR); -} - -static void read_mailbox_3(void) -{ - writel(MBOX_BIT(3), PRCM_ARM_IT1_CLEAR); -} - -static void read_mailbox_4(void) -{ - writel(MBOX_BIT(4), PRCM_ARM_IT1_CLEAR); -} - -static void read_mailbox_5(void) -{ - mb5_transfer.ack.status = readb(ACK_MB5_I2C_STATUS); - mb5_transfer.ack.value = readb(ACK_MB5_I2C_VAL); - complete(&mb5_transfer.work); - writel(MBOX_BIT(5), PRCM_ARM_IT1_CLEAR); -} - -static void read_mailbox_6(void) -{ - writel(MBOX_BIT(6), PRCM_ARM_IT1_CLEAR); -} - -static void read_mailbox_7(void) -{ - writel(MBOX_BIT(7), PRCM_ARM_IT1_CLEAR); -} - -static void (* const read_mailbox[NUM_MBOX])(void) = { - read_mailbox_0, - read_mailbox_1, - read_mailbox_2, - read_mailbox_3, - read_mailbox_4, - read_mailbox_5, - read_mailbox_6, - read_mailbox_7 -}; - -static irqreturn_t prcmu_irq_handler(int irq, void *data) -{ - u32 bits; - u8 n; - - bits = (readl(PRCM_ARM_IT1_VAL) & (MBOX_BIT(NUM_MBOX) - 1)); - if (unlikely(!bits)) - return IRQ_NONE; - - for (n = 0; bits; n++) { - if (bits & MBOX_BIT(n)) { - bits -= MBOX_BIT(n); - read_mailbox[n](); - } - } - return IRQ_HANDLED; -} - -void __init prcmu_early_init(void) -{ - if (cpu_is_u8500v11() || cpu_is_u8500ed()) { - tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE_V1); - } else if (cpu_is_u8500v2()) { - tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE); - } else { - pr_err("prcmu: Unsupported chip version\n"); - BUG(); - } -} - -static int __init prcmu_init(void) -{ - if (cpu_is_u8500ed()) { - pr_err("prcmu: Unsupported chip version\n"); - return 0; - } - - mutex_init(&mb1_transfer.lock); - init_completion(&mb1_transfer.work); - mutex_init(&mb5_transfer.lock); - init_completion(&mb5_transfer.work); - - /* Clean up the mailbox interrupts after pre-kernel code. */ - writel((MBOX_BIT(NUM_MBOX) - 1), PRCM_ARM_IT1_CLEAR); - - return request_irq(IRQ_DB8500_PRCMU1, prcmu_irq_handler, 0, - "prcmu", NULL); -} - -arch_initcall(prcmu_init); diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 3ed3ff06be5d..7eaeb9750793 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -538,7 +538,7 @@ config AB8500_CORE config AB8500_I2C_CORE bool "AB8500 register access via PRCMU I2C" - depends on AB8500_CORE && UX500_SOC_DB8500 + depends on AB8500_CORE && MFD_DB8500_PRCMU default y help This enables register access to the AB8500 chip via PRCMU I2C. @@ -575,6 +575,16 @@ config AB3550_CORE LEDs, vibrator, system power and temperature, power management and ALSA sound. +config MFD_DB8500_PRCMU + bool "ST-Ericsson DB8500 Power Reset Control Management Unit" + depends on UX500_SOC_DB8500 + select MFD_CORE + help + Select this option to enable support for the DB8500 Power Reset + and Control Management Unit. This is basically an autonomous + system controller running an XP70 microprocessor, which is accessed + through a register map. + config MFD_CS5535 tristate "Support for CS5535 and CS5536 southbridge core functions" select MFD_CORE diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 419caa9d7dcf..814c57a692a9 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -74,9 +74,11 @@ obj-$(CONFIG_AB3100_CORE) += ab3100-core.o obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o obj-$(CONFIG_AB3550_CORE) += ab3550-core.o obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-sysctrl.o -obj-$(CONFIG_AB8500_I2C_CORE) += ab8500-i2c.o obj-$(CONFIG_AB8500_DEBUG) += ab8500-debugfs.o obj-$(CONFIG_AB8500_GPADC) += ab8500-gpadc.o +obj-$(CONFIG_MFD_DB8500_PRCMU) += db8500-prcmu.o +# ab8500-i2c need to come after db8500-prcmu (which provides the channel) +obj-$(CONFIG_AB8500_I2C_CORE) += ab8500-i2c.o obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o obj-$(CONFIG_PMIC_ADP5520) += adp5520.o obj-$(CONFIG_LPC_SCH) += lpc_sch.o diff --git a/drivers/mfd/ab8500-i2c.c b/drivers/mfd/ab8500-i2c.c index 821e6b86afd2..9be541c6b004 100644 --- a/drivers/mfd/ab8500-i2c.c +++ b/drivers/mfd/ab8500-i2c.c @@ -11,8 +11,7 @@ #include #include #include - -#include +#include static int ab8500_i2c_write(struct ab8500 *ab8500, u16 addr, u8 data) { diff --git a/drivers/mfd/db8500-prcmu-regs.h b/drivers/mfd/db8500-prcmu-regs.h new file mode 100644 index 000000000000..c1226da19bfb --- /dev/null +++ b/drivers/mfd/db8500-prcmu-regs.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) STMicroelectronics 2009 + * Copyright (C) ST-Ericsson SA 2010 + * + * Author: Kumar Sanghvi + * Author: Sundar Iyer + * + * License Terms: GNU General Public License v2 + * + * PRCM Unit registers + */ + +#ifndef __MACH_PRCMU_REGS_H +#define __MACH_PRCMU_REGS_H + +#include + +#define PRCM_ARM_PLLDIVPS (_PRCMU_BASE + 0x118) +#define PRCM_ARM_CHGCLKREQ (_PRCMU_BASE + 0x114) +#define PRCM_PLLARM_ENABLE (_PRCMU_BASE + 0x98) +#define PRCM_ARMCLKFIX_MGT (_PRCMU_BASE + 0x0) +#define PRCM_A9_RESETN_CLR (_PRCMU_BASE + 0x1f4) +#define PRCM_A9_RESETN_SET (_PRCMU_BASE + 0x1f0) +#define PRCM_ARM_LS_CLAMP (_PRCMU_BASE + 0x30c) +#define PRCM_SRAM_A9 (_PRCMU_BASE + 0x308) + +/* ARM WFI Standby signal register */ +#define PRCM_ARM_WFI_STANDBY (_PRCMU_BASE + 0x130) +#define PRCMU_IOCR (_PRCMU_BASE + 0x310) + +/* CPU mailbox registers */ +#define PRCM_MBOX_CPU_VAL (_PRCMU_BASE + 0x0fc) +#define PRCM_MBOX_CPU_SET (_PRCMU_BASE + 0x100) +#define PRCM_MBOX_CPU_CLR (_PRCMU_BASE + 0x104) + +/* Dual A9 core interrupt management unit registers */ +#define PRCM_A9_MASK_REQ (_PRCMU_BASE + 0x328) +#define PRCM_A9_MASK_ACK (_PRCMU_BASE + 0x32c) +#define PRCM_ARMITMSK31TO0 (_PRCMU_BASE + 0x11c) +#define PRCM_ARMITMSK63TO32 (_PRCMU_BASE + 0x120) +#define PRCM_ARMITMSK95TO64 (_PRCMU_BASE + 0x124) +#define PRCM_ARMITMSK127TO96 (_PRCMU_BASE + 0x128) +#define PRCM_POWER_STATE_VAL (_PRCMU_BASE + 0x25C) +#define PRCM_ARMITVAL31TO0 (_PRCMU_BASE + 0x260) +#define PRCM_ARMITVAL63TO32 (_PRCMU_BASE + 0x264) +#define PRCM_ARMITVAL95TO64 (_PRCMU_BASE + 0x268) +#define PRCM_ARMITVAL127TO96 (_PRCMU_BASE + 0x26C) + +#define PRCM_HOSTACCESS_REQ (_PRCMU_BASE + 0x334) +#define ARM_WAKEUP_MODEM 0x1 + +#define PRCM_ARM_IT1_CLEAR (_PRCMU_BASE + 0x48C) +#define PRCM_ARM_IT1_VAL (_PRCMU_BASE + 0x494) +#define PRCM_HOLD_EVT (_PRCMU_BASE + 0x174) + +#define PRCM_ITSTATUS0 (_PRCMU_BASE + 0x148) +#define PRCM_ITSTATUS1 (_PRCMU_BASE + 0x150) +#define PRCM_ITSTATUS2 (_PRCMU_BASE + 0x158) +#define PRCM_ITSTATUS3 (_PRCMU_BASE + 0x160) +#define PRCM_ITSTATUS4 (_PRCMU_BASE + 0x168) +#define PRCM_ITSTATUS5 (_PRCMU_BASE + 0x484) +#define PRCM_ITCLEAR5 (_PRCMU_BASE + 0x488) +#define PRCM_ARMIT_MASKXP70_IT (_PRCMU_BASE + 0x1018) + +/* System reset register */ +#define PRCM_APE_SOFTRST (_PRCMU_BASE + 0x228) + +/* Level shifter and clamp control registers */ +#define PRCM_MMIP_LS_CLAMP_SET (_PRCMU_BASE + 0x420) +#define PRCM_MMIP_LS_CLAMP_CLR (_PRCMU_BASE + 0x424) + +/* PRCMU clock/PLL/reset registers */ +#define PRCM_PLLDSI_FREQ (_PRCMU_BASE + 0x500) +#define PRCM_PLLDSI_ENABLE (_PRCMU_BASE + 0x504) +#define PRCM_LCDCLK_MGT (_PRCMU_BASE + 0x044) +#define PRCM_MCDECLK_MGT (_PRCMU_BASE + 0x064) +#define PRCM_HDMICLK_MGT (_PRCMU_BASE + 0x058) +#define PRCM_TVCLK_MGT (_PRCMU_BASE + 0x07c) +#define PRCM_DSI_PLLOUT_SEL (_PRCMU_BASE + 0x530) +#define PRCM_DSITVCLK_DIV (_PRCMU_BASE + 0x52C) +#define PRCM_APE_RESETN_SET (_PRCMU_BASE + 0x1E4) +#define PRCM_APE_RESETN_CLR (_PRCMU_BASE + 0x1E8) + +/* ePOD and memory power signal control registers */ +#define PRCM_EPOD_C_SET (_PRCMU_BASE + 0x410) +#define PRCM_SRAM_LS_SLEEP (_PRCMU_BASE + 0x304) + +/* Debug power control unit registers */ +#define PRCM_POWER_STATE_SET (_PRCMU_BASE + 0x254) + +/* Miscellaneous unit registers */ +#define PRCM_DSI_SW_RESET (_PRCMU_BASE + 0x324) + +#endif /* __MACH_PRCMU_REGS_H */ diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c new file mode 100644 index 000000000000..31f18c8c6bf8 --- /dev/null +++ b/drivers/mfd/db8500-prcmu.c @@ -0,0 +1,395 @@ +/* + * Copyright (C) STMicroelectronics 2009 + * Copyright (C) ST-Ericsson SA 2010 + * + * License Terms: GNU General Public License v2 + * Author: Kumar Sanghvi + * Author: Sundar Iyer + * Author: Mattias Nilsson + * + * U8500 PRCM Unit interface driver + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "db8500-prcmu-regs.h" + +/* Global var to runtime determine TCDM base for v2 or v1 */ +static __iomem void *tcdm_base; + +#define _MBOX_HEADER (tcdm_base + 0xFE8) +#define MBOX_HEADER_REQ_MB0 (_MBOX_HEADER + 0x0) + +#define REQ_MB1 (tcdm_base + 0xFD0) +#define REQ_MB5 (tcdm_base + 0xE44) + +#define REQ_MB1_ARMOPP (REQ_MB1 + 0x0) +#define REQ_MB1_APEOPP (REQ_MB1 + 0x1) +#define REQ_MB1_BOOSTOPP (REQ_MB1 + 0x2) + +#define ACK_MB1 (tcdm_base + 0xE04) +#define ACK_MB5 (tcdm_base + 0xDF4) + +#define ACK_MB1_CURR_ARMOPP (ACK_MB1 + 0x0) +#define ACK_MB1_CURR_APEOPP (ACK_MB1 + 0x1) + +#define REQ_MB5_I2C_SLAVE_OP (REQ_MB5) +#define REQ_MB5_I2C_HW_BITS (REQ_MB5 + 1) +#define REQ_MB5_I2C_REG (REQ_MB5 + 2) +#define REQ_MB5_I2C_VAL (REQ_MB5 + 3) + +#define ACK_MB5_I2C_STATUS (ACK_MB5 + 1) +#define ACK_MB5_I2C_VAL (ACK_MB5 + 3) + +#define PRCM_AVS_VARM_MAX_OPP (tcdm_base + 0x2E4) +#define PRCM_AVS_ISMODEENABLE 7 +#define PRCM_AVS_ISMODEENABLE_MASK (1 << PRCM_AVS_ISMODEENABLE) + +#define I2C_WRITE(slave) \ + (((slave) << 1) | (cpu_is_u8500v2() ? BIT(6) : 0)) +#define I2C_READ(slave) \ + (((slave) << 1) | (cpu_is_u8500v2() ? BIT(6) : 0) | BIT(0)) +#define I2C_STOP_EN BIT(3) + +enum mb1_h { + MB1H_ARM_OPP = 1, + MB1H_APE_OPP, + MB1H_ARM_APE_OPP, +}; + +static struct { + struct mutex lock; + struct completion work; + struct { + u8 arm_opp; + u8 ape_opp; + u8 arm_status; + u8 ape_status; + } ack; +} mb1_transfer; + +enum ack_mb5_status { + I2C_WR_OK = 0x01, + I2C_RD_OK = 0x02, +}; + +#define MBOX_BIT BIT +#define NUM_MBOX 8 + +static struct { + struct mutex lock; + struct completion work; + bool failed; + struct { + u8 status; + u8 value; + } ack; +} mb5_transfer; + +/** + * prcmu_abb_read() - Read register value(s) from the ABB. + * @slave: The I2C slave address. + * @reg: The (start) register address. + * @value: The read out value(s). + * @size: The number of registers to read. + * + * Reads register value(s) from the ABB. + * @size has to be 1 for the current firmware version. + */ +int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size) +{ + int r; + + if (size != 1) + return -EINVAL; + + r = mutex_lock_interruptible(&mb5_transfer.lock); + if (r) + return r; + + while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5)) + cpu_relax(); + + writeb(I2C_READ(slave), REQ_MB5_I2C_SLAVE_OP); + writeb(I2C_STOP_EN, REQ_MB5_I2C_HW_BITS); + writeb(reg, REQ_MB5_I2C_REG); + + writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET); + if (!wait_for_completion_timeout(&mb5_transfer.work, + msecs_to_jiffies(500))) { + pr_err("prcmu: prcmu_abb_read timed out.\n"); + r = -EIO; + goto unlock_and_return; + } + r = ((mb5_transfer.ack.status == I2C_RD_OK) ? 0 : -EIO); + if (!r) + *value = mb5_transfer.ack.value; + +unlock_and_return: + mutex_unlock(&mb5_transfer.lock); + return r; +} +EXPORT_SYMBOL(prcmu_abb_read); + +/** + * prcmu_abb_write() - Write register value(s) to the ABB. + * @slave: The I2C slave address. + * @reg: The (start) register address. + * @value: The value(s) to write. + * @size: The number of registers to write. + * + * Reads register value(s) from the ABB. + * @size has to be 1 for the current firmware version. + */ +int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size) +{ + int r; + + if (size != 1) + return -EINVAL; + + r = mutex_lock_interruptible(&mb5_transfer.lock); + if (r) + return r; + + + while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5)) + cpu_relax(); + + writeb(I2C_WRITE(slave), REQ_MB5_I2C_SLAVE_OP); + writeb(I2C_STOP_EN, REQ_MB5_I2C_HW_BITS); + writeb(reg, REQ_MB5_I2C_REG); + writeb(*value, REQ_MB5_I2C_VAL); + + writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET); + if (!wait_for_completion_timeout(&mb5_transfer.work, + msecs_to_jiffies(500))) { + pr_err("prcmu: prcmu_abb_write timed out.\n"); + r = -EIO; + goto unlock_and_return; + } + r = ((mb5_transfer.ack.status == I2C_WR_OK) ? 0 : -EIO); + +unlock_and_return: + mutex_unlock(&mb5_transfer.lock); + return r; +} +EXPORT_SYMBOL(prcmu_abb_write); + +static int set_ape_cpu_opps(u8 header, enum prcmu_ape_opp ape_opp, + enum prcmu_cpu_opp cpu_opp) +{ + bool do_ape; + bool do_arm; + int err = 0; + + do_ape = ((header == MB1H_APE_OPP) || (header == MB1H_ARM_APE_OPP)); + do_arm = ((header == MB1H_ARM_OPP) || (header == MB1H_ARM_APE_OPP)); + + mutex_lock(&mb1_transfer.lock); + + while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(1)) + cpu_relax(); + + writeb(0, MBOX_HEADER_REQ_MB0); + writeb(cpu_opp, REQ_MB1_ARMOPP); + writeb(ape_opp, REQ_MB1_APEOPP); + writeb(0, REQ_MB1_BOOSTOPP); + writel(MBOX_BIT(1), PRCM_MBOX_CPU_SET); + wait_for_completion(&mb1_transfer.work); + if ((do_ape) && (mb1_transfer.ack.ape_status != 0)) + err = -EIO; + if ((do_arm) && (mb1_transfer.ack.arm_status != 0)) + err = -EIO; + + mutex_unlock(&mb1_transfer.lock); + + return err; +} + +/** + * prcmu_set_ape_opp() - Set the OPP of the APE. + * @opp: The OPP to set. + * + * This function sets the OPP of the APE. + */ +int prcmu_set_ape_opp(enum prcmu_ape_opp opp) +{ + return set_ape_cpu_opps(MB1H_APE_OPP, opp, APE_OPP_NO_CHANGE); +} +EXPORT_SYMBOL(prcmu_set_ape_opp); + +/** + * prcmu_set_cpu_opp() - Set the OPP of the CPU. + * @opp: The OPP to set. + * + * This function sets the OPP of the CPU. + */ +int prcmu_set_cpu_opp(enum prcmu_cpu_opp opp) +{ + return set_ape_cpu_opps(MB1H_ARM_OPP, CPU_OPP_NO_CHANGE, opp); +} +EXPORT_SYMBOL(prcmu_set_cpu_opp); + +/** + * prcmu_set_ape_cpu_opps() - Set the OPPs of the APE and the CPU. + * @ape_opp: The APE OPP to set. + * @cpu_opp: The CPU OPP to set. + * + * This function sets the OPPs of the APE and the CPU. + */ +int prcmu_set_ape_cpu_opps(enum prcmu_ape_opp ape_opp, + enum prcmu_cpu_opp cpu_opp) +{ + return set_ape_cpu_opps(MB1H_ARM_APE_OPP, ape_opp, cpu_opp); +} +EXPORT_SYMBOL(prcmu_set_ape_cpu_opps); + +/** + * prcmu_get_ape_opp() - Get the OPP of the APE. + * + * This function gets the OPP of the APE. + */ +enum prcmu_ape_opp prcmu_get_ape_opp(void) +{ + return readb(ACK_MB1_CURR_APEOPP); +} +EXPORT_SYMBOL(prcmu_get_ape_opp); + +/** + * prcmu_get_cpu_opp() - Get the OPP of the CPU. + * + * This function gets the OPP of the CPU. The OPP is specified in %%. + * PRCMU_OPP_EXT is a special OPP value, not specified in %%. + */ +int prcmu_get_cpu_opp(void) +{ + return readb(ACK_MB1_CURR_ARMOPP); +} +EXPORT_SYMBOL(prcmu_get_cpu_opp); + +bool prcmu_has_arm_maxopp(void) +{ + return (readb(PRCM_AVS_VARM_MAX_OPP) & PRCM_AVS_ISMODEENABLE_MASK) + == PRCM_AVS_ISMODEENABLE_MASK; +} + +static void read_mailbox_0(void) +{ + writel(MBOX_BIT(0), PRCM_ARM_IT1_CLEAR); +} + +static void read_mailbox_1(void) +{ + mb1_transfer.ack.arm_opp = readb(ACK_MB1_CURR_ARMOPP); + mb1_transfer.ack.ape_opp = readb(ACK_MB1_CURR_APEOPP); + complete(&mb1_transfer.work); + writel(MBOX_BIT(1), PRCM_ARM_IT1_CLEAR); +} + +static void read_mailbox_2(void) +{ + writel(MBOX_BIT(2), PRCM_ARM_IT1_CLEAR); +} + +static void read_mailbox_3(void) +{ + writel(MBOX_BIT(3), PRCM_ARM_IT1_CLEAR); +} + +static void read_mailbox_4(void) +{ + writel(MBOX_BIT(4), PRCM_ARM_IT1_CLEAR); +} + +static void read_mailbox_5(void) +{ + mb5_transfer.ack.status = readb(ACK_MB5_I2C_STATUS); + mb5_transfer.ack.value = readb(ACK_MB5_I2C_VAL); + complete(&mb5_transfer.work); + writel(MBOX_BIT(5), PRCM_ARM_IT1_CLEAR); +} + +static void read_mailbox_6(void) +{ + writel(MBOX_BIT(6), PRCM_ARM_IT1_CLEAR); +} + +static void read_mailbox_7(void) +{ + writel(MBOX_BIT(7), PRCM_ARM_IT1_CLEAR); +} + +static void (* const read_mailbox[NUM_MBOX])(void) = { + read_mailbox_0, + read_mailbox_1, + read_mailbox_2, + read_mailbox_3, + read_mailbox_4, + read_mailbox_5, + read_mailbox_6, + read_mailbox_7 +}; + +static irqreturn_t prcmu_irq_handler(int irq, void *data) +{ + u32 bits; + u8 n; + + bits = (readl(PRCM_ARM_IT1_VAL) & (MBOX_BIT(NUM_MBOX) - 1)); + if (unlikely(!bits)) + return IRQ_NONE; + + for (n = 0; bits; n++) { + if (bits & MBOX_BIT(n)) { + bits -= MBOX_BIT(n); + read_mailbox[n](); + } + } + return IRQ_HANDLED; +} + +void __init prcmu_early_init(void) +{ + if (cpu_is_u8500v11() || cpu_is_u8500ed()) { + tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE_V1); + } else if (cpu_is_u8500v2()) { + tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE); + } else { + pr_err("prcmu: Unsupported chip version\n"); + BUG(); + } +} + +static int __init prcmu_init(void) +{ + if (cpu_is_u8500ed()) { + pr_err("prcmu: Unsupported chip version\n"); + return 0; + } + + mutex_init(&mb1_transfer.lock); + init_completion(&mb1_transfer.work); + mutex_init(&mb5_transfer.lock); + init_completion(&mb5_transfer.work); + + /* Clean up the mailbox interrupts after pre-kernel code. */ + writel((MBOX_BIT(NUM_MBOX) - 1), PRCM_ARM_IT1_CLEAR); + + return request_irq(IRQ_DB8500_PRCMU1, prcmu_irq_handler, 0, + "prcmu", NULL); +} + +arch_initcall(prcmu_init); diff --git a/include/linux/mfd/db8500-prcmu.h b/include/linux/mfd/db8500-prcmu.h new file mode 100644 index 000000000000..d591d79aa6f0 --- /dev/null +++ b/include/linux/mfd/db8500-prcmu.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) STMicroelectronics 2009 + * Copyright (C) ST-Ericsson SA 2010 + * + * Author: Sundar Iyer + * Author: Martin Persson + * + * License Terms: GNU General Public License v2 + * + * PRCM Unit definitions + */ + +#ifndef __MACH_PRCMU_DEFS_H +#define __MACH_PRCMU_DEFS_H + +enum prcmu_cpu_opp { + CPU_OPP_INIT = 0x00, + CPU_OPP_NO_CHANGE = 0x01, + CPU_OPP_100 = 0x02, + CPU_OPP_50 = 0x03, + CPU_OPP_MAX = 0x04, + CPU_OPP_EXT_CLK = 0x07 +}; +enum prcmu_ape_opp { + APE_OPP_NO_CHANGE = 0x00, + APE_OPP_100 = 0x02, + APE_OPP_50 = 0x03, +}; + +#endif /* __MACH_PRCMU_DEFS_H */ + +/* + * Copyright (C) STMicroelectronics 2009 + * Copyright (C) ST-Ericsson SA 2010 + * + * Author: Kumar Sanghvi + * Author: Sundar Iyer + * Author: Mattias Nilsson + * + * License Terms: GNU General Public License v2 + * + * PRCM Unit f/w API + */ +#ifndef __MACH_PRCMU_H +#define __MACH_PRCMU_H + +void __init prcmu_early_init(void); +int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size); +int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size); +int prcmu_set_ape_opp(enum prcmu_ape_opp opp); +int prcmu_set_cpu_opp(enum prcmu_cpu_opp opp); +int prcmu_set_ape_cpu_opps(enum prcmu_ape_opp ape_opp, + enum prcmu_cpu_opp cpu_opp); +enum prcmu_ape_opp prcmu_get_ape_opp(void); +int prcmu_get_cpu_opp(void); +bool prcmu_has_arm_maxopp(void); + +#endif /* __MACH_PRCMU_H */ -- cgit From 3df57bcf5a6ba74572218a811bd0e311414f2aff Mon Sep 17 00:00:00 2001 From: Mattias Nilsson Date: Mon, 16 May 2011 00:15:05 +0200 Subject: mfd: update DB8500 PRCMU driver This updates the DB8500 PRCMU driver to the latest version available internally. Nominally we would update the dependent CPUfreq driver at the same time but since that is being moved around in this patch set we postpone that by simply deactivating it for the time being. This is a snapshot of the current PRCMU firmware API as it looks right now. The PRCMU firmware is still subject to change. This also updates the CPUfreq driver to a newer version that will utilize the new API. Acked-by: Samuel Ortiz Signed-off-by: Mattias Nilsson Signed-off-by: Martin Persson Signed-off-by: Per Fransson Signed-off-by: Jonas Aaberg Signed-off-by: Sebastien Rault Signed-off-by: Bengt Jonsson Signed-off-by: Rickard Andersson Signed-off-by: Linus Walleij --- arch/arm/mach-ux500/Makefile | 2 +- arch/arm/mach-ux500/cpu-db8500.c | 5 + drivers/mfd/db8500-prcmu-regs.h | 194 ++-- drivers/mfd/db8500-prcmu.c | 1879 ++++++++++++++++++++++++++++++++++---- include/linux/mfd/db8500-prcmu.h | 992 +++++++++++++++++++- 5 files changed, 2782 insertions(+), 290 deletions(-) (limited to 'include/linux') diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile index 7a1d43e04f97..1694916e6822 100644 --- a/arch/arm/mach-ux500/Makefile +++ b/arch/arm/mach-ux500/Makefile @@ -17,4 +17,4 @@ obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o obj-$(CONFIG_U5500_MODEM_IRQ) += modem-irq-db5500.o obj-$(CONFIG_U5500_MBOX) += mbox-db5500.o -obj-$(CONFIG_CPU_FREQ) += cpufreq.o + diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index 3d419fef0470..c3c417656bd9 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -131,9 +131,14 @@ static struct platform_device db8500_pmu_device = { .dev.platform_data = &db8500_pmu_platdata, }; +static struct platform_device db8500_prcmu_device = { + .name = "db8500-prcmu", +}; + static struct platform_device *platform_devs[] __initdata = { &u8500_dma40_device, &db8500_pmu_device, + &db8500_prcmu_device, }; static resource_size_t __initdata db8500_gpio_base[] = { diff --git a/drivers/mfd/db8500-prcmu-regs.h b/drivers/mfd/db8500-prcmu-regs.h index c1226da19bfb..3bbf04d58043 100644 --- a/drivers/mfd/db8500-prcmu-regs.h +++ b/drivers/mfd/db8500-prcmu-regs.h @@ -9,86 +9,158 @@ * * PRCM Unit registers */ +#ifndef __DB8500_PRCMU_REGS_H +#define __DB8500_PRCMU_REGS_H -#ifndef __MACH_PRCMU_REGS_H -#define __MACH_PRCMU_REGS_H - +#include #include -#define PRCM_ARM_PLLDIVPS (_PRCMU_BASE + 0x118) -#define PRCM_ARM_CHGCLKREQ (_PRCMU_BASE + 0x114) -#define PRCM_PLLARM_ENABLE (_PRCMU_BASE + 0x98) -#define PRCM_ARMCLKFIX_MGT (_PRCMU_BASE + 0x0) -#define PRCM_A9_RESETN_CLR (_PRCMU_BASE + 0x1f4) -#define PRCM_A9_RESETN_SET (_PRCMU_BASE + 0x1f0) -#define PRCM_ARM_LS_CLAMP (_PRCMU_BASE + 0x30c) -#define PRCM_SRAM_A9 (_PRCMU_BASE + 0x308) +#define BITS(_start, _end) ((BIT(_end) - BIT(_start)) + BIT(_end)) + +#define PRCM_ARM_PLLDIVPS 0x118 +#define PRCM_ARM_PLLDIVPS_ARM_BRM_RATE BITS(0, 5) +#define PRCM_ARM_PLLDIVPS_MAX_MASK 0xF + +#define PRCM_PLLARM_LOCKP 0x0A8 +#define PRCM_PLLARM_LOCKP_PRCM_PLLARM_LOCKP3 BIT(1) + +#define PRCM_ARM_CHGCLKREQ 0x114 +#define PRCM_ARM_CHGCLKREQ_PRCM_ARM_CHGCLKREQ BIT(0) + +#define PRCM_PLLARM_ENABLE 0x98 +#define PRCM_PLLARM_ENABLE_PRCM_PLLARM_ENABLE BIT(0) +#define PRCM_PLLARM_ENABLE_PRCM_PLLARM_COUNTON BIT(8) + +#define PRCM_ARMCLKFIX_MGT 0x0 +#define PRCM_A9_RESETN_CLR 0x1f4 +#define PRCM_A9_RESETN_SET 0x1f0 +#define PRCM_ARM_LS_CLAMP 0x30C +#define PRCM_SRAM_A9 0x308 /* ARM WFI Standby signal register */ -#define PRCM_ARM_WFI_STANDBY (_PRCMU_BASE + 0x130) -#define PRCMU_IOCR (_PRCMU_BASE + 0x310) +#define PRCM_ARM_WFI_STANDBY 0x130 +#define PRCM_IOCR 0x310 +#define PRCM_IOCR_IOFORCE BIT(0) /* CPU mailbox registers */ -#define PRCM_MBOX_CPU_VAL (_PRCMU_BASE + 0x0fc) -#define PRCM_MBOX_CPU_SET (_PRCMU_BASE + 0x100) -#define PRCM_MBOX_CPU_CLR (_PRCMU_BASE + 0x104) +#define PRCM_MBOX_CPU_VAL 0x0FC +#define PRCM_MBOX_CPU_SET 0x100 /* Dual A9 core interrupt management unit registers */ -#define PRCM_A9_MASK_REQ (_PRCMU_BASE + 0x328) -#define PRCM_A9_MASK_ACK (_PRCMU_BASE + 0x32c) -#define PRCM_ARMITMSK31TO0 (_PRCMU_BASE + 0x11c) -#define PRCM_ARMITMSK63TO32 (_PRCMU_BASE + 0x120) -#define PRCM_ARMITMSK95TO64 (_PRCMU_BASE + 0x124) -#define PRCM_ARMITMSK127TO96 (_PRCMU_BASE + 0x128) -#define PRCM_POWER_STATE_VAL (_PRCMU_BASE + 0x25C) -#define PRCM_ARMITVAL31TO0 (_PRCMU_BASE + 0x260) -#define PRCM_ARMITVAL63TO32 (_PRCMU_BASE + 0x264) -#define PRCM_ARMITVAL95TO64 (_PRCMU_BASE + 0x268) -#define PRCM_ARMITVAL127TO96 (_PRCMU_BASE + 0x26C) - -#define PRCM_HOSTACCESS_REQ (_PRCMU_BASE + 0x334) -#define ARM_WAKEUP_MODEM 0x1 - -#define PRCM_ARM_IT1_CLEAR (_PRCMU_BASE + 0x48C) -#define PRCM_ARM_IT1_VAL (_PRCMU_BASE + 0x494) -#define PRCM_HOLD_EVT (_PRCMU_BASE + 0x174) - -#define PRCM_ITSTATUS0 (_PRCMU_BASE + 0x148) -#define PRCM_ITSTATUS1 (_PRCMU_BASE + 0x150) -#define PRCM_ITSTATUS2 (_PRCMU_BASE + 0x158) -#define PRCM_ITSTATUS3 (_PRCMU_BASE + 0x160) -#define PRCM_ITSTATUS4 (_PRCMU_BASE + 0x168) -#define PRCM_ITSTATUS5 (_PRCMU_BASE + 0x484) -#define PRCM_ITCLEAR5 (_PRCMU_BASE + 0x488) -#define PRCM_ARMIT_MASKXP70_IT (_PRCMU_BASE + 0x1018) +#define PRCM_A9_MASK_REQ 0x328 +#define PRCM_A9_MASK_REQ_PRCM_A9_MASK_REQ BIT(0) + +#define PRCM_A9_MASK_ACK 0x32C +#define PRCM_ARMITMSK31TO0 0x11C +#define PRCM_ARMITMSK63TO32 0x120 +#define PRCM_ARMITMSK95TO64 0x124 +#define PRCM_ARMITMSK127TO96 0x128 +#define PRCM_POWER_STATE_VAL 0x25C +#define PRCM_ARMITVAL31TO0 0x260 +#define PRCM_ARMITVAL63TO32 0x264 +#define PRCM_ARMITVAL95TO64 0x268 +#define PRCM_ARMITVAL127TO96 0x26C + +#define PRCM_HOSTACCESS_REQ 0x334 +#define PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ BIT(0) + +#define PRCM_ARM_IT1_CLR 0x48C +#define PRCM_ARM_IT1_VAL 0x494 + +#define PRCM_ITSTATUS0 0x148 +#define PRCM_ITSTATUS1 0x150 +#define PRCM_ITSTATUS2 0x158 +#define PRCM_ITSTATUS3 0x160 +#define PRCM_ITSTATUS4 0x168 +#define PRCM_ITSTATUS5 0x484 +#define PRCM_ITCLEAR5 0x488 +#define PRCM_ARMIT_MASKXP70_IT 0x1018 /* System reset register */ -#define PRCM_APE_SOFTRST (_PRCMU_BASE + 0x228) +#define PRCM_APE_SOFTRST 0x228 /* Level shifter and clamp control registers */ -#define PRCM_MMIP_LS_CLAMP_SET (_PRCMU_BASE + 0x420) -#define PRCM_MMIP_LS_CLAMP_CLR (_PRCMU_BASE + 0x424) +#define PRCM_MMIP_LS_CLAMP_SET 0x420 +#define PRCM_MMIP_LS_CLAMP_CLR 0x424 + +/* PRCMU HW semaphore */ +#define PRCM_SEM 0x400 +#define PRCM_SEM_PRCM_SEM BIT(0) /* PRCMU clock/PLL/reset registers */ -#define PRCM_PLLDSI_FREQ (_PRCMU_BASE + 0x500) -#define PRCM_PLLDSI_ENABLE (_PRCMU_BASE + 0x504) -#define PRCM_LCDCLK_MGT (_PRCMU_BASE + 0x044) -#define PRCM_MCDECLK_MGT (_PRCMU_BASE + 0x064) -#define PRCM_HDMICLK_MGT (_PRCMU_BASE + 0x058) -#define PRCM_TVCLK_MGT (_PRCMU_BASE + 0x07c) -#define PRCM_DSI_PLLOUT_SEL (_PRCMU_BASE + 0x530) -#define PRCM_DSITVCLK_DIV (_PRCMU_BASE + 0x52C) -#define PRCM_APE_RESETN_SET (_PRCMU_BASE + 0x1E4) -#define PRCM_APE_RESETN_CLR (_PRCMU_BASE + 0x1E8) +#define PRCM_PLLDSI_FREQ 0x500 +#define PRCM_PLLDSI_ENABLE 0x504 +#define PRCM_PLLDSI_LOCKP 0x508 +#define PRCM_DSI_PLLOUT_SEL 0x530 +#define PRCM_DSITVCLK_DIV 0x52C +#define PRCM_APE_RESETN_SET 0x1E4 +#define PRCM_APE_RESETN_CLR 0x1E8 + +#define PRCM_TCR 0x1C8 +#define PRCM_TCR_TENSEL_MASK BITS(0, 7) +#define PRCM_TCR_STOP_TIMERS BIT(16) +#define PRCM_TCR_DOZE_MODE BIT(17) + +#define PRCM_CLKOCR 0x1CC +#define PRCM_CLKOCR_CLKODIV0_SHIFT 0 +#define PRCM_CLKOCR_CLKODIV0_MASK BITS(0, 5) +#define PRCM_CLKOCR_CLKOSEL0_SHIFT 6 +#define PRCM_CLKOCR_CLKOSEL0_MASK BITS(6, 8) +#define PRCM_CLKOCR_CLKODIV1_SHIFT 16 +#define PRCM_CLKOCR_CLKODIV1_MASK BITS(16, 21) +#define PRCM_CLKOCR_CLKOSEL1_SHIFT 22 +#define PRCM_CLKOCR_CLKOSEL1_MASK BITS(22, 24) +#define PRCM_CLKOCR_CLK1TYPE BIT(28) + +#define PRCM_SGACLK_MGT 0x014 +#define PRCM_UARTCLK_MGT 0x018 +#define PRCM_MSP02CLK_MGT 0x01C +#define PRCM_MSP1CLK_MGT 0x288 +#define PRCM_I2CCLK_MGT 0x020 +#define PRCM_SDMMCCLK_MGT 0x024 +#define PRCM_SLIMCLK_MGT 0x028 +#define PRCM_PER1CLK_MGT 0x02C +#define PRCM_PER2CLK_MGT 0x030 +#define PRCM_PER3CLK_MGT 0x034 +#define PRCM_PER5CLK_MGT 0x038 +#define PRCM_PER6CLK_MGT 0x03C +#define PRCM_PER7CLK_MGT 0x040 +#define PRCM_LCDCLK_MGT 0x044 +#define PRCM_BMLCLK_MGT 0x04C +#define PRCM_HSITXCLK_MGT 0x050 +#define PRCM_HSIRXCLK_MGT 0x054 +#define PRCM_HDMICLK_MGT 0x058 +#define PRCM_APEATCLK_MGT 0x05C +#define PRCM_APETRACECLK_MGT 0x060 +#define PRCM_MCDECLK_MGT 0x064 +#define PRCM_IPI2CCLK_MGT 0x068 +#define PRCM_DSIALTCLK_MGT 0x06C +#define PRCM_DMACLK_MGT 0x074 +#define PRCM_B2R2CLK_MGT 0x078 +#define PRCM_TVCLK_MGT 0x07C +#define PRCM_UNIPROCLK_MGT 0x278 +#define PRCM_SSPCLK_MGT 0x280 +#define PRCM_RNGCLK_MGT 0x284 +#define PRCM_UICCCLK_MGT 0x27C + +#define PRCM_CLK_MGT_CLKPLLDIV_MASK BITS(0, 4) +#define PRCM_CLK_MGT_CLKPLLSW_MASK BITS(5, 7) +#define PRCM_CLK_MGT_CLKEN BIT(8) /* ePOD and memory power signal control registers */ -#define PRCM_EPOD_C_SET (_PRCMU_BASE + 0x410) -#define PRCM_SRAM_LS_SLEEP (_PRCMU_BASE + 0x304) +#define PRCM_EPOD_C_SET 0x410 +#define PRCM_SRAM_LS_SLEEP 0x304 /* Debug power control unit registers */ -#define PRCM_POWER_STATE_SET (_PRCMU_BASE + 0x254) +#define PRCM_POWER_STATE_SET 0x254 /* Miscellaneous unit registers */ -#define PRCM_DSI_SW_RESET (_PRCMU_BASE + 0x324) +#define PRCM_DSI_SW_RESET 0x324 +#define PRCM_GPIOCR 0x138 + +/* GPIOCR register */ +#define PRCM_GPIOCR_SPI2_SELECT BIT(23) + +#define PRCM_DDR_SUBSYS_APE_MINBW 0x438 -#endif /* __MACH_PRCMU_REGS_H */ +#endif /* __DB8500_PRCMU_REGS_H */ diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index 31f18c8c6bf8..c44725bd8b9a 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c @@ -10,93 +10,1354 @@ * U8500 PRCM Unit interface driver * */ -#include #include +#include +#include #include #include +#include #include +#include #include #include +#include #include #include -#include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include "db8500-prcmu-regs.h" + +/* Offset for the firmware version within the TCPM */ +#define PRCMU_FW_VERSION_OFFSET 0xA4 + +/* PRCMU project numbers, defined by PRCMU FW */ +#define PRCMU_PROJECT_ID_8500V1_0 1 +#define PRCMU_PROJECT_ID_8500V2_0 2 +#define PRCMU_PROJECT_ID_8400V2_0 3 + +/* Index of different voltages to be used when accessing AVSData */ +#define PRCM_AVS_BASE 0x2FC +#define PRCM_AVS_VBB_RET (PRCM_AVS_BASE + 0x0) +#define PRCM_AVS_VBB_MAX_OPP (PRCM_AVS_BASE + 0x1) +#define PRCM_AVS_VBB_100_OPP (PRCM_AVS_BASE + 0x2) +#define PRCM_AVS_VBB_50_OPP (PRCM_AVS_BASE + 0x3) +#define PRCM_AVS_VARM_MAX_OPP (PRCM_AVS_BASE + 0x4) +#define PRCM_AVS_VARM_100_OPP (PRCM_AVS_BASE + 0x5) +#define PRCM_AVS_VARM_50_OPP (PRCM_AVS_BASE + 0x6) +#define PRCM_AVS_VARM_RET (PRCM_AVS_BASE + 0x7) +#define PRCM_AVS_VAPE_100_OPP (PRCM_AVS_BASE + 0x8) +#define PRCM_AVS_VAPE_50_OPP (PRCM_AVS_BASE + 0x9) +#define PRCM_AVS_VMOD_100_OPP (PRCM_AVS_BASE + 0xA) +#define PRCM_AVS_VMOD_50_OPP (PRCM_AVS_BASE + 0xB) +#define PRCM_AVS_VSAFE (PRCM_AVS_BASE + 0xC) + +#define PRCM_AVS_VOLTAGE 0 +#define PRCM_AVS_VOLTAGE_MASK 0x3f +#define PRCM_AVS_ISSLOWSTARTUP 6 +#define PRCM_AVS_ISSLOWSTARTUP_MASK (1 << PRCM_AVS_ISSLOWSTARTUP) +#define PRCM_AVS_ISMODEENABLE 7 +#define PRCM_AVS_ISMODEENABLE_MASK (1 << PRCM_AVS_ISMODEENABLE) + +#define PRCM_BOOT_STATUS 0xFFF +#define PRCM_ROMCODE_A2P 0xFFE +#define PRCM_ROMCODE_P2A 0xFFD +#define PRCM_XP70_CUR_PWR_STATE 0xFFC /* 4 BYTES */ + +#define PRCM_SW_RST_REASON 0xFF8 /* 2 bytes */ + +#define _PRCM_MBOX_HEADER 0xFE8 /* 16 bytes */ +#define PRCM_MBOX_HEADER_REQ_MB0 (_PRCM_MBOX_HEADER + 0x0) +#define PRCM_MBOX_HEADER_REQ_MB1 (_PRCM_MBOX_HEADER + 0x1) +#define PRCM_MBOX_HEADER_REQ_MB2 (_PRCM_MBOX_HEADER + 0x2) +#define PRCM_MBOX_HEADER_REQ_MB3 (_PRCM_MBOX_HEADER + 0x3) +#define PRCM_MBOX_HEADER_REQ_MB4 (_PRCM_MBOX_HEADER + 0x4) +#define PRCM_MBOX_HEADER_REQ_MB5 (_PRCM_MBOX_HEADER + 0x5) +#define PRCM_MBOX_HEADER_ACK_MB0 (_PRCM_MBOX_HEADER + 0x8) + +/* Req Mailboxes */ +#define PRCM_REQ_MB0 0xFDC /* 12 bytes */ +#define PRCM_REQ_MB1 0xFD0 /* 12 bytes */ +#define PRCM_REQ_MB2 0xFC0 /* 16 bytes */ +#define PRCM_REQ_MB3 0xE4C /* 372 bytes */ +#define PRCM_REQ_MB4 0xE48 /* 4 bytes */ +#define PRCM_REQ_MB5 0xE44 /* 4 bytes */ + +/* Ack Mailboxes */ +#define PRCM_ACK_MB0 0xE08 /* 52 bytes */ +#define PRCM_ACK_MB1 0xE04 /* 4 bytes */ +#define PRCM_ACK_MB2 0xE00 /* 4 bytes */ +#define PRCM_ACK_MB3 0xDFC /* 4 bytes */ +#define PRCM_ACK_MB4 0xDF8 /* 4 bytes */ +#define PRCM_ACK_MB5 0xDF4 /* 4 bytes */ + +/* Mailbox 0 headers */ +#define MB0H_POWER_STATE_TRANS 0 +#define MB0H_CONFIG_WAKEUPS_EXE 1 +#define MB0H_READ_WAKEUP_ACK 3 +#define MB0H_CONFIG_WAKEUPS_SLEEP 4 + +#define MB0H_WAKEUP_EXE 2 +#define MB0H_WAKEUP_SLEEP 5 + +/* Mailbox 0 REQs */ +#define PRCM_REQ_MB0_AP_POWER_STATE (PRCM_REQ_MB0 + 0x0) +#define PRCM_REQ_MB0_AP_PLL_STATE (PRCM_REQ_MB0 + 0x1) +#define PRCM_REQ_MB0_ULP_CLOCK_STATE (PRCM_REQ_MB0 + 0x2) +#define PRCM_REQ_MB0_DO_NOT_WFI (PRCM_REQ_MB0 + 0x3) +#define PRCM_REQ_MB0_WAKEUP_8500 (PRCM_REQ_MB0 + 0x4) +#define PRCM_REQ_MB0_WAKEUP_4500 (PRCM_REQ_MB0 + 0x8) + +/* Mailbox 0 ACKs */ +#define PRCM_ACK_MB0_AP_PWRSTTR_STATUS (PRCM_ACK_MB0 + 0x0) +#define PRCM_ACK_MB0_READ_POINTER (PRCM_ACK_MB0 + 0x1) +#define PRCM_ACK_MB0_WAKEUP_0_8500 (PRCM_ACK_MB0 + 0x4) +#define PRCM_ACK_MB0_WAKEUP_0_4500 (PRCM_ACK_MB0 + 0x8) +#define PRCM_ACK_MB0_WAKEUP_1_8500 (PRCM_ACK_MB0 + 0x1C) +#define PRCM_ACK_MB0_WAKEUP_1_4500 (PRCM_ACK_MB0 + 0x20) +#define PRCM_ACK_MB0_EVENT_4500_NUMBERS 20 + +/* Mailbox 1 headers */ +#define MB1H_ARM_APE_OPP 0x0 +#define MB1H_RESET_MODEM 0x2 +#define MB1H_REQUEST_APE_OPP_100_VOLT 0x3 +#define MB1H_RELEASE_APE_OPP_100_VOLT 0x4 +#define MB1H_RELEASE_USB_WAKEUP 0x5 + +/* Mailbox 1 Requests */ +#define PRCM_REQ_MB1_ARM_OPP (PRCM_REQ_MB1 + 0x0) +#define PRCM_REQ_MB1_APE_OPP (PRCM_REQ_MB1 + 0x1) +#define PRCM_REQ_MB1_APE_OPP_100_RESTORE (PRCM_REQ_MB1 + 0x4) +#define PRCM_REQ_MB1_ARM_OPP_100_RESTORE (PRCM_REQ_MB1 + 0x8) + +/* Mailbox 1 ACKs */ +#define PRCM_ACK_MB1_CURRENT_ARM_OPP (PRCM_ACK_MB1 + 0x0) +#define PRCM_ACK_MB1_CURRENT_APE_OPP (PRCM_ACK_MB1 + 0x1) +#define PRCM_ACK_MB1_APE_VOLTAGE_STATUS (PRCM_ACK_MB1 + 0x2) +#define PRCM_ACK_MB1_DVFS_STATUS (PRCM_ACK_MB1 + 0x3) + +/* Mailbox 2 headers */ +#define MB2H_DPS 0x0 +#define MB2H_AUTO_PWR 0x1 + +/* Mailbox 2 REQs */ +#define PRCM_REQ_MB2_SVA_MMDSP (PRCM_REQ_MB2 + 0x0) +#define PRCM_REQ_MB2_SVA_PIPE (PRCM_REQ_MB2 + 0x1) +#define PRCM_REQ_MB2_SIA_MMDSP (PRCM_REQ_MB2 + 0x2) +#define PRCM_REQ_MB2_SIA_PIPE (PRCM_REQ_MB2 + 0x3) +#define PRCM_REQ_MB2_SGA (PRCM_REQ_MB2 + 0x4) +#define PRCM_REQ_MB2_B2R2_MCDE (PRCM_REQ_MB2 + 0x5) +#define PRCM_REQ_MB2_ESRAM12 (PRCM_REQ_MB2 + 0x6) +#define PRCM_REQ_MB2_ESRAM34 (PRCM_REQ_MB2 + 0x7) +#define PRCM_REQ_MB2_AUTO_PM_SLEEP (PRCM_REQ_MB2 + 0x8) +#define PRCM_REQ_MB2_AUTO_PM_IDLE (PRCM_REQ_MB2 + 0xC) + +/* Mailbox 2 ACKs */ +#define PRCM_ACK_MB2_DPS_STATUS (PRCM_ACK_MB2 + 0x0) +#define HWACC_PWR_ST_OK 0xFE + +/* Mailbox 3 headers */ +#define MB3H_ANC 0x0 +#define MB3H_SIDETONE 0x1 +#define MB3H_SYSCLK 0xE + +/* Mailbox 3 Requests */ +#define PRCM_REQ_MB3_ANC_FIR_COEFF (PRCM_REQ_MB3 + 0x0) +#define PRCM_REQ_MB3_ANC_IIR_COEFF (PRCM_REQ_MB3 + 0x20) +#define PRCM_REQ_MB3_ANC_SHIFTER (PRCM_REQ_MB3 + 0x60) +#define PRCM_REQ_MB3_ANC_WARP (PRCM_REQ_MB3 + 0x64) +#define PRCM_REQ_MB3_SIDETONE_FIR_GAIN (PRCM_REQ_MB3 + 0x68) +#define PRCM_REQ_MB3_SIDETONE_FIR_COEFF (PRCM_REQ_MB3 + 0x6C) +#define PRCM_REQ_MB3_SYSCLK_MGT (PRCM_REQ_MB3 + 0x16C) + +/* Mailbox 4 headers */ +#define MB4H_DDR_INIT 0x0 +#define MB4H_MEM_ST 0x1 +#define MB4H_HOTDOG 0x12 +#define MB4H_HOTMON 0x13 +#define MB4H_HOT_PERIOD 0x14 + +/* Mailbox 4 Requests */ +#define PRCM_REQ_MB4_DDR_ST_AP_SLEEP_IDLE (PRCM_REQ_MB4 + 0x0) +#define PRCM_REQ_MB4_DDR_ST_AP_DEEP_IDLE (PRCM_REQ_MB4 + 0x1) +#define PRCM_REQ_MB4_ESRAM0_ST (PRCM_REQ_MB4 + 0x3) +#define PRCM_REQ_MB4_HOTDOG_THRESHOLD (PRCM_REQ_MB4 + 0x0) +#define PRCM_REQ_MB4_HOTMON_LOW (PRCM_REQ_MB4 + 0x0) +#define PRCM_REQ_MB4_HOTMON_HIGH (PRCM_REQ_MB4 + 0x1) +#define PRCM_REQ_MB4_HOTMON_CONFIG (PRCM_REQ_MB4 + 0x2) +#define PRCM_REQ_MB4_HOT_PERIOD (PRCM_REQ_MB4 + 0x0) +#define HOTMON_CONFIG_LOW BIT(0) +#define HOTMON_CONFIG_HIGH BIT(1) + +/* Mailbox 5 Requests */ +#define PRCM_REQ_MB5_I2C_SLAVE_OP (PRCM_REQ_MB5 + 0x0) +#define PRCM_REQ_MB5_I2C_HW_BITS (PRCM_REQ_MB5 + 0x1) +#define PRCM_REQ_MB5_I2C_REG (PRCM_REQ_MB5 + 0x2) +#define PRCM_REQ_MB5_I2C_VAL (PRCM_REQ_MB5 + 0x3) +#define PRCMU_I2C_WRITE(slave) \ + (((slave) << 1) | (cpu_is_u8500v2() ? BIT(6) : 0)) +#define PRCMU_I2C_READ(slave) \ + (((slave) << 1) | BIT(0) | (cpu_is_u8500v2() ? BIT(6) : 0)) +#define PRCMU_I2C_STOP_EN BIT(3) + +/* Mailbox 5 ACKs */ +#define PRCM_ACK_MB5_I2C_STATUS (PRCM_ACK_MB5 + 0x1) +#define PRCM_ACK_MB5_I2C_VAL (PRCM_ACK_MB5 + 0x3) +#define I2C_WR_OK 0x1 +#define I2C_RD_OK 0x2 + +#define NUM_MB 8 +#define MBOX_BIT BIT +#define ALL_MBOX_BITS (MBOX_BIT(NUM_MB) - 1) + +/* + * Wakeups/IRQs + */ + +#define WAKEUP_BIT_RTC BIT(0) +#define WAKEUP_BIT_RTT0 BIT(1) +#define WAKEUP_BIT_RTT1 BIT(2) +#define WAKEUP_BIT_HSI0 BIT(3) +#define WAKEUP_BIT_HSI1 BIT(4) +#define WAKEUP_BIT_CA_WAKE BIT(5) +#define WAKEUP_BIT_USB BIT(6) +#define WAKEUP_BIT_ABB BIT(7) +#define WAKEUP_BIT_ABB_FIFO BIT(8) +#define WAKEUP_BIT_SYSCLK_OK BIT(9) +#define WAKEUP_BIT_CA_SLEEP BIT(10) +#define WAKEUP_BIT_AC_WAKE_ACK BIT(11) +#define WAKEUP_BIT_SIDE_TONE_OK BIT(12) +#define WAKEUP_BIT_ANC_OK BIT(13) +#define WAKEUP_BIT_SW_ERROR BIT(14) +#define WAKEUP_BIT_AC_SLEEP_ACK BIT(15) +#define WAKEUP_BIT_ARM BIT(17) +#define WAKEUP_BIT_HOTMON_LOW BIT(18) +#define WAKEUP_BIT_HOTMON_HIGH BIT(19) +#define WAKEUP_BIT_MODEM_SW_RESET_REQ BIT(20) +#define WAKEUP_BIT_GPIO0 BIT(23) +#define WAKEUP_BIT_GPIO1 BIT(24) +#define WAKEUP_BIT_GPIO2 BIT(25) +#define WAKEUP_BIT_GPIO3 BIT(26) +#define WAKEUP_BIT_GPIO4 BIT(27) +#define WAKEUP_BIT_GPIO5 BIT(28) +#define WAKEUP_BIT_GPIO6 BIT(29) +#define WAKEUP_BIT_GPIO7 BIT(30) +#define WAKEUP_BIT_GPIO8 BIT(31) + +/* + * This vector maps irq numbers to the bits in the bit field used in + * communication with the PRCMU firmware. + * + * The reason for having this is to keep the irq numbers contiguous even though + * the bits in the bit field are not. (The bits also have a tendency to move + * around, to further complicate matters.) + */ +#define IRQ_INDEX(_name) ((IRQ_PRCMU_##_name) - IRQ_PRCMU_BASE) +#define IRQ_ENTRY(_name)[IRQ_INDEX(_name)] = (WAKEUP_BIT_##_name) +static u32 prcmu_irq_bit[NUM_PRCMU_WAKEUPS] = { + IRQ_ENTRY(RTC), + IRQ_ENTRY(RTT0), + IRQ_ENTRY(RTT1), + IRQ_ENTRY(HSI0), + IRQ_ENTRY(HSI1), + IRQ_ENTRY(CA_WAKE), + IRQ_ENTRY(USB), + IRQ_ENTRY(ABB), + IRQ_ENTRY(ABB_FIFO), + IRQ_ENTRY(CA_SLEEP), + IRQ_ENTRY(ARM), + IRQ_ENTRY(HOTMON_LOW), + IRQ_ENTRY(HOTMON_HIGH), + IRQ_ENTRY(MODEM_SW_RESET_REQ), + IRQ_ENTRY(GPIO0), + IRQ_ENTRY(GPIO1), + IRQ_ENTRY(GPIO2), + IRQ_ENTRY(GPIO3), + IRQ_ENTRY(GPIO4), + IRQ_ENTRY(GPIO5), + IRQ_ENTRY(GPIO6), + IRQ_ENTRY(GPIO7), + IRQ_ENTRY(GPIO8) +}; + +#define VALID_WAKEUPS (BIT(NUM_PRCMU_WAKEUP_INDICES) - 1) +#define WAKEUP_ENTRY(_name)[PRCMU_WAKEUP_INDEX_##_name] = (WAKEUP_BIT_##_name) +static u32 prcmu_wakeup_bit[NUM_PRCMU_WAKEUP_INDICES] = { + WAKEUP_ENTRY(RTC), + WAKEUP_ENTRY(RTT0), + WAKEUP_ENTRY(RTT1), + WAKEUP_ENTRY(HSI0), + WAKEUP_ENTRY(HSI1), + WAKEUP_ENTRY(USB), + WAKEUP_ENTRY(ABB), + WAKEUP_ENTRY(ABB_FIFO), + WAKEUP_ENTRY(ARM) +}; + +/* + * mb0_transfer - state needed for mailbox 0 communication. + * @lock: The transaction lock. + * @dbb_events_lock: A lock used to handle concurrent access to (parts of) + * the request data. + * @mask_work: Work structure used for (un)masking wakeup interrupts. + * @req: Request data that need to persist between requests. + */ +static struct { + spinlock_t lock; + spinlock_t dbb_irqs_lock; + struct work_struct mask_work; + struct mutex ac_wake_lock; + struct completion ac_wake_work; + struct { + u32 dbb_irqs; + u32 dbb_wakeups; + u32 abb_events; + } req; +} mb0_transfer; + +/* + * mb1_transfer - state needed for mailbox 1 communication. + * @lock: The transaction lock. + * @work: The transaction completion structure. + * @ack: Reply ("acknowledge") data. + */ +static struct { + struct mutex lock; + struct completion work; + struct { + u8 header; + u8 arm_opp; + u8 ape_opp; + u8 ape_voltage_status; + } ack; +} mb1_transfer; + +/* + * mb2_transfer - state needed for mailbox 2 communication. + * @lock: The transaction lock. + * @work: The transaction completion structure. + * @auto_pm_lock: The autonomous power management configuration lock. + * @auto_pm_enabled: A flag indicating whether autonomous PM is enabled. + * @req: Request data that need to persist between requests. + * @ack: Reply ("acknowledge") data. + */ +static struct { + struct mutex lock; + struct completion work; + spinlock_t auto_pm_lock; + bool auto_pm_enabled; + struct { + u8 status; + } ack; +} mb2_transfer; + +/* + * mb3_transfer - state needed for mailbox 3 communication. + * @lock: The request lock. + * @sysclk_lock: A lock used to handle concurrent sysclk requests. + * @sysclk_work: Work structure used for sysclk requests. + */ +static struct { + spinlock_t lock; + struct mutex sysclk_lock; + struct completion sysclk_work; +} mb3_transfer; + +/* + * mb4_transfer - state needed for mailbox 4 communication. + * @lock: The transaction lock. + * @work: The transaction completion structure. + */ +static struct { + struct mutex lock; + struct completion work; +} mb4_transfer; + +/* + * mb5_transfer - state needed for mailbox 5 communication. + * @lock: The transaction lock. + * @work: The transaction completion structure. + * @ack: Reply ("acknowledge") data. + */ +static struct { + struct mutex lock; + struct completion work; + struct { + u8 status; + u8 value; + } ack; +} mb5_transfer; + +static atomic_t ac_wake_req_state = ATOMIC_INIT(0); + +/* Spinlocks */ +static DEFINE_SPINLOCK(clkout_lock); +static DEFINE_SPINLOCK(gpiocr_lock); + +/* Global var to runtime determine TCDM base for v2 or v1 */ +static __iomem void *tcdm_base; + +struct clk_mgt { + unsigned int offset; + u32 pllsw; +}; + +static DEFINE_SPINLOCK(clk_mgt_lock); + +#define CLK_MGT_ENTRY(_name)[PRCMU_##_name] = { (PRCM_##_name##_MGT), 0 } +struct clk_mgt clk_mgt[PRCMU_NUM_REG_CLOCKS] = { + CLK_MGT_ENTRY(SGACLK), + CLK_MGT_ENTRY(UARTCLK), + CLK_MGT_ENTRY(MSP02CLK), + CLK_MGT_ENTRY(MSP1CLK), + CLK_MGT_ENTRY(I2CCLK), + CLK_MGT_ENTRY(SDMMCCLK), + CLK_MGT_ENTRY(SLIMCLK), + CLK_MGT_ENTRY(PER1CLK), + CLK_MGT_ENTRY(PER2CLK), + CLK_MGT_ENTRY(PER3CLK), + CLK_MGT_ENTRY(PER5CLK), + CLK_MGT_ENTRY(PER6CLK), + CLK_MGT_ENTRY(PER7CLK), + CLK_MGT_ENTRY(LCDCLK), + CLK_MGT_ENTRY(BMLCLK), + CLK_MGT_ENTRY(HSITXCLK), + CLK_MGT_ENTRY(HSIRXCLK), + CLK_MGT_ENTRY(HDMICLK), + CLK_MGT_ENTRY(APEATCLK), + CLK_MGT_ENTRY(APETRACECLK), + CLK_MGT_ENTRY(MCDECLK), + CLK_MGT_ENTRY(IPI2CCLK), + CLK_MGT_ENTRY(DSIALTCLK), + CLK_MGT_ENTRY(DMACLK), + CLK_MGT_ENTRY(B2R2CLK), + CLK_MGT_ENTRY(TVCLK), + CLK_MGT_ENTRY(SSPCLK), + CLK_MGT_ENTRY(RNGCLK), + CLK_MGT_ENTRY(UICCCLK), +}; + +/* +* Used by MCDE to setup all necessary PRCMU registers +*/ +#define PRCMU_RESET_DSIPLL 0x00004000 +#define PRCMU_UNCLAMP_DSIPLL 0x00400800 + +#define PRCMU_CLK_PLL_DIV_SHIFT 0 +#define PRCMU_CLK_PLL_SW_SHIFT 5 +#define PRCMU_CLK_38 (1 << 9) +#define PRCMU_CLK_38_SRC (1 << 10) +#define PRCMU_CLK_38_DIV (1 << 11) + +/* PLLDIV=12, PLLSW=4 (PLLDDR) */ +#define PRCMU_DSI_CLOCK_SETTING 0x0000008C + +/* PLLDIV=8, PLLSW=4 (PLLDDR) */ +#define PRCMU_DSI_CLOCK_SETTING_U8400 0x00000088 + +/* DPI 50000000 Hz */ +#define PRCMU_DPI_CLOCK_SETTING ((1 << PRCMU_CLK_PLL_SW_SHIFT) | \ + (16 << PRCMU_CLK_PLL_DIV_SHIFT)) +#define PRCMU_DSI_LP_CLOCK_SETTING 0x00000E00 + +/* D=101, N=1, R=4, SELDIV2=0 */ +#define PRCMU_PLLDSI_FREQ_SETTING 0x00040165 + +/* D=70, N=1, R=3, SELDIV2=0 */ +#define PRCMU_PLLDSI_FREQ_SETTING_U8400 0x00030146 + +#define PRCMU_ENABLE_PLLDSI 0x00000001 +#define PRCMU_DISABLE_PLLDSI 0x00000000 +#define PRCMU_RELEASE_RESET_DSS 0x0000400C +#define PRCMU_DSI_PLLOUT_SEL_SETTING 0x00000202 +/* ESC clk, div0=1, div1=1, div2=3 */ +#define PRCMU_ENABLE_ESCAPE_CLOCK_DIV 0x07030101 +#define PRCMU_DISABLE_ESCAPE_CLOCK_DIV 0x00030101 +#define PRCMU_DSI_RESET_SW 0x00000007 + +#define PRCMU_PLLDSI_LOCKP_LOCKED 0x3 + +static struct { + u8 project_number; + u8 api_version; + u8 func_version; + u8 errata; +} prcmu_version; + + +int prcmu_enable_dsipll(void) +{ + int i; + unsigned int plldsifreq; + + /* Clear DSIPLL_RESETN */ + writel(PRCMU_RESET_DSIPLL, (_PRCMU_BASE + PRCM_APE_RESETN_CLR)); + /* Unclamp DSIPLL in/out */ + writel(PRCMU_UNCLAMP_DSIPLL, (_PRCMU_BASE + PRCM_MMIP_LS_CLAMP_CLR)); + + if (prcmu_is_u8400()) + plldsifreq = PRCMU_PLLDSI_FREQ_SETTING_U8400; + else + plldsifreq = PRCMU_PLLDSI_FREQ_SETTING; + /* Set DSI PLL FREQ */ + writel(plldsifreq, (_PRCMU_BASE + PRCM_PLLDSI_FREQ)); + writel(PRCMU_DSI_PLLOUT_SEL_SETTING, + (_PRCMU_BASE + PRCM_DSI_PLLOUT_SEL)); + /* Enable Escape clocks */ + writel(PRCMU_ENABLE_ESCAPE_CLOCK_DIV, + (_PRCMU_BASE + PRCM_DSITVCLK_DIV)); + + /* Start DSI PLL */ + writel(PRCMU_ENABLE_PLLDSI, (_PRCMU_BASE + PRCM_PLLDSI_ENABLE)); + /* Reset DSI PLL */ + writel(PRCMU_DSI_RESET_SW, (_PRCMU_BASE + PRCM_DSI_SW_RESET)); + for (i = 0; i < 10; i++) { + if ((readl(_PRCMU_BASE + PRCM_PLLDSI_LOCKP) & + PRCMU_PLLDSI_LOCKP_LOCKED) + == PRCMU_PLLDSI_LOCKP_LOCKED) + break; + udelay(100); + } + /* Set DSIPLL_RESETN */ + writel(PRCMU_RESET_DSIPLL, (_PRCMU_BASE + PRCM_APE_RESETN_SET)); + return 0; +} + +int prcmu_disable_dsipll(void) +{ + /* Disable dsi pll */ + writel(PRCMU_DISABLE_PLLDSI, (_PRCMU_BASE + PRCM_PLLDSI_ENABLE)); + /* Disable escapeclock */ + writel(PRCMU_DISABLE_ESCAPE_CLOCK_DIV, + (_PRCMU_BASE + PRCM_DSITVCLK_DIV)); + return 0; +} + +int prcmu_set_display_clocks(void) +{ + unsigned long flags; + unsigned int dsiclk; + + if (prcmu_is_u8400()) + dsiclk = PRCMU_DSI_CLOCK_SETTING_U8400; + else + dsiclk = PRCMU_DSI_CLOCK_SETTING; + + spin_lock_irqsave(&clk_mgt_lock, flags); + + /* Grab the HW semaphore. */ + while ((readl(_PRCMU_BASE + PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0) + cpu_relax(); + + writel(dsiclk, (_PRCMU_BASE + PRCM_HDMICLK_MGT)); + writel(PRCMU_DSI_LP_CLOCK_SETTING, (_PRCMU_BASE + PRCM_TVCLK_MGT)); + writel(PRCMU_DPI_CLOCK_SETTING, (_PRCMU_BASE + PRCM_LCDCLK_MGT)); + + /* Release the HW semaphore. */ + writel(0, (_PRCMU_BASE + PRCM_SEM)); + + spin_unlock_irqrestore(&clk_mgt_lock, flags); + + return 0; +} + +/** + * prcmu_enable_spi2 - Enables pin muxing for SPI2 on OtherAlternateC1. + */ +void prcmu_enable_spi2(void) +{ + u32 reg; + unsigned long flags; + + spin_lock_irqsave(&gpiocr_lock, flags); + reg = readl(_PRCMU_BASE + PRCM_GPIOCR); + writel(reg | PRCM_GPIOCR_SPI2_SELECT, _PRCMU_BASE + PRCM_GPIOCR); + spin_unlock_irqrestore(&gpiocr_lock, flags); +} + +/** + * prcmu_disable_spi2 - Disables pin muxing for SPI2 on OtherAlternateC1. + */ +void prcmu_disable_spi2(void) +{ + u32 reg; + unsigned long flags; + + spin_lock_irqsave(&gpiocr_lock, flags); + reg = readl(_PRCMU_BASE + PRCM_GPIOCR); + writel(reg & ~PRCM_GPIOCR_SPI2_SELECT, _PRCMU_BASE + PRCM_GPIOCR); + spin_unlock_irqrestore(&gpiocr_lock, flags); +} + +bool prcmu_has_arm_maxopp(void) +{ + return (readb(tcdm_base + PRCM_AVS_VARM_MAX_OPP) & + PRCM_AVS_ISMODEENABLE_MASK) == PRCM_AVS_ISMODEENABLE_MASK; +} + +bool prcmu_is_u8400(void) +{ + return prcmu_version.project_number == PRCMU_PROJECT_ID_8400V2_0; +} + +/** + * prcmu_get_boot_status - PRCMU boot status checking + * Returns: the current PRCMU boot status + */ +int prcmu_get_boot_status(void) +{ + return readb(tcdm_base + PRCM_BOOT_STATUS); +} + +/** + * prcmu_set_rc_a2p - This function is used to run few power state sequences + * @val: Value to be set, i.e. transition requested + * Returns: 0 on success, -EINVAL on invalid argument + * + * This function is used to run the following power state sequences - + * any state to ApReset, ApDeepSleep to ApExecute, ApExecute to ApDeepSleep + */ +int prcmu_set_rc_a2p(enum romcode_write val) +{ + if (val < RDY_2_DS || val > RDY_2_XP70_RST) + return -EINVAL; + writeb(val, (tcdm_base + PRCM_ROMCODE_A2P)); + return 0; +} + +/** + * prcmu_get_rc_p2a - This function is used to get power state sequences + * Returns: the power transition that has last happened + * + * This function can return the following transitions- + * any state to ApReset, ApDeepSleep to ApExecute, ApExecute to ApDeepSleep + */ +enum romcode_read prcmu_get_rc_p2a(void) +{ + return readb(tcdm_base + PRCM_ROMCODE_P2A); +} + +/** + * prcmu_get_current_mode - Return the current XP70 power mode + * Returns: Returns the current AP(ARM) power mode: init, + * apBoot, apExecute, apDeepSleep, apSleep, apIdle, apReset + */ +enum ap_pwrst prcmu_get_xp70_current_state(void) +{ + return readb(tcdm_base + PRCM_XP70_CUR_PWR_STATE); +} + +/** + * prcmu_config_clkout - Configure one of the programmable clock outputs. + * @clkout: The CLKOUT number (0 or 1). + * @source: The clock to be used (one of the PRCMU_CLKSRC_*). + * @div: The divider to be applied. + * + * Configures one of the programmable clock outputs (CLKOUTs). + * @div should be in the range [1,63] to request a configuration, or 0 to + * inform that the configuration is no longer requested. + */ +int prcmu_config_clkout(u8 clkout, u8 source, u8 div) +{ + static int requests[2]; + int r = 0; + unsigned long flags; + u32 val; + u32 bits; + u32 mask; + u32 div_mask; + + BUG_ON(clkout > 1); + BUG_ON(div > 63); + BUG_ON((clkout == 0) && (source > PRCMU_CLKSRC_CLK009)); + + if (!div && !requests[clkout]) + return -EINVAL; + + switch (clkout) { + case 0: + div_mask = PRCM_CLKOCR_CLKODIV0_MASK; + mask = (PRCM_CLKOCR_CLKODIV0_MASK | PRCM_CLKOCR_CLKOSEL0_MASK); + bits = ((source << PRCM_CLKOCR_CLKOSEL0_SHIFT) | + (div << PRCM_CLKOCR_CLKODIV0_SHIFT)); + break; + case 1: + div_mask = PRCM_CLKOCR_CLKODIV1_MASK; + mask = (PRCM_CLKOCR_CLKODIV1_MASK | PRCM_CLKOCR_CLKOSEL1_MASK | + PRCM_CLKOCR_CLK1TYPE); + bits = ((source << PRCM_CLKOCR_CLKOSEL1_SHIFT) | + (div << PRCM_CLKOCR_CLKODIV1_SHIFT)); + break; + } + bits &= mask; + + spin_lock_irqsave(&clkout_lock, flags); + + val = readl(_PRCMU_BASE + PRCM_CLKOCR); + if (val & div_mask) { + if (div) { + if ((val & mask) != bits) { + r = -EBUSY; + goto unlock_and_return; + } + } else { + if ((val & mask & ~div_mask) != bits) { + r = -EINVAL; + goto unlock_and_return; + } + } + } + writel((bits | (val & ~mask)), (_PRCMU_BASE + PRCM_CLKOCR)); + requests[clkout] += (div ? 1 : -1); + +unlock_and_return: + spin_unlock_irqrestore(&clkout_lock, flags); + + return r; +} + +int prcmu_set_power_state(u8 state, bool keep_ulp_clk, bool keep_ap_pll) +{ + unsigned long flags; + + BUG_ON((state < PRCMU_AP_SLEEP) || (PRCMU_AP_DEEP_IDLE < state)); + + spin_lock_irqsave(&mb0_transfer.lock, flags); + + while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(0)) + cpu_relax(); + + writeb(MB0H_POWER_STATE_TRANS, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB0)); + writeb(state, (tcdm_base + PRCM_REQ_MB0_AP_POWER_STATE)); + writeb((keep_ap_pll ? 1 : 0), (tcdm_base + PRCM_REQ_MB0_AP_PLL_STATE)); + writeb((keep_ulp_clk ? 1 : 0), + (tcdm_base + PRCM_REQ_MB0_ULP_CLOCK_STATE)); + writeb(0, (tcdm_base + PRCM_REQ_MB0_DO_NOT_WFI)); + writel(MBOX_BIT(0), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); + + spin_unlock_irqrestore(&mb0_transfer.lock, flags); + + return 0; +} + +/* This function should only be called while mb0_transfer.lock is held. */ +static void config_wakeups(void) +{ + const u8 header[2] = { + MB0H_CONFIG_WAKEUPS_EXE, + MB0H_CONFIG_WAKEUPS_SLEEP + }; + static u32 last_dbb_events; + static u32 last_abb_events; + u32 dbb_events; + u32 abb_events; + unsigned int i; + + dbb_events = mb0_transfer.req.dbb_irqs | mb0_transfer.req.dbb_wakeups; + dbb_events |= (WAKEUP_BIT_AC_WAKE_ACK | WAKEUP_BIT_AC_SLEEP_ACK); + + abb_events = mb0_transfer.req.abb_events; + + if ((dbb_events == last_dbb_events) && (abb_events == last_abb_events)) + return; + + for (i = 0; i < 2; i++) { + while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(0)) + cpu_relax(); + writel(dbb_events, (tcdm_base + PRCM_REQ_MB0_WAKEUP_8500)); + writel(abb_events, (tcdm_base + PRCM_REQ_MB0_WAKEUP_4500)); + writeb(header[i], (tcdm_base + PRCM_MBOX_HEADER_REQ_MB0)); + writel(MBOX_BIT(0), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); + } + last_dbb_events = dbb_events; + last_abb_events = abb_events; +} + +void prcmu_enable_wakeups(u32 wakeups) +{ + unsigned long flags; + u32 bits; + int i; + + BUG_ON(wakeups != (wakeups & VALID_WAKEUPS)); + + for (i = 0, bits = 0; i < NUM_PRCMU_WAKEUP_INDICES; i++) { + if (wakeups & BIT(i)) + bits |= prcmu_wakeup_bit[i]; + } + + spin_lock_irqsave(&mb0_transfer.lock, flags); + + mb0_transfer.req.dbb_wakeups = bits; + config_wakeups(); + + spin_unlock_irqrestore(&mb0_transfer.lock, flags); +} + +void prcmu_config_abb_event_readout(u32 abb_events) +{ + unsigned long flags; + + spin_lock_irqsave(&mb0_transfer.lock, flags); + + mb0_transfer.req.abb_events = abb_events; + config_wakeups(); + + spin_unlock_irqrestore(&mb0_transfer.lock, flags); +} + +void prcmu_get_abb_event_buffer(void __iomem **buf) +{ + if (readb(tcdm_base + PRCM_ACK_MB0_READ_POINTER) & 1) + *buf = (tcdm_base + PRCM_ACK_MB0_WAKEUP_1_4500); + else + *buf = (tcdm_base + PRCM_ACK_MB0_WAKEUP_0_4500); +} + +/** + * prcmu_set_arm_opp - set the appropriate ARM OPP + * @opp: The new ARM operating point to which transition is to be made + * Returns: 0 on success, non-zero on failure + * + * This function sets the the operating point of the ARM. + */ +int prcmu_set_arm_opp(u8 opp) +{ + int r; + + if (opp < ARM_NO_CHANGE || opp > ARM_EXTCLK) + return -EINVAL; + + r = 0; + + mutex_lock(&mb1_transfer.lock); + + while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(1)) + cpu_relax(); + + writeb(MB1H_ARM_APE_OPP, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1)); + writeb(opp, (tcdm_base + PRCM_REQ_MB1_ARM_OPP)); + writeb(APE_NO_CHANGE, (tcdm_base + PRCM_REQ_MB1_APE_OPP)); + + writel(MBOX_BIT(1), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); + wait_for_completion(&mb1_transfer.work); + + if ((mb1_transfer.ack.header != MB1H_ARM_APE_OPP) || + (mb1_transfer.ack.arm_opp != opp)) + r = -EIO; + + mutex_unlock(&mb1_transfer.lock); + + return r; +} + +/** + * prcmu_get_arm_opp - get the current ARM OPP + * + * Returns: the current ARM OPP + */ +int prcmu_get_arm_opp(void) +{ + return readb(tcdm_base + PRCM_ACK_MB1_CURRENT_ARM_OPP); +} + +/** + * prcmu_get_ddr_opp - get the current DDR OPP + * + * Returns: the current DDR OPP + */ +int prcmu_get_ddr_opp(void) +{ + return readb(_PRCMU_BASE + PRCM_DDR_SUBSYS_APE_MINBW); +} + +/** + * set_ddr_opp - set the appropriate DDR OPP + * @opp: The new DDR operating point to which transition is to be made + * Returns: 0 on success, non-zero on failure + * + * This function sets the operating point of the DDR. + */ +int prcmu_set_ddr_opp(u8 opp) +{ + if (opp < DDR_100_OPP || opp > DDR_25_OPP) + return -EINVAL; + /* Changing the DDR OPP can hang the hardware pre-v21 */ + if (cpu_is_u8500v20_or_later() && !cpu_is_u8500v20()) + writeb(opp, (_PRCMU_BASE + PRCM_DDR_SUBSYS_APE_MINBW)); + + return 0; +} +/** + * set_ape_opp - set the appropriate APE OPP + * @opp: The new APE operating point to which transition is to be made + * Returns: 0 on success, non-zero on failure + * + * This function sets the operating point of the APE. + */ +int prcmu_set_ape_opp(u8 opp) +{ + int r = 0; + + mutex_lock(&mb1_transfer.lock); + + while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(1)) + cpu_relax(); + + writeb(MB1H_ARM_APE_OPP, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1)); + writeb(ARM_NO_CHANGE, (tcdm_base + PRCM_REQ_MB1_ARM_OPP)); + writeb(opp, (tcdm_base + PRCM_REQ_MB1_APE_OPP)); + + writel(MBOX_BIT(1), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); + wait_for_completion(&mb1_transfer.work); + + if ((mb1_transfer.ack.header != MB1H_ARM_APE_OPP) || + (mb1_transfer.ack.ape_opp != opp)) + r = -EIO; + + mutex_unlock(&mb1_transfer.lock); + + return r; +} + +/** + * prcmu_get_ape_opp - get the current APE OPP + * + * Returns: the current APE OPP + */ +int prcmu_get_ape_opp(void) +{ + return readb(tcdm_base + PRCM_ACK_MB1_CURRENT_APE_OPP); +} + +/** + * prcmu_request_ape_opp_100_voltage - Request APE OPP 100% voltage + * @enable: true to request the higher voltage, false to drop a request. + * + * Calls to this function to enable and disable requests must be balanced. + */ +int prcmu_request_ape_opp_100_voltage(bool enable) +{ + int r = 0; + u8 header; + static unsigned int requests; + + mutex_lock(&mb1_transfer.lock); + + if (enable) { + if (0 != requests++) + goto unlock_and_return; + header = MB1H_REQUEST_APE_OPP_100_VOLT; + } else { + if (requests == 0) { + r = -EIO; + goto unlock_and_return; + } else if (1 != requests--) { + goto unlock_and_return; + } + header = MB1H_RELEASE_APE_OPP_100_VOLT; + } + + while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(1)) + cpu_relax(); + + writeb(header, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1)); + + writel(MBOX_BIT(1), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); + wait_for_completion(&mb1_transfer.work); + + if ((mb1_transfer.ack.header != header) || + ((mb1_transfer.ack.ape_voltage_status & BIT(0)) != 0)) + r = -EIO; + +unlock_and_return: + mutex_unlock(&mb1_transfer.lock); + + return r; +} + +/** + * prcmu_release_usb_wakeup_state - release the state required by a USB wakeup + * + * This function releases the power state requirements of a USB wakeup. + */ +int prcmu_release_usb_wakeup_state(void) +{ + int r = 0; + + mutex_lock(&mb1_transfer.lock); + + while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(1)) + cpu_relax(); + + writeb(MB1H_RELEASE_USB_WAKEUP, + (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1)); + + writel(MBOX_BIT(1), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); + wait_for_completion(&mb1_transfer.work); + + if ((mb1_transfer.ack.header != MB1H_RELEASE_USB_WAKEUP) || + ((mb1_transfer.ack.ape_voltage_status & BIT(0)) != 0)) + r = -EIO; + + mutex_unlock(&mb1_transfer.lock); + + return r; +} + +/** + * prcmu_set_epod - set the state of a EPOD (power domain) + * @epod_id: The EPOD to set + * @epod_state: The new EPOD state + * + * This function sets the state of a EPOD (power domain). It may not be called + * from interrupt context. + */ +int prcmu_set_epod(u16 epod_id, u8 epod_state) +{ + int r = 0; + bool ram_retention = false; + int i; + + /* check argument */ + BUG_ON(epod_id >= NUM_EPOD_ID); + + /* set flag if retention is possible */ + switch (epod_id) { + case EPOD_ID_SVAMMDSP: + case EPOD_ID_SIAMMDSP: + case EPOD_ID_ESRAM12: + case EPOD_ID_ESRAM34: + ram_retention = true; + break; + } + + /* check argument */ + BUG_ON(epod_state > EPOD_STATE_ON); + BUG_ON(epod_state == EPOD_STATE_RAMRET && !ram_retention); + + /* get lock */ + mutex_lock(&mb2_transfer.lock); + + /* wait for mailbox */ + while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(2)) + cpu_relax(); + + /* fill in mailbox */ + for (i = 0; i < NUM_EPOD_ID; i++) + writeb(EPOD_STATE_NO_CHANGE, (tcdm_base + PRCM_REQ_MB2 + i)); + writeb(epod_state, (tcdm_base + PRCM_REQ_MB2 + epod_id)); + + writeb(MB2H_DPS, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB2)); + + writel(MBOX_BIT(2), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); + + /* + * The current firmware version does not handle errors correctly, + * and we cannot recover if there is an error. + * This is expected to change when the firmware is updated. + */ + if (!wait_for_completion_timeout(&mb2_transfer.work, + msecs_to_jiffies(20000))) { + pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n", + __func__); + r = -EIO; + goto unlock_and_return; + } + + if (mb2_transfer.ack.status != HWACC_PWR_ST_OK) + r = -EIO; + +unlock_and_return: + mutex_unlock(&mb2_transfer.lock); + return r; +} + +/** + * prcmu_configure_auto_pm - Configure autonomous power management. + * @sleep: Configuration for ApSleep. + * @idle: Configuration for ApIdle. + */ +void prcmu_configure_auto_pm(struct prcmu_auto_pm_config *sleep, + struct prcmu_auto_pm_config *idle) +{ + u32 sleep_cfg; + u32 idle_cfg; + unsigned long flags; -#include + BUG_ON((sleep == NULL) || (idle == NULL)); -#include "db8500-prcmu-regs.h" + sleep_cfg = (sleep->sva_auto_pm_enable & 0xF); + sleep_cfg = ((sleep_cfg << 4) | (sleep->sia_auto_pm_enable & 0xF)); + sleep_cfg = ((sleep_cfg << 8) | (sleep->sva_power_on & 0xFF)); + sleep_cfg = ((sleep_cfg << 8) | (sleep->sia_power_on & 0xFF)); + sleep_cfg = ((sleep_cfg << 4) | (sleep->sva_policy & 0xF)); + sleep_cfg = ((sleep_cfg << 4) | (sleep->sia_policy & 0xF)); -/* Global var to runtime determine TCDM base for v2 or v1 */ -static __iomem void *tcdm_base; + idle_cfg = (idle->sva_auto_pm_enable & 0xF); + idle_cfg = ((idle_cfg << 4) | (idle->sia_auto_pm_enable & 0xF)); + idle_cfg = ((idle_cfg << 8) | (idle->sva_power_on & 0xFF)); + idle_cfg = ((idle_cfg << 8) | (idle->sia_power_on & 0xFF)); + idle_cfg = ((idle_cfg << 4) | (idle->sva_policy & 0xF)); + idle_cfg = ((idle_cfg << 4) | (idle->sia_policy & 0xF)); -#define _MBOX_HEADER (tcdm_base + 0xFE8) -#define MBOX_HEADER_REQ_MB0 (_MBOX_HEADER + 0x0) + spin_lock_irqsave(&mb2_transfer.auto_pm_lock, flags); -#define REQ_MB1 (tcdm_base + 0xFD0) -#define REQ_MB5 (tcdm_base + 0xE44) + /* + * The autonomous power management configuration is done through + * fields in mailbox 2, but these fields are only used as shared + * variables - i.e. there is no need to send a message. + */ + writel(sleep_cfg, (tcdm_base + PRCM_REQ_MB2_AUTO_PM_SLEEP)); + writel(idle_cfg, (tcdm_base + PRCM_REQ_MB2_AUTO_PM_IDLE)); -#define REQ_MB1_ARMOPP (REQ_MB1 + 0x0) -#define REQ_MB1_APEOPP (REQ_MB1 + 0x1) -#define REQ_MB1_BOOSTOPP (REQ_MB1 + 0x2) + mb2_transfer.auto_pm_enabled = + ((sleep->sva_auto_pm_enable == PRCMU_AUTO_PM_ON) || + (sleep->sia_auto_pm_enable == PRCMU_AUTO_PM_ON) || + (idle->sva_auto_pm_enable == PRCMU_AUTO_PM_ON) || + (idle->sia_auto_pm_enable == PRCMU_AUTO_PM_ON)); -#define ACK_MB1 (tcdm_base + 0xE04) -#define ACK_MB5 (tcdm_base + 0xDF4) + spin_unlock_irqrestore(&mb2_transfer.auto_pm_lock, flags); +} +EXPORT_SYMBOL(prcmu_configure_auto_pm); -#define ACK_MB1_CURR_ARMOPP (ACK_MB1 + 0x0) -#define ACK_MB1_CURR_APEOPP (ACK_MB1 + 0x1) +bool prcmu_is_auto_pm_enabled(void) +{ + return mb2_transfer.auto_pm_enabled; +} -#define REQ_MB5_I2C_SLAVE_OP (REQ_MB5) -#define REQ_MB5_I2C_HW_BITS (REQ_MB5 + 1) -#define REQ_MB5_I2C_REG (REQ_MB5 + 2) -#define REQ_MB5_I2C_VAL (REQ_MB5 + 3) +static int request_sysclk(bool enable) +{ + int r; + unsigned long flags; -#define ACK_MB5_I2C_STATUS (ACK_MB5 + 1) -#define ACK_MB5_I2C_VAL (ACK_MB5 + 3) + r = 0; -#define PRCM_AVS_VARM_MAX_OPP (tcdm_base + 0x2E4) -#define PRCM_AVS_ISMODEENABLE 7 -#define PRCM_AVS_ISMODEENABLE_MASK (1 << PRCM_AVS_ISMODEENABLE) + mutex_lock(&mb3_transfer.sysclk_lock); -#define I2C_WRITE(slave) \ - (((slave) << 1) | (cpu_is_u8500v2() ? BIT(6) : 0)) -#define I2C_READ(slave) \ - (((slave) << 1) | (cpu_is_u8500v2() ? BIT(6) : 0) | BIT(0)) -#define I2C_STOP_EN BIT(3) - -enum mb1_h { - MB1H_ARM_OPP = 1, - MB1H_APE_OPP, - MB1H_ARM_APE_OPP, -}; + spin_lock_irqsave(&mb3_transfer.lock, flags); -static struct { - struct mutex lock; - struct completion work; - struct { - u8 arm_opp; - u8 ape_opp; - u8 arm_status; - u8 ape_status; - } ack; -} mb1_transfer; + while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(3)) + cpu_relax(); -enum ack_mb5_status { - I2C_WR_OK = 0x01, - I2C_RD_OK = 0x02, -}; + writeb((enable ? ON : OFF), (tcdm_base + PRCM_REQ_MB3_SYSCLK_MGT)); -#define MBOX_BIT BIT -#define NUM_MBOX 8 + writeb(MB3H_SYSCLK, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB3)); + writel(MBOX_BIT(3), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); -static struct { - struct mutex lock; - struct completion work; - bool failed; - struct { - u8 status; - u8 value; - } ack; -} mb5_transfer; + spin_unlock_irqrestore(&mb3_transfer.lock, flags); + + /* + * The firmware only sends an ACK if we want to enable the + * SysClk, and it succeeds. + */ + if (enable && !wait_for_completion_timeout(&mb3_transfer.sysclk_work, + msecs_to_jiffies(20000))) { + pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n", + __func__); + r = -EIO; + } + + mutex_unlock(&mb3_transfer.sysclk_lock); + + return r; +} + +static int request_timclk(bool enable) +{ + u32 val = (PRCM_TCR_DOZE_MODE | PRCM_TCR_TENSEL_MASK); + + if (!enable) + val |= PRCM_TCR_STOP_TIMERS; + writel(val, (_PRCMU_BASE + PRCM_TCR)); + + return 0; +} + +static int request_reg_clock(u8 clock, bool enable) +{ + u32 val; + unsigned long flags; + + spin_lock_irqsave(&clk_mgt_lock, flags); + + /* Grab the HW semaphore. */ + while ((readl(_PRCMU_BASE + PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0) + cpu_relax(); + + val = readl(_PRCMU_BASE + clk_mgt[clock].offset); + if (enable) { + val |= (PRCM_CLK_MGT_CLKEN | clk_mgt[clock].pllsw); + } else { + clk_mgt[clock].pllsw = (val & PRCM_CLK_MGT_CLKPLLSW_MASK); + val &= ~(PRCM_CLK_MGT_CLKEN | PRCM_CLK_MGT_CLKPLLSW_MASK); + } + writel(val, (_PRCMU_BASE + clk_mgt[clock].offset)); + + /* Release the HW semaphore. */ + writel(0, (_PRCMU_BASE + PRCM_SEM)); + + spin_unlock_irqrestore(&clk_mgt_lock, flags); + + return 0; +} + +/** + * prcmu_request_clock() - Request for a clock to be enabled or disabled. + * @clock: The clock for which the request is made. + * @enable: Whether the clock should be enabled (true) or disabled (false). + * + * This function should only be used by the clock implementation. + * Do not use it from any other place! + */ +int prcmu_request_clock(u8 clock, bool enable) +{ + if (clock < PRCMU_NUM_REG_CLOCKS) + return request_reg_clock(clock, enable); + else if (clock == PRCMU_TIMCLK) + return request_timclk(enable); + else if (clock == PRCMU_SYSCLK) + return request_sysclk(enable); + else + return -EINVAL; +} + +int prcmu_config_esram0_deep_sleep(u8 state) +{ + if ((state > ESRAM0_DEEP_SLEEP_STATE_RET) || + (state < ESRAM0_DEEP_SLEEP_STATE_OFF)) + return -EINVAL; + + mutex_lock(&mb4_transfer.lock); + + while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(4)) + cpu_relax(); + + writeb(MB4H_MEM_ST, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB4)); + writeb(((DDR_PWR_STATE_OFFHIGHLAT << 4) | DDR_PWR_STATE_ON), + (tcdm_base + PRCM_REQ_MB4_DDR_ST_AP_SLEEP_IDLE)); + writeb(DDR_PWR_STATE_ON, + (tcdm_base + PRCM_REQ_MB4_DDR_ST_AP_DEEP_IDLE)); + writeb(state, (tcdm_base + PRCM_REQ_MB4_ESRAM0_ST)); + + writel(MBOX_BIT(4), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); + wait_for_completion(&mb4_transfer.work); + + mutex_unlock(&mb4_transfer.lock); + + return 0; +} + +int prcmu_config_hotdog(u8 threshold) +{ + mutex_lock(&mb4_transfer.lock); + + while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(4)) + cpu_relax(); + + writeb(threshold, (tcdm_base + PRCM_REQ_MB4_HOTDOG_THRESHOLD)); + writeb(MB4H_HOTDOG, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB4)); + + writel(MBOX_BIT(4), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); + wait_for_completion(&mb4_transfer.work); + + mutex_unlock(&mb4_transfer.lock); + + return 0; +} + +int prcmu_config_hotmon(u8 low, u8 high) +{ + mutex_lock(&mb4_transfer.lock); + + while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(4)) + cpu_relax(); + + writeb(low, (tcdm_base + PRCM_REQ_MB4_HOTMON_LOW)); + writeb(high, (tcdm_base + PRCM_REQ_MB4_HOTMON_HIGH)); + writeb((HOTMON_CONFIG_LOW | HOTMON_CONFIG_HIGH), + (tcdm_base + PRCM_REQ_MB4_HOTMON_CONFIG)); + writeb(MB4H_HOTMON, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB4)); + + writel(MBOX_BIT(4), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); + wait_for_completion(&mb4_transfer.work); + + mutex_unlock(&mb4_transfer.lock); + + return 0; +} + +static int config_hot_period(u16 val) +{ + mutex_lock(&mb4_transfer.lock); + + while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(4)) + cpu_relax(); + + writew(val, (tcdm_base + PRCM_REQ_MB4_HOT_PERIOD)); + writeb(MB4H_HOT_PERIOD, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB4)); + + writel(MBOX_BIT(4), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); + wait_for_completion(&mb4_transfer.work); + + mutex_unlock(&mb4_transfer.lock); + + return 0; +} + +int prcmu_start_temp_sense(u16 cycles32k) +{ + if (cycles32k == 0xFFFF) + return -EINVAL; + + return config_hot_period(cycles32k); +} + +int prcmu_stop_temp_sense(void) +{ + return config_hot_period(0xFFFF); +} + +/** + * prcmu_set_clock_divider() - Configure the clock divider. + * @clock: The clock for which the request is made. + * @divider: The clock divider. (< 32) + * + * This function should only be used by the clock implementation. + * Do not use it from any other place! + */ +int prcmu_set_clock_divider(u8 clock, u8 divider) +{ + u32 val; + unsigned long flags; + + if ((clock >= PRCMU_NUM_REG_CLOCKS) || (divider < 1) || (31 < divider)) + return -EINVAL; + + spin_lock_irqsave(&clk_mgt_lock, flags); + + /* Grab the HW semaphore. */ + while ((readl(_PRCMU_BASE + PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0) + cpu_relax(); + + val = readl(_PRCMU_BASE + clk_mgt[clock].offset); + val &= ~(PRCM_CLK_MGT_CLKPLLDIV_MASK); + val |= (u32)divider; + writel(val, (_PRCMU_BASE + clk_mgt[clock].offset)); + + /* Release the HW semaphore. */ + writel(0, (_PRCMU_BASE + PRCM_SEM)); + + spin_unlock_irqrestore(&clk_mgt_lock, flags); + + return 0; +} /** * prcmu_abb_read() - Read register value(s) from the ABB. @@ -115,33 +1376,34 @@ int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size) if (size != 1) return -EINVAL; - r = mutex_lock_interruptible(&mb5_transfer.lock); - if (r) - return r; + mutex_lock(&mb5_transfer.lock); - while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5)) + while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(5)) cpu_relax(); - writeb(I2C_READ(slave), REQ_MB5_I2C_SLAVE_OP); - writeb(I2C_STOP_EN, REQ_MB5_I2C_HW_BITS); - writeb(reg, REQ_MB5_I2C_REG); + writeb(PRCMU_I2C_READ(slave), (tcdm_base + PRCM_REQ_MB5_I2C_SLAVE_OP)); + writeb(PRCMU_I2C_STOP_EN, (tcdm_base + PRCM_REQ_MB5_I2C_HW_BITS)); + writeb(reg, (tcdm_base + PRCM_REQ_MB5_I2C_REG)); + writeb(0, (tcdm_base + PRCM_REQ_MB5_I2C_VAL)); + + writel(MBOX_BIT(5), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); - writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET); if (!wait_for_completion_timeout(&mb5_transfer.work, - msecs_to_jiffies(500))) { - pr_err("prcmu: prcmu_abb_read timed out.\n"); + msecs_to_jiffies(20000))) { + pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n", + __func__); r = -EIO; - goto unlock_and_return; + } else { + r = ((mb5_transfer.ack.status == I2C_RD_OK) ? 0 : -EIO); } - r = ((mb5_transfer.ack.status == I2C_RD_OK) ? 0 : -EIO); + if (!r) *value = mb5_transfer.ack.value; -unlock_and_return: mutex_unlock(&mb5_transfer.lock); + return r; } -EXPORT_SYMBOL(prcmu_abb_read); /** * prcmu_abb_write() - Write register value(s) to the ABB. @@ -160,179 +1422,262 @@ int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size) if (size != 1) return -EINVAL; - r = mutex_lock_interruptible(&mb5_transfer.lock); - if (r) - return r; + mutex_lock(&mb5_transfer.lock); - - while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5)) + while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(5)) cpu_relax(); - writeb(I2C_WRITE(slave), REQ_MB5_I2C_SLAVE_OP); - writeb(I2C_STOP_EN, REQ_MB5_I2C_HW_BITS); - writeb(reg, REQ_MB5_I2C_REG); - writeb(*value, REQ_MB5_I2C_VAL); + writeb(PRCMU_I2C_WRITE(slave), (tcdm_base + PRCM_REQ_MB5_I2C_SLAVE_OP)); + writeb(PRCMU_I2C_STOP_EN, (tcdm_base + PRCM_REQ_MB5_I2C_HW_BITS)); + writeb(reg, (tcdm_base + PRCM_REQ_MB5_I2C_REG)); + writeb(*value, (tcdm_base + PRCM_REQ_MB5_I2C_VAL)); + + writel(MBOX_BIT(5), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); - writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET); if (!wait_for_completion_timeout(&mb5_transfer.work, - msecs_to_jiffies(500))) { - pr_err("prcmu: prcmu_abb_write timed out.\n"); + msecs_to_jiffies(20000))) { + pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n", + __func__); r = -EIO; - goto unlock_and_return; + } else { + r = ((mb5_transfer.ack.status == I2C_WR_OK) ? 0 : -EIO); } - r = ((mb5_transfer.ack.status == I2C_WR_OK) ? 0 : -EIO); -unlock_and_return: mutex_unlock(&mb5_transfer.lock); + return r; } -EXPORT_SYMBOL(prcmu_abb_write); -static int set_ape_cpu_opps(u8 header, enum prcmu_ape_opp ape_opp, - enum prcmu_cpu_opp cpu_opp) +/** + * prcmu_ac_wake_req - should be called whenever ARM wants to wakeup Modem + */ +void prcmu_ac_wake_req(void) { - bool do_ape; - bool do_arm; - int err = 0; + u32 val; - do_ape = ((header == MB1H_APE_OPP) || (header == MB1H_ARM_APE_OPP)); - do_arm = ((header == MB1H_ARM_OPP) || (header == MB1H_ARM_APE_OPP)); + mutex_lock(&mb0_transfer.ac_wake_lock); - mutex_lock(&mb1_transfer.lock); + val = readl(_PRCMU_BASE + PRCM_HOSTACCESS_REQ); + if (val & PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ) + goto unlock_and_return; - while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(1)) - cpu_relax(); + atomic_set(&ac_wake_req_state, 1); - writeb(0, MBOX_HEADER_REQ_MB0); - writeb(cpu_opp, REQ_MB1_ARMOPP); - writeb(ape_opp, REQ_MB1_APEOPP); - writeb(0, REQ_MB1_BOOSTOPP); - writel(MBOX_BIT(1), PRCM_MBOX_CPU_SET); - wait_for_completion(&mb1_transfer.work); - if ((do_ape) && (mb1_transfer.ack.ape_status != 0)) - err = -EIO; - if ((do_arm) && (mb1_transfer.ack.arm_status != 0)) - err = -EIO; + writel((val | PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ), + (_PRCMU_BASE + PRCM_HOSTACCESS_REQ)); - mutex_unlock(&mb1_transfer.lock); + if (!wait_for_completion_timeout(&mb0_transfer.ac_wake_work, + msecs_to_jiffies(20000))) { + pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n", + __func__); + } - return err; +unlock_and_return: + mutex_unlock(&mb0_transfer.ac_wake_lock); } /** - * prcmu_set_ape_opp() - Set the OPP of the APE. - * @opp: The OPP to set. - * - * This function sets the OPP of the APE. + * prcmu_ac_sleep_req - called when ARM no longer needs to talk to modem */ -int prcmu_set_ape_opp(enum prcmu_ape_opp opp) +void prcmu_ac_sleep_req() { - return set_ape_cpu_opps(MB1H_APE_OPP, opp, APE_OPP_NO_CHANGE); + u32 val; + + mutex_lock(&mb0_transfer.ac_wake_lock); + + val = readl(_PRCMU_BASE + PRCM_HOSTACCESS_REQ); + if (!(val & PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ)) + goto unlock_and_return; + + writel((val & ~PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ), + (_PRCMU_BASE + PRCM_HOSTACCESS_REQ)); + + if (!wait_for_completion_timeout(&mb0_transfer.ac_wake_work, + msecs_to_jiffies(20000))) { + pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n", + __func__); + } + + atomic_set(&ac_wake_req_state, 0); + +unlock_and_return: + mutex_unlock(&mb0_transfer.ac_wake_lock); } -EXPORT_SYMBOL(prcmu_set_ape_opp); -/** - * prcmu_set_cpu_opp() - Set the OPP of the CPU. - * @opp: The OPP to set. - * - * This function sets the OPP of the CPU. - */ -int prcmu_set_cpu_opp(enum prcmu_cpu_opp opp) +bool prcmu_is_ac_wake_requested(void) { - return set_ape_cpu_opps(MB1H_ARM_OPP, CPU_OPP_NO_CHANGE, opp); + return (atomic_read(&ac_wake_req_state) != 0); } -EXPORT_SYMBOL(prcmu_set_cpu_opp); /** - * prcmu_set_ape_cpu_opps() - Set the OPPs of the APE and the CPU. - * @ape_opp: The APE OPP to set. - * @cpu_opp: The CPU OPP to set. + * prcmu_system_reset - System reset * - * This function sets the OPPs of the APE and the CPU. + * Saves the reset reason code and then sets the APE_SOFRST register which + * fires interrupt to fw */ -int prcmu_set_ape_cpu_opps(enum prcmu_ape_opp ape_opp, - enum prcmu_cpu_opp cpu_opp) +void prcmu_system_reset(u16 reset_code) { - return set_ape_cpu_opps(MB1H_ARM_APE_OPP, ape_opp, cpu_opp); + writew(reset_code, (tcdm_base + PRCM_SW_RST_REASON)); + writel(1, (_PRCMU_BASE + PRCM_APE_SOFTRST)); } -EXPORT_SYMBOL(prcmu_set_ape_cpu_opps); /** - * prcmu_get_ape_opp() - Get the OPP of the APE. - * - * This function gets the OPP of the APE. + * prcmu_reset_modem - ask the PRCMU to reset modem */ -enum prcmu_ape_opp prcmu_get_ape_opp(void) +void prcmu_modem_reset(void) { - return readb(ACK_MB1_CURR_APEOPP); + mutex_lock(&mb1_transfer.lock); + + while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(1)) + cpu_relax(); + + writeb(MB1H_RESET_MODEM, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1)); + writel(MBOX_BIT(1), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); + wait_for_completion(&mb1_transfer.work); + + /* + * No need to check return from PRCMU as modem should go in reset state + * This state is already managed by upper layer + */ + + mutex_unlock(&mb1_transfer.lock); } -EXPORT_SYMBOL(prcmu_get_ape_opp); -/** - * prcmu_get_cpu_opp() - Get the OPP of the CPU. - * - * This function gets the OPP of the CPU. The OPP is specified in %%. - * PRCMU_OPP_EXT is a special OPP value, not specified in %%. - */ -int prcmu_get_cpu_opp(void) +static void ack_dbb_wakeup(void) { - return readb(ACK_MB1_CURR_ARMOPP); + unsigned long flags; + + spin_lock_irqsave(&mb0_transfer.lock, flags); + + while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(0)) + cpu_relax(); + + writeb(MB0H_READ_WAKEUP_ACK, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB0)); + writel(MBOX_BIT(0), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); + + spin_unlock_irqrestore(&mb0_transfer.lock, flags); } -EXPORT_SYMBOL(prcmu_get_cpu_opp); -bool prcmu_has_arm_maxopp(void) +static inline void print_unknown_header_warning(u8 n, u8 header) { - return (readb(PRCM_AVS_VARM_MAX_OPP) & PRCM_AVS_ISMODEENABLE_MASK) - == PRCM_AVS_ISMODEENABLE_MASK; + pr_warning("prcmu: Unknown message header (%d) in mailbox %d.\n", + header, n); } -static void read_mailbox_0(void) +static bool read_mailbox_0(void) { - writel(MBOX_BIT(0), PRCM_ARM_IT1_CLEAR); + bool r; + u32 ev; + unsigned int n; + u8 header; + + header = readb(tcdm_base + PRCM_MBOX_HEADER_ACK_MB0); + switch (header) { + case MB0H_WAKEUP_EXE: + case MB0H_WAKEUP_SLEEP: + if (readb(tcdm_base + PRCM_ACK_MB0_READ_POINTER) & 1) + ev = readl(tcdm_base + PRCM_ACK_MB0_WAKEUP_1_8500); + else + ev = readl(tcdm_base + PRCM_ACK_MB0_WAKEUP_0_8500); + + if (ev & (WAKEUP_BIT_AC_WAKE_ACK | WAKEUP_BIT_AC_SLEEP_ACK)) + complete(&mb0_transfer.ac_wake_work); + if (ev & WAKEUP_BIT_SYSCLK_OK) + complete(&mb3_transfer.sysclk_work); + + ev &= mb0_transfer.req.dbb_irqs; + + for (n = 0; n < NUM_PRCMU_WAKEUPS; n++) { + if (ev & prcmu_irq_bit[n]) + generic_handle_irq(IRQ_PRCMU_BASE + n); + } + r = true; + break; + default: + print_unknown_header_warning(0, header); + r = false; + break; + } + writel(MBOX_BIT(0), (_PRCMU_BASE + PRCM_ARM_IT1_CLR)); + return r; } -static void read_mailbox_1(void) +static bool read_mailbox_1(void) { - mb1_transfer.ack.arm_opp = readb(ACK_MB1_CURR_ARMOPP); - mb1_transfer.ack.ape_opp = readb(ACK_MB1_CURR_APEOPP); + mb1_transfer.ack.header = readb(tcdm_base + PRCM_MBOX_HEADER_REQ_MB1); + mb1_transfer.ack.arm_opp = readb(tcdm_base + + PRCM_ACK_MB1_CURRENT_ARM_OPP); + mb1_transfer.ack.ape_opp = readb(tcdm_base + + PRCM_ACK_MB1_CURRENT_APE_OPP); + mb1_transfer.ack.ape_voltage_status = readb(tcdm_base + + PRCM_ACK_MB1_APE_VOLTAGE_STATUS); + writel(MBOX_BIT(1), (_PRCMU_BASE + PRCM_ARM_IT1_CLR)); complete(&mb1_transfer.work); - writel(MBOX_BIT(1), PRCM_ARM_IT1_CLEAR); + return false; } -static void read_mailbox_2(void) +static bool read_mailbox_2(void) { - writel(MBOX_BIT(2), PRCM_ARM_IT1_CLEAR); + mb2_transfer.ack.status = readb(tcdm_base + PRCM_ACK_MB2_DPS_STATUS); + writel(MBOX_BIT(2), (_PRCMU_BASE + PRCM_ARM_IT1_CLR)); + complete(&mb2_transfer.work); + return false; } -static void read_mailbox_3(void) +static bool read_mailbox_3(void) { - writel(MBOX_BIT(3), PRCM_ARM_IT1_CLEAR); + writel(MBOX_BIT(3), (_PRCMU_BASE + PRCM_ARM_IT1_CLR)); + return false; } -static void read_mailbox_4(void) +static bool read_mailbox_4(void) { - writel(MBOX_BIT(4), PRCM_ARM_IT1_CLEAR); + u8 header; + bool do_complete = true; + + header = readb(tcdm_base + PRCM_MBOX_HEADER_REQ_MB4); + switch (header) { + case MB4H_MEM_ST: + case MB4H_HOTDOG: + case MB4H_HOTMON: + case MB4H_HOT_PERIOD: + break; + default: + print_unknown_header_warning(4, header); + do_complete = false; + break; + } + + writel(MBOX_BIT(4), (_PRCMU_BASE + PRCM_ARM_IT1_CLR)); + + if (do_complete) + complete(&mb4_transfer.work); + + return false; } -static void read_mailbox_5(void) +static bool read_mailbox_5(void) { - mb5_transfer.ack.status = readb(ACK_MB5_I2C_STATUS); - mb5_transfer.ack.value = readb(ACK_MB5_I2C_VAL); + mb5_transfer.ack.status = readb(tcdm_base + PRCM_ACK_MB5_I2C_STATUS); + mb5_transfer.ack.value = readb(tcdm_base + PRCM_ACK_MB5_I2C_VAL); + writel(MBOX_BIT(5), (_PRCMU_BASE + PRCM_ARM_IT1_CLR)); complete(&mb5_transfer.work); - writel(MBOX_BIT(5), PRCM_ARM_IT1_CLEAR); + return false; } -static void read_mailbox_6(void) +static bool read_mailbox_6(void) { - writel(MBOX_BIT(6), PRCM_ARM_IT1_CLEAR); + writel(MBOX_BIT(6), (_PRCMU_BASE + PRCM_ARM_IT1_CLR)); + return false; } -static void read_mailbox_7(void) +static bool read_mailbox_7(void) { - writel(MBOX_BIT(7), PRCM_ARM_IT1_CLEAR); + writel(MBOX_BIT(7), (_PRCMU_BASE + PRCM_ARM_IT1_CLR)); + return false; } -static void (* const read_mailbox[NUM_MBOX])(void) = { +static bool (* const read_mailbox[NUM_MB])(void) = { read_mailbox_0, read_mailbox_1, read_mailbox_2, @@ -347,49 +1692,199 @@ static irqreturn_t prcmu_irq_handler(int irq, void *data) { u32 bits; u8 n; + irqreturn_t r; - bits = (readl(PRCM_ARM_IT1_VAL) & (MBOX_BIT(NUM_MBOX) - 1)); + bits = (readl(_PRCMU_BASE + PRCM_ARM_IT1_VAL) & ALL_MBOX_BITS); if (unlikely(!bits)) return IRQ_NONE; + r = IRQ_HANDLED; for (n = 0; bits; n++) { if (bits & MBOX_BIT(n)) { bits -= MBOX_BIT(n); - read_mailbox[n](); + if (read_mailbox[n]()) + r = IRQ_WAKE_THREAD; } } + return r; +} + +static irqreturn_t prcmu_irq_thread_fn(int irq, void *data) +{ + ack_dbb_wakeup(); return IRQ_HANDLED; } +static void prcmu_mask_work(struct work_struct *work) +{ + unsigned long flags; + + spin_lock_irqsave(&mb0_transfer.lock, flags); + + config_wakeups(); + + spin_unlock_irqrestore(&mb0_transfer.lock, flags); +} + +static void prcmu_irq_mask(struct irq_data *d) +{ + unsigned long flags; + + spin_lock_irqsave(&mb0_transfer.dbb_irqs_lock, flags); + + mb0_transfer.req.dbb_irqs &= ~prcmu_irq_bit[d->irq - IRQ_PRCMU_BASE]; + + spin_unlock_irqrestore(&mb0_transfer.dbb_irqs_lock, flags); + + if (d->irq != IRQ_PRCMU_CA_SLEEP) + schedule_work(&mb0_transfer.mask_work); +} + +static void prcmu_irq_unmask(struct irq_data *d) +{ + unsigned long flags; + + spin_lock_irqsave(&mb0_transfer.dbb_irqs_lock, flags); + + mb0_transfer.req.dbb_irqs |= prcmu_irq_bit[d->irq - IRQ_PRCMU_BASE]; + + spin_unlock_irqrestore(&mb0_transfer.dbb_irqs_lock, flags); + + if (d->irq != IRQ_PRCMU_CA_SLEEP) + schedule_work(&mb0_transfer.mask_work); +} + +static void noop(struct irq_data *d) +{ +} + +static struct irq_chip prcmu_irq_chip = { + .name = "prcmu", + .irq_disable = prcmu_irq_mask, + .irq_ack = noop, + .irq_mask = prcmu_irq_mask, + .irq_unmask = prcmu_irq_unmask, +}; + void __init prcmu_early_init(void) { - if (cpu_is_u8500v11() || cpu_is_u8500ed()) { + unsigned int i; + + if (cpu_is_u8500v1()) { tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE_V1); } else if (cpu_is_u8500v2()) { + void *tcpm_base = ioremap_nocache(U8500_PRCMU_TCPM_BASE, SZ_4K); + + if (tcpm_base != NULL) { + int version; + version = readl(tcpm_base + PRCMU_FW_VERSION_OFFSET); + prcmu_version.project_number = version & 0xFF; + prcmu_version.api_version = (version >> 8) & 0xFF; + prcmu_version.func_version = (version >> 16) & 0xFF; + prcmu_version.errata = (version >> 24) & 0xFF; + pr_info("PRCMU firmware version %d.%d.%d\n", + (version >> 8) & 0xFF, (version >> 16) & 0xFF, + (version >> 24) & 0xFF); + iounmap(tcpm_base); + } + tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE); } else { pr_err("prcmu: Unsupported chip version\n"); BUG(); } -} - -static int __init prcmu_init(void) -{ - if (cpu_is_u8500ed()) { - pr_err("prcmu: Unsupported chip version\n"); - return 0; - } + spin_lock_init(&mb0_transfer.lock); + spin_lock_init(&mb0_transfer.dbb_irqs_lock); + mutex_init(&mb0_transfer.ac_wake_lock); + init_completion(&mb0_transfer.ac_wake_work); mutex_init(&mb1_transfer.lock); init_completion(&mb1_transfer.work); + mutex_init(&mb2_transfer.lock); + init_completion(&mb2_transfer.work); + spin_lock_init(&mb2_transfer.auto_pm_lock); + spin_lock_init(&mb3_transfer.lock); + mutex_init(&mb3_transfer.sysclk_lock); + init_completion(&mb3_transfer.sysclk_work); + mutex_init(&mb4_transfer.lock); + init_completion(&mb4_transfer.work); mutex_init(&mb5_transfer.lock); init_completion(&mb5_transfer.work); + INIT_WORK(&mb0_transfer.mask_work, prcmu_mask_work); + + /* Initalize irqs. */ + for (i = 0; i < NUM_PRCMU_WAKEUPS; i++) { + unsigned int irq; + + irq = IRQ_PRCMU_BASE + i; + irq_set_chip_and_handler(irq, &prcmu_irq_chip, + handle_simple_irq); + set_irq_flags(irq, IRQF_VALID); + } +} + +static struct mfd_cell db8500_prcmu_devs[] = { + { + .name = "db8500-prcmu-regulators", + }, + { + .name = "cpufreq-u8500", + }, +}; + +/** + * prcmu_fw_init - arch init call for the Linux PRCMU fw init logic + * + */ +static int __init db8500_prcmu_probe(struct platform_device *pdev) +{ + int err = 0; + + if (ux500_is_svp()) + return -ENODEV; + /* Clean up the mailbox interrupts after pre-kernel code. */ - writel((MBOX_BIT(NUM_MBOX) - 1), PRCM_ARM_IT1_CLEAR); + writel(ALL_MBOX_BITS, (_PRCMU_BASE + PRCM_ARM_IT1_CLR)); + + err = request_threaded_irq(IRQ_DB8500_PRCMU1, prcmu_irq_handler, + prcmu_irq_thread_fn, IRQF_NO_SUSPEND, "prcmu", NULL); + if (err < 0) { + pr_err("prcmu: Failed to allocate IRQ_DB8500_PRCMU1.\n"); + err = -EBUSY; + goto no_irq_return; + } + + if (cpu_is_u8500v20_or_later()) + prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET); + + err = mfd_add_devices(&pdev->dev, 0, db8500_prcmu_devs, + ARRAY_SIZE(db8500_prcmu_devs), NULL, + 0); - return request_irq(IRQ_DB8500_PRCMU1, prcmu_irq_handler, 0, - "prcmu", NULL); + if (err) + pr_err("prcmu: Failed to add subdevices\n"); + else + pr_info("DB8500 PRCMU initialized\n"); + +no_irq_return: + return err; +} + +static struct platform_driver db8500_prcmu_driver = { + .driver = { + .name = "db8500-prcmu", + .owner = THIS_MODULE, + }, +}; + +static int __init db8500_prcmu_init(void) +{ + return platform_driver_probe(&db8500_prcmu_driver, db8500_prcmu_probe); } -arch_initcall(prcmu_init); +arch_initcall(db8500_prcmu_init); + +MODULE_AUTHOR("Mattias Nilsson "); +MODULE_DESCRIPTION("DB8500 PRCM Unit driver"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/mfd/db8500-prcmu.h b/include/linux/mfd/db8500-prcmu.h index d591d79aa6f0..917dbcab701c 100644 --- a/include/linux/mfd/db8500-prcmu.h +++ b/include/linux/mfd/db8500-prcmu.h @@ -2,57 +2,977 @@ * Copyright (C) STMicroelectronics 2009 * Copyright (C) ST-Ericsson SA 2010 * - * Author: Sundar Iyer - * Author: Martin Persson - * * License Terms: GNU General Public License v2 + * Author: Kumar Sanghvi * - * PRCM Unit definitions + * PRCMU f/w APIs */ +#ifndef __MFD_DB8500_PRCMU_H +#define __MFD_DB8500_PRCMU_H + +#include +#include -#ifndef __MACH_PRCMU_DEFS_H -#define __MACH_PRCMU_DEFS_H +/* This portion previously known as */ -enum prcmu_cpu_opp { - CPU_OPP_INIT = 0x00, - CPU_OPP_NO_CHANGE = 0x01, - CPU_OPP_100 = 0x02, - CPU_OPP_50 = 0x03, - CPU_OPP_MAX = 0x04, - CPU_OPP_EXT_CLK = 0x07 +/** + * enum state - ON/OFF state definition + * @OFF: State is ON + * @ON: State is OFF + * + */ +enum state { + OFF = 0x0, + ON = 0x1, }; -enum prcmu_ape_opp { - APE_OPP_NO_CHANGE = 0x00, - APE_OPP_100 = 0x02, - APE_OPP_50 = 0x03, + +/** + * enum ret_state - general purpose On/Off/Retention states + * + */ +enum ret_state { + OFFST = 0, + ONST = 1, + RETST = 2 }; -#endif /* __MACH_PRCMU_DEFS_H */ +/** + * enum clk_arm - ARM Cortex A9 clock schemes + * @A9_OFF: + * @A9_BOOT: + * @A9_OPPT1: + * @A9_OPPT2: + * @A9_EXTCLK: + */ +enum clk_arm { + A9_OFF, + A9_BOOT, + A9_OPPT1, + A9_OPPT2, + A9_EXTCLK +}; -/* - * Copyright (C) STMicroelectronics 2009 - * Copyright (C) ST-Ericsson SA 2010 +/** + * enum clk_gen - GEN#0/GEN#1 clock schemes + * @GEN_OFF: + * @GEN_BOOT: + * @GEN_OPPT1: + */ +enum clk_gen { + GEN_OFF, + GEN_BOOT, + GEN_OPPT1, +}; + +/* some information between arm and xp70 */ + +/** + * enum romcode_write - Romcode message written by A9 AND read by XP70 + * @RDY_2_DS: Value set when ApDeepSleep state can be executed by XP70 + * @RDY_2_XP70_RST: Value set when 0x0F has been successfully polled by the + * romcode. The xp70 will go into self-reset + */ +enum romcode_write { + RDY_2_DS = 0x09, + RDY_2_XP70_RST = 0x10 +}; + +/** + * enum romcode_read - Romcode message written by XP70 and read by A9 + * @INIT: Init value when romcode field is not used + * @FS_2_DS: Value set when power state is going from ApExecute to + * ApDeepSleep + * @END_DS: Value set when ApDeepSleep power state is reached coming from + * ApExecute state + * @DS_TO_FS: Value set when power state is going from ApDeepSleep to + * ApExecute + * @END_FS: Value set when ApExecute power state is reached coming from + * ApDeepSleep state + * @SWR: Value set when power state is going to ApReset + * @END_SWR: Value set when the xp70 finished executing ApReset actions and + * waits for romcode acknowledgment to go to self-reset + */ +enum romcode_read { + INIT = 0x00, + FS_2_DS = 0x0A, + END_DS = 0x0B, + DS_TO_FS = 0x0C, + END_FS = 0x0D, + SWR = 0x0E, + END_SWR = 0x0F +}; + +/** + * enum ap_pwrst - current power states defined in PRCMU firmware + * @NO_PWRST: Current power state init + * @AP_BOOT: Current power state is apBoot + * @AP_EXECUTE: Current power state is apExecute + * @AP_DEEP_SLEEP: Current power state is apDeepSleep + * @AP_SLEEP: Current power state is apSleep + * @AP_IDLE: Current power state is apIdle + * @AP_RESET: Current power state is apReset + */ +enum ap_pwrst { + NO_PWRST = 0x00, + AP_BOOT = 0x01, + AP_EXECUTE = 0x02, + AP_DEEP_SLEEP = 0x03, + AP_SLEEP = 0x04, + AP_IDLE = 0x05, + AP_RESET = 0x06 +}; + +/** + * enum ap_pwrst_trans - Transition states defined in PRCMU firmware + * @NO_TRANSITION: No power state transition + * @APEXECUTE_TO_APSLEEP: Power state transition from ApExecute to ApSleep + * @APIDLE_TO_APSLEEP: Power state transition from ApIdle to ApSleep + * @APBOOT_TO_APEXECUTE: Power state transition from ApBoot to ApExecute + * @APEXECUTE_TO_APDEEPSLEEP: Power state transition from ApExecute to + * ApDeepSleep + * @APEXECUTE_TO_APIDLE: Power state transition from ApExecute to ApIdle + */ +enum ap_pwrst_trans { + NO_TRANSITION = 0x00, + APEXECUTE_TO_APSLEEP = 0x01, + APIDLE_TO_APSLEEP = 0x02, /* To be removed */ + PRCMU_AP_SLEEP = 0x01, + APBOOT_TO_APEXECUTE = 0x03, + APEXECUTE_TO_APDEEPSLEEP = 0x04, /* To be removed */ + PRCMU_AP_DEEP_SLEEP = 0x04, + APEXECUTE_TO_APIDLE = 0x05, /* To be removed */ + PRCMU_AP_IDLE = 0x05, + PRCMU_AP_DEEP_IDLE = 0x07, +}; + +/** + * enum ddr_pwrst - DDR power states definition + * @DDR_PWR_STATE_UNCHANGED: SDRAM and DDR controller state is unchanged + * @DDR_PWR_STATE_ON: + * @DDR_PWR_STATE_OFFLOWLAT: + * @DDR_PWR_STATE_OFFHIGHLAT: + */ +enum ddr_pwrst { + DDR_PWR_STATE_UNCHANGED = 0x00, + DDR_PWR_STATE_ON = 0x01, + DDR_PWR_STATE_OFFLOWLAT = 0x02, + DDR_PWR_STATE_OFFHIGHLAT = 0x03 +}; + +/** + * enum arm_opp - ARM OPP states definition + * @ARM_OPP_INIT: + * @ARM_NO_CHANGE: The ARM operating point is unchanged + * @ARM_100_OPP: The new ARM operating point is arm100opp + * @ARM_50_OPP: The new ARM operating point is arm50opp + * @ARM_MAX_OPP: Operating point is "max" (more than 100) + * @ARM_MAX_FREQ100OPP: Set max opp if available, else 100 + * @ARM_EXTCLK: The new ARM operating point is armExtClk + */ +enum arm_opp { + ARM_OPP_INIT = 0x00, + ARM_NO_CHANGE = 0x01, + ARM_100_OPP = 0x02, + ARM_50_OPP = 0x03, + ARM_MAX_OPP = 0x04, + ARM_MAX_FREQ100OPP = 0x05, + ARM_EXTCLK = 0x07 +}; + +/** + * enum ape_opp - APE OPP states definition + * @APE_OPP_INIT: + * @APE_NO_CHANGE: The APE operating point is unchanged + * @APE_100_OPP: The new APE operating point is ape100opp + * @APE_50_OPP: 50% + */ +enum ape_opp { + APE_OPP_INIT = 0x00, + APE_NO_CHANGE = 0x01, + APE_100_OPP = 0x02, + APE_50_OPP = 0x03 +}; + +/** + * enum hw_acc_state - State definition for hardware accelerator + * @HW_NO_CHANGE: The hardware accelerator state must remain unchanged + * @HW_OFF: The hardware accelerator must be switched off + * @HW_OFF_RAMRET: The hardware accelerator must be switched off with its + * internal RAM in retention + * @HW_ON: The hwa hardware accelerator hwa must be switched on * - * Author: Kumar Sanghvi - * Author: Sundar Iyer - * Author: Mattias Nilsson + * NOTE! Deprecated, to be removed when all users switched over to use the + * regulator API. + */ +enum hw_acc_state { + HW_NO_CHANGE = 0x00, + HW_OFF = 0x01, + HW_OFF_RAMRET = 0x02, + HW_ON = 0x04 +}; + +/** + * enum mbox_2_arm_stat - Status messages definition for mbox_arm + * @BOOT_TO_EXECUTEOK: The apBoot to apExecute state transition has been + * completed + * @DEEPSLEEPOK: The apExecute to apDeepSleep state transition has been + * completed + * @SLEEPOK: The apExecute to apSleep state transition has been completed + * @IDLEOK: The apExecute to apIdle state transition has been completed + * @SOFTRESETOK: The A9 watchdog/ SoftReset state has been completed + * @SOFTRESETGO : The A9 watchdog/SoftReset state is on going + * @BOOT_TO_EXECUTE: The apBoot to apExecute state transition is on going + * @EXECUTE_TO_DEEPSLEEP: The apExecute to apDeepSleep state transition is on + * going + * @DEEPSLEEP_TO_EXECUTE: The apDeepSleep to apExecute state transition is on + * going + * @DEEPSLEEP_TO_EXECUTEOK: The apDeepSleep to apExecute state transition has + * been completed + * @EXECUTE_TO_SLEEP: The apExecute to apSleep state transition is on going + * @SLEEP_TO_EXECUTE: The apSleep to apExecute state transition is on going + * @SLEEP_TO_EXECUTEOK: The apSleep to apExecute state transition has been + * completed + * @EXECUTE_TO_IDLE: The apExecute to apIdle state transition is on going + * @IDLE_TO_EXECUTE: The apIdle to apExecute state transition is on going + * @IDLE_TO_EXECUTEOK: The apIdle to apExecute state transition has been + * completed + * @INIT_STATUS: Status init + */ +enum ap_pwrsttr_status { + BOOT_TO_EXECUTEOK = 0xFF, + DEEPSLEEPOK = 0xFE, + SLEEPOK = 0xFD, + IDLEOK = 0xFC, + SOFTRESETOK = 0xFB, + SOFTRESETGO = 0xFA, + BOOT_TO_EXECUTE = 0xF9, + EXECUTE_TO_DEEPSLEEP = 0xF8, + DEEPSLEEP_TO_EXECUTE = 0xF7, + DEEPSLEEP_TO_EXECUTEOK = 0xF6, + EXECUTE_TO_SLEEP = 0xF5, + SLEEP_TO_EXECUTE = 0xF4, + SLEEP_TO_EXECUTEOK = 0xF3, + EXECUTE_TO_IDLE = 0xF2, + IDLE_TO_EXECUTE = 0xF1, + IDLE_TO_EXECUTEOK = 0xF0, + RDYTODS_RETURNTOEXE = 0xEF, + NORDYTODS_RETURNTOEXE = 0xEE, + EXETOSLEEP_RETURNTOEXE = 0xED, + EXETOIDLE_RETURNTOEXE = 0xEC, + INIT_STATUS = 0xEB, + + /*error messages */ + INITERROR = 0x00, + PLLARMLOCKP_ER = 0x01, + PLLDDRLOCKP_ER = 0x02, + PLLSOCLOCKP_ER = 0x03, + PLLSOCK1LOCKP_ER = 0x04, + ARMWFI_ER = 0x05, + SYSCLKOK_ER = 0x06, + I2C_NACK_DATA_ER = 0x07, + BOOT_ER = 0x08, + I2C_STATUS_ALWAYS_1 = 0x0A, + I2C_NACK_REG_ADDR_ER = 0x0B, + I2C_NACK_DATA0123_ER = 0x1B, + I2C_NACK_ADDR_ER = 0x1F, + CURAPPWRSTISNOT_BOOT = 0x20, + CURAPPWRSTISNOT_EXECUTE = 0x21, + CURAPPWRSTISNOT_SLEEPMODE = 0x22, + CURAPPWRSTISNOT_CORRECTFORIT10 = 0x23, + FIFO4500WUISNOT_WUPEVENT = 0x24, + PLL32KLOCKP_ER = 0x29, + DDRDEEPSLEEPOK_ER = 0x2A, + ROMCODEREADY_ER = 0x50, + WUPBEFOREDS = 0x51, + DDRCONFIG_ER = 0x52, + WUPBEFORESLEEP = 0x53, + WUPBEFOREIDLE = 0x54 +}; /* earlier called as mbox_2_arm_stat */ + +/** + * enum dvfs_stat - DVFS status messages definition + * @DVFS_GO: A state transition DVFS is on going + * @DVFS_ARM100OPPOK: The state transition DVFS has been completed for 100OPP + * @DVFS_ARM50OPPOK: The state transition DVFS has been completed for 50OPP + * @DVFS_ARMEXTCLKOK: The state transition DVFS has been completed for EXTCLK + * @DVFS_NOCHGTCLKOK: The state transition DVFS has been completed for + * NOCHGCLK + * @DVFS_INITSTATUS: Value init + */ +enum dvfs_stat { + DVFS_GO = 0xFF, + DVFS_ARM100OPPOK = 0xFE, + DVFS_ARM50OPPOK = 0xFD, + DVFS_ARMEXTCLKOK = 0xFC, + DVFS_NOCHGTCLKOK = 0xFB, + DVFS_INITSTATUS = 0x00 +}; + +/** + * enum sva_mmdsp_stat - SVA MMDSP status messages + * @SVA_MMDSP_GO: SVAMMDSP interrupt has happened + * @SVA_MMDSP_INIT: Status init + */ +enum sva_mmdsp_stat { + SVA_MMDSP_GO = 0xFF, + SVA_MMDSP_INIT = 0x00 +}; + +/** + * enum sia_mmdsp_stat - SIA MMDSP status messages + * @SIA_MMDSP_GO: SIAMMDSP interrupt has happened + * @SIA_MMDSP_INIT: Status init + */ +enum sia_mmdsp_stat { + SIA_MMDSP_GO = 0xFF, + SIA_MMDSP_INIT = 0x00 +}; + +/** + * enum mbox_to_arm_err - Error messages definition + * @INIT_ERR: Init value + * @PLLARMLOCKP_ERR: PLLARM has not been correctly locked in given time + * @PLLDDRLOCKP_ERR: PLLDDR has not been correctly locked in the given time + * @PLLSOC0LOCKP_ERR: PLLSOC0 has not been correctly locked in the given time + * @PLLSOC1LOCKP_ERR: PLLSOC1 has not been correctly locked in the given time + * @ARMWFI_ERR: The ARM WFI has not been correctly executed in the given time + * @SYSCLKOK_ERR: The SYSCLK is not available in the given time + * @BOOT_ERR: Romcode has not validated the XP70 self reset in the given time + * @ROMCODESAVECONTEXT: The Romcode didn.t correctly save it secure context + * @VARMHIGHSPEEDVALTO_ERR: The ARM high speed supply value transfered + * through I2C has not been correctly executed in the given time + * @VARMHIGHSPEEDACCESS_ERR: The command value of VarmHighSpeedVal transfered + * through I2C has not been correctly executed in the given time + * @VARMLOWSPEEDVALTO_ERR:The ARM low speed supply value transfered through + * I2C has not been correctly executed in the given time + * @VARMLOWSPEEDACCESS_ERR: The command value of VarmLowSpeedVal transfered + * through I2C has not been correctly executed in the given time + * @VARMRETENTIONVALTO_ERR: The ARM retention supply value transfered through + * I2C has not been correctly executed in the given time + * @VARMRETENTIONACCESS_ERR: The command value of VarmRetentionVal transfered + * through I2C has not been correctly executed in the given time + * @VAPEHIGHSPEEDVALTO_ERR: The APE highspeed supply value transfered through + * I2C has not been correctly executed in the given time + * @VSAFEHPVALTO_ERR: The SAFE high power supply value transfered through I2C + * has not been correctly executed in the given time + * @VMODSEL1VALTO_ERR: The MODEM sel1 supply value transfered through I2C has + * not been correctly executed in the given time + * @VMODSEL2VALTO_ERR: The MODEM sel2 supply value transfered through I2C has + * not been correctly executed in the given time + * @VARMOFFACCESS_ERR: The command value of Varm ON/OFF transfered through + * I2C has not been correctly executed in the given time + * @VAPEOFFACCESS_ERR: The command value of Vape ON/OFF transfered through + * I2C has not been correctly executed in the given time + * @VARMRETACCES_ERR: The command value of Varm retention ON/OFF transfered + * through I2C has not been correctly executed in the given time + * @CURAPPWRSTISNOTBOOT:Generated when Arm want to do power state transition + * ApBoot to ApExecute but the power current state is not Apboot + * @CURAPPWRSTISNOTEXECUTE: Generated when Arm want to do power state + * transition from ApExecute to others power state but the + * power current state is not ApExecute + * @CURAPPWRSTISNOTSLEEPMODE: Generated when wake up events are transmitted + * but the power current state is not ApDeepSleep/ApSleep/ApIdle + * @CURAPPWRSTISNOTCORRECTDBG: Generated when wake up events are transmitted + * but the power current state is not correct + * @ARMREGU1VALTO_ERR:The ArmRegu1 value transferred through I2C has not + * been correctly executed in the given time + * @ARMREGU2VALTO_ERR: The ArmRegu2 value transferred through I2C has not + * been correctly executed in the given time + * @VAPEREGUVALTO_ERR: The VApeRegu value transfered through I2C has not + * been correctly executed in the given time + * @VSMPS3REGUVALTO_ERR: The VSmps3Regu value transfered through I2C has not + * been correctly executed in the given time + * @VMODREGUVALTO_ERR: The VModemRegu value transfered through I2C has not + * been correctly executed in the given time + */ +enum mbox_to_arm_err { + INIT_ERR = 0x00, + PLLARMLOCKP_ERR = 0x01, + PLLDDRLOCKP_ERR = 0x02, + PLLSOC0LOCKP_ERR = 0x03, + PLLSOC1LOCKP_ERR = 0x04, + ARMWFI_ERR = 0x05, + SYSCLKOK_ERR = 0x06, + BOOT_ERR = 0x07, + ROMCODESAVECONTEXT = 0x08, + VARMHIGHSPEEDVALTO_ERR = 0x10, + VARMHIGHSPEEDACCESS_ERR = 0x11, + VARMLOWSPEEDVALTO_ERR = 0x12, + VARMLOWSPEEDACCESS_ERR = 0x13, + VARMRETENTIONVALTO_ERR = 0x14, + VARMRETENTIONACCESS_ERR = 0x15, + VAPEHIGHSPEEDVALTO_ERR = 0x16, + VSAFEHPVALTO_ERR = 0x17, + VMODSEL1VALTO_ERR = 0x18, + VMODSEL2VALTO_ERR = 0x19, + VARMOFFACCESS_ERR = 0x1A, + VAPEOFFACCESS_ERR = 0x1B, + VARMRETACCES_ERR = 0x1C, + CURAPPWRSTISNOTBOOT = 0x20, + CURAPPWRSTISNOTEXECUTE = 0x21, + CURAPPWRSTISNOTSLEEPMODE = 0x22, + CURAPPWRSTISNOTCORRECTDBG = 0x23, + ARMREGU1VALTO_ERR = 0x24, + ARMREGU2VALTO_ERR = 0x25, + VAPEREGUVALTO_ERR = 0x26, + VSMPS3REGUVALTO_ERR = 0x27, + VMODREGUVALTO_ERR = 0x28 +}; + +enum hw_acc { + SVAMMDSP = 0, + SVAPIPE = 1, + SIAMMDSP = 2, + SIAPIPE = 3, + SGA = 4, + B2R2MCDE = 5, + ESRAM12 = 6, + ESRAM34 = 7, +}; + +enum cs_pwrmgt { + PWRDNCS0 = 0, + WKUPCS0 = 1, + PWRDNCS1 = 2, + WKUPCS1 = 3 +}; + +/* Defs related to autonomous power management */ + +/** + * enum sia_sva_pwr_policy - Power policy + * @NO_CHGT: No change + * @DSPOFF_HWPOFF: + * @DSPOFFRAMRET_HWPOFF: + * @DSPCLKOFF_HWPOFF: + * @DSPCLKOFF_HWPCLKOFF: * - * License Terms: GNU General Public License v2 + */ +enum sia_sva_pwr_policy { + NO_CHGT = 0x0, + DSPOFF_HWPOFF = 0x1, + DSPOFFRAMRET_HWPOFF = 0x2, + DSPCLKOFF_HWPOFF = 0x3, + DSPCLKOFF_HWPCLKOFF = 0x4, +}; + +/** + * enum auto_enable - Auto Power enable + * @AUTO_OFF: + * @AUTO_ON: + * + */ +enum auto_enable { + AUTO_OFF = 0x0, + AUTO_ON = 0x1, +}; + +/* End of file previously known as prcmu-fw-defs_v1.h */ + +/* PRCMU Wakeup defines */ +enum prcmu_wakeup_index { + PRCMU_WAKEUP_INDEX_RTC, + PRCMU_WAKEUP_INDEX_RTT0, + PRCMU_WAKEUP_INDEX_RTT1, + PRCMU_WAKEUP_INDEX_HSI0, + PRCMU_WAKEUP_INDEX_HSI1, + PRCMU_WAKEUP_INDEX_USB, + PRCMU_WAKEUP_INDEX_ABB, + PRCMU_WAKEUP_INDEX_ABB_FIFO, + PRCMU_WAKEUP_INDEX_ARM, + NUM_PRCMU_WAKEUP_INDICES +}; +#define PRCMU_WAKEUP(_name) (BIT(PRCMU_WAKEUP_INDEX_##_name)) + +/* PRCMU QoS APE OPP class */ +#define PRCMU_QOS_APE_OPP 1 +#define PRCMU_QOS_DDR_OPP 2 +#define PRCMU_QOS_DEFAULT_VALUE -1 + +/** + * enum hw_acc_dev - enum for hw accelerators + * @HW_ACC_SVAMMDSP: for SVAMMDSP + * @HW_ACC_SVAPIPE: for SVAPIPE + * @HW_ACC_SIAMMDSP: for SIAMMDSP + * @HW_ACC_SIAPIPE: for SIAPIPE + * @HW_ACC_SGA: for SGA + * @HW_ACC_B2R2: for B2R2 + * @HW_ACC_MCDE: for MCDE + * @HW_ACC_ESRAM1: for ESRAM1 + * @HW_ACC_ESRAM2: for ESRAM2 + * @HW_ACC_ESRAM3: for ESRAM3 + * @HW_ACC_ESRAM4: for ESRAM4 + * @NUM_HW_ACC: number of hardware accelerators + * + * Different hw accelerators which can be turned ON/ + * OFF or put into retention (MMDSPs and ESRAMs). + * Used with EPOD API. * - * PRCM Unit f/w API + * NOTE! Deprecated, to be removed when all users switched over to use the + * regulator API. + */ +enum hw_acc_dev { + HW_ACC_SVAMMDSP, + HW_ACC_SVAPIPE, + HW_ACC_SIAMMDSP, + HW_ACC_SIAPIPE, + HW_ACC_SGA, + HW_ACC_B2R2, + HW_ACC_MCDE, + HW_ACC_ESRAM1, + HW_ACC_ESRAM2, + HW_ACC_ESRAM3, + HW_ACC_ESRAM4, + NUM_HW_ACC +}; + +/* + * Ids for all EPODs (power domains) + * - EPOD_ID_SVAMMDSP: power domain for SVA MMDSP + * - EPOD_ID_SVAPIPE: power domain for SVA pipe + * - EPOD_ID_SIAMMDSP: power domain for SIA MMDSP + * - EPOD_ID_SIAPIPE: power domain for SIA pipe + * - EPOD_ID_SGA: power domain for SGA + * - EPOD_ID_B2R2_MCDE: power domain for B2R2 and MCDE + * - EPOD_ID_ESRAM12: power domain for ESRAM 1 and 2 + * - EPOD_ID_ESRAM34: power domain for ESRAM 3 and 4 + * - NUM_EPOD_ID: number of power domains + */ +#define EPOD_ID_SVAMMDSP 0 +#define EPOD_ID_SVAPIPE 1 +#define EPOD_ID_SIAMMDSP 2 +#define EPOD_ID_SIAPIPE 3 +#define EPOD_ID_SGA 4 +#define EPOD_ID_B2R2_MCDE 5 +#define EPOD_ID_ESRAM12 6 +#define EPOD_ID_ESRAM34 7 +#define NUM_EPOD_ID 8 + +/* + * state definition for EPOD (power domain) + * - EPOD_STATE_NO_CHANGE: The EPOD should remain unchanged + * - EPOD_STATE_OFF: The EPOD is switched off + * - EPOD_STATE_RAMRET: The EPOD is switched off with its internal RAM in + * retention + * - EPOD_STATE_ON_CLK_OFF: The EPOD is switched on, clock is still off + * - EPOD_STATE_ON: Same as above, but with clock enabled */ -#ifndef __MACH_PRCMU_H -#define __MACH_PRCMU_H +#define EPOD_STATE_NO_CHANGE 0x00 +#define EPOD_STATE_OFF 0x01 +#define EPOD_STATE_RAMRET 0x02 +#define EPOD_STATE_ON_CLK_OFF 0x03 +#define EPOD_STATE_ON 0x04 +/* + * CLKOUT sources + */ +#define PRCMU_CLKSRC_CLK38M 0x00 +#define PRCMU_CLKSRC_ACLK 0x01 +#define PRCMU_CLKSRC_SYSCLK 0x02 +#define PRCMU_CLKSRC_LCDCLK 0x03 +#define PRCMU_CLKSRC_SDMMCCLK 0x04 +#define PRCMU_CLKSRC_TVCLK 0x05 +#define PRCMU_CLKSRC_TIMCLK 0x06 +#define PRCMU_CLKSRC_CLK009 0x07 +/* These are only valid for CLKOUT1: */ +#define PRCMU_CLKSRC_SIAMMDSPCLK 0x40 +#define PRCMU_CLKSRC_I2CCLK 0x41 +#define PRCMU_CLKSRC_MSP02CLK 0x42 +#define PRCMU_CLKSRC_ARMPLL_OBSCLK 0x43 +#define PRCMU_CLKSRC_HSIRXCLK 0x44 +#define PRCMU_CLKSRC_HSITXCLK 0x45 +#define PRCMU_CLKSRC_ARMCLKFIX 0x46 +#define PRCMU_CLKSRC_HDMICLK 0x47 + +/* + * Definitions for autonomous power management configuration. + */ + +#define PRCMU_AUTO_PM_OFF 0 +#define PRCMU_AUTO_PM_ON 1 + +#define PRCMU_AUTO_PM_POWER_ON_HSEM BIT(0) +#define PRCMU_AUTO_PM_POWER_ON_ABB_FIFO_IT BIT(1) + +enum prcmu_auto_pm_policy { + PRCMU_AUTO_PM_POLICY_NO_CHANGE, + PRCMU_AUTO_PM_POLICY_DSP_OFF_HWP_OFF, + PRCMU_AUTO_PM_POLICY_DSP_OFF_RAMRET_HWP_OFF, + PRCMU_AUTO_PM_POLICY_DSP_CLK_OFF_HWP_OFF, + PRCMU_AUTO_PM_POLICY_DSP_CLK_OFF_HWP_CLK_OFF, +}; + +/** + * struct prcmu_auto_pm_config - Autonomous power management configuration. + * @sia_auto_pm_enable: SIA autonomous pm enable. (PRCMU_AUTO_PM_{OFF,ON}) + * @sia_power_on: SIA power ON enable. (PRCMU_AUTO_PM_POWER_ON_* bitmask) + * @sia_policy: SIA power policy. (enum prcmu_auto_pm_policy) + * @sva_auto_pm_enable: SVA autonomous pm enable. (PRCMU_AUTO_PM_{OFF,ON}) + * @sva_power_on: SVA power ON enable. (PRCMU_AUTO_PM_POWER_ON_* bitmask) + * @sva_policy: SVA power policy. (enum prcmu_auto_pm_policy) + */ +struct prcmu_auto_pm_config { + u8 sia_auto_pm_enable; + u8 sia_power_on; + u8 sia_policy; + u8 sva_auto_pm_enable; + u8 sva_power_on; + u8 sva_policy; +}; + +/** + * enum ddr_opp - DDR OPP states definition + * @DDR_100_OPP: The new DDR operating point is ddr100opp + * @DDR_50_OPP: The new DDR operating point is ddr50opp + * @DDR_25_OPP: The new DDR operating point is ddr25opp + */ +enum ddr_opp { + DDR_100_OPP = 0x00, + DDR_50_OPP = 0x01, + DDR_25_OPP = 0x02, +}; + +/* + * Clock identifiers. + */ +enum prcmu_clock { + PRCMU_SGACLK, + PRCMU_UARTCLK, + PRCMU_MSP02CLK, + PRCMU_MSP1CLK, + PRCMU_I2CCLK, + PRCMU_SDMMCCLK, + PRCMU_SLIMCLK, + PRCMU_PER1CLK, + PRCMU_PER2CLK, + PRCMU_PER3CLK, + PRCMU_PER5CLK, + PRCMU_PER6CLK, + PRCMU_PER7CLK, + PRCMU_LCDCLK, + PRCMU_BMLCLK, + PRCMU_HSITXCLK, + PRCMU_HSIRXCLK, + PRCMU_HDMICLK, + PRCMU_APEATCLK, + PRCMU_APETRACECLK, + PRCMU_MCDECLK, + PRCMU_IPI2CCLK, + PRCMU_DSIALTCLK, + PRCMU_DMACLK, + PRCMU_B2R2CLK, + PRCMU_TVCLK, + PRCMU_SSPCLK, + PRCMU_RNGCLK, + PRCMU_UICCCLK, + PRCMU_NUM_REG_CLOCKS, + PRCMU_SYSCLK = PRCMU_NUM_REG_CLOCKS, + PRCMU_TIMCLK, +}; + +/* + * Definitions for controlling ESRAM0 in deep sleep. + */ +#define ESRAM0_DEEP_SLEEP_STATE_OFF 1 +#define ESRAM0_DEEP_SLEEP_STATE_RET 2 + +#ifdef CONFIG_MFD_DB8500_PRCMU void __init prcmu_early_init(void); +int prcmu_set_display_clocks(void); +int prcmu_disable_dsipll(void); +int prcmu_enable_dsipll(void); +#else +static inline void __init prcmu_early_init(void) {} +#endif + +#ifdef CONFIG_MFD_DB8500_PRCMU + +int prcmu_set_rc_a2p(enum romcode_write); +enum romcode_read prcmu_get_rc_p2a(void); +enum ap_pwrst prcmu_get_xp70_current_state(void); +int prcmu_set_power_state(u8 state, bool keep_ulp_clk, bool keep_ap_pll); + +void prcmu_enable_wakeups(u32 wakeups); +static inline void prcmu_disable_wakeups(void) +{ + prcmu_enable_wakeups(0); +} + +void prcmu_config_abb_event_readout(u32 abb_events); +void prcmu_get_abb_event_buffer(void __iomem **buf); +int prcmu_set_arm_opp(u8 opp); +int prcmu_get_arm_opp(void); +bool prcmu_has_arm_maxopp(void); +bool prcmu_is_u8400(void); +int prcmu_set_ape_opp(u8 opp); +int prcmu_get_ape_opp(void); +int prcmu_request_ape_opp_100_voltage(bool enable); +int prcmu_release_usb_wakeup_state(void); +int prcmu_set_ddr_opp(u8 opp); +int prcmu_get_ddr_opp(void); +unsigned long prcmu_qos_get_cpufreq_opp_delay(void); +void prcmu_qos_set_cpufreq_opp_delay(unsigned long); +/* NOTE! Use regulator framework instead */ +int prcmu_set_hwacc(u16 hw_acc_dev, u8 state); +int prcmu_set_epod(u16 epod_id, u8 epod_state); +void prcmu_configure_auto_pm(struct prcmu_auto_pm_config *sleep, + struct prcmu_auto_pm_config *idle); +bool prcmu_is_auto_pm_enabled(void); + +int prcmu_config_clkout(u8 clkout, u8 source, u8 div); +int prcmu_request_clock(u8 clock, bool enable); +int prcmu_set_clock_divider(u8 clock, u8 divider); +int prcmu_config_esram0_deep_sleep(u8 state); +int prcmu_config_hotdog(u8 threshold); +int prcmu_config_hotmon(u8 low, u8 high); +int prcmu_start_temp_sense(u16 cycles32k); +int prcmu_stop_temp_sense(void); int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size); int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size); -int prcmu_set_ape_opp(enum prcmu_ape_opp opp); -int prcmu_set_cpu_opp(enum prcmu_cpu_opp opp); -int prcmu_set_ape_cpu_opps(enum prcmu_ape_opp ape_opp, - enum prcmu_cpu_opp cpu_opp); -enum prcmu_ape_opp prcmu_get_ape_opp(void); -int prcmu_get_cpu_opp(void); -bool prcmu_has_arm_maxopp(void); -#endif /* __MACH_PRCMU_H */ +void prcmu_ac_wake_req(void); +void prcmu_ac_sleep_req(void); +void prcmu_system_reset(u16 reset_code); +void prcmu_modem_reset(void); +bool prcmu_is_ac_wake_requested(void); +void prcmu_enable_spi2(void); +void prcmu_disable_spi2(void); + +#else /* !CONFIG_MFD_DB8500_PRCMU */ + +static inline int prcmu_set_rc_a2p(enum romcode_write code) +{ + return 0; +} + +static inline enum romcode_read prcmu_get_rc_p2a(void) +{ + return INIT; +} + +static inline enum ap_pwrst prcmu_get_xp70_current_state(void) +{ + return AP_EXECUTE; +} + +static inline int prcmu_set_power_state(u8 state, bool keep_ulp_clk, + bool keep_ap_pll) +{ + return 0; +} + +static inline void prcmu_enable_wakeups(u32 wakeups) {} + +static inline void prcmu_disable_wakeups(void) {} + +static inline void prcmu_config_abb_event_readout(u32 abb_events) {} + +static inline int prcmu_set_arm_opp(u8 opp) +{ + return 0; +} + +static inline int prcmu_get_arm_opp(void) +{ + return ARM_100_OPP; +} + +static bool prcmu_has_arm_maxopp(void) +{ + return false; +} + +static bool prcmu_is_u8400(void) +{ + return false; +} + +static inline int prcmu_set_ape_opp(u8 opp) +{ + return 0; +} + +static inline int prcmu_get_ape_opp(void) +{ + return APE_100_OPP; +} + +static inline int prcmu_request_ape_opp_100_voltage(bool enable) +{ + return 0; +} + +static inline int prcmu_release_usb_wakeup_state(void) +{ + return 0; +} + +static inline int prcmu_set_ddr_opp(u8 opp) +{ + return 0; +} + +static inline int prcmu_get_ddr_opp(void) +{ + return DDR_100_OPP; +} + +static inline unsigned long prcmu_qos_get_cpufreq_opp_delay(void) +{ + return 0; +} + +static inline void prcmu_qos_set_cpufreq_opp_delay(unsigned long n) {} + +static inline int prcmu_set_hwacc(u16 hw_acc_dev, u8 state) +{ + return 0; +} + +static inline void prcmu_configure_auto_pm(struct prcmu_auto_pm_config *sleep, + struct prcmu_auto_pm_config *idle) +{ +} + +static inline bool prcmu_is_auto_pm_enabled(void) +{ + return false; +} + +static inline int prcmu_config_clkout(u8 clkout, u8 source, u8 div) +{ + return 0; +} + +static inline int prcmu_request_clock(u8 clock, bool enable) +{ + return 0; +} + +static inline int prcmu_set_clock_divider(u8 clock, u8 divider) +{ + return 0; +} + +int prcmu_config_esram0_deep_sleep(u8 state) +{ + return 0; +} + +static inline int prcmu_config_hotdog(u8 threshold) +{ + return 0; +} + +static inline int prcmu_config_hotmon(u8 low, u8 high) +{ + return 0; +} + +static inline int prcmu_start_temp_sense(u16 cycles32k) +{ + return 0; +} + +static inline int prcmu_stop_temp_sense(void) +{ + return 0; +} + +static inline int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size) +{ + return -ENOSYS; +} + +static inline int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size) +{ + return -ENOSYS; +} + +static inline void prcmu_ac_wake_req(void) {} + +static inline void prcmu_ac_sleep_req(void) {} + +static inline void prcmu_system_reset(u16 reset_code) {} + +static inline void prcmu_modem_reset(void) {} + +static inline bool prcmu_is_ac_wake_requested(void) +{ + return false; +} + +#ifndef CONFIG_UX500_SOC_DB5500 +static inline int prcmu_set_display_clocks(void) +{ + return 0; +} + +static inline int prcmu_disable_dsipll(void) +{ + return 0; +} + +static inline int prcmu_enable_dsipll(void) +{ + return 0; +} +#endif + +static inline int prcmu_enable_spi2(void) +{ + return 0; +} + +static inline int prcmu_disable_spi2(void) +{ + return 0; +} + +#endif /* !CONFIG_MFD_DB8500_PRCMU */ + +#ifdef CONFIG_UX500_PRCMU_QOS_POWER +int prcmu_qos_requirement(int pm_qos_class); +int prcmu_qos_add_requirement(int pm_qos_class, char *name, s32 value); +int prcmu_qos_update_requirement(int pm_qos_class, char *name, s32 new_value); +void prcmu_qos_remove_requirement(int pm_qos_class, char *name); +int prcmu_qos_add_notifier(int prcmu_qos_class, + struct notifier_block *notifier); +int prcmu_qos_remove_notifier(int prcmu_qos_class, + struct notifier_block *notifier); +#else +static inline int prcmu_qos_requirement(int prcmu_qos_class) +{ + return 0; +} + +static inline int prcmu_qos_add_requirement(int prcmu_qos_class, + char *name, s32 value) +{ + return 0; +} + +static inline int prcmu_qos_update_requirement(int prcmu_qos_class, + char *name, s32 new_value) +{ + return 0; +} + +static inline void prcmu_qos_remove_requirement(int prcmu_qos_class, char *name) +{ +} + +static inline int prcmu_qos_add_notifier(int prcmu_qos_class, + struct notifier_block *notifier) +{ + return 0; +} +static inline int prcmu_qos_remove_notifier(int prcmu_qos_class, + struct notifier_block *notifier) +{ + return 0; +} + +#endif + +#endif /* __MFD_DB8500_PRCMU_H */ -- cgit From 8317797ca657081ed81312ea3501f3a3d59d52e9 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 3 May 2011 18:14:48 +0200 Subject: mfd: add DB5500 PRCMU driver This adds the DB5500 PRCMU driver. Right now this one is pretty restricted in functionality, exposing a simple interface to send I2C messages. Acked-by: Samuel Ortiz Signed-off-by: Linus Walleij --- arch/arm/mach-ux500/Kconfig | 1 + arch/arm/mach-ux500/cpu.c | 3 + drivers/mfd/Kconfig | 10 + drivers/mfd/Makefile | 1 + drivers/mfd/db5500-prcmu-regs.h | 115 ++++++++++ drivers/mfd/db5500-prcmu.c | 448 +++++++++++++++++++++++++++++++++++++++ include/linux/mfd/db5500-prcmu.h | 45 ++++ 7 files changed, 623 insertions(+) create mode 100644 drivers/mfd/db5500-prcmu-regs.h create mode 100644 drivers/mfd/db5500-prcmu.c create mode 100644 include/linux/mfd/db5500-prcmu.h (limited to 'include/linux') diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index 8071d2746f70..365c4c35faa7 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig @@ -12,6 +12,7 @@ menu "Ux500 SoC" config UX500_SOC_DB5500 bool "DB5500" + select MFD_DB5500_PRCMU config UX500_SOC_DB8500 bool "DB8500" diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c index 11360f734cec..1da23bb87c16 100644 --- a/arch/arm/mach-ux500/cpu.c +++ b/arch/arm/mach-ux500/cpu.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -49,6 +50,8 @@ void __init ux500_init_irq(void) * Init clocks here so that they are available for system timer * initialization. */ + if (cpu_is_u5500()) + db5500_prcmu_early_init(); if (cpu_is_u8500()) prcmu_early_init(); clk_init(); diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 7eaeb9750793..481770ab2716 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -585,6 +585,16 @@ config MFD_DB8500_PRCMU system controller running an XP70 microprocessor, which is accessed through a register map. +config MFD_DB5500_PRCMU + bool "ST-Ericsson DB5500 Power Reset Control Management Unit" + depends on UX500_SOC_DB5500 + select MFD_CORE + help + Select this option to enable support for the DB5500 Power Reset + and Control Management Unit. This is basically an autonomous + system controller running an XP70 microprocessor, which is accessed + through a register map. + config MFD_CS5535 tristate "Support for CS5535 and CS5536 southbridge core functions" select MFD_CORE diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 814c57a692a9..24aa44448daf 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -79,6 +79,7 @@ obj-$(CONFIG_AB8500_GPADC) += ab8500-gpadc.o obj-$(CONFIG_MFD_DB8500_PRCMU) += db8500-prcmu.o # ab8500-i2c need to come after db8500-prcmu (which provides the channel) obj-$(CONFIG_AB8500_I2C_CORE) += ab8500-i2c.o +obj-$(CONFIG_MFD_DB5500_PRCMU) += db5500-prcmu.o obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o obj-$(CONFIG_PMIC_ADP5520) += adp5520.o obj-$(CONFIG_LPC_SCH) += lpc_sch.o diff --git a/drivers/mfd/db5500-prcmu-regs.h b/drivers/mfd/db5500-prcmu-regs.h new file mode 100644 index 000000000000..9a8e9e4ddd33 --- /dev/null +++ b/drivers/mfd/db5500-prcmu-regs.h @@ -0,0 +1,115 @@ +/* + * Copyright (C) STMicroelectronics 2009 + * Copyright (C) ST-Ericsson SA 2010 + * + * Author: Kumar Sanghvi + * Author: Sundar Iyer + * + * License Terms: GNU General Public License v2 + * + * PRCM Unit registers + */ + +#ifndef __MACH_PRCMU_REGS_H +#define __MACH_PRCMU_REGS_H + +#include + +#define PRCM_ARM_PLLDIVPS (_PRCMU_BASE + 0x118) +#define PRCM_ARM_PLLDIVPS_ARM_BRM_RATE 0x3f +#define PRCM_ARM_PLLDIVPS_MAX_MASK 0xf + +#define PRCM_PLLARM_LOCKP (_PRCMU_BASE + 0x0a8) +#define PRCM_PLLARM_LOCKP_PRCM_PLLARM_LOCKP3 0x2 + +#define PRCM_ARM_CHGCLKREQ (_PRCMU_BASE + 0x114) +#define PRCM_ARM_CHGCLKREQ_PRCM_ARM_CHGCLKREQ 0x1 + +#define PRCM_PLLARM_ENABLE (_PRCMU_BASE + 0x98) +#define PRCM_PLLARM_ENABLE_PRCM_PLLARM_ENABLE 0x1 +#define PRCM_PLLARM_ENABLE_PRCM_PLLARM_COUNTON 0x100 + +#define PRCM_ARMCLKFIX_MGT (_PRCMU_BASE + 0x0) +#define PRCM_A9_RESETN_CLR (_PRCMU_BASE + 0x1f4) +#define PRCM_A9_RESETN_SET (_PRCMU_BASE + 0x1f0) +#define PRCM_ARM_LS_CLAMP (_PRCMU_BASE + 0x30c) +#define PRCM_SRAM_A9 (_PRCMU_BASE + 0x308) + +/* ARM WFI Standby signal register */ +#define PRCM_ARM_WFI_STANDBY (_PRCMU_BASE + 0x130) +#define PRCM_IOCR (_PRCMU_BASE + 0x310) +#define PRCM_IOCR_IOFORCE 0x1 + +/* CPU mailbox registers */ +#define PRCM_MBOX_CPU_VAL (_PRCMU_BASE + 0x0fc) +#define PRCM_MBOX_CPU_SET (_PRCMU_BASE + 0x100) +#define PRCM_MBOX_CPU_CLR (_PRCMU_BASE + 0x104) + +/* Dual A9 core interrupt management unit registers */ +#define PRCM_A9_MASK_REQ (_PRCMU_BASE + 0x328) +#define PRCM_A9_MASK_REQ_PRCM_A9_MASK_REQ 0x1 + +#define PRCM_A9_MASK_ACK (_PRCMU_BASE + 0x32c) +#define PRCM_ARMITMSK31TO0 (_PRCMU_BASE + 0x11c) +#define PRCM_ARMITMSK63TO32 (_PRCMU_BASE + 0x120) +#define PRCM_ARMITMSK95TO64 (_PRCMU_BASE + 0x124) +#define PRCM_ARMITMSK127TO96 (_PRCMU_BASE + 0x128) +#define PRCM_POWER_STATE_VAL (_PRCMU_BASE + 0x25C) +#define PRCM_ARMITVAL31TO0 (_PRCMU_BASE + 0x260) +#define PRCM_ARMITVAL63TO32 (_PRCMU_BASE + 0x264) +#define PRCM_ARMITVAL95TO64 (_PRCMU_BASE + 0x268) +#define PRCM_ARMITVAL127TO96 (_PRCMU_BASE + 0x26C) + +#define PRCM_HOSTACCESS_REQ (_PRCMU_BASE + 0x334) +#define ARM_WAKEUP_MODEM 0x1 + +#define PRCM_ARM_IT1_CLEAR (_PRCMU_BASE + 0x48C) +#define PRCM_ARM_IT1_VAL (_PRCMU_BASE + 0x494) +#define PRCM_HOLD_EVT (_PRCMU_BASE + 0x174) + +#define PRCM_ITSTATUS0 (_PRCMU_BASE + 0x148) +#define PRCM_ITSTATUS1 (_PRCMU_BASE + 0x150) +#define PRCM_ITSTATUS2 (_PRCMU_BASE + 0x158) +#define PRCM_ITSTATUS3 (_PRCMU_BASE + 0x160) +#define PRCM_ITSTATUS4 (_PRCMU_BASE + 0x168) +#define PRCM_ITSTATUS5 (_PRCMU_BASE + 0x484) +#define PRCM_ITCLEAR5 (_PRCMU_BASE + 0x488) +#define PRCM_ARMIT_MASKXP70_IT (_PRCMU_BASE + 0x1018) + +/* System reset register */ +#define PRCM_APE_SOFTRST (_PRCMU_BASE + 0x228) + +/* Level shifter and clamp control registers */ +#define PRCM_MMIP_LS_CLAMP_SET (_PRCMU_BASE + 0x420) +#define PRCM_MMIP_LS_CLAMP_CLR (_PRCMU_BASE + 0x424) + +/* PRCMU clock/PLL/reset registers */ +#define PRCM_PLLDSI_FREQ (_PRCMU_BASE + 0x500) +#define PRCM_PLLDSI_ENABLE (_PRCMU_BASE + 0x504) +#define PRCM_PLLDSI_LOCKP (_PRCMU_BASE + 0x508) +#define PRCM_LCDCLK_MGT (_PRCMU_BASE + 0x044) +#define PRCM_MCDECLK_MGT (_PRCMU_BASE + 0x064) +#define PRCM_HDMICLK_MGT (_PRCMU_BASE + 0x058) +#define PRCM_TVCLK_MGT (_PRCMU_BASE + 0x07c) +#define PRCM_DSI_PLLOUT_SEL (_PRCMU_BASE + 0x530) +#define PRCM_DSITVCLK_DIV (_PRCMU_BASE + 0x52C) +#define PRCM_PLLDSI_LOCKP (_PRCMU_BASE + 0x508) +#define PRCM_APE_RESETN_SET (_PRCMU_BASE + 0x1E4) +#define PRCM_APE_RESETN_CLR (_PRCMU_BASE + 0x1E8) +#define PRCM_CLKOCR (_PRCMU_BASE + 0x1CC) + +/* ePOD and memory power signal control registers */ +#define PRCM_EPOD_C_SET (_PRCMU_BASE + 0x410) +#define PRCM_SRAM_LS_SLEEP (_PRCMU_BASE + 0x304) + +/* Debug power control unit registers */ +#define PRCM_POWER_STATE_SET (_PRCMU_BASE + 0x254) + +/* Miscellaneous unit registers */ +#define PRCM_DSI_SW_RESET (_PRCMU_BASE + 0x324) +#define PRCM_GPIOCR (_PRCMU_BASE + 0x138) +#define PRCM_GPIOCR_DBG_STM_MOD_CMD1 0x800 +#define PRCM_GPIOCR_DBG_UARTMOD_CMD0 0x1 + + +#endif /* __MACH_PRCMU__REGS_H */ diff --git a/drivers/mfd/db5500-prcmu.c b/drivers/mfd/db5500-prcmu.c new file mode 100644 index 000000000000..9dbb3cab4a6f --- /dev/null +++ b/drivers/mfd/db5500-prcmu.c @@ -0,0 +1,448 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * License Terms: GNU General Public License v2 + * Author: Mattias Nilsson + * + * U5500 PRCM Unit interface driver + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "db5500-prcmu-regs.h" + +#define _PRCM_MB_HEADER (tcdm_base + 0xFE8) +#define PRCM_REQ_MB0_HEADER (_PRCM_MB_HEADER + 0x0) +#define PRCM_REQ_MB1_HEADER (_PRCM_MB_HEADER + 0x1) +#define PRCM_REQ_MB2_HEADER (_PRCM_MB_HEADER + 0x2) +#define PRCM_REQ_MB3_HEADER (_PRCM_MB_HEADER + 0x3) +#define PRCM_REQ_MB4_HEADER (_PRCM_MB_HEADER + 0x4) +#define PRCM_REQ_MB5_HEADER (_PRCM_MB_HEADER + 0x5) +#define PRCM_REQ_MB6_HEADER (_PRCM_MB_HEADER + 0x6) +#define PRCM_REQ_MB7_HEADER (_PRCM_MB_HEADER + 0x7) +#define PRCM_ACK_MB0_HEADER (_PRCM_MB_HEADER + 0x8) +#define PRCM_ACK_MB1_HEADER (_PRCM_MB_HEADER + 0x9) +#define PRCM_ACK_MB2_HEADER (_PRCM_MB_HEADER + 0xa) +#define PRCM_ACK_MB3_HEADER (_PRCM_MB_HEADER + 0xb) +#define PRCM_ACK_MB4_HEADER (_PRCM_MB_HEADER + 0xc) +#define PRCM_ACK_MB5_HEADER (_PRCM_MB_HEADER + 0xd) +#define PRCM_ACK_MB6_HEADER (_PRCM_MB_HEADER + 0xe) +#define PRCM_ACK_MB7_HEADER (_PRCM_MB_HEADER + 0xf) + +/* Req Mailboxes */ +#define PRCM_REQ_MB0 (tcdm_base + 0xFD8) +#define PRCM_REQ_MB1 (tcdm_base + 0xFCC) +#define PRCM_REQ_MB2 (tcdm_base + 0xFC4) +#define PRCM_REQ_MB3 (tcdm_base + 0xFC0) +#define PRCM_REQ_MB4 (tcdm_base + 0xF98) +#define PRCM_REQ_MB5 (tcdm_base + 0xF90) +#define PRCM_REQ_MB6 (tcdm_base + 0xF8C) +#define PRCM_REQ_MB7 (tcdm_base + 0xF84) + +/* Ack Mailboxes */ +#define PRCM_ACK_MB0 (tcdm_base + 0xF38) +#define PRCM_ACK_MB1 (tcdm_base + 0xF30) +#define PRCM_ACK_MB2 (tcdm_base + 0xF24) +#define PRCM_ACK_MB3 (tcdm_base + 0xF20) +#define PRCM_ACK_MB4 (tcdm_base + 0xF1C) +#define PRCM_ACK_MB5 (tcdm_base + 0xF14) +#define PRCM_ACK_MB6 (tcdm_base + 0xF0C) +#define PRCM_ACK_MB7 (tcdm_base + 0xF08) + +enum mb_return_code { + RC_SUCCESS, + RC_FAIL, +}; + +/* Mailbox 0 headers. */ +enum mb0_header { + /* request */ + RMB0H_PWR_STATE_TRANS = 1, + RMB0H_WAKE_UP_CFG, + RMB0H_RD_WAKE_UP_ACK, + /* acknowledge */ + AMB0H_WAKE_UP = 1, +}; + +/* Mailbox 5 headers. */ +enum mb5_header { + MB5H_I2C_WRITE = 1, + MB5H_I2C_READ, +}; + +/* Request mailbox 5 fields. */ +#define PRCM_REQ_MB5_I2C_SLAVE (PRCM_REQ_MB5 + 0) +#define PRCM_REQ_MB5_I2C_REG (PRCM_REQ_MB5 + 1) +#define PRCM_REQ_MB5_I2C_SIZE (PRCM_REQ_MB5 + 2) +#define PRCM_REQ_MB5_I2C_DATA (PRCM_REQ_MB5 + 4) + +/* Acknowledge mailbox 5 fields. */ +#define PRCM_ACK_MB5_RETURN_CODE (PRCM_ACK_MB5 + 0) +#define PRCM_ACK_MB5_I2C_DATA (PRCM_ACK_MB5 + 4) + +#define NUM_MB 8 +#define MBOX_BIT BIT +#define ALL_MBOX_BITS (MBOX_BIT(NUM_MB) - 1) + +/* +* Used by MCDE to setup all necessary PRCMU registers +*/ +#define PRCMU_RESET_DSIPLL 0x00004000 +#define PRCMU_UNCLAMP_DSIPLL 0x00400800 + +/* HDMI CLK MGT PLLSW=001 (PLLSOC0), PLLDIV=0x8, = 50 Mhz*/ +#define PRCMU_DSI_CLOCK_SETTING 0x00000128 +/* TVCLK_MGT PLLSW=001 (PLLSOC0) PLLDIV=0x13, = 19.05 MHZ */ +#define PRCMU_DSI_LP_CLOCK_SETTING 0x00000135 +#define PRCMU_PLLDSI_FREQ_SETTING 0x0004013C +#define PRCMU_DSI_PLLOUT_SEL_SETTING 0x00000002 +#define PRCMU_ENABLE_ESCAPE_CLOCK_DIV 0x03000101 +#define PRCMU_DISABLE_ESCAPE_CLOCK_DIV 0x00000101 + +#define PRCMU_ENABLE_PLLDSI 0x00000001 +#define PRCMU_DISABLE_PLLDSI 0x00000000 + +#define PRCMU_DSI_RESET_SW 0x00000003 + +#define PRCMU_PLLDSI_LOCKP_LOCKED 0x3 + +/* + * mb0_transfer - state needed for mailbox 0 communication. + * @lock: The transaction lock. + */ +static struct { + spinlock_t lock; +} mb0_transfer; + +/* + * mb5_transfer - state needed for mailbox 5 communication. + * @lock: The transaction lock. + * @work: The transaction completion structure. + * @ack: Reply ("acknowledge") data. + */ +static struct { + struct mutex lock; + struct completion work; + struct { + u8 header; + u8 status; + u8 value[4]; + } ack; +} mb5_transfer; + +/* PRCMU TCDM base IO address. */ +static __iomem void *tcdm_base; + +/** + * db5500_prcmu_abb_read() - Read register value(s) from the ABB. + * @slave: The I2C slave address. + * @reg: The (start) register address. + * @value: The read out value(s). + * @size: The number of registers to read. + * + * Reads register value(s) from the ABB. + * @size has to be <= 4. + */ +int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size) +{ + int r; + + if ((size < 1) || (4 < size)) + return -EINVAL; + + mutex_lock(&mb5_transfer.lock); + + while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5)) + cpu_relax(); + writeb(slave, PRCM_REQ_MB5_I2C_SLAVE); + writeb(reg, PRCM_REQ_MB5_I2C_REG); + writeb(size, PRCM_REQ_MB5_I2C_SIZE); + writeb(MB5H_I2C_READ, PRCM_REQ_MB5_HEADER); + + writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET); + wait_for_completion(&mb5_transfer.work); + + r = 0; + if ((mb5_transfer.ack.header == MB5H_I2C_READ) && + (mb5_transfer.ack.status == RC_SUCCESS)) + memcpy(value, mb5_transfer.ack.value, (size_t)size); + else + r = -EIO; + + mutex_unlock(&mb5_transfer.lock); + + return r; +} + +/** + * db5500_prcmu_abb_write() - Write register value(s) to the ABB. + * @slave: The I2C slave address. + * @reg: The (start) register address. + * @value: The value(s) to write. + * @size: The number of registers to write. + * + * Writes register value(s) to the ABB. + * @size has to be <= 4. + */ +int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size) +{ + int r; + + if ((size < 1) || (4 < size)) + return -EINVAL; + + mutex_lock(&mb5_transfer.lock); + + while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5)) + cpu_relax(); + writeb(slave, PRCM_REQ_MB5_I2C_SLAVE); + writeb(reg, PRCM_REQ_MB5_I2C_REG); + writeb(size, PRCM_REQ_MB5_I2C_SIZE); + memcpy_toio(PRCM_REQ_MB5_I2C_DATA, value, size); + writeb(MB5H_I2C_WRITE, PRCM_REQ_MB5_HEADER); + + writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET); + wait_for_completion(&mb5_transfer.work); + + if ((mb5_transfer.ack.header == MB5H_I2C_WRITE) && + (mb5_transfer.ack.status == RC_SUCCESS)) + r = 0; + else + r = -EIO; + + mutex_unlock(&mb5_transfer.lock); + + return r; +} + +int db5500_prcmu_enable_dsipll(void) +{ + int i; + + /* Enable DSIPLL_RESETN resets */ + writel(PRCMU_RESET_DSIPLL, PRCM_APE_RESETN_CLR); + /* Unclamp DSIPLL in/out */ + writel(PRCMU_UNCLAMP_DSIPLL, PRCM_MMIP_LS_CLAMP_CLR); + /* Set DSI PLL FREQ */ + writel(PRCMU_PLLDSI_FREQ_SETTING, PRCM_PLLDSI_FREQ); + writel(PRCMU_DSI_PLLOUT_SEL_SETTING, + PRCM_DSI_PLLOUT_SEL); + /* Enable Escape clocks */ + writel(PRCMU_ENABLE_ESCAPE_CLOCK_DIV, PRCM_DSITVCLK_DIV); + + /* Start DSI PLL */ + writel(PRCMU_ENABLE_PLLDSI, PRCM_PLLDSI_ENABLE); + /* Reset DSI PLL */ + writel(PRCMU_DSI_RESET_SW, PRCM_DSI_SW_RESET); + for (i = 0; i < 10; i++) { + if ((readl(PRCM_PLLDSI_LOCKP) & + PRCMU_PLLDSI_LOCKP_LOCKED) == PRCMU_PLLDSI_LOCKP_LOCKED) + break; + udelay(100); + } + /* Release DSIPLL_RESETN */ + writel(PRCMU_RESET_DSIPLL, PRCM_APE_RESETN_SET); + return 0; +} + +int db5500_prcmu_disable_dsipll(void) +{ + /* Disable dsi pll */ + writel(PRCMU_DISABLE_PLLDSI, PRCM_PLLDSI_ENABLE); + /* Disable escapeclock */ + writel(PRCMU_DISABLE_ESCAPE_CLOCK_DIV, PRCM_DSITVCLK_DIV); + return 0; +} + +int db5500_prcmu_set_display_clocks(void) +{ + /* HDMI and TVCLK Should be handled somewhere else */ + /* PLLDIV=8, PLLSW=2, CLKEN=1 */ + writel(PRCMU_DSI_CLOCK_SETTING, PRCM_HDMICLK_MGT); + /* PLLDIV=14, PLLSW=2, CLKEN=1 */ + writel(PRCMU_DSI_LP_CLOCK_SETTING, PRCM_TVCLK_MGT); + return 0; +} + +static void ack_dbb_wakeup(void) +{ + unsigned long flags; + + spin_lock_irqsave(&mb0_transfer.lock, flags); + + while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(0)) + cpu_relax(); + + writeb(RMB0H_RD_WAKE_UP_ACK, PRCM_REQ_MB0_HEADER); + writel(MBOX_BIT(0), PRCM_MBOX_CPU_SET); + + spin_unlock_irqrestore(&mb0_transfer.lock, flags); +} + +static inline void print_unknown_header_warning(u8 n, u8 header) +{ + pr_warning("prcmu: Unknown message header (%d) in mailbox %d.\n", + header, n); +} + +static bool read_mailbox_0(void) +{ + bool r; + u8 header; + + header = readb(PRCM_ACK_MB0_HEADER); + switch (header) { + case AMB0H_WAKE_UP: + r = true; + break; + default: + print_unknown_header_warning(0, header); + r = false; + break; + } + writel(MBOX_BIT(0), PRCM_ARM_IT1_CLEAR); + return r; +} + +static bool read_mailbox_1(void) +{ + writel(MBOX_BIT(1), PRCM_ARM_IT1_CLEAR); + return false; +} + +static bool read_mailbox_2(void) +{ + writel(MBOX_BIT(2), PRCM_ARM_IT1_CLEAR); + return false; +} + +static bool read_mailbox_3(void) +{ + writel(MBOX_BIT(3), PRCM_ARM_IT1_CLEAR); + return false; +} + +static bool read_mailbox_4(void) +{ + writel(MBOX_BIT(4), PRCM_ARM_IT1_CLEAR); + return false; +} + +static bool read_mailbox_5(void) +{ + u8 header; + + header = readb(PRCM_ACK_MB5_HEADER); + switch (header) { + case MB5H_I2C_READ: + memcpy_fromio(mb5_transfer.ack.value, PRCM_ACK_MB5_I2C_DATA, 4); + case MB5H_I2C_WRITE: + mb5_transfer.ack.header = header; + mb5_transfer.ack.status = readb(PRCM_ACK_MB5_RETURN_CODE); + complete(&mb5_transfer.work); + break; + default: + print_unknown_header_warning(5, header); + break; + } + writel(MBOX_BIT(5), PRCM_ARM_IT1_CLEAR); + return false; +} + +static bool read_mailbox_6(void) +{ + writel(MBOX_BIT(6), PRCM_ARM_IT1_CLEAR); + return false; +} + +static bool read_mailbox_7(void) +{ + writel(MBOX_BIT(7), PRCM_ARM_IT1_CLEAR); + return false; +} + +static bool (* const read_mailbox[NUM_MB])(void) = { + read_mailbox_0, + read_mailbox_1, + read_mailbox_2, + read_mailbox_3, + read_mailbox_4, + read_mailbox_5, + read_mailbox_6, + read_mailbox_7 +}; + +static irqreturn_t prcmu_irq_handler(int irq, void *data) +{ + u32 bits; + u8 n; + irqreturn_t r; + + bits = (readl(PRCM_ARM_IT1_VAL) & ALL_MBOX_BITS); + if (unlikely(!bits)) + return IRQ_NONE; + + r = IRQ_HANDLED; + for (n = 0; bits; n++) { + if (bits & MBOX_BIT(n)) { + bits -= MBOX_BIT(n); + if (read_mailbox[n]()) + r = IRQ_WAKE_THREAD; + } + } + return r; +} + +static irqreturn_t prcmu_irq_thread_fn(int irq, void *data) +{ + ack_dbb_wakeup(); + return IRQ_HANDLED; +} + +void __init db5500_prcmu_early_init(void) +{ + tcdm_base = __io_address(U5500_PRCMU_TCDM_BASE); + spin_lock_init(&mb0_transfer.lock); + mutex_init(&mb5_transfer.lock); + init_completion(&mb5_transfer.work); +} + +/** + * prcmu_fw_init - arch init call for the Linux PRCMU fw init logic + * + */ +int __init db5500_prcmu_init(void) +{ + int r = 0; + + if (ux500_is_svp() || !cpu_is_u5500()) + return -ENODEV; + + /* Clean up the mailbox interrupts after pre-kernel code. */ + writel(ALL_MBOX_BITS, PRCM_ARM_IT1_CLEAR); + + r = request_threaded_irq(IRQ_DB5500_PRCMU1, prcmu_irq_handler, + prcmu_irq_thread_fn, 0, "prcmu", NULL); + if (r < 0) { + pr_err("prcmu: Failed to allocate IRQ_DB5500_PRCMU1.\n"); + return -EBUSY; + } + return 0; +} + +arch_initcall(db5500_prcmu_init); diff --git a/include/linux/mfd/db5500-prcmu.h b/include/linux/mfd/db5500-prcmu.h new file mode 100644 index 000000000000..f0977986402c --- /dev/null +++ b/include/linux/mfd/db5500-prcmu.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * License Terms: GNU General Public License v2 + * + * U5500 PRCMU API. + */ +#ifndef __MACH_PRCMU_U5500_H +#define __MACH_PRCMU_U5500_H + +#ifdef CONFIG_UX500_SOC_DB5500 + +void db5500_prcmu_early_init(void); + +int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size); +int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size); + +#else /* !CONFIG_UX500_SOC_DB5500 */ + +static inline void db5500_prcmu_early_init(void) +{ +} + +static inline int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size) +{ + return -ENOSYS; +} + +static inline int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size) +{ + return -ENOSYS; +} + +#endif /* CONFIG_UX500_SOC_DB5500 */ + +static inline int db5500_prcmu_config_abb_event_readout(u32 abb_events) +{ +#ifdef CONFIG_MACH_U5500_SIMULATOR + return 0; +#else + return -1; +#endif +} + +#endif /* __MACH_PRCMU_U5500_H */ -- cgit From 1032fbfd792f2b384ac16a63993b8fae5eea9083 Mon Sep 17 00:00:00 2001 From: Bengt Jonsson Date: Fri, 1 Apr 2011 14:43:33 +0200 Subject: mach-ux500: voltage domain regulators for DB8500 The DB8500 has ePOD:s (electronic power domains) which are possible to switch on/off to deactivate silicon blocks on the DB8500 SoC by cutting their power without retention. We model these as simple regulators with one bit on/off settings. Acked-by: Liam Girdwood Acked-by: Mark Brown Signed-off-by: Bengt Jonsson Signed-off-by: Sundar Iyer Signed-off-by: Jonas Aberg Signed-off-by: Virupax Sadashivpetimath Signed-off-by: Martin Persson Signed-off-by: Linus Walleij --- arch/arm/mach-ux500/Kconfig | 1 + drivers/mfd/db8500-prcmu.c | 179 +++++++++++ drivers/regulator/Kconfig | 7 + drivers/regulator/Makefile | 1 + drivers/regulator/db8500-prcmu.c | 558 +++++++++++++++++++++++++++++++++ include/linux/regulator/db8500-prcmu.h | 45 +++ 6 files changed, 791 insertions(+) create mode 100644 drivers/regulator/db8500-prcmu.c create mode 100644 include/linux/regulator/db8500-prcmu.h (limited to 'include/linux') diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index 365c4c35faa7..54429d015954 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig @@ -17,6 +17,7 @@ config UX500_SOC_DB5500 config UX500_SOC_DB8500 bool "DB8500" select MFD_DB8500_PRCMU + select REGULATOR_DB8500_PRCMU endmenu diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index c44725bd8b9a..e63782107e2f 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include #include #include @@ -1824,9 +1826,186 @@ void __init prcmu_early_init(void) } } +/* + * Power domain switches (ePODs) modeled as regulators for the DB8500 SoC + */ +static struct regulator_consumer_supply db8500_vape_consumers[] = { + REGULATOR_SUPPLY("v-ape", NULL), + REGULATOR_SUPPLY("v-i2c", "nmk-i2c.0"), + REGULATOR_SUPPLY("v-i2c", "nmk-i2c.1"), + REGULATOR_SUPPLY("v-i2c", "nmk-i2c.2"), + REGULATOR_SUPPLY("v-i2c", "nmk-i2c.3"), + /* "v-mmc" changed to "vcore" in the mainline kernel */ + REGULATOR_SUPPLY("vcore", "sdi0"), + REGULATOR_SUPPLY("vcore", "sdi1"), + REGULATOR_SUPPLY("vcore", "sdi2"), + REGULATOR_SUPPLY("vcore", "sdi3"), + REGULATOR_SUPPLY("vcore", "sdi4"), + REGULATOR_SUPPLY("v-dma", "dma40.0"), + REGULATOR_SUPPLY("v-ape", "ab8500-usb.0"), + /* "v-uart" changed to "vcore" in the mainline kernel */ + REGULATOR_SUPPLY("vcore", "uart0"), + REGULATOR_SUPPLY("vcore", "uart1"), + REGULATOR_SUPPLY("vcore", "uart2"), + REGULATOR_SUPPLY("v-ape", "nmk-ske-keypad.0"), +}; + +static struct regulator_consumer_supply db8500_vsmps2_consumers[] = { + /* CG2900 and CW1200 power to off-chip peripherals */ + REGULATOR_SUPPLY("gbf_1v8", "cg2900-uart.0"), + REGULATOR_SUPPLY("wlan_1v8", "cw1200.0"), + REGULATOR_SUPPLY("musb_1v8", "ab8500-usb.0"), + /* AV8100 regulator */ + REGULATOR_SUPPLY("hdmi_1v8", "0-0070"), +}; + +static struct regulator_consumer_supply db8500_b2r2_mcde_consumers[] = { + REGULATOR_SUPPLY("vsupply", "b2r2.0"), + REGULATOR_SUPPLY("vsupply", "mcde.0"), +}; + +static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = { + [DB8500_REGULATOR_VAPE] = { + .constraints = { + .name = "db8500-vape", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .consumer_supplies = db8500_vape_consumers, + .num_consumer_supplies = ARRAY_SIZE(db8500_vape_consumers), + }, + [DB8500_REGULATOR_VARM] = { + .constraints = { + .name = "db8500-varm", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + }, + [DB8500_REGULATOR_VMODEM] = { + .constraints = { + .name = "db8500-vmodem", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + }, + [DB8500_REGULATOR_VPLL] = { + .constraints = { + .name = "db8500-vpll", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + }, + [DB8500_REGULATOR_VSMPS1] = { + .constraints = { + .name = "db8500-vsmps1", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + }, + [DB8500_REGULATOR_VSMPS2] = { + .constraints = { + .name = "db8500-vsmps2", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .consumer_supplies = db8500_vsmps2_consumers, + .num_consumer_supplies = ARRAY_SIZE(db8500_vsmps2_consumers), + }, + [DB8500_REGULATOR_VSMPS3] = { + .constraints = { + .name = "db8500-vsmps3", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + }, + [DB8500_REGULATOR_VRF1] = { + .constraints = { + .name = "db8500-vrf1", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + }, + [DB8500_REGULATOR_SWITCH_SVAMMDSP] = { + .supply_regulator = "db8500-vape", + .constraints = { + .name = "db8500-sva-mmdsp", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + }, + [DB8500_REGULATOR_SWITCH_SVAMMDSPRET] = { + .constraints = { + /* "ret" means "retention" */ + .name = "db8500-sva-mmdsp-ret", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + }, + [DB8500_REGULATOR_SWITCH_SVAPIPE] = { + .supply_regulator = "db8500-vape", + .constraints = { + .name = "db8500-sva-pipe", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + }, + [DB8500_REGULATOR_SWITCH_SIAMMDSP] = { + .supply_regulator = "db8500-vape", + .constraints = { + .name = "db8500-sia-mmdsp", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + }, + [DB8500_REGULATOR_SWITCH_SIAMMDSPRET] = { + .constraints = { + .name = "db8500-sia-mmdsp-ret", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + }, + [DB8500_REGULATOR_SWITCH_SIAPIPE] = { + .supply_regulator = "db8500-vape", + .constraints = { + .name = "db8500-sia-pipe", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + }, + [DB8500_REGULATOR_SWITCH_SGA] = { + .supply_regulator = "db8500-vape", + .constraints = { + .name = "db8500-sga", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + }, + [DB8500_REGULATOR_SWITCH_B2R2_MCDE] = { + .supply_regulator = "db8500-vape", + .constraints = { + .name = "db8500-b2r2-mcde", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .consumer_supplies = db8500_b2r2_mcde_consumers, + .num_consumer_supplies = ARRAY_SIZE(db8500_b2r2_mcde_consumers), + }, + [DB8500_REGULATOR_SWITCH_ESRAM12] = { + .supply_regulator = "db8500-vape", + .constraints = { + .name = "db8500-esram12", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + }, + [DB8500_REGULATOR_SWITCH_ESRAM12RET] = { + .constraints = { + .name = "db8500-esram12-ret", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + }, + [DB8500_REGULATOR_SWITCH_ESRAM34] = { + .supply_regulator = "db8500-vape", + .constraints = { + .name = "db8500-esram34", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + }, + [DB8500_REGULATOR_SWITCH_ESRAM34RET] = { + .constraints = { + .name = "db8500-esram34-ret", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + }, +}; + static struct mfd_cell db8500_prcmu_devs[] = { { .name = "db8500-prcmu-regulators", + .mfd_data = &db8500_regulators, }, { .name = "cpufreq-u8500", diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index b9f29e0d4295..f0b13a0d1851 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -274,6 +274,13 @@ config REGULATOR_AB8500 This driver supports the regulators found on the ST-Ericsson mixed signal AB8500 PMIC +config REGULATOR_DB8500_PRCMU + bool "ST-Ericsson DB8500 Voltage Domain Regulators" + depends on MFD_DB8500_PRCMU + help + This driver supports the voltage domain regulators controlled by the + DB8500 PRCMU + config REGULATOR_TPS6586X tristate "TI TPS6586X Power regulators" depends on MFD_TPS6586X diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index d72a42756778..165ff5371e9e 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -41,5 +41,6 @@ obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o +obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG diff --git a/drivers/regulator/db8500-prcmu.c b/drivers/regulator/db8500-prcmu.c new file mode 100644 index 000000000000..1089a961616e --- /dev/null +++ b/drivers/regulator/db8500-prcmu.c @@ -0,0 +1,558 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * License Terms: GNU General Public License v2 + * Authors: Sundar Iyer for ST-Ericsson + * Bengt Jonsson for ST-Ericsson + * + * Power domain regulators on DB8500 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * power state reference count + */ +static int power_state_active_cnt; /* will initialize to zero */ +static DEFINE_SPINLOCK(power_state_active_lock); + +static void power_state_active_enable(void) +{ + unsigned long flags; + + spin_lock_irqsave(&power_state_active_lock, flags); + power_state_active_cnt++; + spin_unlock_irqrestore(&power_state_active_lock, flags); +} + +static int power_state_active_disable(void) +{ + int ret = 0; + unsigned long flags; + + spin_lock_irqsave(&power_state_active_lock, flags); + if (power_state_active_cnt <= 0) { + pr_err("power state: unbalanced enable/disable calls\n"); + ret = -EINVAL; + goto out; + } + + power_state_active_cnt--; +out: + spin_unlock_irqrestore(&power_state_active_lock, flags); + return ret; +} + +/* + * Exported interface for CPUIdle only. This function is called when interrupts + * are turned off. Hence, no locking. + */ +int power_state_active_is_enabled(void) +{ + return (power_state_active_cnt > 0); +} + +/** + * struct db8500_regulator_info - db8500 regulator information + * @dev: device pointer + * @desc: regulator description + * @rdev: regulator device pointer + * @is_enabled: status of the regulator + * @epod_id: id for EPOD (power domain) + * @is_ramret: RAM retention switch for EPOD (power domain) + * @operating_point: operating point (only for vape, to be removed) + * + */ +struct db8500_regulator_info { + struct device *dev; + struct regulator_desc desc; + struct regulator_dev *rdev; + bool is_enabled; + u16 epod_id; + bool is_ramret; + bool exclude_from_power_state; + unsigned int operating_point; +}; + +static int db8500_regulator_enable(struct regulator_dev *rdev) +{ + struct db8500_regulator_info *info = rdev_get_drvdata(rdev); + + if (info == NULL) + return -EINVAL; + + dev_vdbg(rdev_get_dev(rdev), "regulator-%s-enable\n", + info->desc.name); + + info->is_enabled = true; + if (!info->exclude_from_power_state) + power_state_active_enable(); + + return 0; +} + +static int db8500_regulator_disable(struct regulator_dev *rdev) +{ + struct db8500_regulator_info *info = rdev_get_drvdata(rdev); + int ret = 0; + + if (info == NULL) + return -EINVAL; + + dev_vdbg(rdev_get_dev(rdev), "regulator-%s-disable\n", + info->desc.name); + + info->is_enabled = false; + if (!info->exclude_from_power_state) + ret = power_state_active_disable(); + + return ret; +} + +static int db8500_regulator_is_enabled(struct regulator_dev *rdev) +{ + struct db8500_regulator_info *info = rdev_get_drvdata(rdev); + + if (info == NULL) + return -EINVAL; + + dev_vdbg(rdev_get_dev(rdev), "regulator-%s-is_enabled (is_enabled):" + " %i\n", info->desc.name, info->is_enabled); + + return info->is_enabled; +} + +/* db8500 regulator operations */ +static struct regulator_ops db8500_regulator_ops = { + .enable = db8500_regulator_enable, + .disable = db8500_regulator_disable, + .is_enabled = db8500_regulator_is_enabled, +}; + +/* + * EPOD control + */ +static bool epod_on[NUM_EPOD_ID]; +static bool epod_ramret[NUM_EPOD_ID]; + +static int enable_epod(u16 epod_id, bool ramret) +{ + int ret; + + if (ramret) { + if (!epod_on[epod_id]) { + ret = prcmu_set_epod(epod_id, EPOD_STATE_RAMRET); + if (ret < 0) + return ret; + } + epod_ramret[epod_id] = true; + } else { + ret = prcmu_set_epod(epod_id, EPOD_STATE_ON); + if (ret < 0) + return ret; + epod_on[epod_id] = true; + } + + return 0; +} + +static int disable_epod(u16 epod_id, bool ramret) +{ + int ret; + + if (ramret) { + if (!epod_on[epod_id]) { + ret = prcmu_set_epod(epod_id, EPOD_STATE_OFF); + if (ret < 0) + return ret; + } + epod_ramret[epod_id] = false; + } else { + if (epod_ramret[epod_id]) { + ret = prcmu_set_epod(epod_id, EPOD_STATE_RAMRET); + if (ret < 0) + return ret; + } else { + ret = prcmu_set_epod(epod_id, EPOD_STATE_OFF); + if (ret < 0) + return ret; + } + epod_on[epod_id] = false; + } + + return 0; +} + +/* + * Regulator switch + */ +static int db8500_regulator_switch_enable(struct regulator_dev *rdev) +{ + struct db8500_regulator_info *info = rdev_get_drvdata(rdev); + int ret; + + if (info == NULL) + return -EINVAL; + + dev_vdbg(rdev_get_dev(rdev), "regulator-switch-%s-enable\n", + info->desc.name); + + ret = enable_epod(info->epod_id, info->is_ramret); + if (ret < 0) { + dev_err(rdev_get_dev(rdev), + "regulator-switch-%s-enable: prcmu call failed\n", + info->desc.name); + goto out; + } + + info->is_enabled = true; +out: + return ret; +} + +static int db8500_regulator_switch_disable(struct regulator_dev *rdev) +{ + struct db8500_regulator_info *info = rdev_get_drvdata(rdev); + int ret; + + if (info == NULL) + return -EINVAL; + + dev_vdbg(rdev_get_dev(rdev), "regulator-switch-%s-disable\n", + info->desc.name); + + ret = disable_epod(info->epod_id, info->is_ramret); + if (ret < 0) { + dev_err(rdev_get_dev(rdev), + "regulator_switch-%s-disable: prcmu call failed\n", + info->desc.name); + goto out; + } + + info->is_enabled = 0; +out: + return ret; +} + +static int db8500_regulator_switch_is_enabled(struct regulator_dev *rdev) +{ + struct db8500_regulator_info *info = rdev_get_drvdata(rdev); + + if (info == NULL) + return -EINVAL; + + dev_vdbg(rdev_get_dev(rdev), + "regulator-switch-%s-is_enabled (is_enabled): %i\n", + info->desc.name, info->is_enabled); + + return info->is_enabled; +} + +static struct regulator_ops db8500_regulator_switch_ops = { + .enable = db8500_regulator_switch_enable, + .disable = db8500_regulator_switch_disable, + .is_enabled = db8500_regulator_switch_is_enabled, +}; + +/* + * Regulator information + */ +static struct db8500_regulator_info + db8500_regulator_info[DB8500_NUM_REGULATORS] = { + [DB8500_REGULATOR_VAPE] = { + .desc = { + .name = "db8500-vape", + .id = DB8500_REGULATOR_VAPE, + .ops = &db8500_regulator_ops, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + }, + }, + [DB8500_REGULATOR_VARM] = { + .desc = { + .name = "db8500-varm", + .id = DB8500_REGULATOR_VARM, + .ops = &db8500_regulator_ops, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + }, + }, + [DB8500_REGULATOR_VMODEM] = { + .desc = { + .name = "db8500-vmodem", + .id = DB8500_REGULATOR_VMODEM, + .ops = &db8500_regulator_ops, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + }, + }, + [DB8500_REGULATOR_VPLL] = { + .desc = { + .name = "db8500-vpll", + .id = DB8500_REGULATOR_VPLL, + .ops = &db8500_regulator_ops, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + }, + }, + [DB8500_REGULATOR_VSMPS1] = { + .desc = { + .name = "db8500-vsmps1", + .id = DB8500_REGULATOR_VSMPS1, + .ops = &db8500_regulator_ops, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + }, + }, + [DB8500_REGULATOR_VSMPS2] = { + .desc = { + .name = "db8500-vsmps2", + .id = DB8500_REGULATOR_VSMPS2, + .ops = &db8500_regulator_ops, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + }, + .exclude_from_power_state = true, + }, + [DB8500_REGULATOR_VSMPS3] = { + .desc = { + .name = "db8500-vsmps3", + .id = DB8500_REGULATOR_VSMPS3, + .ops = &db8500_regulator_ops, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + }, + }, + [DB8500_REGULATOR_VRF1] = { + .desc = { + .name = "db8500-vrf1", + .id = DB8500_REGULATOR_VRF1, + .ops = &db8500_regulator_ops, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + }, + }, + [DB8500_REGULATOR_SWITCH_SVAMMDSP] = { + .desc = { + .name = "db8500-sva-mmdsp", + .id = DB8500_REGULATOR_SWITCH_SVAMMDSP, + .ops = &db8500_regulator_switch_ops, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + }, + .epod_id = EPOD_ID_SVAMMDSP, + }, + [DB8500_REGULATOR_SWITCH_SVAMMDSPRET] = { + .desc = { + .name = "db8500-sva-mmdsp-ret", + .id = DB8500_REGULATOR_SWITCH_SVAMMDSPRET, + .ops = &db8500_regulator_switch_ops, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + }, + .epod_id = EPOD_ID_SVAMMDSP, + .is_ramret = true, + }, + [DB8500_REGULATOR_SWITCH_SVAPIPE] = { + .desc = { + .name = "db8500-sva-pipe", + .id = DB8500_REGULATOR_SWITCH_SVAPIPE, + .ops = &db8500_regulator_switch_ops, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + }, + .epod_id = EPOD_ID_SVAPIPE, + }, + [DB8500_REGULATOR_SWITCH_SIAMMDSP] = { + .desc = { + .name = "db8500-sia-mmdsp", + .id = DB8500_REGULATOR_SWITCH_SIAMMDSP, + .ops = &db8500_regulator_switch_ops, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + }, + .epod_id = EPOD_ID_SIAMMDSP, + }, + [DB8500_REGULATOR_SWITCH_SIAMMDSPRET] = { + .desc = { + .name = "db8500-sia-mmdsp-ret", + .id = DB8500_REGULATOR_SWITCH_SIAMMDSPRET, + .ops = &db8500_regulator_switch_ops, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + }, + .epod_id = EPOD_ID_SIAMMDSP, + .is_ramret = true, + }, + [DB8500_REGULATOR_SWITCH_SIAPIPE] = { + .desc = { + .name = "db8500-sia-pipe", + .id = DB8500_REGULATOR_SWITCH_SIAPIPE, + .ops = &db8500_regulator_switch_ops, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + }, + .epod_id = EPOD_ID_SIAPIPE, + }, + [DB8500_REGULATOR_SWITCH_SGA] = { + .desc = { + .name = "db8500-sga", + .id = DB8500_REGULATOR_SWITCH_SGA, + .ops = &db8500_regulator_switch_ops, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + }, + .epod_id = EPOD_ID_SGA, + }, + [DB8500_REGULATOR_SWITCH_B2R2_MCDE] = { + .desc = { + .name = "db8500-b2r2-mcde", + .id = DB8500_REGULATOR_SWITCH_B2R2_MCDE, + .ops = &db8500_regulator_switch_ops, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + }, + .epod_id = EPOD_ID_B2R2_MCDE, + }, + [DB8500_REGULATOR_SWITCH_ESRAM12] = { + .desc = { + .name = "db8500-esram12", + .id = DB8500_REGULATOR_SWITCH_ESRAM12, + .ops = &db8500_regulator_switch_ops, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + }, + .epod_id = EPOD_ID_ESRAM12, + .is_enabled = true, + }, + [DB8500_REGULATOR_SWITCH_ESRAM12RET] = { + .desc = { + .name = "db8500-esram12-ret", + .id = DB8500_REGULATOR_SWITCH_ESRAM12RET, + .ops = &db8500_regulator_switch_ops, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + }, + .epod_id = EPOD_ID_ESRAM12, + .is_ramret = true, + }, + [DB8500_REGULATOR_SWITCH_ESRAM34] = { + .desc = { + .name = "db8500-esram34", + .id = DB8500_REGULATOR_SWITCH_ESRAM34, + .ops = &db8500_regulator_switch_ops, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + }, + .epod_id = EPOD_ID_ESRAM34, + .is_enabled = true, + }, + [DB8500_REGULATOR_SWITCH_ESRAM34RET] = { + .desc = { + .name = "db8500-esram34-ret", + .id = DB8500_REGULATOR_SWITCH_ESRAM34RET, + .ops = &db8500_regulator_switch_ops, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + }, + .epod_id = EPOD_ID_ESRAM34, + .is_ramret = true, + }, +}; + +static int __devinit db8500_regulator_probe(struct platform_device *pdev) +{ + struct regulator_init_data *db8500_init_data = mfd_get_data(pdev); + int i, err; + + /* register all regulators */ + for (i = 0; i < ARRAY_SIZE(db8500_regulator_info); i++) { + struct db8500_regulator_info *info; + struct regulator_init_data *init_data = &db8500_init_data[i]; + + /* assign per-regulator data */ + info = &db8500_regulator_info[i]; + info->dev = &pdev->dev; + + /* register with the regulator framework */ + info->rdev = regulator_register(&info->desc, &pdev->dev, + init_data, info); + if (IS_ERR(info->rdev)) { + err = PTR_ERR(info->rdev); + dev_err(&pdev->dev, "failed to register %s: err %i\n", + info->desc.name, err); + + /* if failing, unregister all earlier regulators */ + i--; + while (i >= 0) { + info = &db8500_regulator_info[i]; + regulator_unregister(info->rdev); + i--; + } + return err; + } + + dev_dbg(rdev_get_dev(info->rdev), + "regulator-%s-probed\n", info->desc.name); + } + + return 0; +} + +static int __exit db8500_regulator_remove(struct platform_device *pdev) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(db8500_regulator_info); i++) { + struct db8500_regulator_info *info; + info = &db8500_regulator_info[i]; + + dev_vdbg(rdev_get_dev(info->rdev), + "regulator-%s-remove\n", info->desc.name); + + regulator_unregister(info->rdev); + } + + return 0; +} + +static struct platform_driver db8500_regulator_driver = { + .driver = { + .name = "db8500-prcmu-regulators", + .owner = THIS_MODULE, + }, + .probe = db8500_regulator_probe, + .remove = __exit_p(db8500_regulator_remove), +}; + +static int __init db8500_regulator_init(void) +{ + int ret; + + ret = platform_driver_register(&db8500_regulator_driver); + if (ret < 0) + return -ENODEV; + + return 0; +} + +static void __exit db8500_regulator_exit(void) +{ + platform_driver_unregister(&db8500_regulator_driver); +} + +arch_initcall(db8500_regulator_init); +module_exit(db8500_regulator_exit); + +MODULE_AUTHOR("STMicroelectronics/ST-Ericsson"); +MODULE_DESCRIPTION("DB8500 regulator driver"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/regulator/db8500-prcmu.h b/include/linux/regulator/db8500-prcmu.h new file mode 100644 index 000000000000..612062313b68 --- /dev/null +++ b/include/linux/regulator/db8500-prcmu.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * License Terms: GNU General Public License v2 + * + * Author: Bengt Jonsson for ST-Ericsson + * + * Interface to power domain regulators on DB8500 + */ + +#ifndef __REGULATOR_H__ +#define __REGULATOR_H__ + +/* Number of DB8500 regulators and regulator enumeration */ +enum db8500_regulator_id { + DB8500_REGULATOR_VAPE, + DB8500_REGULATOR_VARM, + DB8500_REGULATOR_VMODEM, + DB8500_REGULATOR_VPLL, + DB8500_REGULATOR_VSMPS1, + DB8500_REGULATOR_VSMPS2, + DB8500_REGULATOR_VSMPS3, + DB8500_REGULATOR_VRF1, + DB8500_REGULATOR_SWITCH_SVAMMDSP, + DB8500_REGULATOR_SWITCH_SVAMMDSPRET, + DB8500_REGULATOR_SWITCH_SVAPIPE, + DB8500_REGULATOR_SWITCH_SIAMMDSP, + DB8500_REGULATOR_SWITCH_SIAMMDSPRET, + DB8500_REGULATOR_SWITCH_SIAPIPE, + DB8500_REGULATOR_SWITCH_SGA, + DB8500_REGULATOR_SWITCH_B2R2_MCDE, + DB8500_REGULATOR_SWITCH_ESRAM12, + DB8500_REGULATOR_SWITCH_ESRAM12RET, + DB8500_REGULATOR_SWITCH_ESRAM34, + DB8500_REGULATOR_SWITCH_ESRAM34RET, + DB8500_NUM_REGULATORS +}; + +/* + * Exported interface for CPUIdle only. This function is called with all + * interrupts turned off. + */ +int power_state_active_is_enabled(void); + +#endif -- cgit From 618e724b8d79c6232daac49cb39b0723bf5c4b08 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Wed, 11 May 2011 14:06:58 -0700 Subject: ns: Declare sys_setns in syscalls.h Ooops I overlooked this one, and missing it causes compile errors of the powerpc syscall. Signed-off-by: Eric W. Biederman --- include/linux/syscalls.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 83ecc1749ef6..b8b380443d05 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -844,4 +844,5 @@ asmlinkage long sys_name_to_handle_at(int dfd, const char __user *name, asmlinkage long sys_open_by_handle_at(int mountdirfd, struct file_handle __user *handle, int flags); +asmlinkage long sys_setns(int fd, int nstype); #endif -- cgit From a626743f579aa743473fd8b9215ca198bacf2ac4 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 18 Mar 2011 21:53:41 -0700 Subject: mtd: nand: renumber conflicting BBT flags The NAND_USE_FLASH_BBT_NO_OOB and NAND_CREATE_EMPTY_BBT flags conflict with the NAND_BBT_SCANBYTE1AND6 and NAND_BBT_DYNAMICSTRUCT flags, respectively. This change will allow us to utilize these options independently. Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- include/linux/mtd/nand.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index d44192740f6f..c2b9ac4fbc4a 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -237,9 +237,9 @@ typedef enum { * If passed additionally to NAND_USE_FLASH_BBT then BBT code will not touch * the OOB area. */ -#define NAND_USE_FLASH_BBT_NO_OOB 0x00100000 +#define NAND_USE_FLASH_BBT_NO_OOB 0x00800000 /* Create an empty BBT with no vendor information if the BBT is available */ -#define NAND_CREATE_EMPTY_BBT 0x00200000 +#define NAND_CREATE_EMPTY_BBT 0x01000000 /* Options set by nand scan */ /* Nand scan has allocated controller struct */ -- cgit From 41e2a4893566ced3c46af15df5b727326881e47d Mon Sep 17 00:00:00 2001 From: Philip Rakity Date: Sat, 19 Mar 2011 14:10:33 -0400 Subject: mmc: Ensure linux starts in eMMC user partition uBoot sometimes leaves eMMC pointing to the private boot partition. Ensure we always start looking at the user partition. Signed-off-by: Philip Rakity Signed-off-by: Bruce Clemens Signed-off-by: Mark F. Brown Signed-off-by: Chris Ball --- drivers/mmc/core/mmc.c | 10 ++++++++++ include/linux/mmc/card.h | 1 + include/linux/mmc/mmc.h | 1 + 3 files changed, 12 insertions(+) (limited to 'include/linux') diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 772d0d0a541b..5c611a6e0080 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -288,6 +288,7 @@ static int mmc_read_ext_csd(struct mmc_card *card) if (card->ext_csd.rev >= 3) { u8 sa_shift = ext_csd[EXT_CSD_S_A_TIMEOUT]; + card->ext_csd.bootconfig = ext_csd[EXT_CSD_BOOT_CONFIG]; /* Sleep / awake timeout in 100ns units */ if (sa_shift > 0 && sa_shift <= 0x17) @@ -567,6 +568,15 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, } } + /* + * Ensure eMMC user default partition is enabled + */ + if (card->ext_csd.bootconfig & 0x7) { + card->ext_csd.bootconfig &= ~0x7; + mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_CONFIG, + card->ext_csd.bootconfig); + } + /* * Activate high speed (if supported) */ diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index adb4888248be..557b73263390 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -45,6 +45,7 @@ struct mmc_ext_csd { u8 rev; u8 erase_group_def; u8 sec_feature_support; + u8 bootconfig; unsigned int sa_timeout; /* Units: 100ns */ unsigned int hs_max_dtr; unsigned int sectors; diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index 264ba5451e3b..b5ec88fd1352 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -256,6 +256,7 @@ struct _mmc_csd { #define EXT_CSD_PARTITION_ATTRIBUTE 156 /* R/W */ #define EXT_CSD_PARTITION_SUPPORT 160 /* RO */ #define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */ +#define EXT_CSD_BOOT_CONFIG 179 /* R/W */ #define EXT_CSD_ERASED_MEM_CONT 181 /* RO */ #define EXT_CSD_BUS_WIDTH 183 /* R/W */ #define EXT_CSD_HS_TIMING 185 /* R/W */ -- cgit From f4c5522b0a8827f39f83f928961d87e081bfe71c Mon Sep 17 00:00:00 2001 From: Andrei Warkentin Date: Thu, 31 Mar 2011 18:40:00 -0500 Subject: mmc: Reliable write support. Allows reliable writes to be used for MMC writes. Reliable writes are used to service write REQ_FUA/REQ_META requests. Handles both the legacy and the enhanced reliable write support in MMC cards. Signed-off-by: Andrei Warkentin Reviewed-by: Arnd Bergmann Signed-off-by: Chris Ball --- drivers/mmc/card/block.c | 81 +++++++++++++++++++++++++++++++++++++++++++++--- drivers/mmc/core/mmc.c | 5 +++ include/linux/mmc/card.h | 2 ++ include/linux/mmc/mmc.h | 4 +++ 4 files changed, 88 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 61d233a7c118..91a676773608 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -48,6 +48,10 @@ MODULE_ALIAS("mmc:block"); #endif #define MODULE_PARAM_PREFIX "mmcblk." +#define REL_WRITES_SUPPORTED(card) (mmc_card_mmc((card)) && \ + (((card)->ext_csd.rel_param & EXT_CSD_WR_REL_PARAM_EN) || \ + ((card)->ext_csd.rel_sectors))) + static DEFINE_MUTEX(block_mutex); /* @@ -331,6 +335,57 @@ out: return err ? 0 : 1; } +static int mmc_blk_issue_flush(struct mmc_queue *mq, struct request *req) +{ + struct mmc_blk_data *md = mq->data; + + /* + * No-op, only service this because we need REQ_FUA for reliable + * writes. + */ + spin_lock_irq(&md->lock); + __blk_end_request_all(req, 0); + spin_unlock_irq(&md->lock); + + return 1; +} + +/* + * Reformat current write as a reliable write, supporting + * both legacy and the enhanced reliable write MMC cards. + * In each transfer we'll handle only as much as a single + * reliable write can handle, thus finish the request in + * partial completions. + */ +static inline int mmc_apply_rel_rw(struct mmc_blk_request *brq, + struct mmc_card *card, + struct request *req) +{ + int err; + struct mmc_command set_count; + + if (!(card->ext_csd.rel_param & EXT_CSD_WR_REL_PARAM_EN)) { + /* Legacy mode imposes restrictions on transfers. */ + if (!IS_ALIGNED(brq->cmd.arg, card->ext_csd.rel_sectors)) + brq->data.blocks = 1; + + if (brq->data.blocks > card->ext_csd.rel_sectors) + brq->data.blocks = card->ext_csd.rel_sectors; + else if (brq->data.blocks < card->ext_csd.rel_sectors) + brq->data.blocks = 1; + } + + memset(&set_count, 0, sizeof(struct mmc_command)); + set_count.opcode = MMC_SET_BLOCK_COUNT; + set_count.arg = brq->data.blocks | (1 << 31); + set_count.flags = MMC_RSP_R1 | MMC_CMD_AC; + err = mmc_wait_for_cmd(card->host, &set_count, 0); + if (err) + printk(KERN_ERR "%s: error %d SET_BLOCK_COUNT\n", + req->rq_disk->disk_name, err); + return err; +} + static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) { struct mmc_blk_data *md = mq->data; @@ -338,6 +393,15 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) struct mmc_blk_request brq; int ret = 1, disable_multi = 0; + /* + * Reliable writes are used to implement Forced Unit Access and + * REQ_META accesses, and are supported only on MMCs. + */ + bool do_rel_wr = ((req->cmd_flags & REQ_FUA) || + (req->cmd_flags & REQ_META)) && + (rq_data_dir(req) == WRITE) && + REL_WRITES_SUPPORTED(card); + mmc_claim_host(card->host); do { @@ -374,12 +438,14 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) if (disable_multi && brq.data.blocks > 1) brq.data.blocks = 1; - if (brq.data.blocks > 1) { + if (brq.data.blocks > 1 || do_rel_wr) { /* SPI multiblock writes terminate using a special - * token, not a STOP_TRANSMISSION request. + * token, not a STOP_TRANSMISSION request. Reliable + * writes use SET_BLOCK_COUNT and do not use a + * STOP_TRANSMISSION request either. */ - if (!mmc_host_is_spi(card->host) - || rq_data_dir(req) == READ) + if ((!mmc_host_is_spi(card->host) && !do_rel_wr) || + rq_data_dir(req) == READ) brq.mrq.stop = &brq.stop; readcmd = MMC_READ_MULTIPLE_BLOCK; writecmd = MMC_WRITE_MULTIPLE_BLOCK; @@ -396,6 +462,9 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) brq.data.flags |= MMC_DATA_WRITE; } + if (do_rel_wr && mmc_apply_rel_rw(&brq, card, req)) + goto cmd_err; + mmc_set_data_timeout(&brq.data, card); brq.data.sg = mq->sg; @@ -565,6 +634,8 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) return mmc_blk_issue_secdiscard_rq(mq, req); else return mmc_blk_issue_discard_rq(mq, req); + } else if (req->cmd_flags & REQ_FLUSH) { + return mmc_blk_issue_flush(mq, req); } else { return mmc_blk_issue_rw_rq(mq, req); } @@ -622,6 +693,8 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) md->disk->queue = md->queue.queue; md->disk->driverfs_dev = &card->dev; set_disk_ro(md->disk, md->read_only); + if (REL_WRITES_SUPPORTED(card)) + blk_queue_flush(md->queue.queue, REQ_FLUSH | REQ_FUA); /* * As discussed on lkml, GENHD_FL_REMOVABLE should: diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 5c611a6e0080..ae6b8fd38800 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -300,6 +300,8 @@ static int mmc_read_ext_csd(struct mmc_card *card) ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT]; card->ext_csd.hc_erase_size = ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] << 10; + + card->ext_csd.rel_sectors = ext_csd[EXT_CSD_REL_WR_SEC_C]; } if (card->ext_csd.rev >= 4) { @@ -351,6 +353,9 @@ static int mmc_read_ext_csd(struct mmc_card *card) ext_csd[EXT_CSD_TRIM_MULT]; } + if (card->ext_csd.rev >= 5) + card->ext_csd.rel_param = ext_csd[EXT_CSD_WR_REL_PARAM]; + if (ext_csd[EXT_CSD_ERASED_MEM_CONT]) card->erased_byte = 0xFF; else diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 557b73263390..c4e96fa5fb2b 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -45,6 +45,8 @@ struct mmc_ext_csd { u8 rev; u8 erase_group_def; u8 sec_feature_support; + u8 rel_sectors; + u8 rel_param; u8 bootconfig; unsigned int sa_timeout; /* Units: 100ns */ unsigned int hs_max_dtr; diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index b5ec88fd1352..390aa6eef676 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -255,6 +255,7 @@ struct _mmc_csd { #define EXT_CSD_PARTITION_ATTRIBUTE 156 /* R/W */ #define EXT_CSD_PARTITION_SUPPORT 160 /* RO */ +#define EXT_CSD_WR_REL_PARAM 166 /* RO */ #define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */ #define EXT_CSD_BOOT_CONFIG 179 /* R/W */ #define EXT_CSD_ERASED_MEM_CONT 181 /* RO */ @@ -265,6 +266,7 @@ struct _mmc_csd { #define EXT_CSD_CARD_TYPE 196 /* RO */ #define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */ #define EXT_CSD_S_A_TIMEOUT 217 /* RO */ +#define EXT_CSD_REL_WR_SEC_C 222 /* RO */ #define EXT_CSD_HC_WP_GRP_SIZE 221 /* RO */ #define EXT_CSD_ERASE_TIMEOUT_MULT 223 /* RO */ #define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */ @@ -277,6 +279,8 @@ struct _mmc_csd { * EXT_CSD field definitions */ +#define EXT_CSD_WR_REL_PARAM_EN (1<<2) + #define EXT_CSD_CMD_SET_NORMAL (1<<0) #define EXT_CSD_CMD_SET_SECURE (1<<1) #define EXT_CSD_CMD_SET_CPSECURE (1<<2) -- cgit From a5e9425d2010978c5f85986cc70a9fa0c0d5b912 Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Tue, 5 Apr 2011 17:43:20 +0300 Subject: mmc: mmc_card_keep_power cleanups mmc_card_is_powered_resumed is a mouthful; instead, simply use mmc_card_keep_power, which also better explains the purpose of the macro. Employ mmc_card_keep_power() where possible. Signed-off-by: Ohad Ben-Cohen Signed-off-by: Chris Ball --- drivers/mmc/core/core.c | 4 ++-- drivers/mmc/core/sdio.c | 10 +++++----- include/linux/mmc/host.h | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'include/linux') diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 1f453acc8682..c2350e474159 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -1746,7 +1746,7 @@ int mmc_suspend_host(struct mmc_host *host) } mmc_bus_put(host); - if (!err && !(host->pm_flags & MMC_PM_KEEP_POWER)) + if (!err && !mmc_card_keep_power(host)) mmc_power_off(host); return err; @@ -1764,7 +1764,7 @@ int mmc_resume_host(struct mmc_host *host) mmc_bus_get(host); if (host->bus_ops && !host->bus_dead) { - if (!(host->pm_flags & MMC_PM_KEEP_POWER)) { + if (!mmc_card_keep_power(host)) { mmc_power_up(host); mmc_select_voltage(host, host->ocr); /* diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index db0f0b44d684..0f7d4362d213 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -625,7 +625,7 @@ static int mmc_sdio_suspend(struct mmc_host *host) } } - if (!err && host->pm_flags & MMC_PM_KEEP_POWER) { + if (!err && mmc_card_keep_power(host)) { mmc_claim_host(host); sdio_disable_wide(host->card); mmc_release_host(host); @@ -645,10 +645,10 @@ static int mmc_sdio_resume(struct mmc_host *host) mmc_claim_host(host); /* No need to reinitialize powered-resumed nonremovable cards */ - if (mmc_card_is_removable(host) || !mmc_card_is_powered_resumed(host)) + if (mmc_card_is_removable(host) || !mmc_card_keep_power(host)) err = mmc_sdio_init_card(host, host->ocr, host->card, - (host->pm_flags & MMC_PM_KEEP_POWER)); - else if (mmc_card_is_powered_resumed(host)) { + mmc_card_keep_power(host)); + else if (mmc_card_keep_power(host)) { /* We may have switched to 1-bit mode during suspend */ err = sdio_enable_4bit_bus(host->card); if (err > 0) { @@ -691,7 +691,7 @@ static int mmc_sdio_power_restore(struct mmc_host *host) mmc_claim_host(host); ret = mmc_sdio_init_card(host, host->ocr, host->card, - (host->pm_flags & MMC_PM_KEEP_POWER)); + mmc_card_keep_power(host)); if (!ret && host->sdio_irqs) mmc_signal_sdio_irq(host); mmc_release_host(host); diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index eb792cb6d745..8ad3a9c6f495 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -320,7 +320,7 @@ static inline int mmc_card_is_removable(struct mmc_host *host) return !(host->caps & MMC_CAP_NONREMOVABLE) && mmc_assume_removable; } -static inline int mmc_card_is_powered_resumed(struct mmc_host *host) +static inline int mmc_card_keep_power(struct mmc_host *host) { return host->pm_flags & MMC_PM_KEEP_POWER; } -- cgit From 33b53716bc4b3ff3da2bc41581226424443f9d5a Mon Sep 17 00:00:00 2001 From: Grant Erickson Date: Fri, 8 Apr 2011 08:51:32 -0700 Subject: mtd: create function to perform large allocations Introduce a common function to handle large, contiguous kmalloc buffer allocations by exponentially backing off on the size of the requested kernel transfer buffer until it succeeds or until the requested transfer buffer size falls below the page size. This helps ensure the operation can succeed under low-memory, highly- fragmented situations albeit somewhat more slowly. Artem: so this patch solves the problem that the kernel tries to kmalloc too large buffers, which (a) may fail and does fail - people complain about this, and (b) slows down the system in case of high memory fragmentation, because the kernel starts dropping caches, writing back, swapping, etc. But we do not really have to allocate a lot of memory to do the I/O, we may do this even with as little as one min. I/O unit (NAND page) of RAM. So the idea of this patch is that if the user asks to read or write a lot, we try to kmalloc a lot, with GFP flags which make the kernel _not_ drop caches, etc. If we can allocate it - good, if not - we try to allocate twice as less, and so on, until we reach the min. I/O unit size, which is our last resort allocation and use the normal GFP_KERNEL flag. Artem: re-write the allocation function so that it makes sure the allocated buffer is aligned to the min. I/O size of the flash. Signed-off-by: Grant Erickson Tested-by: Ben Gardiner Tested-by: Stefano Babic Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/mtdcore.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/mtd/mtd.h | 2 ++ 2 files changed, 51 insertions(+) (limited to 'include/linux') diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index da69bc8a5a7d..a50348b60d79 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -638,6 +638,54 @@ int default_mtd_writev(struct mtd_info *mtd, const struct kvec *vecs, return ret; } +/** + * mtd_kmalloc_up_to - allocate a contiguous buffer up to the specified size + * @size: A pointer to the ideal or maximum size of the allocation. Points + * to the actual allocation size on success. + * + * This routine attempts to allocate a contiguous kernel buffer up to + * the specified size, backing off the size of the request exponentially + * until the request succeeds or until the allocation size falls below + * the system page size. This attempts to make sure it does not adversely + * impact system performance, so when allocating more than one page, we + * ask the memory allocator to avoid re-trying, swapping, writing back + * or performing I/O. + * + * Note, this function also makes sure that the allocated buffer is aligned to + * the MTD device's min. I/O unit, i.e. the "mtd->writesize" value. + * + * This is called, for example by mtd_{read,write} and jffs2_scan_medium, + * to handle smaller (i.e. degraded) buffer allocations under low- or + * fragmented-memory situations where such reduced allocations, from a + * requested ideal, are allowed. + * + * Returns a pointer to the allocated buffer on success; otherwise, NULL. + */ +void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size) +{ + gfp_t flags = __GFP_NOWARN | __GFP_WAIT | + __GFP_NORETRY | __GFP_NO_KSWAPD; + size_t min_alloc = max_t(size_t, mtd->writesize, PAGE_SIZE); + void *kbuf; + + *size = min_t(size_t, *size, KMALLOC_MAX_SIZE); + + while (*size > min_alloc) { + kbuf = kmalloc(*size, flags); + if (kbuf) + return kbuf; + + *size >>= 1; + *size = ALIGN(*size, mtd->writesize); + } + + /* + * For the last resort allocation allow 'kmalloc()' to do all sorts of + * things (write-back, dropping caches, etc) by using GFP_KERNEL. + */ + return kmalloc(*size, GFP_KERNEL); +} + EXPORT_SYMBOL_GPL(add_mtd_device); EXPORT_SYMBOL_GPL(del_mtd_device); EXPORT_SYMBOL_GPL(get_mtd_device); @@ -648,6 +696,7 @@ EXPORT_SYMBOL_GPL(__put_mtd_device); EXPORT_SYMBOL_GPL(register_mtd_user); EXPORT_SYMBOL_GPL(unregister_mtd_user); EXPORT_SYMBOL_GPL(default_mtd_writev); +EXPORT_SYMBOL_GPL(mtd_kmalloc_up_to); #ifdef CONFIG_PROC_FS diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 9d5306bad117..06b489a7605b 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -348,6 +348,8 @@ int default_mtd_writev(struct mtd_info *mtd, const struct kvec *vecs, int default_mtd_readv(struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, size_t *retlen); +void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size); + #ifdef CONFIG_MTD_PARTITIONS void mtd_erase_callback(struct erase_info *instr); #else -- cgit From 6b93d01fe5971951911a070f51f412d50e9536dc Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Tue, 5 Apr 2011 17:43:21 +0300 Subject: mmc: do not switch to 1-bit mode if not required 6b5eda36 followed SDIO spec part E1 section 8, which states that in case SDIO interrupts are being used to wake up a suspended host, then it is required to switch to 1-bit mode before stopping the clock. Before switching to 1-bit mode (or back to 4-bit mode on resume), make sure that SDIO interrupts are really being used to wake the host. This is helpful for devices which have an external irq line (e.g. wl1271), and do not use SDIO interrupts to wake up the host. In this case, switching to 1-bit mode (and back to 4-bit mode on resume) is not necessary. Reported-by: Eliad Peller Signed-off-by: Ohad Ben-Cohen Signed-off-by: Chris Ball --- drivers/mmc/core/sdio.c | 4 ++-- include/linux/mmc/host.h | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 0f7d4362d213..4221670bf82e 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -625,7 +625,7 @@ static int mmc_sdio_suspend(struct mmc_host *host) } } - if (!err && mmc_card_keep_power(host)) { + if (!err && mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)) { mmc_claim_host(host); sdio_disable_wide(host->card); mmc_release_host(host); @@ -648,7 +648,7 @@ static int mmc_sdio_resume(struct mmc_host *host) if (mmc_card_is_removable(host) || !mmc_card_keep_power(host)) err = mmc_sdio_init_card(host, host->ocr, host->card, mmc_card_keep_power(host)); - else if (mmc_card_keep_power(host)) { + else if (mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)) { /* We may have switched to 1-bit mode during suspend */ err = sdio_enable_4bit_bus(host->card); if (err > 0) { diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 8ad3a9c6f495..0fffa5cdc183 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -325,5 +325,9 @@ static inline int mmc_card_keep_power(struct mmc_host *host) return host->pm_flags & MMC_PM_KEEP_POWER; } +static inline int mmc_card_wake_sdio_irq(struct mmc_host *host) +{ + return host->pm_flags & MMC_PM_WAKE_SDIO_IRQ; +} #endif -- cgit From eab4068795d670b065164096805cbf15a19e9690 Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Tue, 5 Apr 2011 17:50:14 +0300 Subject: mmc: add MMC_QUIRK_NONSTD_FUNC_IF Introduce MMC_QUIRK_NONSTD_FUNC_IF to ignore the "SDIO Standard Function interface code" as indicated by the card's FBR, and instead treat all functions as non-standard interfaces. This is required to prevent standard drivers from facing errors when trying to communicate with SDIO cards that erroneously indicate standard function interface codes. Signed-off-by: Ohad Ben-Cohen Signed-off-by: Chris Ball --- drivers/mmc/core/sdio.c | 6 ++++++ include/linux/mmc/card.h | 6 ++++++ 2 files changed, 12 insertions(+) (limited to 'include/linux') diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 4221670bf82e..c3c2bd0874e8 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "core.h" #include "bus.h" @@ -31,6 +32,11 @@ static int sdio_read_fbr(struct sdio_func *func) int ret; unsigned char data; + if (mmc_card_nonstd_func_interface(func->card)) { + func->class = SDIO_CLASS_NONE; + return 0; + } + ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_FBR_BASE(func->num) + SDIO_FBR_STD_IF, 0, &data); if (ret) diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index c4e96fa5fb2b..317a0029e7d7 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -128,6 +128,7 @@ struct mmc_card { #define MMC_QUIRK_NONSTD_SDIO (1<<2) /* non-standard SDIO card attached */ /* (missing CIA registers) */ #define MMC_QUIRK_BROKEN_CLK_GATING (1<<3) /* clock gating the sdio bus will make card fail */ +#define MMC_QUIRK_NONSTD_FUNC_IF (1<<4) /* SDIO card has nonstd function interfaces */ unsigned int erase_size; /* erase size in sectors */ unsigned int erase_shift; /* if erase unit is power 2 */ @@ -183,6 +184,11 @@ static inline int mmc_blksz_for_byte_mode(const struct mmc_card *c) return c->quirks & MMC_QUIRK_BLKSZ_FOR_BYTE_MODE; } +static inline int mmc_card_nonstd_func_interface(const struct mmc_card *c) +{ + return c->quirks & MMC_QUIRK_NONSTD_FUNC_IF; +} + #define mmc_card_name(c) ((c)->cid.prod_name) #define mmc_card_id(c) (dev_name(&(c)->dev)) -- cgit From 2059a02dcb84236f9db9197fa9b00418d7b8465b Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Tue, 5 Apr 2011 18:02:25 +0300 Subject: mmc: add MMC_QUIRK_DISABLE_CD 006ebd5d introduced sdio_disable_cd(), which disconnects the pull-up resistor on CD/DAT[3] (pin 1) of the card. Make it possible to start using sdio_disable_cd() by introducing MMC_QUIRK_DISABLE_CD. Signed-off-by: Ohad Ben-Cohen Signed-off-by: Chris Ball --- drivers/mmc/core/sdio.c | 2 +- include/linux/mmc/card.h | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index c3c2bd0874e8..a5840c0de2e4 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -187,7 +187,7 @@ static int sdio_disable_cd(struct mmc_card *card) int ret; u8 ctrl; - if (!card->cccr.disable_cd) + if (!mmc_card_disable_cd(card)) return 0; ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_IF, 0, &ctrl); diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 317a0029e7d7..2a7e54970c93 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -129,6 +129,7 @@ struct mmc_card { /* (missing CIA registers) */ #define MMC_QUIRK_BROKEN_CLK_GATING (1<<3) /* clock gating the sdio bus will make card fail */ #define MMC_QUIRK_NONSTD_FUNC_IF (1<<4) /* SDIO card has nonstd function interfaces */ +#define MMC_QUIRK_DISABLE_CD (1<<5) /* disconnect CD/DAT[3] resistor */ unsigned int erase_size; /* erase size in sectors */ unsigned int erase_shift; /* if erase unit is power 2 */ @@ -184,6 +185,11 @@ static inline int mmc_blksz_for_byte_mode(const struct mmc_card *c) return c->quirks & MMC_QUIRK_BLKSZ_FOR_BYTE_MODE; } +static inline int mmc_card_disable_cd(const struct mmc_card *c) +{ + return c->quirks & MMC_QUIRK_DISABLE_CD; +} + static inline int mmc_card_nonstd_func_interface(const struct mmc_card *c) { return c->quirks & MMC_QUIRK_NONSTD_FUNC_IF; -- cgit From 32780cd1350e651e68bdf33b7f5b009d21d5b794 Mon Sep 17 00:00:00 2001 From: Andrei Warkentin Date: Mon, 11 Apr 2011 17:02:15 -0500 Subject: mmc: quirks: Extends card quirks with MMC/SD quirks matching the CID. The current mechanism is SDIO-only. This allows us to create function-specific quirks, without creating messy Kconfig dependencies, or polluting core/ with function-specific code. Signed-off-by: Andrei Warkentin Acked-by: Arnd Bergmann Signed-off-by: Chris Ball --- drivers/mmc/core/core.h | 2 - drivers/mmc/core/quirks.c | 93 +++++++++++++++++++++-------------------------- drivers/mmc/core/sdio.c | 2 +- include/linux/mmc/card.h | 91 +++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 133 insertions(+), 55 deletions(-) (limited to 'include/linux') diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index 20b1c0831eac..ca1fdde29df6 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h @@ -61,8 +61,6 @@ int mmc_attach_mmc(struct mmc_host *host); int mmc_attach_sd(struct mmc_host *host); int mmc_attach_sdio(struct mmc_host *host); -void mmc_fixup_device(struct mmc_card *card); - /* Module parameters */ extern int use_spi_crc; diff --git a/drivers/mmc/core/quirks.c b/drivers/mmc/core/quirks.c index a4c42edc6cb3..3a596217029e 100644 --- a/drivers/mmc/core/quirks.c +++ b/drivers/mmc/core/quirks.c @@ -1,7 +1,8 @@ /* - * This file contains work-arounds for many known sdio hardware - * bugs. + * This file contains work-arounds for many known SD/MMC + * and SDIO hardware bugs. * + * Copyright (c) 2011 Andrei Warkentin * Copyright (c) 2011 Pierre Tardy * Inspired from pci fixup code: * Copyright (c) 1999 Martin Mares @@ -11,34 +12,14 @@ #include #include #include -#include -/* - * The world is not perfect and supplies us with broken mmc/sdio devices. - * For at least a part of these bugs we need a work-around - */ - -struct mmc_fixup { - u16 vendor, device; /* You can use SDIO_ANY_ID here of course */ - void (*vendor_fixup)(struct mmc_card *card, int data); - int data; -}; - -/* - * This hook just adds a quirk unconditionnally - */ -static void __maybe_unused add_quirk(struct mmc_card *card, int data) -{ - card->quirks |= data; -} +#ifndef SDIO_VENDOR_ID_TI +#define SDIO_VENDOR_ID_TI 0x0097 +#endif -/* - * This hook just removes a quirk unconditionnally - */ -static void __maybe_unused remove_quirk(struct mmc_card *card, int data) -{ - card->quirks &= ~data; -} +#ifndef SDIO_DEVICE_ID_TI_WL1271 +#define SDIO_DEVICE_ID_TI_WL1271 0x4076 +#endif /* * This hook just adds a quirk for all sdio devices @@ -49,37 +30,47 @@ static void add_quirk_for_sdio_devices(struct mmc_card *card, int data) card->quirks |= data; } -#ifndef SDIO_VENDOR_ID_TI -#define SDIO_VENDOR_ID_TI 0x0097 -#endif - -#ifndef SDIO_DEVICE_ID_TI_WL1271 -#define SDIO_DEVICE_ID_TI_WL1271 0x4076 -#endif - static const struct mmc_fixup mmc_fixup_methods[] = { /* by default sdio devices are considered CLK_GATING broken */ /* good cards will be whitelisted as they are tested */ - { SDIO_ANY_ID, SDIO_ANY_ID, - add_quirk_for_sdio_devices, MMC_QUIRK_BROKEN_CLK_GATING }, - { SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271, - remove_quirk, MMC_QUIRK_BROKEN_CLK_GATING }, - { SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271, - add_quirk, MMC_QUIRK_NONSTD_FUNC_IF }, - { SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271, - add_quirk, MMC_QUIRK_DISABLE_CD }, - { 0 } + SDIO_FIXUP(SDIO_ANY_ID, SDIO_ANY_ID, + add_quirk_for_sdio_devices, + MMC_QUIRK_BROKEN_CLK_GATING), + + SDIO_FIXUP(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271, + remove_quirk, MMC_QUIRK_BROKEN_CLK_GATING), + + SDIO_FIXUP(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271, + add_quirk, MMC_QUIRK_NONSTD_FUNC_IF), + + SDIO_FIXUP(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271, + add_quirk, MMC_QUIRK_DISABLE_CD), + + END_FIXUP }; -void mmc_fixup_device(struct mmc_card *card) +void mmc_fixup_device(struct mmc_card *card, const struct mmc_fixup *table) { const struct mmc_fixup *f; + u64 rev = cid_rev_card(card); + + /* Non-core specific workarounds. */ + if (!table) + table = mmc_fixup_methods; - for (f = mmc_fixup_methods; f->vendor_fixup; f++) { - if ((f->vendor == card->cis.vendor - || f->vendor == (u16) SDIO_ANY_ID) && - (f->device == card->cis.device - || f->device == (u16) SDIO_ANY_ID)) { + for (f = table; f->vendor_fixup; f++) { + if ((f->manfid == CID_MANFID_ANY || + f->manfid == card->cid.manfid) && + (f->oemid == CID_OEMID_ANY || + f->oemid == card->cid.oemid) && + (f->name == CID_NAME_ANY || + !strncmp(f->name, card->cid.prod_name, + sizeof(card->cid.prod_name))) && + (f->cis_vendor == card->cis.vendor || + f->cis_vendor == (u16) SDIO_ANY_ID) && + (f->cis_device == card->cis.device || + f->cis_device == (u16) SDIO_ANY_ID) && + rev >= f->rev_start && rev <= f->rev_end) { dev_dbg(&card->dev, "calling %pF\n", f->vendor_fixup); f->vendor_fixup(card, f->data); } diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index a5840c0de2e4..1e6095961500 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -472,7 +472,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, card = oldcard; } - mmc_fixup_device(card); + mmc_fixup_device(card, NULL); if (card->type == MMC_TYPE_SD_COMBO) { err = mmc_sd_setup_card(host, card, oldcard != NULL); diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 2a7e54970c93..c6513175f7f1 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -11,6 +11,7 @@ #define LINUX_MMC_CARD_H #include +#include struct mmc_cid { unsigned int manfid; @@ -157,7 +158,92 @@ struct mmc_card { struct dentry *debugfs_root; }; -void mmc_fixup_device(struct mmc_card *dev); +/* + * The world is not perfect and supplies us with broken mmc/sdio devices. + * For at least some of these bugs we need a work-around. + */ + +struct mmc_fixup { + /* CID-specific fields. */ + const char *name; + + /* Valid revision range */ + u64 rev_start, rev_end; + + unsigned int manfid; + unsigned short oemid; + + /* SDIO-specfic fields. You can use SDIO_ANY_ID here of course */ + u16 cis_vendor, cis_device; + + void (*vendor_fixup)(struct mmc_card *card, int data); + int data; +}; + +#define CID_MANFID_ANY (-1ul) +#define CID_OEMID_ANY ((unsigned short) -1) +#define CID_NAME_ANY (NULL) + +#define END_FIXUP { 0 } + +#define _FIXUP_EXT(_name, _manfid, _oemid, _rev_start, _rev_end, \ + _cis_vendor, _cis_device, \ + _fixup, _data) \ + { \ + .name = (_name), \ + .manfid = (_manfid), \ + .oemid = (_oemid), \ + .rev_start = (_rev_start), \ + .rev_end = (_rev_end), \ + .cis_vendor = (_cis_vendor), \ + .cis_device = (_cis_device), \ + .vendor_fixup = (_fixup), \ + .data = (_data), \ + } + +#define MMC_FIXUP_REV(_name, _manfid, _oemid, _rev_start, _rev_end, \ + _fixup, _data) \ + _FIXUP_EXT(_name, _manfid, \ + _oemid, _rev_start, _rev_end, \ + SDIO_ANY_ID, SDIO_ANY_ID, \ + _fixup, _data) \ + +#define MMC_FIXUP(_name, _manfid, _oemid, _fixup, _data) \ + MMC_FIXUP_REV(_name, _manfid, _oemid, 0, -1ull, _fixup, _data) + +#define SDIO_FIXUP(_vendor, _device, _fixup, _data) \ + _FIXUP_EXT(CID_NAME_ANY, CID_MANFID_ANY, \ + CID_OEMID_ANY, 0, -1ull, \ + _vendor, _device, \ + _fixup, _data) \ + +#define cid_rev(hwrev, fwrev, year, month) \ + (((u64) hwrev) << 40 | \ + ((u64) fwrev) << 32 | \ + ((u64) year) << 16 | \ + ((u64) month)) + +#define cid_rev_card(card) \ + cid_rev(card->cid.hwrev, \ + card->cid.fwrev, \ + card->cid.year, \ + card->cid.month) + +/* + * This hook just adds a quirk unconditionally. + */ +static inline void __maybe_unused add_quirk(struct mmc_card *card, int data) +{ + card->quirks |= data; +} + +/* + * This hook just removes a quirk unconditionally. + */ +static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data) +{ + card->quirks &= ~data; +} #define mmc_card_mmc(c) ((c)->type == MMC_TYPE_MMC) #define mmc_card_sd(c) ((c)->type == MMC_TYPE_SD) @@ -218,4 +304,7 @@ struct mmc_driver { extern int mmc_register_driver(struct mmc_driver *); extern void mmc_unregister_driver(struct mmc_driver *); +extern void mmc_fixup_device(struct mmc_card *card, + const struct mmc_fixup *table); + #endif -- cgit From 853c6cac0dc0d9d330deb5b48c19eebafaed1841 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 12 Apr 2011 12:59:09 -0400 Subject: mmc: quirks: fix truncation warnings Fix data truncation warnings: .manfid is not unsigned long: drivers/mmc/core/quirks.c:36: warning: large integer implicitly truncated to unsigned type drivers/mmc/core/quirks.c:40: warning: large integer implicitly truncated to unsigned type drivers/mmc/core/quirks.c:43: warning: large integer implicitly truncated to unsigned type drivers/mmc/core/quirks.c:46: warning: large integer implicitly truncated to unsigned type Signed-off-by: Randy Dunlap Signed-off-by: Chris Ball --- include/linux/mmc/card.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index c6513175f7f1..937f852cf01e 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -180,7 +180,7 @@ struct mmc_fixup { int data; }; -#define CID_MANFID_ANY (-1ul) +#define CID_MANFID_ANY (-1u) #define CID_OEMID_ANY ((unsigned short) -1) #define CID_NAME_ANY (NULL) -- cgit From eaa02f751ff4f8abfc2e55a15c20a5a274244418 Mon Sep 17 00:00:00 2001 From: Andrei Warkentin Date: Mon, 11 Apr 2011 16:13:41 -0500 Subject: mmc: core: Rename erase_timeout to cmd_timeout_ms. Renames erase_timeout to cmd_timeout_ms inside struct mmc_command. First step to making host honor timeouts for non-data-transfer commands. Cleans up erase timeout code. Signed-off-by: Andrei Warkentin Signed-off-by: Chris Ball --- drivers/mmc/core/core.c | 39 +++++++++++++++++++++------------------ include/linux/mmc/core.h | 2 +- 2 files changed, 22 insertions(+), 19 deletions(-) (limited to 'include/linux') diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index c2350e474159..5178d5daa5f4 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -1187,9 +1187,8 @@ void mmc_init_erase(struct mmc_card *card) } } -static void mmc_set_mmc_erase_timeout(struct mmc_card *card, - struct mmc_command *cmd, - unsigned int arg, unsigned int qty) +static unsigned int mmc_mmc_erase_timeout(struct mmc_card *card, + unsigned int arg, unsigned int qty) { unsigned int erase_timeout; @@ -1246,38 +1245,42 @@ static void mmc_set_mmc_erase_timeout(struct mmc_card *card, if (mmc_host_is_spi(card->host) && erase_timeout < 1000) erase_timeout = 1000; - cmd->erase_timeout = erase_timeout; + return erase_timeout; } -static void mmc_set_sd_erase_timeout(struct mmc_card *card, - struct mmc_command *cmd, unsigned int arg, - unsigned int qty) +static unsigned int mmc_sd_erase_timeout(struct mmc_card *card, + unsigned int arg, + unsigned int qty) { + unsigned int erase_timeout; + if (card->ssr.erase_timeout) { /* Erase timeout specified in SD Status Register (SSR) */ - cmd->erase_timeout = card->ssr.erase_timeout * qty + - card->ssr.erase_offset; + erase_timeout = card->ssr.erase_timeout * qty + + card->ssr.erase_offset; } else { /* * Erase timeout not specified in SD Status Register (SSR) so * use 250ms per write block. */ - cmd->erase_timeout = 250 * qty; + erase_timeout = 250 * qty; } /* Must not be less than 1 second */ - if (cmd->erase_timeout < 1000) - cmd->erase_timeout = 1000; + if (erase_timeout < 1000) + erase_timeout = 1000; + + return erase_timeout; } -static void mmc_set_erase_timeout(struct mmc_card *card, - struct mmc_command *cmd, unsigned int arg, - unsigned int qty) +static unsigned int mmc_erase_timeout(struct mmc_card *card, + unsigned int arg, + unsigned int qty) { if (mmc_card_sd(card)) - mmc_set_sd_erase_timeout(card, cmd, arg, qty); + return mmc_sd_erase_timeout(card, arg, qty); else - mmc_set_mmc_erase_timeout(card, cmd, arg, qty); + return mmc_mmc_erase_timeout(card, arg, qty); } static int mmc_do_erase(struct mmc_card *card, unsigned int from, @@ -1351,7 +1354,7 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from, cmd.opcode = MMC_ERASE; cmd.arg = arg; cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; - mmc_set_erase_timeout(card, &cmd, arg, qty); + cmd.cmd_timeout_ms = mmc_erase_timeout(card, arg, qty); err = mmc_wait_for_cmd(card->host, &cmd, 0); if (err) { printk(KERN_ERR "mmc_erase: erase error %d, status %#x\n", diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 07f27af4dba5..811e96e8d1fe 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -92,7 +92,7 @@ struct mmc_command { * actively failing requests */ - unsigned int erase_timeout; /* in milliseconds */ + unsigned int cmd_timeout_ms; /* in milliseconds */ struct mmc_data *data; /* data segment associated with cmd */ struct mmc_request *mrq; /* associated request */ -- cgit From d3a8d95dcbb726b9cf0bbc166b2473bdd236c88c Mon Sep 17 00:00:00 2001 From: Andrei Warkentin Date: Mon, 11 Apr 2011 16:13:43 -0500 Subject: mmc: core: Allow setting CMD timeout for CMD6 (SWITCH). CMD6 is an R1B-type command, where DAT is used as busy. Depending on register written using CMD6, timeout value can be different as per spec. Signed-off-by: Andrei Warkentin Signed-off-by: Chris Ball --- drivers/mmc/core/mmc.c | 14 ++++++++------ drivers/mmc/core/mmc_ops.c | 16 +++++++++++++++- drivers/mmc/core/mmc_ops.h | 1 - include/linux/mmc/core.h | 1 + 4 files changed, 24 insertions(+), 8 deletions(-) (limited to 'include/linux') diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index ae6b8fd38800..396cb23625d2 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -548,7 +548,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, */ if (card->ext_csd.enhanced_area_en) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_ERASE_GROUP_DEF, 1); + EXT_CSD_ERASE_GROUP_DEF, 1, 0); if (err && err != -EBADMSG) goto free_card; @@ -579,7 +579,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, if (card->ext_csd.bootconfig & 0x7) { card->ext_csd.bootconfig &= ~0x7; mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_CONFIG, - card->ext_csd.bootconfig); + card->ext_csd.bootconfig, 0); } /* @@ -588,7 +588,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, if ((card->ext_csd.hs_max_dtr != 0) && (host->caps & MMC_CAP_MMC_HIGHSPEED)) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_HS_TIMING, 1); + EXT_CSD_HS_TIMING, 1, 0); if (err && err != -EBADMSG) goto free_card; @@ -655,7 +655,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, ddr = 0; /* no DDR for 1-bit width */ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, - ext_csd_bits[idx][0]); + ext_csd_bits[idx][0], + 0); if (!err) { mmc_set_bus_width_ddr(card->host, bus_width, MMC_SDR_MODE); @@ -674,8 +675,9 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, if (!err && ddr) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_BUS_WIDTH, - ext_csd_bits[idx][1]); + EXT_CSD_BUS_WIDTH, + ext_csd_bits[idx][1], + 0); } if (err) { printk(KERN_WARNING "%s: switch to bus width %d ddr %d " diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index f3b22bf89cc9..a2bae625332a 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c @@ -387,7 +387,19 @@ int mmc_spi_set_crc(struct mmc_host *host, int use_crc) return err; } -int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value) +/** + * mmc_switch - modify EXT_CSD register + * @card: the MMC card associated with the data transfer + * @set: cmd set values + * @index: EXT_CSD register index + * @value: value to program into EXT_CSD register + * @timeout_ms: timeout (ms) for operation performed by register write, + * timeout of zero implies maximum possible timeout + * + * Modifies the EXT_CSD register for selected card. + */ +int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, + unsigned int timeout_ms) { int err; struct mmc_command cmd; @@ -404,6 +416,7 @@ int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value) (value << 8) | set; cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; + cmd.cmd_timeout_ms = timeout_ms; err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); if (err) @@ -433,6 +446,7 @@ int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value) return 0; } +EXPORT_SYMBOL_GPL(mmc_switch); int mmc_send_status(struct mmc_card *card, u32 *status) { diff --git a/drivers/mmc/core/mmc_ops.h b/drivers/mmc/core/mmc_ops.h index e6d44b8a18db..9276946fa5b7 100644 --- a/drivers/mmc/core/mmc_ops.h +++ b/drivers/mmc/core/mmc_ops.h @@ -20,7 +20,6 @@ int mmc_all_send_cid(struct mmc_host *host, u32 *cid); int mmc_set_relative_addr(struct mmc_card *card); int mmc_send_csd(struct mmc_card *card, u32 *csd); int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd); -int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value); int mmc_send_status(struct mmc_card *card, u32 *status); int mmc_send_cid(struct mmc_host *host, u32 *cid); int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp); diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 811e96e8d1fe..f8e4bcbd2846 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -135,6 +135,7 @@ extern void mmc_wait_for_req(struct mmc_host *, struct mmc_request *); extern int mmc_wait_for_cmd(struct mmc_host *, struct mmc_command *, int); extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *, struct mmc_command *, int); +extern int mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int); #define MMC_ERASE_ARG 0x00000000 #define MMC_SECURE_ERASE_ARG 0x80000000 -- cgit From 371a689f64b0da140c3bcd3f55305ffa1c3a58ef Mon Sep 17 00:00:00 2001 From: Andrei Warkentin Date: Mon, 11 Apr 2011 18:10:25 -0500 Subject: mmc: MMC boot partitions support. Allows device MMC boot partitions to be accessed. MMC partitions are treated effectively as separate block devices on the same MMC card. Signed-off-by: Andrei Warkentin Acked-by: Arnd Bergmann Signed-off-by: Chris Ball --- Documentation/mmc/00-INDEX | 2 + Documentation/mmc/mmc-dev-attrs.txt | 10 ++ Documentation/mmc/mmc-dev-parts.txt | 27 ++++ drivers/mmc/card/block.c | 274 +++++++++++++++++++++++++++++++----- drivers/mmc/core/mmc.c | 22 ++- include/linux/mmc/card.h | 4 +- include/linux/mmc/mmc.h | 8 +- 7 files changed, 305 insertions(+), 42 deletions(-) create mode 100644 Documentation/mmc/mmc-dev-parts.txt (limited to 'include/linux') diff --git a/Documentation/mmc/00-INDEX b/Documentation/mmc/00-INDEX index fca586f5b853..93dd7a714075 100644 --- a/Documentation/mmc/00-INDEX +++ b/Documentation/mmc/00-INDEX @@ -2,3 +2,5 @@ - this file mmc-dev-attrs.txt - info on SD and MMC device attributes +mmc-dev-parts.txt + - info on SD and MMC device partitions diff --git a/Documentation/mmc/mmc-dev-attrs.txt b/Documentation/mmc/mmc-dev-attrs.txt index ff2bd685bced..8898a95b41e5 100644 --- a/Documentation/mmc/mmc-dev-attrs.txt +++ b/Documentation/mmc/mmc-dev-attrs.txt @@ -1,3 +1,13 @@ +SD and MMC Block Device Attributes +================================== + +These attributes are defined for the block devices associated with the +SD or MMC device. + +The following attributes are read/write. + + force_ro Enforce read-only access even if write protect switch is off. + SD and MMC Device Attributes ============================ diff --git a/Documentation/mmc/mmc-dev-parts.txt b/Documentation/mmc/mmc-dev-parts.txt new file mode 100644 index 000000000000..2db28b8e662f --- /dev/null +++ b/Documentation/mmc/mmc-dev-parts.txt @@ -0,0 +1,27 @@ +SD and MMC Device Partitions +============================ + +Device partitions are additional logical block devices present on the +SD/MMC device. + +As of this writing, MMC boot partitions as supported and exposed as +/dev/mmcblkXboot0 and /dev/mmcblkXboot1, where X is the index of the +parent /dev/mmcblkX. + +MMC Boot Partitions +=================== + +Read and write access is provided to the two MMC boot partitions. Due to +the sensitive nature of the boot partition contents, which often store +a bootloader or bootloader configuration tables crucial to booting the +platform, write access is disabled by default to reduce the chance of +accidental bricking. + +To enable write access to /dev/mmcblkXbootY, disable the forced read-only +access with: + +echo 0 > /sys/block/mmcblkXbootY/force_ro + +To re-enable read-only access: + +echo 1 > /sys/block/mmcblkXbootY/force_ro diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 3e9082b729ff..1e6bd910e79e 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -76,9 +76,19 @@ struct mmc_blk_data { spinlock_t lock; struct gendisk *disk; struct mmc_queue queue; + struct list_head part; unsigned int usage; unsigned int read_only; + unsigned int part_type; + + /* + * Only set in main mmc_blk_data associated + * with mmc_card with mmc_set_drvdata, and keeps + * track of the current selected device partition. + */ + unsigned int part_curr; + struct device_attribute force_ro; }; static DEFINE_MUTEX(open_lock); @@ -101,17 +111,22 @@ static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk) return md; } +static inline int mmc_get_devidx(struct gendisk *disk) +{ + int devmaj = MAJOR(disk_devt(disk)); + int devidx = MINOR(disk_devt(disk)) / perdev_minors; + + if (!devmaj) + devidx = disk->first_minor / perdev_minors; + return devidx; +} + static void mmc_blk_put(struct mmc_blk_data *md) { mutex_lock(&open_lock); md->usage--; if (md->usage == 0) { - int devmaj = MAJOR(disk_devt(md->disk)); - int devidx = MINOR(disk_devt(md->disk)) / perdev_minors; - - if (!devmaj) - devidx = md->disk->first_minor / perdev_minors; - + int devidx = mmc_get_devidx(md->disk); blk_cleanup_queue(md->queue.queue); __clear_bit(devidx, dev_use); @@ -122,6 +137,38 @@ static void mmc_blk_put(struct mmc_blk_data *md) mutex_unlock(&open_lock); } +static ssize_t force_ro_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int ret; + struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev)); + + ret = snprintf(buf, PAGE_SIZE, "%d", + get_disk_ro(dev_to_disk(dev)) ^ + md->read_only); + mmc_blk_put(md); + return ret; +} + +static ssize_t force_ro_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + char *end; + struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev)); + unsigned long set = simple_strtoul(buf, &end, 0); + if (end == buf) { + ret = -EINVAL; + goto out; + } + + set_disk_ro(dev_to_disk(dev), set || md->read_only); + ret = count; +out: + mmc_blk_put(md); + return ret; +} + static int mmc_blk_open(struct block_device *bdev, fmode_t mode) { struct mmc_blk_data *md = mmc_blk_get(bdev->bd_disk); @@ -176,6 +223,29 @@ struct mmc_blk_request { struct mmc_data data; }; +static inline int mmc_blk_part_switch(struct mmc_card *card, + struct mmc_blk_data *md) +{ + int ret; + struct mmc_blk_data *main_md = mmc_get_drvdata(card); + if (main_md->part_curr == md->part_type) + return 0; + + if (mmc_card_mmc(card)) { + card->ext_csd.part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK; + card->ext_csd.part_config |= md->part_type; + + ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_PART_CONFIG, card->ext_csd.part_config, + card->ext_csd.part_time); + if (ret) + return ret; +} + + main_md->part_curr = md->part_type; + return 0; +} + static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) { int err; @@ -620,6 +690,11 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) struct mmc_card *card = md->queue.card; mmc_claim_host(card->host); + ret = mmc_blk_part_switch(card, md); + if (ret) { + ret = 0; + goto out; + } if (req->cmd_flags & REQ_DISCARD) { if (req->cmd_flags & REQ_SECURE) @@ -632,6 +707,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) ret = mmc_blk_issue_rw_rq(mq, req); } +out: mmc_release_host(card->host); return ret; } @@ -642,7 +718,11 @@ static inline int mmc_blk_readonly(struct mmc_card *card) !(card->csd.cmdclass & CCC_BLOCK_WRITE); } -static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) +static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, + struct device *parent, + sector_t size, + bool default_ro, + const char *subname) { struct mmc_blk_data *md; int devidx, ret; @@ -658,7 +738,6 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) goto out; } - /* * Set the read-only status based on the supported commands * and the write protect switch. @@ -672,6 +751,7 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) } spin_lock_init(&md->lock); + INIT_LIST_HEAD(&md->part); md->usage = 1; ret = mmc_init_queue(&md->queue, card, &md->lock); @@ -686,8 +766,8 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) md->disk->fops = &mmc_bdops; md->disk->private_data = md; md->disk->queue = md->queue.queue; - md->disk->driverfs_dev = &card->dev; - set_disk_ro(md->disk, md->read_only); + md->disk->driverfs_dev = parent; + set_disk_ro(md->disk, md->read_only || default_ro); if (REL_WRITES_SUPPORTED(card)) blk_queue_flush(md->queue.queue, REQ_FLUSH | REQ_FUA); @@ -703,33 +783,97 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) * messages to tell when the card is present. */ - snprintf(md->disk->disk_name, sizeof(md->disk->disk_name), - "mmcblk%d", devidx); + if (subname) + snprintf(md->disk->disk_name, sizeof(md->disk->disk_name), + "mmcblk%d%s", + mmc_get_devidx(dev_to_disk(parent)), subname); + else + snprintf(md->disk->disk_name, sizeof(md->disk->disk_name), + "mmcblk%d", devidx); blk_queue_logical_block_size(md->queue.queue, 512); + set_capacity(md->disk, size); + return md; + + err_putdisk: + put_disk(md->disk); + err_kfree: + kfree(md); + out: + return ERR_PTR(ret); +} + +static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) +{ + sector_t size; + struct mmc_blk_data *md; if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) { /* * The EXT_CSD sector count is in number or 512 byte * sectors. */ - set_capacity(md->disk, card->ext_csd.sectors); + size = card->ext_csd.sectors; } else { /* * The CSD capacity field is in units of read_blkbits. * set_capacity takes units of 512 bytes. */ - set_capacity(md->disk, - card->csd.capacity << (card->csd.read_blkbits - 9)); + size = card->csd.capacity << (card->csd.read_blkbits - 9); } + + md = mmc_blk_alloc_req(card, &card->dev, size, false, NULL); return md; +} - err_putdisk: - put_disk(md->disk); - err_kfree: - kfree(md); - out: - return ERR_PTR(ret); +static int mmc_blk_alloc_part(struct mmc_card *card, + struct mmc_blk_data *md, + unsigned int part_type, + sector_t size, + bool default_ro, + const char *subname) +{ + char cap_str[10]; + struct mmc_blk_data *part_md; + + part_md = mmc_blk_alloc_req(card, disk_to_dev(md->disk), size, default_ro, + subname); + if (IS_ERR(part_md)) + return PTR_ERR(part_md); + part_md->part_type = part_type; + list_add(&part_md->part, &md->part); + + string_get_size((u64)get_capacity(part_md->disk) << 9, STRING_UNITS_2, + cap_str, sizeof(cap_str)); + printk(KERN_INFO "%s: %s %s partition %u %s\n", + part_md->disk->disk_name, mmc_card_id(card), + mmc_card_name(card), part_md->part_type, cap_str); + return 0; +} + +static int mmc_blk_alloc_parts(struct mmc_card *card, struct mmc_blk_data *md) +{ + int ret = 0; + + if (!mmc_card_mmc(card)) + return 0; + + if (card->ext_csd.boot_size) { + ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_BOOT0, + card->ext_csd.boot_size >> 9, + true, + "boot0"); + if (ret) + return ret; + ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_BOOT1, + card->ext_csd.boot_size >> 9, + true, + "boot1"); + if (ret) + return ret; + } + + return ret; } static int @@ -750,9 +894,54 @@ mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card) return 0; } +static void mmc_blk_remove_req(struct mmc_blk_data *md) +{ + if (md) { + if (md->disk->flags & GENHD_FL_UP) { + device_remove_file(disk_to_dev(md->disk), &md->force_ro); + + /* Stop new requests from getting into the queue */ + del_gendisk(md->disk); + } + + /* Then flush out any already in there */ + mmc_cleanup_queue(&md->queue); + mmc_blk_put(md); + } +} + +static void mmc_blk_remove_parts(struct mmc_card *card, + struct mmc_blk_data *md) +{ + struct list_head *pos, *q; + struct mmc_blk_data *part_md; + + list_for_each_safe(pos, q, &md->part) { + part_md = list_entry(pos, struct mmc_blk_data, part); + list_del(pos); + mmc_blk_remove_req(part_md); + } +} + +static int mmc_add_disk(struct mmc_blk_data *md) +{ + int ret; + + add_disk(md->disk); + md->force_ro.show = force_ro_show; + md->force_ro.store = force_ro_store; + md->force_ro.attr.name = "force_ro"; + md->force_ro.attr.mode = S_IRUGO | S_IWUSR; + ret = device_create_file(disk_to_dev(md->disk), &md->force_ro); + if (ret) + del_gendisk(md->disk); + + return ret; +} + static int mmc_blk_probe(struct mmc_card *card) { - struct mmc_blk_data *md; + struct mmc_blk_data *md, *part_md; int err; char cap_str[10]; @@ -776,14 +965,22 @@ static int mmc_blk_probe(struct mmc_card *card) md->disk->disk_name, mmc_card_id(card), mmc_card_name(card), cap_str, md->read_only ? "(ro)" : ""); + if (mmc_blk_alloc_parts(card, md)) + goto out; + mmc_set_drvdata(card, md); - add_disk(md->disk); + if (mmc_add_disk(md)) + goto out; + + list_for_each_entry(part_md, &md->part, part) { + if (mmc_add_disk(part_md)) + goto out; + } return 0; out: - mmc_cleanup_queue(&md->queue); - mmc_blk_put(md); - + mmc_blk_remove_parts(card, md); + mmc_blk_remove_req(md); return err; } @@ -791,36 +988,43 @@ static void mmc_blk_remove(struct mmc_card *card) { struct mmc_blk_data *md = mmc_get_drvdata(card); - if (md) { - /* Stop new requests from getting into the queue */ - del_gendisk(md->disk); - - /* Then flush out any already in there */ - mmc_cleanup_queue(&md->queue); - - mmc_blk_put(md); - } + mmc_blk_remove_parts(card, md); + mmc_blk_remove_req(md); mmc_set_drvdata(card, NULL); } #ifdef CONFIG_PM static int mmc_blk_suspend(struct mmc_card *card, pm_message_t state) { + struct mmc_blk_data *part_md; struct mmc_blk_data *md = mmc_get_drvdata(card); if (md) { mmc_queue_suspend(&md->queue); + list_for_each_entry(part_md, &md->part, part) { + mmc_queue_suspend(&part_md->queue); + } } return 0; } static int mmc_blk_resume(struct mmc_card *card) { + struct mmc_blk_data *part_md; struct mmc_blk_data *md = mmc_get_drvdata(card); if (md) { mmc_blk_set_blksize(md, card); + + /* + * Resume involves the card going into idle state, + * so current partition is always the main one. + */ + md->part_curr = md->part_type; mmc_queue_resume(&md->queue); + list_for_each_entry(part_md, &md->part, part) { + mmc_queue_resume(&part_md->queue); + } } return 0; } diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 396cb23625d2..a2c795e8f9dd 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -288,7 +288,10 @@ static int mmc_read_ext_csd(struct mmc_card *card) if (card->ext_csd.rev >= 3) { u8 sa_shift = ext_csd[EXT_CSD_S_A_TIMEOUT]; - card->ext_csd.bootconfig = ext_csd[EXT_CSD_BOOT_CONFIG]; + card->ext_csd.part_config = ext_csd[EXT_CSD_PART_CONFIG]; + + /* EXT_CSD value is in units of 10ms, but we store in ms */ + card->ext_csd.part_time = 10 * ext_csd[EXT_CSD_PART_SWITCH_TIME]; /* Sleep / awake timeout in 100ns units */ if (sa_shift > 0 && sa_shift <= 0x17) @@ -302,6 +305,12 @@ static int mmc_read_ext_csd(struct mmc_card *card) ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] << 10; card->ext_csd.rel_sectors = ext_csd[EXT_CSD_REL_WR_SEC_C]; + + /* + * There are two boot regions of equal size, defined in + * multiples of 128K. + */ + card->ext_csd.boot_size = ext_csd[EXT_CSD_BOOT_MULT] << 17; } if (card->ext_csd.rev >= 4) { @@ -576,10 +585,13 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, /* * Ensure eMMC user default partition is enabled */ - if (card->ext_csd.bootconfig & 0x7) { - card->ext_csd.bootconfig &= ~0x7; - mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_CONFIG, - card->ext_csd.bootconfig, 0); + if (card->ext_csd.part_config & EXT_CSD_PART_CONFIG_ACC_MASK) { + card->ext_csd.part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK; + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONFIG, + card->ext_csd.part_config, + card->ext_csd.part_time); + if (err && err != -EBADMSG) + goto free_card; } /* diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 937f852cf01e..0c7a58b14343 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -48,7 +48,8 @@ struct mmc_ext_csd { u8 sec_feature_support; u8 rel_sectors; u8 rel_param; - u8 bootconfig; + u8 part_config; + unsigned int part_time; /* Units: ms */ unsigned int sa_timeout; /* Units: 100ns */ unsigned int hs_max_dtr; unsigned int sectors; @@ -61,6 +62,7 @@ struct mmc_ext_csd { bool enhanced_area_en; /* enable bit */ unsigned long long enhanced_area_offset; /* Units: Byte */ unsigned int enhanced_area_size; /* Units: KB */ + unsigned int boot_size; /* in bytes */ }; struct sd_scr { diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index 390aa6eef676..373b2bf5e5b5 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -257,19 +257,21 @@ struct _mmc_csd { #define EXT_CSD_PARTITION_SUPPORT 160 /* RO */ #define EXT_CSD_WR_REL_PARAM 166 /* RO */ #define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */ -#define EXT_CSD_BOOT_CONFIG 179 /* R/W */ +#define EXT_CSD_PART_CONFIG 179 /* R/W */ #define EXT_CSD_ERASED_MEM_CONT 181 /* RO */ #define EXT_CSD_BUS_WIDTH 183 /* R/W */ #define EXT_CSD_HS_TIMING 185 /* R/W */ #define EXT_CSD_REV 192 /* RO */ #define EXT_CSD_STRUCTURE 194 /* RO */ #define EXT_CSD_CARD_TYPE 196 /* RO */ +#define EXT_CSD_PART_SWITCH_TIME 199 /* RO */ #define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */ #define EXT_CSD_S_A_TIMEOUT 217 /* RO */ #define EXT_CSD_REL_WR_SEC_C 222 /* RO */ #define EXT_CSD_HC_WP_GRP_SIZE 221 /* RO */ #define EXT_CSD_ERASE_TIMEOUT_MULT 223 /* RO */ #define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */ +#define EXT_CSD_BOOT_MULT 226 /* RO */ #define EXT_CSD_SEC_TRIM_MULT 229 /* RO */ #define EXT_CSD_SEC_ERASE_MULT 230 /* RO */ #define EXT_CSD_SEC_FEATURE_SUPPORT 231 /* RO */ @@ -281,6 +283,10 @@ struct _mmc_csd { #define EXT_CSD_WR_REL_PARAM_EN (1<<2) +#define EXT_CSD_PART_CONFIG_ACC_MASK (0x7) +#define EXT_CSD_PART_CONFIG_ACC_BOOT0 (0x1) +#define EXT_CSD_PART_CONFIG_ACC_BOOT1 (0x2) + #define EXT_CSD_CMD_SET_NORMAL (1<<0) #define EXT_CSD_CMD_SET_SECURE (1<<1) #define EXT_CSD_CMD_SET_CPSECURE (1<<2) -- cgit From 6a7a6b45f454686a1549729bfbae31f0b3b595d6 Mon Sep 17 00:00:00 2001 From: Andrei Warkentin Date: Tue, 12 Apr 2011 15:06:53 -0500 Subject: mmc: quirks: Fix erase/trim for certain SanDisk cards. CMD38 argument is passed through EXT_CSD[113]. Signed-off-by: Andrei Warkentin Signed-off-by: Chris Ball --- drivers/mmc/card/block.c | 43 ++++++++++++++++++++++++++++++++++++++++++- include/linux/mmc/card.h | 1 + 2 files changed, 43 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 288d27394ef9..c20995323348 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -48,6 +48,13 @@ MODULE_ALIAS("mmc:block"); #endif #define MODULE_PARAM_PREFIX "mmcblk." +#define INAND_CMD38_ARG_EXT_CSD 113 +#define INAND_CMD38_ARG_ERASE 0x00 +#define INAND_CMD38_ARG_TRIM 0x01 +#define INAND_CMD38_ARG_SECERASE 0x80 +#define INAND_CMD38_ARG_SECTRIM1 0x81 +#define INAND_CMD38_ARG_SECTRIM2 0x88 + #define REL_WRITES_SUPPORTED(card) (mmc_card_mmc((card)) && \ (((card)->ext_csd.rel_param & EXT_CSD_WR_REL_PARAM_EN) || \ ((card)->ext_csd.rel_sectors))) @@ -356,6 +363,16 @@ static int mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req) else arg = MMC_ERASE_ARG; + if (card->quirks & MMC_QUIRK_INAND_CMD38) { + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, + INAND_CMD38_ARG_EXT_CSD, + arg == MMC_TRIM_ARG ? + INAND_CMD38_ARG_TRIM : + INAND_CMD38_ARG_ERASE, + 0); + if (err) + goto out; + } err = mmc_erase(card, from, nr, arg); out: spin_lock_irq(&md->lock); @@ -386,9 +403,28 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq, else arg = MMC_SECURE_ERASE_ARG; + if (card->quirks & MMC_QUIRK_INAND_CMD38) { + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, + INAND_CMD38_ARG_EXT_CSD, + arg == MMC_SECURE_TRIM1_ARG ? + INAND_CMD38_ARG_SECTRIM1 : + INAND_CMD38_ARG_SECERASE, + 0); + if (err) + goto out; + } err = mmc_erase(card, from, nr, arg); - if (!err && arg == MMC_SECURE_TRIM1_ARG) + if (!err && arg == MMC_SECURE_TRIM1_ARG) { + if (card->quirks & MMC_QUIRK_INAND_CMD38) { + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, + INAND_CMD38_ARG_EXT_CSD, + INAND_CMD38_ARG_SECTRIM2, + 0); + if (err) + goto out; + } err = mmc_erase(card, from, nr, MMC_SECURE_TRIM2_ARG); + } out: spin_lock_irq(&md->lock); __blk_end_request(req, err, blk_rq_bytes(req)); @@ -941,6 +977,11 @@ static int mmc_add_disk(struct mmc_blk_data *md) static const struct mmc_fixup blk_fixups[] = { + MMC_FIXUP("SEM02G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38), + MMC_FIXUP("SEM04G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38), + MMC_FIXUP("SEM08G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38), + MMC_FIXUP("SEM16G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38), + MMC_FIXUP("SEM32G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38), END_FIXUP }; diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 0c7a58b14343..72a98681ef47 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -133,6 +133,7 @@ struct mmc_card { #define MMC_QUIRK_BROKEN_CLK_GATING (1<<3) /* clock gating the sdio bus will make card fail */ #define MMC_QUIRK_NONSTD_FUNC_IF (1<<4) /* SDIO card has nonstd function interfaces */ #define MMC_QUIRK_DISABLE_CD (1<<5) /* disconnect CD/DAT[3] resistor */ +#define MMC_QUIRK_INAND_CMD38 (1<<6) /* iNAND devices have broken CMD38 */ unsigned int erase_size; /* erase size in sectors */ unsigned int erase_shift; /* if erase unit is power 2 */ -- cgit From 82b0e23a295cc58d1290017ee97a40956ad68d94 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 21 Apr 2011 20:26:38 +0200 Subject: mmc: sdhci: Fix read-only detection with JMicron 388 chip On HP laptops with JMicron 388 chip, the write-locked SD card isn't detected correctly as read-only in many cases. This is because the PRESENT_STATE register becomes unsable just after plugging, and it returns the WRITE_PROTECT bit wrongly at the first read. This patch fixes the read-only detection by adding a new sdhci quirk indicating to check the register more intensively with a relatively long delay. The patch is tested with 2.6.39-rc4 kernel. Cc: Aries Lee Signed-off-by: Takashi Iwai Signed-off-by: Chris Ball --- drivers/mmc/host/sdhci-pci.c | 5 +++++ drivers/mmc/host/sdhci.c | 28 ++++++++++++++++++++++++---- include/linux/mmc/sdhci.h | 2 ++ 3 files changed, 31 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 82c5dc412679..936bbca19c0a 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c @@ -327,6 +327,11 @@ static int jmicron_probe(struct sdhci_pci_chip *chip) return ret; } + /* quirk for unsable RO-detection on JM388 chips */ + if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_SD || + chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD) + chip->quirks |= SDHCI_QUIRK_UNSTABLE_RO_DETECT; + return 0; } diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index a70a3d1ef35a..e5cfe70dc23b 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1256,14 +1256,11 @@ out: spin_unlock_irqrestore(&host->lock, flags); } -static int sdhci_get_ro(struct mmc_host *mmc) +static int check_ro(struct sdhci_host *host) { - struct sdhci_host *host; unsigned long flags; int is_readonly; - host = mmc_priv(mmc); - spin_lock_irqsave(&host->lock, flags); if (host->flags & SDHCI_DEVICE_DEAD) @@ -1281,6 +1278,29 @@ static int sdhci_get_ro(struct mmc_host *mmc) !is_readonly : is_readonly; } +#define SAMPLE_COUNT 5 + +static int sdhci_get_ro(struct mmc_host *mmc) +{ + struct sdhci_host *host; + int i, ro_count; + + host = mmc_priv(mmc); + + if (!(host->quirks & SDHCI_QUIRK_UNSTABLE_RO_DETECT)) + return check_ro(host); + + ro_count = 0; + for (i = 0; i < SAMPLE_COUNT; i++) { + if (check_ro(host)) { + if (++ro_count > SAMPLE_COUNT / 2) + return 1; + } + msleep(30); + } + return 0; +} + static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable) { struct sdhci_host *host; diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h index 83bd9f76709a..92e1c9ad126c 100644 --- a/include/linux/mmc/sdhci.h +++ b/include/linux/mmc/sdhci.h @@ -85,6 +85,8 @@ struct sdhci_host { #define SDHCI_QUIRK_NO_HISPD_BIT (1<<29) /* Controller treats ADMA descriptors with length 0000h incorrectly */ #define SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC (1<<30) +/* The read-only detection via SDHCI_PRESENT_STATE register is unstable */ +#define SDHCI_QUIRK_UNSTABLE_RO_DETECT (1<<31) int irq; /* Device IRQ */ void __iomem *ioaddr; /* Mapped address */ -- cgit From cb87ea28ed9e75a41eb456bfcb547b4e6f10e750 Mon Sep 17 00:00:00 2001 From: John Calixto Date: Tue, 26 Apr 2011 18:56:29 -0400 Subject: mmc: core: Add mmc CMD+ACMD passthrough ioctl Allows appropriately-privileged applications to send CMD (normal) and ACMD (application-specific; preceded with CMD55) commands to cards/devices on the mmc bus. This is primarily useful for enabling the security functionality built in to every SD card. It can also be used as a generic passthrough (e.g. to enable virtual machines to control mmc bus devices directly). However, this use case has not been tested rigorously. Generic passthrough testing was only conducted for a few non-security opcodes to prove the feasibility of the passthrough. Since any opcode can be sent using this passthrough, it is very possible to render the card/device unusable. Applications that use this ioctl must have CAP_SYS_RAWIO. Security commands tested on TI PCIxx12 (SDHCI), Sigma Designs SMP8652 SoC, TI OMAP3621/OMAP3630 SoC, Samsung S5PC110 SoC, Qualcomm MSM7200A SoC. Signed-off-by: John Calixto Reviewed-by: Andrei Warkentin Reviewed-by: Arnd Bergmann Signed-off-by: Chris Ball --- Documentation/ioctl/ioctl-number.txt | 1 + drivers/mmc/card/block.c | 201 +++++++++++++++++++++++++++++++++++ drivers/mmc/core/sd_ops.c | 3 +- include/linux/Kbuild | 1 + include/linux/mmc/Kbuild | 1 + include/linux/mmc/core.h | 1 + include/linux/mmc/ioctl.h | 54 ++++++++++ 7 files changed, 261 insertions(+), 1 deletion(-) create mode 100644 include/linux/mmc/Kbuild create mode 100644 include/linux/mmc/ioctl.h (limited to 'include/linux') diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt index a0a5d82b6b0b..2a34d822e6d6 100644 --- a/Documentation/ioctl/ioctl-number.txt +++ b/Documentation/ioctl/ioctl-number.txt @@ -304,6 +304,7 @@ Code Seq#(hex) Include File Comments 0xB0 all RATIO devices in development: 0xB1 00-1F PPPoX +0xB3 00 linux/mmc/ioctl.h 0xC0 00-0F linux/usb/iowarrior.h 0xCB 00-1F CBM serial IEC bus in development: diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index e7efd6faeaf9..407836d55712 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -31,7 +31,11 @@ #include #include #include +#include +#include +#include +#include #include #include #include @@ -218,11 +222,208 @@ mmc_blk_getgeo(struct block_device *bdev, struct hd_geometry *geo) return 0; } +struct mmc_blk_ioc_data { + struct mmc_ioc_cmd ic; + unsigned char *buf; + u64 buf_bytes; +}; + +static struct mmc_blk_ioc_data *mmc_blk_ioctl_copy_from_user( + struct mmc_ioc_cmd __user *user) +{ + struct mmc_blk_ioc_data *idata; + int err; + + idata = kzalloc(sizeof(*idata), GFP_KERNEL); + if (!idata) { + err = -ENOMEM; + goto copy_err; + } + + if (copy_from_user(&idata->ic, user, sizeof(idata->ic))) { + err = -EFAULT; + goto copy_err; + } + + idata->buf_bytes = (u64) idata->ic.blksz * idata->ic.blocks; + if (idata->buf_bytes > MMC_IOC_MAX_BYTES) { + err = -EOVERFLOW; + goto copy_err; + } + + idata->buf = kzalloc(idata->buf_bytes, GFP_KERNEL); + if (!idata->buf) { + err = -ENOMEM; + goto copy_err; + } + + if (copy_from_user(idata->buf, (void __user *)(unsigned long) + idata->ic.data_ptr, idata->buf_bytes)) { + err = -EFAULT; + goto copy_err; + } + + return idata; + +copy_err: + kfree(idata->buf); + kfree(idata); + return ERR_PTR(err); + +} + +static int mmc_blk_ioctl_cmd(struct block_device *bdev, + struct mmc_ioc_cmd __user *ic_ptr) +{ + struct mmc_blk_ioc_data *idata; + struct mmc_blk_data *md; + struct mmc_card *card; + struct mmc_command cmd = {0}; + struct mmc_data data = {0}; + struct mmc_request mrq = {0}; + struct scatterlist sg; + int err; + + /* + * The caller must have CAP_SYS_RAWIO, and must be calling this on the + * whole block device, not on a partition. This prevents overspray + * between sibling partitions. + */ + if ((!capable(CAP_SYS_RAWIO)) || (bdev != bdev->bd_contains)) + return -EPERM; + + idata = mmc_blk_ioctl_copy_from_user(ic_ptr); + if (IS_ERR(idata)) + return PTR_ERR(idata); + + cmd.opcode = idata->ic.opcode; + cmd.arg = idata->ic.arg; + cmd.flags = idata->ic.flags; + + data.sg = &sg; + data.sg_len = 1; + data.blksz = idata->ic.blksz; + data.blocks = idata->ic.blocks; + + sg_init_one(data.sg, idata->buf, idata->buf_bytes); + + if (idata->ic.write_flag) + data.flags = MMC_DATA_WRITE; + else + data.flags = MMC_DATA_READ; + + mrq.cmd = &cmd; + mrq.data = &data; + + md = mmc_blk_get(bdev->bd_disk); + if (!md) { + err = -EINVAL; + goto cmd_done; + } + + card = md->queue.card; + if (IS_ERR(card)) { + err = PTR_ERR(card); + goto cmd_done; + } + + mmc_claim_host(card->host); + + if (idata->ic.is_acmd) { + err = mmc_app_cmd(card->host, card); + if (err) + goto cmd_rel_host; + } + + /* data.flags must already be set before doing this. */ + mmc_set_data_timeout(&data, card); + /* Allow overriding the timeout_ns for empirical tuning. */ + if (idata->ic.data_timeout_ns) + data.timeout_ns = idata->ic.data_timeout_ns; + + if ((cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B) { + /* + * Pretend this is a data transfer and rely on the host driver + * to compute timeout. When all host drivers support + * cmd.cmd_timeout for R1B, this can be changed to: + * + * mrq.data = NULL; + * cmd.cmd_timeout = idata->ic.cmd_timeout_ms; + */ + data.timeout_ns = idata->ic.cmd_timeout_ms * 1000000; + } + + mmc_wait_for_req(card->host, &mrq); + + if (cmd.error) { + dev_err(mmc_dev(card->host), "%s: cmd error %d\n", + __func__, cmd.error); + err = cmd.error; + goto cmd_rel_host; + } + if (data.error) { + dev_err(mmc_dev(card->host), "%s: data error %d\n", + __func__, data.error); + err = data.error; + goto cmd_rel_host; + } + + /* + * According to the SD specs, some commands require a delay after + * issuing the command. + */ + if (idata->ic.postsleep_min_us) + usleep_range(idata->ic.postsleep_min_us, idata->ic.postsleep_max_us); + + if (copy_to_user(&(ic_ptr->response), cmd.resp, sizeof(cmd.resp))) { + err = -EFAULT; + goto cmd_rel_host; + } + + if (!idata->ic.write_flag) { + if (copy_to_user((void __user *)(unsigned long) idata->ic.data_ptr, + idata->buf, idata->buf_bytes)) { + err = -EFAULT; + goto cmd_rel_host; + } + } + +cmd_rel_host: + mmc_release_host(card->host); + +cmd_done: + mmc_blk_put(md); + kfree(idata->buf); + kfree(idata); + return err; +} + +static int mmc_blk_ioctl(struct block_device *bdev, fmode_t mode, + unsigned int cmd, unsigned long arg) +{ + int ret = -EINVAL; + if (cmd == MMC_IOC_CMD) + ret = mmc_blk_ioctl_cmd(bdev, (struct mmc_ioc_cmd __user *)arg); + return ret; +} + +#ifdef CONFIG_COMPAT +static int mmc_blk_compat_ioctl(struct block_device *bdev, fmode_t mode, + unsigned int cmd, unsigned long arg) +{ + return mmc_blk_ioctl(bdev, mode, cmd, (unsigned long) compat_ptr(arg)); +} +#endif + static const struct block_device_operations mmc_bdops = { .open = mmc_blk_open, .release = mmc_blk_release, .getgeo = mmc_blk_getgeo, .owner = THIS_MODULE, + .ioctl = mmc_blk_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = mmc_blk_compat_ioctl, +#endif }; struct mmc_blk_request { diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c index a206aea5360d..021fed153804 100644 --- a/drivers/mmc/core/sd_ops.c +++ b/drivers/mmc/core/sd_ops.c @@ -21,7 +21,7 @@ #include "core.h" #include "sd_ops.h" -static int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card) +int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card) { int err; struct mmc_command cmd = {0}; @@ -49,6 +49,7 @@ static int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card) return 0; } +EXPORT_SYMBOL_GPL(mmc_app_cmd); /** * mmc_wait_for_app_cmd - start an application command and wait for diff --git a/include/linux/Kbuild b/include/linux/Kbuild index 75cf611641e6..ed38527599ee 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild @@ -4,6 +4,7 @@ header-y += caif/ header-y += dvb/ header-y += hdlc/ header-y += isdn/ +header-y += mmc/ header-y += nfsd/ header-y += raid/ header-y += spi/ diff --git a/include/linux/mmc/Kbuild b/include/linux/mmc/Kbuild new file mode 100644 index 000000000000..1fb26448faa9 --- /dev/null +++ b/include/linux/mmc/Kbuild @@ -0,0 +1 @@ +header-y += ioctl.h diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index f8e4bcbd2846..cbe8d55f64c4 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -133,6 +133,7 @@ struct mmc_card; extern void mmc_wait_for_req(struct mmc_host *, struct mmc_request *); extern int mmc_wait_for_cmd(struct mmc_host *, struct mmc_command *, int); +extern int mmc_app_cmd(struct mmc_host *, struct mmc_card *); extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *, struct mmc_command *, int); extern int mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int); diff --git a/include/linux/mmc/ioctl.h b/include/linux/mmc/ioctl.h new file mode 100644 index 000000000000..5baf2983a12f --- /dev/null +++ b/include/linux/mmc/ioctl.h @@ -0,0 +1,54 @@ +#ifndef LINUX_MMC_IOCTL_H +#define LINUX_MMC_IOCTL_H +struct mmc_ioc_cmd { + /* Implies direction of data. true = write, false = read */ + int write_flag; + + /* Application-specific command. true = precede with CMD55 */ + int is_acmd; + + __u32 opcode; + __u32 arg; + __u32 response[4]; /* CMD response */ + unsigned int flags; + unsigned int blksz; + unsigned int blocks; + + /* + * Sleep at least postsleep_min_us useconds, and at most + * postsleep_max_us useconds *after* issuing command. Needed for + * some read commands for which cards have no other way of indicating + * they're ready for the next command (i.e. there is no equivalent of + * a "busy" indicator for read operations). + */ + unsigned int postsleep_min_us; + unsigned int postsleep_max_us; + + /* + * Override driver-computed timeouts. Note the difference in units! + */ + unsigned int data_timeout_ns; + unsigned int cmd_timeout_ms; + + /* + * For 64-bit machines, the next member, ``__u64 data_ptr``, wants to + * be 8-byte aligned. Make sure this struct is the same size when + * built for 32-bit. + */ + __u32 __pad; + + /* DAT buffer */ + __u64 data_ptr; +}; +#define mmc_ioc_cmd_set_data(ic, ptr) ic.data_ptr = (__u64)(unsigned long) ptr + +#define MMC_IOC_CMD _IOWR(MMC_BLOCK_MAJOR, 0, struct mmc_ioc_cmd) + +/* + * Since this ioctl is only meant to enhance (and not replace) normal access + * to the mmc bus device, an upper data transfer limit of MMC_IOC_MAX_BYTES + * is enforced per ioctl call. For larger data transfers, use the normal + * block device operations. + */ +#define MMC_IOC_MAX_BYTES (512L * 256) +#endif /* LINUX_MMC_IOCTL_H */ -- cgit From f2119df6b764609af4baceb68caf1e848c1c8aa7 Mon Sep 17 00:00:00 2001 From: Arindam Nath Date: Thu, 5 May 2011 12:18:57 +0530 Subject: mmc: sd: add support for signal voltage switch procedure Host Controller v3.00 adds another Capabilities register. Apart from other things, this new register indicates whether the Host Controller supports SDR50, SDR104, and DDR50 UHS-I modes. The spec doesn't mention about explicit support for SDR12 and SDR25 UHS-I modes, so the Host Controller v3.00 should support them by default. Also if the controller supports SDR104 mode, it will also support SDR50 mode as well. So depending on the host support, we set the corresponding MMC_CAP_* flags. One more new register. Host Control2 is added in v3.00, which is used during Signal Voltage Switch procedure described below. Since as per v3.00 spec, UHS-I supported hosts should set S18R to 1, we set S18R (bit 24) of OCR before sending ACMD41. We also need to set XPC (bit 28) of OCR in case the host can supply >150mA. This support is indicated by the Maximum Current Capabilities register of the Host Controller. If the response of ACMD41 has both CCS and S18A set, we start the signal voltage switch procedure, which if successfull, will switch the card from 3.3V signalling to 1.8V signalling. Signal voltage switch procedure adds support for a new command CMD11 in the Physical Layer Spec v3.01. As part of this procedure, we need to set 1.8V Signalling Enable (bit 3) of Host Control2 register, which if remains set after 5ms, means the switch to 1.8V signalling is successfull. Otherwise, we clear bit 24 of OCR and retry the initialization sequence. When we remove the card, and insert the same or another card, we need to make sure that we start with 3.3V signalling voltage. So we call mmc_set_signal_voltage() with MMC_SIGNAL_VOLTAGE_330 set so that we are back to 3.3V signalling voltage before we actually start initializing the card. Tested by Zhangfei Gao with a Toshiba uhs card and general hs card, on mmp2 in SDMA mode. Signed-off-by: Arindam Nath Reviewed-by: Philip Rakity Tested-by: Philip Rakity Acked-by: Zhangfei Gao Signed-off-by: Chris Ball --- drivers/mmc/core/core.c | 32 ++++++++ drivers/mmc/core/core.h | 1 + drivers/mmc/core/sd.c | 36 ++++++++- drivers/mmc/host/sdhci.c | 192 +++++++++++++++++++++++++++++++++++++++++++---- drivers/mmc/host/sdhci.h | 18 ++++- include/linux/mmc/host.h | 15 ++++ include/linux/mmc/sd.h | 7 ++ 7 files changed, 284 insertions(+), 17 deletions(-) (limited to 'include/linux') diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 1dbc18576219..5005a6323165 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -942,6 +942,38 @@ u32 mmc_select_voltage(struct mmc_host *host, u32 ocr) return ocr; } +int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage) +{ + struct mmc_command cmd = {0}; + int err = 0; + + BUG_ON(!host); + + /* + * Send CMD11 only if the request is to switch the card to + * 1.8V signalling. + */ + if (signal_voltage == MMC_SIGNAL_VOLTAGE_180) { + cmd.opcode = SD_SWITCH_VOLTAGE; + cmd.arg = 0; + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; + + err = mmc_wait_for_cmd(host, &cmd, 0); + if (err) + return err; + + if (!mmc_host_is_spi(host) && (cmd.resp[0] & R1_ERROR)) + return -EIO; + } + + host->ios.signal_voltage = signal_voltage; + + if (host->ops->start_signal_voltage_switch) + err = host->ops->start_signal_voltage_switch(host, &host->ios); + + return err; +} + /* * Select timing parameters for host. */ diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index ca1fdde29df6..7745dea430b8 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h @@ -41,6 +41,7 @@ void mmc_set_bus_width(struct mmc_host *host, unsigned int width); void mmc_set_bus_width_ddr(struct mmc_host *host, unsigned int width, unsigned int ddr); u32 mmc_select_voltage(struct mmc_host *host, u32 ocr); +int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage); void mmc_set_timing(struct mmc_host *host, unsigned int timing); static inline void mmc_delay(unsigned int ms) diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 6dac89fe0535..b0cd285d272a 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -403,6 +403,7 @@ struct device_type sd_type = { int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid) { int err; + u32 rocr; /* * Since we're changing the OCR value, we seem to @@ -420,12 +421,38 @@ int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid) */ err = mmc_send_if_cond(host, ocr); if (!err) - ocr |= 1 << 30; + ocr |= SD_OCR_CCS; - err = mmc_send_app_op_cond(host, ocr, NULL); + /* + * If the host supports one of UHS-I modes, request the card + * to switch to 1.8V signaling level. + */ + if (host->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | + MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_DDR50)) + ocr |= SD_OCR_S18R; + + /* If the host can supply more than 150mA, XPC should be set to 1. */ + if (host->caps & (MMC_CAP_SET_XPC_330 | MMC_CAP_SET_XPC_300 | + MMC_CAP_SET_XPC_180)) + ocr |= SD_OCR_XPC; + +try_again: + err = mmc_send_app_op_cond(host, ocr, &rocr); if (err) return err; + /* + * In case CCS and S18A in the response is set, start Signal Voltage + * Switch procedure. SPI mode doesn't support CMD11. + */ + if (!mmc_host_is_spi(host) && ((rocr & 0x41000000) == 0x41000000)) { + err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180); + if (err) { + ocr &= ~SD_OCR_S18R; + goto try_again; + } + } + if (mmc_host_is_spi(host)) err = mmc_send_cid(host, cid); else @@ -773,6 +800,11 @@ int mmc_attach_sd(struct mmc_host *host) BUG_ON(!host); WARN_ON(!host->claimed); + /* Make sure we are at 3.3V signalling voltage */ + err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330); + if (err) + return err; + err = mmc_send_app_op_cond(host, 0, &ocr); if (err) return err; diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index e5cfe70dc23b..4e2031449a23 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -83,6 +83,8 @@ static void sdhci_dumpregs(struct sdhci_host *host) printk(KERN_DEBUG DRIVER_NAME ": Cmd: 0x%08x | Max curr: 0x%08x\n", sdhci_readw(host, SDHCI_COMMAND), sdhci_readl(host, SDHCI_MAX_CURRENT)); + printk(KERN_DEBUG DRIVER_NAME ": Host ctl2: 0x%08x\n", + sdhci_readw(host, SDHCI_HOST_CONTROL2)); if (host->flags & SDHCI_USE_ADMA) printk(KERN_DEBUG DRIVER_NAME ": ADMA Err: 0x%08x | ADMA Ptr: 0x%08x\n", @@ -1323,11 +1325,114 @@ out: spin_unlock_irqrestore(&host->lock, flags); } +static int sdhci_start_signal_voltage_switch(struct mmc_host *mmc, + struct mmc_ios *ios) +{ + struct sdhci_host *host; + u8 pwr; + u16 clk, ctrl; + u32 present_state; + + host = mmc_priv(mmc); + + /* + * Signal Voltage Switching is only applicable for Host Controllers + * v3.00 and above. + */ + if (host->version < SDHCI_SPEC_300) + return 0; + + /* + * We first check whether the request is to set signalling voltage + * to 3.3V. If so, we change the voltage to 3.3V and return quickly. + */ + ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); + if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) { + /* Set 1.8V Signal Enable in the Host Control2 register to 0 */ + ctrl &= ~SDHCI_CTRL_VDD_180; + sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); + + /* Wait for 5ms */ + usleep_range(5000, 5500); + + /* 3.3V regulator output should be stable within 5 ms */ + ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); + if (!(ctrl & SDHCI_CTRL_VDD_180)) + return 0; + else { + printk(KERN_INFO DRIVER_NAME ": Switching to 3.3V " + "signalling voltage failed\n"); + return -EIO; + } + } else if (!(ctrl & SDHCI_CTRL_VDD_180) && + (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180)) { + /* Stop SDCLK */ + clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); + clk &= ~SDHCI_CLOCK_CARD_EN; + sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); + + /* Check whether DAT[3:0] is 0000 */ + present_state = sdhci_readl(host, SDHCI_PRESENT_STATE); + if (!((present_state & SDHCI_DATA_LVL_MASK) >> + SDHCI_DATA_LVL_SHIFT)) { + /* + * Enable 1.8V Signal Enable in the Host Control2 + * register + */ + ctrl |= SDHCI_CTRL_VDD_180; + sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); + + /* Wait for 5ms */ + usleep_range(5000, 5500); + + ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); + if (ctrl & SDHCI_CTRL_VDD_180) { + /* Provide SDCLK again and wait for 1ms*/ + clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); + clk |= SDHCI_CLOCK_CARD_EN; + sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); + usleep_range(1000, 1500); + + /* + * If DAT[3:0] level is 1111b, then the card + * was successfully switched to 1.8V signaling. + */ + present_state = sdhci_readl(host, + SDHCI_PRESENT_STATE); + if ((present_state & SDHCI_DATA_LVL_MASK) == + SDHCI_DATA_LVL_MASK) + return 0; + } + } + + /* + * If we are here, that means the switch to 1.8V signaling + * failed. We power cycle the card, and retry initialization + * sequence by setting S18R to 0. + */ + pwr = sdhci_readb(host, SDHCI_POWER_CONTROL); + pwr &= ~SDHCI_POWER_ON; + sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); + + /* Wait for 1ms as per the spec */ + usleep_range(1000, 1500); + pwr |= SDHCI_POWER_ON; + sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); + + printk(KERN_INFO DRIVER_NAME ": Switching to 1.8V signalling " + "voltage failed, retrying with S18R set to 0\n"); + return -EAGAIN; + } else + /* No signal voltage switch required */ + return 0; +} + static const struct mmc_host_ops sdhci_ops = { .request = sdhci_request, .set_ios = sdhci_set_ios, .get_ro = sdhci_get_ro, .enable_sdio_irq = sdhci_enable_sdio_irq, + .start_signal_voltage_switch = sdhci_start_signal_voltage_switch, }; /*****************************************************************************\ @@ -1808,7 +1913,9 @@ EXPORT_SYMBOL_GPL(sdhci_alloc_host); int sdhci_add_host(struct sdhci_host *host) { struct mmc_host *mmc; - unsigned int caps, ocr_avail; + u32 caps[2]; + u32 max_current_caps; + unsigned int ocr_avail; int ret; WARN_ON(host == NULL); @@ -1831,12 +1938,15 @@ int sdhci_add_host(struct sdhci_host *host) host->version); } - caps = (host->quirks & SDHCI_QUIRK_MISSING_CAPS) ? host->caps : + caps[0] = (host->quirks & SDHCI_QUIRK_MISSING_CAPS) ? host->caps : sdhci_readl(host, SDHCI_CAPABILITIES); + caps[1] = (host->version >= SDHCI_SPEC_300) ? + sdhci_readl(host, SDHCI_CAPABILITIES_1) : 0; + if (host->quirks & SDHCI_QUIRK_FORCE_DMA) host->flags |= SDHCI_USE_SDMA; - else if (!(caps & SDHCI_CAN_DO_SDMA)) + else if (!(caps[0] & SDHCI_CAN_DO_SDMA)) DBG("Controller doesn't have SDMA capability\n"); else host->flags |= SDHCI_USE_SDMA; @@ -1847,7 +1957,8 @@ int sdhci_add_host(struct sdhci_host *host) host->flags &= ~SDHCI_USE_SDMA; } - if ((host->version >= SDHCI_SPEC_200) && (caps & SDHCI_CAN_DO_ADMA2)) + if ((host->version >= SDHCI_SPEC_200) && + (caps[0] & SDHCI_CAN_DO_ADMA2)) host->flags |= SDHCI_USE_ADMA; if ((host->quirks & SDHCI_QUIRK_BROKEN_ADMA) && @@ -1897,10 +2008,10 @@ int sdhci_add_host(struct sdhci_host *host) } if (host->version >= SDHCI_SPEC_300) - host->max_clk = (caps & SDHCI_CLOCK_V3_BASE_MASK) + host->max_clk = (caps[0] & SDHCI_CLOCK_V3_BASE_MASK) >> SDHCI_CLOCK_BASE_SHIFT; else - host->max_clk = (caps & SDHCI_CLOCK_BASE_MASK) + host->max_clk = (caps[0] & SDHCI_CLOCK_BASE_MASK) >> SDHCI_CLOCK_BASE_SHIFT; host->max_clk *= 1000000; @@ -1916,7 +2027,7 @@ int sdhci_add_host(struct sdhci_host *host) } host->timeout_clk = - (caps & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT; + (caps[0] & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT; if (host->timeout_clk == 0) { if (host->ops->get_timeout_clock) { host->timeout_clk = host->ops->get_timeout_clock(host); @@ -1928,7 +2039,7 @@ int sdhci_add_host(struct sdhci_host *host) return -ENODEV; } } - if (caps & SDHCI_TIMEOUT_CLK_UNIT) + if (caps[0] & SDHCI_TIMEOUT_CLK_UNIT) host->timeout_clk *= 1000; /* @@ -1955,21 +2066,76 @@ int sdhci_add_host(struct sdhci_host *host) if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA)) mmc->caps |= MMC_CAP_4_BIT_DATA; - if (caps & SDHCI_CAN_DO_HISPD) + if (caps[0] & SDHCI_CAN_DO_HISPD) mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED; if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) && mmc_card_is_removable(mmc)) mmc->caps |= MMC_CAP_NEEDS_POLL; + /* UHS-I mode(s) supported by the host controller. */ + if (host->version >= SDHCI_SPEC_300) + mmc->caps |= MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25; + + /* SDR104 supports also implies SDR50 support */ + if (caps[1] & SDHCI_SUPPORT_SDR104) + mmc->caps |= MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_SDR50; + else if (caps[1] & SDHCI_SUPPORT_SDR50) + mmc->caps |= MMC_CAP_UHS_SDR50; + + if (caps[1] & SDHCI_SUPPORT_DDR50) + mmc->caps |= MMC_CAP_UHS_DDR50; + ocr_avail = 0; - if (caps & SDHCI_CAN_VDD_330) + /* + * According to SD Host Controller spec v3.00, if the Host System + * can afford more than 150mA, Host Driver should set XPC to 1. Also + * the value is meaningful only if Voltage Support in the Capabilities + * register is set. The actual current value is 4 times the register + * value. + */ + max_current_caps = sdhci_readl(host, SDHCI_MAX_CURRENT); + + if (caps[0] & SDHCI_CAN_VDD_330) { + int max_current_330; + ocr_avail |= MMC_VDD_32_33 | MMC_VDD_33_34; - if (caps & SDHCI_CAN_VDD_300) + + max_current_330 = ((max_current_caps & + SDHCI_MAX_CURRENT_330_MASK) >> + SDHCI_MAX_CURRENT_330_SHIFT) * + SDHCI_MAX_CURRENT_MULTIPLIER; + + if (max_current_330 > 150) + mmc->caps |= MMC_CAP_SET_XPC_330; + } + if (caps[0] & SDHCI_CAN_VDD_300) { + int max_current_300; + ocr_avail |= MMC_VDD_29_30 | MMC_VDD_30_31; - if (caps & SDHCI_CAN_VDD_180) + + max_current_300 = ((max_current_caps & + SDHCI_MAX_CURRENT_300_MASK) >> + SDHCI_MAX_CURRENT_300_SHIFT) * + SDHCI_MAX_CURRENT_MULTIPLIER; + + if (max_current_300 > 150) + mmc->caps |= MMC_CAP_SET_XPC_300; + } + if (caps[0] & SDHCI_CAN_VDD_180) { + int max_current_180; + ocr_avail |= MMC_VDD_165_195; + max_current_180 = ((max_current_caps & + SDHCI_MAX_CURRENT_180_MASK) >> + SDHCI_MAX_CURRENT_180_SHIFT) * + SDHCI_MAX_CURRENT_MULTIPLIER; + + if (max_current_180 > 150) + mmc->caps |= MMC_CAP_SET_XPC_180; + } + mmc->ocr_avail = ocr_avail; mmc->ocr_avail_sdio = ocr_avail; if (host->ocr_avail_sdio) @@ -2029,7 +2195,7 @@ int sdhci_add_host(struct sdhci_host *host) if (host->quirks & SDHCI_QUIRK_FORCE_BLK_SZ_2048) { mmc->max_blk_size = 2; } else { - mmc->max_blk_size = (caps & SDHCI_MAX_BLOCK_MASK) >> + mmc->max_blk_size = (caps[0] & SDHCI_MAX_BLOCK_MASK) >> SDHCI_MAX_BLOCK_SHIFT; if (mmc->max_blk_size >= 3) { printk(KERN_WARNING "%s: Invalid maximum block size, " diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index c6e25a76d269..5cba2fea46e0 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -68,6 +68,8 @@ #define SDHCI_DATA_AVAILABLE 0x00000800 #define SDHCI_CARD_PRESENT 0x00010000 #define SDHCI_WRITE_PROTECT 0x00080000 +#define SDHCI_DATA_LVL_MASK 0x00F00000 +#define SDHCI_DATA_LVL_SHIFT 20 #define SDHCI_HOST_CONTROL 0x28 #define SDHCI_CTRL_LED 0x01 @@ -146,7 +148,8 @@ #define SDHCI_ACMD12_ERR 0x3C -/* 3E-3F reserved */ +#define SDHCI_HOST_CONTROL2 0x3E +#define SDHCI_CTRL_VDD_180 0x0008 #define SDHCI_CAPABILITIES 0x40 #define SDHCI_TIMEOUT_CLK_MASK 0x0000003F @@ -167,9 +170,20 @@ #define SDHCI_CAN_VDD_180 0x04000000 #define SDHCI_CAN_64BIT 0x10000000 +#define SDHCI_SUPPORT_SDR50 0x00000001 +#define SDHCI_SUPPORT_SDR104 0x00000002 +#define SDHCI_SUPPORT_DDR50 0x00000004 + #define SDHCI_CAPABILITIES_1 0x44 -#define SDHCI_MAX_CURRENT 0x48 +#define SDHCI_MAX_CURRENT 0x48 +#define SDHCI_MAX_CURRENT_330_MASK 0x0000FF +#define SDHCI_MAX_CURRENT_330_SHIFT 0 +#define SDHCI_MAX_CURRENT_300_MASK 0x00FF00 +#define SDHCI_MAX_CURRENT_300_SHIFT 8 +#define SDHCI_MAX_CURRENT_180_MASK 0xFF0000 +#define SDHCI_MAX_CURRENT_180_SHIFT 16 +#define SDHCI_MAX_CURRENT_MULTIPLIER 4 /* 4C-4F reserved for more max current */ diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 0fffa5cdc183..bde5a0b1c47e 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -56,6 +56,11 @@ struct mmc_ios { #define MMC_SDR_MODE 0 #define MMC_1_2V_DDR_MODE 1 #define MMC_1_8V_DDR_MODE 2 + + unsigned char signal_voltage; /* signalling voltage (1.8V or 3.3V) */ + +#define MMC_SIGNAL_VOLTAGE_330 0 +#define MMC_SIGNAL_VOLTAGE_180 1 }; struct mmc_host_ops { @@ -117,6 +122,8 @@ struct mmc_host_ops { /* optional callback for HC quirks */ void (*init_card)(struct mmc_host *host, struct mmc_card *card); + + int (*start_signal_voltage_switch)(struct mmc_host *host, struct mmc_ios *ios); }; struct mmc_card; @@ -173,6 +180,14 @@ struct mmc_host { /* DDR mode at 1.2V */ #define MMC_CAP_POWER_OFF_CARD (1 << 13) /* Can power off after boot */ #define MMC_CAP_BUS_WIDTH_TEST (1 << 14) /* CMD14/CMD19 bus width ok */ +#define MMC_CAP_UHS_SDR12 (1 << 15) /* Host supports UHS SDR12 mode */ +#define MMC_CAP_UHS_SDR25 (1 << 16) /* Host supports UHS SDR25 mode */ +#define MMC_CAP_UHS_SDR50 (1 << 17) /* Host supports UHS SDR50 mode */ +#define MMC_CAP_UHS_SDR104 (1 << 18) /* Host supports UHS SDR104 mode */ +#define MMC_CAP_UHS_DDR50 (1 << 19) /* Host supports UHS DDR50 mode */ +#define MMC_CAP_SET_XPC_330 (1 << 20) /* Host supports >150mA current at 3.3V */ +#define MMC_CAP_SET_XPC_300 (1 << 21) /* Host supports >150mA current at 3.0V */ +#define MMC_CAP_SET_XPC_180 (1 << 22) /* Host supports >150mA current at 1.8V */ mmc_pm_flag_t pm_caps; /* supported pm features */ diff --git a/include/linux/mmc/sd.h b/include/linux/mmc/sd.h index 3fd85e088cc3..c648878f6734 100644 --- a/include/linux/mmc/sd.h +++ b/include/linux/mmc/sd.h @@ -17,6 +17,7 @@ /* This is basically the same command as for MMC with some quirks. */ #define SD_SEND_RELATIVE_ADDR 3 /* bcr R6 */ #define SD_SEND_IF_COND 8 /* bcr [11:0] See below R7 */ +#define SD_SWITCH_VOLTAGE 11 /* ac R1 */ /* class 10 */ #define SD_SWITCH 6 /* adtc [31:0] See below R1 */ @@ -32,6 +33,12 @@ #define SD_APP_OP_COND 41 /* bcr [31:0] OCR R3 */ #define SD_APP_SEND_SCR 51 /* adtc R1 */ +/* OCR bit definitions */ +#define SD_OCR_S18R (1 << 24) /* 1.8V switching request */ +#define SD_ROCR_S18A SD_OCR_S18R /* 1.8V switching accepted by card */ +#define SD_OCR_XPC (1 << 28) /* SDXC power control */ +#define SD_OCR_CCS (1 << 30) /* Card Capacity Status */ + /* * SD_SWITCH argument format: * -- cgit From 013909c4ffd16ded4895528b856fd8782df04dc6 Mon Sep 17 00:00:00 2001 From: Arindam Nath Date: Thu, 5 May 2011 12:18:58 +0530 Subject: mmc: sd: query function modes for uhs cards SD cards which conform to Physical Layer Spec v3.01 can support additional Bus Speed Modes, Driver Strength, and Current Limit other than the default values. We use CMD6 mode 0 to read these additional card functions. The values read here will be used during UHS-I initialization steps. Tested by Zhangfei Gao with a Toshiba uhs card and general hs card, on mmp2 in SDMA mode. Signed-off-by: Arindam Nath Reviewed-by: Philip Rakity Tested-by: Philip Rakity Acked-by: Zhangfei Gao Signed-off-by: Chris Ball --- drivers/mmc/core/sd.c | 68 +++++++++++++++++++++++++++++++++++++++++------- include/linux/mmc/card.h | 4 +++ 2 files changed, 62 insertions(+), 10 deletions(-) (limited to 'include/linux') diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index b0cd285d272a..8285842f19e9 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -189,6 +189,9 @@ static int mmc_decode_scr(struct mmc_card *card) scr->sda_vsn = UNSTUFF_BITS(resp, 56, 4); scr->bus_widths = UNSTUFF_BITS(resp, 48, 4); + if (scr->sda_vsn == SCR_SPEC_VER_2) + /* Check if Physical Layer Spec v3.0 is supported */ + scr->sda_spec3 = UNSTUFF_BITS(resp, 47, 1); if (UNSTUFF_BITS(resp, 55, 1)) card->erased_byte = 0xFF; @@ -274,29 +277,74 @@ static int mmc_read_switch(struct mmc_card *card) status = kmalloc(64, GFP_KERNEL); if (!status) { printk(KERN_ERR "%s: could not allocate a buffer for " - "switch capabilities.\n", mmc_hostname(card->host)); + "switch capabilities.\n", + mmc_hostname(card->host)); return -ENOMEM; } + /* Find out the supported Bus Speed Modes. */ err = mmc_sd_switch(card, 0, 0, 1, status); if (err) { - /* If the host or the card can't do the switch, - * fail more gracefully. */ - if ((err != -EINVAL) - && (err != -ENOSYS) - && (err != -EFAULT)) + /* + * If the host or the card can't do the switch, + * fail more gracefully. + */ + if (err != -EINVAL && err != -ENOSYS && err != -EFAULT) goto out; - printk(KERN_WARNING "%s: problem reading switch " - "capabilities, performance might suffer.\n", + printk(KERN_WARNING "%s: problem reading Bus Speed modes.\n", mmc_hostname(card->host)); err = 0; goto out; } - if (status[13] & 0x02) - card->sw_caps.hs_max_dtr = 50000000; + if (card->scr.sda_spec3) { + card->sw_caps.sd3_bus_mode = status[13]; + + /* Find out Driver Strengths supported by the card */ + err = mmc_sd_switch(card, 0, 2, 1, status); + if (err) { + /* + * If the host or the card can't do the switch, + * fail more gracefully. + */ + if (err != -EINVAL && err != -ENOSYS && err != -EFAULT) + goto out; + + printk(KERN_WARNING "%s: problem reading " + "Driver Strength.\n", + mmc_hostname(card->host)); + err = 0; + + goto out; + } + + card->sw_caps.sd3_drv_type = status[9]; + + /* Find out Current Limits supported by the card */ + err = mmc_sd_switch(card, 0, 3, 1, status); + if (err) { + /* + * If the host or the card can't do the switch, + * fail more gracefully. + */ + if (err != -EINVAL && err != -ENOSYS && err != -EFAULT) + goto out; + + printk(KERN_WARNING "%s: problem reading " + "Current Limit.\n", + mmc_hostname(card->host)); + err = 0; + + goto out; + } + + card->sw_caps.sd3_curr_limit = status[7]; + } else { + if (status[13] & 0x02) + card->sw_caps.hs_max_dtr = 50000000; + } out: kfree(status); diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 72a98681ef47..56f4d9234a66 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -67,6 +67,7 @@ struct mmc_ext_csd { struct sd_scr { unsigned char sda_vsn; + unsigned char sda_spec3; unsigned char bus_widths; #define SD_SCR_BUS_WIDTH_1 (1<<0) #define SD_SCR_BUS_WIDTH_4 (1<<2) @@ -80,6 +81,9 @@ struct sd_ssr { struct sd_switch_caps { unsigned int hs_max_dtr; + unsigned int sd3_bus_mode; + unsigned int sd3_drv_type; + unsigned int sd3_curr_limit; }; struct sdio_cccr { -- cgit From f5671ab3f67a10f7234de21464391c20c1ef8ebb Mon Sep 17 00:00:00 2001 From: Jamie Iles Date: Mon, 23 May 2011 17:15:46 +0100 Subject: mtd: introduce mtd_device_(un)register() To prepare for the removal of add_mtd_device and add_mtd_partitions(), introduce mtd_device_register(). This will create partitions if they are supplied or register the whole device if there are no partitions. Once all drivers are converted to use mtd_device_register(), add_mtd_device() and add_mtd_partitions() will be made internal only. v2: move kerneldoc to implementation file and fixup some kerneldoc warnings. Artem: tweak comments: remove junk tabs, use dots consistently. Signed-off-by: Jamie Iles Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/mtdcore.c | 45 ++++++++++++++++++++++++++++++++++++++++++ include/linux/mtd/mtd.h | 6 ++++++ include/linux/mtd/partitions.h | 2 +- 3 files changed, 52 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index f3c94006ffe6..9af103bf9218 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -38,6 +38,7 @@ #include #include +#include #include "mtdcore.h" /* @@ -427,6 +428,50 @@ out_error: return ret; } +/** + * mtd_device_register - register an MTD device. + * + * @master: the MTD device to register + * @parts: the partitions to register - only valid if nr_parts > 0 + * @nr_parts: the number of partitions in parts. If zero then the full MTD + * device is registered + * + * Register an MTD device with the system and optionally, a number of + * partitions. If nr_parts is 0 then the whole device is registered, otherwise + * only the partitions are registered. To register both the full device *and* + * the partitions, call mtd_device_register() twice, once with nr_parts == 0 + * and once equal to the number of partitions. + */ +int mtd_device_register(struct mtd_info *master, + const struct mtd_partition *parts, + int nr_parts) +{ + return parts ? add_mtd_partitions(master, parts, nr_parts) : + add_mtd_device(master); +} +EXPORT_SYMBOL_GPL(mtd_device_register); + +/** + * mtd_device_unregister - unregister an existing MTD device. + * + * @master: the MTD device to unregister. This will unregister both the master + * and any partitions if registered. + */ +int mtd_device_unregister(struct mtd_info *master) +{ + int err; + + err = del_mtd_partitions(master); + if (err) + return err; + + if (!device_is_registered(&master->dev)) + return 0; + + return del_mtd_device(master); +} +EXPORT_SYMBOL_GPL(mtd_device_unregister); + /** * register_mtd_user - register a 'user' of MTD devices. * @new: pointer to notifier info structure diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 06b489a7605b..f4b0b27a7bbe 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -325,6 +325,12 @@ static inline uint32_t mtd_mod_by_ws(uint64_t sz, struct mtd_info *mtd) extern int add_mtd_device(struct mtd_info *mtd); extern int del_mtd_device (struct mtd_info *mtd); +struct mtd_partition; + +extern int mtd_device_register(struct mtd_info *master, + const struct mtd_partition *parts, + int nr_parts); +extern int mtd_device_unregister(struct mtd_info *master); extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num); extern int __get_mtd_device(struct mtd_info *mtd); extern void __put_mtd_device(struct mtd_info *mtd); diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h index 4a0a8ba90a72..998a6cf35167 100644 --- a/include/linux/mtd/partitions.h +++ b/include/linux/mtd/partitions.h @@ -16,7 +16,7 @@ * Partition definition structure: * * An array of struct partition is passed along with a MTD object to - * add_mtd_partitions() to create them. + * mtd_device_register() to create them. * * For each partition, these fields are available: * name: string that will be used to label the partition's MTD device. -- cgit From 11b73c8b10e58ae90c12e51be5531007e86a9c66 Mon Sep 17 00:00:00 2001 From: Jamie Iles Date: Mon, 23 May 2011 10:22:44 +0100 Subject: mtd: provide of_mtd_parse_partitions for !CONFIG_MTD_OF_PARTS If we don't have OpenFirmware enabled then provide a stub of_mtd_parse_partitions that returns no partitions so drivers don't need ifdeffery inside. Signed-off-by: Jamie Iles Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- include/linux/mtd/partitions.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h index 998a6cf35167..afe32db14a87 100644 --- a/include/linux/mtd/partitions.h +++ b/include/linux/mtd/partitions.h @@ -73,9 +73,18 @@ extern int parse_mtd_partitions(struct mtd_info *master, const char **types, struct device; struct device_node; +#ifdef CONFIG_MTD_OF_PARTS int __devinit of_mtd_parse_partitions(struct device *dev, struct device_node *node, struct mtd_partition **pparts); +#else +static inline int of_mtd_parse_partitions(struct device *dev, + struct device_node *node, + struct mtd_partition **pparts) +{ + return 0; +} +#endif #ifdef CONFIG_MTD_PARTITIONS static inline int mtd_has_partitions(void) { return 1; } -- cgit From 984e6d8ec5abe0487e4c3c22d233cd6ba8695cda Mon Sep 17 00:00:00 2001 From: Jamie Iles Date: Mon, 23 May 2011 10:22:45 +0100 Subject: mtd: physmap: convert to mtd_device_register() Convert to mtd_device_register() and remove the CONFIG_MTD_PARTITIONS preprocessor conditionals as partitioning is always available. Signed-off-by: Jamie Iles Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/maps/physmap.c | 34 +++++++++------------------------- drivers/mtd/maps/physmap_of.c | 30 ++++-------------------------- include/linux/mtd/physmap.h | 4 ---- 3 files changed, 13 insertions(+), 55 deletions(-) (limited to 'include/linux') diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c index 7522df4f71f1..d2059261ca8b 100644 --- a/drivers/mtd/maps/physmap.c +++ b/drivers/mtd/maps/physmap.c @@ -27,10 +27,8 @@ struct physmap_flash_info { struct mtd_info *mtd[MAX_RESOURCES]; struct mtd_info *cmtd; struct map_info map[MAX_RESOURCES]; -#ifdef CONFIG_MTD_PARTITIONS int nr_parts; struct mtd_partition *parts; -#endif }; static int physmap_flash_remove(struct platform_device *dev) @@ -47,18 +45,9 @@ static int physmap_flash_remove(struct platform_device *dev) physmap_data = dev->dev.platform_data; if (info->cmtd) { -#ifdef CONFIG_MTD_PARTITIONS - if (info->nr_parts || physmap_data->nr_parts) { - del_mtd_partitions(info->cmtd); - - if (info->nr_parts) - kfree(info->parts); - } else { - del_mtd_device(info->cmtd); - } -#else - del_mtd_device(info->cmtd); -#endif + mtd_device_unregister(info->cmtd); + if (info->nr_parts) + kfree(info->parts); if (info->cmtd != info->mtd[0]) mtd_concat_destroy(info->cmtd); } @@ -76,9 +65,7 @@ static const char *rom_probe_types[] = { "qinfo_probe", "map_rom", NULL }; -#ifdef CONFIG_MTD_PARTITIONS static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL }; -#endif static int physmap_flash_probe(struct platform_device *dev) { @@ -164,24 +151,23 @@ static int physmap_flash_probe(struct platform_device *dev) if (err) goto err_out; -#ifdef CONFIG_MTD_PARTITIONS err = parse_mtd_partitions(info->cmtd, part_probe_types, - &info->parts, 0); + &info->parts, 0); if (err > 0) { - add_mtd_partitions(info->cmtd, info->parts, err); + mtd_device_register(info->cmtd, info->parts, err); info->nr_parts = err; return 0; } if (physmap_data->nr_parts) { printk(KERN_NOTICE "Using physmap partition information\n"); - add_mtd_partitions(info->cmtd, physmap_data->parts, - physmap_data->nr_parts); + mtd_device_register(info->cmtd, physmap_data->parts, + physmap_data->nr_parts); return 0; } -#endif - add_mtd_device(info->cmtd); + mtd_device_register(info->cmtd, NULL, 0); + return 0; err_out: @@ -245,14 +231,12 @@ void physmap_configure(unsigned long addr, unsigned long size, physmap_flash_data.set_vpp = set_vpp; } -#ifdef CONFIG_MTD_PARTITIONS void physmap_set_partitions(struct mtd_partition *parts, int num_parts) { physmap_flash_data.nr_parts = num_parts; physmap_flash_data.parts = parts; } #endif -#endif static int __init physmap_init(void) { diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c index c1d33464aee8..d251d1db129b 100644 --- a/drivers/mtd/maps/physmap_of.c +++ b/drivers/mtd/maps/physmap_of.c @@ -34,16 +34,12 @@ struct of_flash_list { struct of_flash { struct mtd_info *cmtd; -#ifdef CONFIG_MTD_PARTITIONS struct mtd_partition *parts; -#endif int list_size; /* number of elements in of_flash_list */ struct of_flash_list list[0]; }; -#ifdef CONFIG_MTD_PARTITIONS #define OF_FLASH_PARTS(info) ((info)->parts) - static int parse_obsolete_partitions(struct platform_device *dev, struct of_flash *info, struct device_node *dp) @@ -89,10 +85,6 @@ static int parse_obsolete_partitions(struct platform_device *dev, return nr_parts; } -#else /* MTD_PARTITIONS */ -#define OF_FLASH_PARTS(info) (0) -#define parse_partitions(info, dev) (0) -#endif /* MTD_PARTITIONS */ static int of_flash_remove(struct platform_device *dev) { @@ -105,17 +97,14 @@ static int of_flash_remove(struct platform_device *dev) dev_set_drvdata(&dev->dev, NULL); if (info->cmtd != info->list[0].mtd) { - del_mtd_device(info->cmtd); + mtd_device_unregister(info->cmtd); mtd_concat_destroy(info->cmtd); } if (info->cmtd) { - if (OF_FLASH_PARTS(info)) { - del_mtd_partitions(info->cmtd); + if (OF_FLASH_PARTS(info)) kfree(OF_FLASH_PARTS(info)); - } else { - del_mtd_device(info->cmtd); - } + mtd_device_unregister(info->cmtd); } for (i = 0; i < info->list_size; i++) { @@ -172,7 +161,6 @@ static struct mtd_info * __devinit obsolete_probe(struct platform_device *dev, } } -#ifdef CONFIG_MTD_PARTITIONS /* When partitions are set we look for a linux,part-probe property which specifies the list of partition probers to use. If none is given then the default is use. These take precedence over other device tree @@ -212,14 +200,11 @@ static void __devinit of_free_probes(const char **probes) if (probes != part_probe_types_def) kfree(probes); } -#endif static struct of_device_id of_flash_match[]; static int __devinit of_flash_probe(struct platform_device *dev) { -#ifdef CONFIG_MTD_PARTITIONS const char **part_probe_types; -#endif const struct of_device_id *match; struct device_node *dp = dev->dev.of_node; struct resource res; @@ -346,7 +331,6 @@ static int __devinit of_flash_probe(struct platform_device *dev) if (err) goto err_out; -#ifdef CONFIG_MTD_PARTITIONS part_probe_types = of_get_probes(dp); err = parse_mtd_partitions(info->cmtd, part_probe_types, &info->parts, 0); @@ -356,13 +340,11 @@ static int __devinit of_flash_probe(struct platform_device *dev) } of_free_probes(part_probe_types); -#ifdef CONFIG_MTD_OF_PARTS if (err == 0) { err = of_mtd_parse_partitions(&dev->dev, dp, &info->parts); if (err < 0) goto err_out; } -#endif if (err == 0) { err = parse_obsolete_partitions(dev, info, dp); @@ -370,11 +352,7 @@ static int __devinit of_flash_probe(struct platform_device *dev) goto err_out; } - if (err > 0) - add_mtd_partitions(info->cmtd, info->parts, err); - else -#endif - add_mtd_device(info->cmtd); + mtd_device_register(info->cmtd, info->parts, err); kfree(mtd_list); diff --git a/include/linux/mtd/physmap.h b/include/linux/mtd/physmap.h index bcfd9f777454..e963b86e296b 100644 --- a/include/linux/mtd/physmap.h +++ b/include/linux/mtd/physmap.h @@ -35,8 +35,6 @@ struct physmap_flash_data { void physmap_configure(unsigned long addr, unsigned long size, int bankwidth, void (*set_vpp)(struct map_info *, int) ); -#ifdef CONFIG_MTD_PARTITIONS - /* * Machines that wish to do flash partition may want to call this function in * their setup routine. @@ -48,6 +46,4 @@ void physmap_configure(unsigned long addr, unsigned long size, */ void physmap_set_partitions(struct mtd_partition *parts, int num_parts); -#endif /* defined(CONFIG_MTD_PARTITIONS) */ - #endif /* __LINUX_MTD_PHYSMAP__ */ -- cgit From eea72d5fdf59879edb2c6639b0b7cc385e0df646 Mon Sep 17 00:00:00 2001 From: Jamie Iles Date: Mon, 23 May 2011 10:23:42 +0100 Subject: mtd: remove add_mtd_partitions, add_mtd_device and friends These symbols are replaced with mtd_device_register() (and removal with mtd_device_unregister()) for public registration. Signed-off-by: Jamie Iles Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/mtdcore.c | 4 +--- drivers/mtd/mtdcore.h | 6 ++++++ drivers/mtd/mtdpart.c | 4 ++-- include/linux/mtd/mtd.h | 3 --- include/linux/mtd/partitions.h | 9 --------- 5 files changed, 9 insertions(+), 17 deletions(-) (limited to 'include/linux') diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 9af103bf9218..c510aff289a8 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -393,7 +393,7 @@ fail_locked: * if the requested device does not appear to be present in the list. */ -int del_mtd_device (struct mtd_info *mtd) +int del_mtd_device(struct mtd_info *mtd) { int ret; struct mtd_notifier *not; @@ -723,8 +723,6 @@ void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size) return kmalloc(*size, GFP_KERNEL); } -EXPORT_SYMBOL_GPL(add_mtd_device); -EXPORT_SYMBOL_GPL(del_mtd_device); EXPORT_SYMBOL_GPL(get_mtd_device); EXPORT_SYMBOL_GPL(get_mtd_device_nm); EXPORT_SYMBOL_GPL(__get_mtd_device); diff --git a/drivers/mtd/mtdcore.h b/drivers/mtd/mtdcore.h index 6a64fdebc898..0ed6126b4c1f 100644 --- a/drivers/mtd/mtdcore.h +++ b/drivers/mtd/mtdcore.h @@ -10,6 +10,12 @@ extern struct mutex mtd_table_mutex; extern struct mtd_info *__mtd_next_device(int i); +extern int add_mtd_device(struct mtd_info *mtd); +extern int del_mtd_device(struct mtd_info *mtd); +extern int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, + int); +extern int del_mtd_partitions(struct mtd_info *); + #define mtd_for_each_device(mtd) \ for ((mtd) = __mtd_next_device(0); \ (mtd) != NULL; \ diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index cd631e773a7b..630be3e7da04 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -31,6 +31,8 @@ #include #include +#include "mtdcore.h" + /* Our partition linked list */ static LIST_HEAD(mtd_partitions); static DEFINE_MUTEX(mtd_partitions_mutex); @@ -376,7 +378,6 @@ int del_mtd_partitions(struct mtd_info *master) return err; } -EXPORT_SYMBOL(del_mtd_partitions); static struct mtd_part *allocate_partition(struct mtd_info *master, const struct mtd_partition *part, int partno, @@ -671,7 +672,6 @@ int add_mtd_partitions(struct mtd_info *master, return 0; } -EXPORT_SYMBOL(add_mtd_partitions); static DEFINE_SPINLOCK(part_parser_lock); static LIST_HEAD(part_parsers); diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index f4b0b27a7bbe..1e3887bc105c 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -322,9 +322,6 @@ static inline uint32_t mtd_mod_by_ws(uint64_t sz, struct mtd_info *mtd) /* Kernel-side ioctl definitions */ -extern int add_mtd_device(struct mtd_info *mtd); -extern int del_mtd_device (struct mtd_info *mtd); - struct mtd_partition; extern int mtd_device_register(struct mtd_info *master, diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h index afe32db14a87..3a6f0372fc96 100644 --- a/include/linux/mtd/partitions.h +++ b/include/linux/mtd/partitions.h @@ -49,9 +49,6 @@ struct mtd_partition { struct mtd_info; -int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int); -int del_mtd_partitions(struct mtd_info *); - /* * Functions dealing with the various ways of partitioning the space */ @@ -86,12 +83,6 @@ static inline int of_mtd_parse_partitions(struct device *dev, } #endif -#ifdef CONFIG_MTD_PARTITIONS -static inline int mtd_has_partitions(void) { return 1; } -#else -static inline int mtd_has_partitions(void) { return 0; } -#endif - #ifdef CONFIG_MTD_CMDLINE_PARTS static inline int mtd_has_cmdlinepart(void) { return 1; } #else -- cgit From 6a8a98b22b10f1560d5f90aded4a54234b9b2724 Mon Sep 17 00:00:00 2001 From: Jamie Iles Date: Mon, 23 May 2011 10:23:43 +0100 Subject: mtd: kill CONFIG_MTD_PARTITIONS Now that none of the drivers use CONFIG_MTD_PARTITIONS we can remove it from Kconfig and the last remaining uses. Signed-off-by: Jamie Iles Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- Documentation/DocBook/mtdnand.tmpl | 3 +-- drivers/mtd/Kconfig | 10 +--------- drivers/mtd/Makefile | 3 +-- drivers/mtd/maps/Kconfig | 14 +++++--------- drivers/mtd/mtdchar.c | 5 ----- drivers/mtd/nand/Kconfig | 3 +-- include/linux/mtd/mtd.h | 8 -------- 7 files changed, 9 insertions(+), 37 deletions(-) (limited to 'include/linux') diff --git a/Documentation/DocBook/mtdnand.tmpl b/Documentation/DocBook/mtdnand.tmpl index 6f242d5dee9a..17910e2052ad 100644 --- a/Documentation/DocBook/mtdnand.tmpl +++ b/Documentation/DocBook/mtdnand.tmpl @@ -189,8 +189,7 @@ static void __iomem *baseaddr; Partition defines If you want to divide your device into partitions, then - enable the configuration switch CONFIG_MTD_PARTITIONS and define - a partitioning scheme suitable to your board. + define a partitioning scheme suitable to your board. #define NUM_PARTITIONS 2 diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index 8b61b0cc7b45..62b4fdbb9ad1 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -1,7 +1,6 @@ menuconfig MTD tristate "Memory Technology Device (MTD) support" depends on HAS_IOMEM - select MTD_PARTITIONS help Memory Technology Devices are flash, RAM and similar chips, often used for solid state file systems on embedded devices. This option @@ -34,11 +33,6 @@ config MTD_TESTS should normally be compiled as kernel modules. The modules perform various checks and verifications when loaded. -config MTD_PARTITIONS - bool - -if MTD_PARTITIONS - config MTD_REDBOOT_PARTS tristate "RedBoot partition table parsing" ---help--- @@ -91,7 +85,7 @@ endif # MTD_REDBOOT_PARTS config MTD_CMDLINE_PARTS bool "Command line partition table parsing" - depends on MTD_PARTITIONS = "y" && MTD = "y" + depends on MTD = "y" ---help--- Allow generic configuration of the MTD partition tables via the kernel command line. Multiple flash resources are supported for hardware where @@ -156,8 +150,6 @@ config MTD_AR7_PARTS ---help--- TI AR7 partitioning support -endif # MTD_PARTITIONS - comment "User Modules And Translation Layers" config MTD_CHAR diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile index d578095fb255..39664c4229ff 100644 --- a/drivers/mtd/Makefile +++ b/drivers/mtd/Makefile @@ -4,8 +4,7 @@ # Core functionality. obj-$(CONFIG_MTD) += mtd.o -mtd-y := mtdcore.o mtdsuper.o mtdconcat.o -mtd-$(CONFIG_MTD_PARTITIONS) += mtdpart.o +mtd-y := mtdcore.o mtdsuper.o mtdconcat.o mtdpart.o mtd-$(CONFIG_MTD_OF_PARTS) += ofpart.o obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index 44032433730d..195b9ef3b7ee 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig @@ -82,7 +82,6 @@ config MTD_PHYSMAP_OF config MTD_PMC_MSP_EVM tristate "CFI Flash device mapped on PMC-Sierra MSP" depends on PMC_MSP && MTD_CFI - select MTD_PARTITIONS help This provides a 'mapping' driver which supports the way in which user-programmable flash chips are connected on the @@ -122,7 +121,7 @@ config MTD_SC520CDP config MTD_NETSC520 tristate "CFI Flash device mapped on AMD NetSc520" - depends on X86 && MTD_CFI && MTD_PARTITIONS + depends on X86 && MTD_CFI help This enables access routines for the flash chips on the AMD NetSc520 demonstration board. If you have one of these boards and would like @@ -131,7 +130,6 @@ config MTD_NETSC520 config MTD_TS5500 tristate "JEDEC Flash device mapped on Technologic Systems TS-5500" depends on X86 - select MTD_PARTITIONS select MTD_JEDECPROBE select MTD_CFI_AMDSTD help @@ -149,7 +147,7 @@ config MTD_TS5500 config MTD_SBC_GXX tristate "CFI Flash device mapped on Arcom SBC-GXx boards" - depends on X86 && MTD_CFI_INTELEXT && MTD_PARTITIONS && MTD_COMPLEX_MAPPINGS + depends on X86 && MTD_CFI_INTELEXT && MTD_COMPLEX_MAPPINGS help This provides a driver for the on-board flash of Arcom Control Systems' SBC-GXn family of boards, formerly known as SBC-MediaGX. @@ -246,7 +244,7 @@ config MTD_TSUNAMI config MTD_NETtel tristate "CFI flash device on SnapGear/SecureEdge" - depends on X86 && MTD_PARTITIONS && MTD_JEDECPROBE + depends on X86 && MTD_JEDECPROBE help Support for flash chips on NETtel/SecureEdge/SnapGear boards. @@ -261,7 +259,7 @@ config MTD_BCM963XX config MTD_DILNETPC tristate "CFI Flash device mapped on DIL/Net PC" - depends on X86 && MTD_PARTITIONS && MTD_CFI_INTELEXT && BROKEN + depends on X86 && MTD_CFI_INTELEXT && BROKEN help MTD map driver for SSV DIL/Net PC Boards "DNP" and "ADNP". For details, see @@ -381,7 +379,7 @@ config MTD_IXP2000 config MTD_FORTUNET tristate "CFI Flash device mapped on the FortuNet board" - depends on MTD_CFI && MTD_PARTITIONS && SA1100_FORTUNET + depends on MTD_CFI && SA1100_FORTUNET help This enables access to the Flash on the FortuNet board. If you have such a board, say 'Y'. @@ -479,7 +477,6 @@ config MTD_UCLINUX config MTD_WRSBC8260 tristate "Map driver for WindRiver PowerQUICC II MPC82xx board" depends on (SBC82xx || SBC8560) - select MTD_PARTITIONS select MTD_MAP_BANK_WIDTH_4 select MTD_MAP_BANK_WIDTH_1 select MTD_CFI_I1 @@ -492,7 +489,6 @@ config MTD_WRSBC8260 config MTD_DMV182 tristate "Map driver for Dy-4 SVME/DMV-182 board." depends on DMV182 - select MTD_PARTITIONS select MTD_MAP_BANK_WIDTH_32 select MTD_CFI_I8 select MTD_CFI_AMDSTD diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index f488eabaa7b5..3f92731a5b9e 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -508,7 +508,6 @@ static int shrink_ecclayout(const struct nand_ecclayout *from, return 0; } -#ifdef CONFIG_MTD_PARTITIONS static int mtd_blkpg_ioctl(struct mtd_info *mtd, struct blkpg_ioctl_arg __user *arg) { @@ -544,8 +543,6 @@ static int mtd_blkpg_ioctl(struct mtd_info *mtd, return -EINVAL; } } -#endif - static int mtd_ioctl(struct file *file, u_int cmd, u_long arg) { @@ -937,7 +934,6 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg) break; } -#ifdef CONFIG_MTD_PARTITIONS case BLKPG: { ret = mtd_blkpg_ioctl(mtd, @@ -951,7 +947,6 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg) ret = 0; break; } -#endif default: ret = -ENOTTY; diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 333d23122226..4c3425235adc 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -419,7 +419,6 @@ config MTD_NAND_TMIO config MTD_NAND_NANDSIM tristate "Support for NAND Flash Simulator" - depends on MTD_PARTITIONS help The simulator may simulate various NAND flash chips for the MTD nand layer. @@ -513,7 +512,7 @@ config MTD_NAND_SOCRATES config MTD_NAND_NUC900 tristate "Support for NAND on Nuvoton NUC9xx/w90p910 evaluation boards." - depends on ARCH_W90X900 && MTD_PARTITIONS + depends on ARCH_W90X900 help This enables the driver for the NAND Flash on evaluation board based on w90p910 / NUC9xx. diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 1e3887bc105c..2541fb848daa 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -353,15 +353,7 @@ int default_mtd_readv(struct mtd_info *mtd, struct kvec *vecs, void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size); -#ifdef CONFIG_MTD_PARTITIONS void mtd_erase_callback(struct erase_info *instr); -#else -static inline void mtd_erase_callback(struct erase_info *instr) -{ - if (instr->callback) - instr->callback(instr); -} -#endif /* * Debugging macro and defines -- cgit From d6d50a15a2897d4133d536dd4343b5cf21163db3 Mon Sep 17 00:00:00 2001 From: Arindam Nath Date: Thu, 5 May 2011 12:18:59 +0530 Subject: mmc: sd: add support for driver type selection This patch adds support for setting driver strength during UHS-I initialization procedure. Since UHS-I cards set S18A (bit 24) in response to ACMD41, we use this as a base for UHS-I initialization. We modify the parameter list of mmc_sd_get_cid() so that we can save the ROCR from ACMD41 to check whether bit 24 is set. We decide whether the Host Controller supports A, C, or D driver type depending on the Capabilities register. Driver type B is suported by default. We then set the appropriate driver type for the card using CMD6 mode 1. As per Host Controller spec v3.00, we set driver type for the host only if Preset Value Enable in the Host Control2 register is not set. SDHCI_HOST_CONTROL has been renamed to SDHCI_HOST_CONTROL1 to conform to the spec. Tested by Zhangfei Gao with a Toshiba uhs card and general hs card, on mmp2 in SDMA mode. Signed-off-by: Arindam Nath Reviewed-by: Philip Rakity Tested-by: Philip Rakity Acked-by: Zhangfei Gao Signed-off-by: Chris Ball --- drivers/mmc/core/core.c | 9 +++ drivers/mmc/core/core.h | 1 + drivers/mmc/core/sd.c | 152 +++++++++++++++++++++++++++++++++++++++-------- drivers/mmc/core/sd.h | 2 +- drivers/mmc/core/sdio.c | 4 +- drivers/mmc/host/sdhci.c | 27 +++++++++ drivers/mmc/host/sdhci.h | 11 +++- include/linux/mmc/card.h | 4 ++ include/linux/mmc/host.h | 10 ++++ 9 files changed, 190 insertions(+), 30 deletions(-) (limited to 'include/linux') diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 5005a6323165..61c6c0b8f0e0 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -983,6 +983,15 @@ void mmc_set_timing(struct mmc_host *host, unsigned int timing) mmc_set_ios(host); } +/* + * Select appropriate driver type for host. + */ +void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type) +{ + host->ios.drv_type = drv_type; + mmc_set_ios(host); +} + /* * Apply power to the MMC stack. This is a two-stage process. * First, we enable power to the card without the clock running. diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index 7745dea430b8..93f33973de39 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h @@ -43,6 +43,7 @@ void mmc_set_bus_width_ddr(struct mmc_host *host, unsigned int width, u32 mmc_select_voltage(struct mmc_host *host, u32 ocr); int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage); void mmc_set_timing(struct mmc_host *host, unsigned int timing); +void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type); static inline void mmc_delay(unsigned int ms) { diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 8285842f19e9..5b7c99855635 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -400,6 +400,98 @@ out: return err; } +static int sd_select_driver_type(struct mmc_card *card, u8 *status) +{ + int host_drv_type = 0, card_drv_type = 0; + int err; + + /* + * If the host doesn't support any of the Driver Types A,C or D, + * default Driver Type B is used. + */ + if (!(card->host->caps & (MMC_CAP_DRIVER_TYPE_A | MMC_CAP_DRIVER_TYPE_C + | MMC_CAP_DRIVER_TYPE_D))) + return 0; + + if (card->host->caps & MMC_CAP_DRIVER_TYPE_A) { + host_drv_type = MMC_SET_DRIVER_TYPE_A; + if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_A) + card_drv_type = MMC_SET_DRIVER_TYPE_A; + else if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_B) + card_drv_type = MMC_SET_DRIVER_TYPE_B; + else if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_C) + card_drv_type = MMC_SET_DRIVER_TYPE_C; + } else if (card->host->caps & MMC_CAP_DRIVER_TYPE_C) { + host_drv_type = MMC_SET_DRIVER_TYPE_C; + if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_C) + card_drv_type = MMC_SET_DRIVER_TYPE_C; + } else if (!(card->host->caps & MMC_CAP_DRIVER_TYPE_D)) { + /* + * If we are here, that means only the default driver type + * B is supported by the host. + */ + host_drv_type = MMC_SET_DRIVER_TYPE_B; + if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_B) + card_drv_type = MMC_SET_DRIVER_TYPE_B; + else if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_C) + card_drv_type = MMC_SET_DRIVER_TYPE_C; + } + + err = mmc_sd_switch(card, 1, 2, card_drv_type, status); + if (err) + return err; + + if ((status[15] & 0xF) != card_drv_type) { + printk(KERN_WARNING "%s: Problem setting driver strength!\n", + mmc_hostname(card->host)); + return 0; + } + + mmc_set_driver_type(card->host, host_drv_type); + + return 0; +} + +/* + * UHS-I specific initialization procedure + */ +static int mmc_sd_init_uhs_card(struct mmc_card *card) +{ + int err; + u8 *status; + + if (!card->scr.sda_spec3) + return 0; + + if (!(card->csd.cmdclass & CCC_SWITCH)) + return 0; + + status = kmalloc(64, GFP_KERNEL); + if (!status) { + printk(KERN_ERR "%s: could not allocate a buffer for " + "switch capabilities.\n", mmc_hostname(card->host)); + return -ENOMEM; + } + + /* Set 4-bit bus width */ + if ((card->host->caps & MMC_CAP_4_BIT_DATA) && + (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) { + err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4); + if (err) + goto out; + + mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); + } + + /* Set the driver strength for the card */ + err = sd_select_driver_type(card, status); + +out: + kfree(status); + + return err; +} + MMC_DEV_ATTR(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1], card->raw_cid[2], card->raw_cid[3]); MMC_DEV_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1], @@ -448,10 +540,9 @@ struct device_type sd_type = { /* * Fetch CID from card. */ -int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid) +int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr) { int err; - u32 rocr; /* * Since we're changing the OCR value, we seem to @@ -485,7 +576,7 @@ int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid) ocr |= SD_OCR_XPC; try_again: - err = mmc_send_app_op_cond(host, ocr, &rocr); + err = mmc_send_app_op_cond(host, ocr, rocr); if (err) return err; @@ -493,7 +584,8 @@ try_again: * In case CCS and S18A in the response is set, start Signal Voltage * Switch procedure. SPI mode doesn't support CMD11. */ - if (!mmc_host_is_spi(host) && ((rocr & 0x41000000) == 0x41000000)) { + if (!mmc_host_is_spi(host) && rocr && + ((*rocr & 0x41000000) == 0x41000000)) { err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180); if (err) { ocr &= ~SD_OCR_S18R; @@ -628,11 +720,12 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, struct mmc_card *card; int err; u32 cid[4]; + u32 rocr = 0; BUG_ON(!host); WARN_ON(!host->claimed); - err = mmc_sd_get_cid(host, ocr, cid); + err = mmc_sd_get_cid(host, ocr, cid, &rocr); if (err) return err; @@ -685,30 +778,37 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, if (err) goto free_card; - /* - * Attempt to change to high-speed (if supported) - */ - err = mmc_sd_switch_hs(card); - if (err > 0) - mmc_sd_go_highspeed(card); - else if (err) - goto free_card; - - /* - * Set bus speed. - */ - mmc_set_clock(host, mmc_sd_get_max_clock(card)); - - /* - * Switch to wider bus (if supported). - */ - if ((host->caps & MMC_CAP_4_BIT_DATA) && - (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) { - err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4); + /* Initialization sequence for UHS-I cards */ + if (rocr & SD_ROCR_S18A) { + err = mmc_sd_init_uhs_card(card); if (err) goto free_card; + } else { + /* + * Attempt to change to high-speed (if supported) + */ + err = mmc_sd_switch_hs(card); + if (err > 0) + mmc_sd_go_highspeed(card); + else if (err) + goto free_card; + + /* + * Set bus speed. + */ + mmc_set_clock(host, mmc_sd_get_max_clock(card)); - mmc_set_bus_width(host, MMC_BUS_WIDTH_4); + /* + * Switch to wider bus (if supported). + */ + if ((host->caps & MMC_CAP_4_BIT_DATA) && + (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) { + err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4); + if (err) + goto free_card; + + mmc_set_bus_width(host, MMC_BUS_WIDTH_4); + } } host->card = card; diff --git a/drivers/mmc/core/sd.h b/drivers/mmc/core/sd.h index 3d8800fa7600..4b34b24f3f76 100644 --- a/drivers/mmc/core/sd.h +++ b/drivers/mmc/core/sd.h @@ -5,7 +5,7 @@ extern struct device_type sd_type; -int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid); +int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr); int mmc_sd_get_csd(struct mmc_host *host, struct mmc_card *card); void mmc_decode_cid(struct mmc_card *card); int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card, diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 1e6095961500..4d0c15bfa514 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -369,8 +369,8 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, goto err; } - if (ocr & R4_MEMORY_PRESENT - && mmc_sd_get_cid(host, host->ocr & ocr, card->raw_cid) == 0) { + if ((ocr & R4_MEMORY_PRESENT) && + mmc_sd_get_cid(host, host->ocr & ocr, card->raw_cid, NULL) == 0) { card->type = MMC_TYPE_SD_COMBO; if (oldcard && (oldcard->type != MMC_TYPE_SD_COMBO || diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 4e2031449a23..8072e16d6d46 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1245,6 +1245,25 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); + if (host->version >= SDHCI_SPEC_300) { + u16 ctrl_2; + + ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); + if (!(ctrl_2 & SDHCI_CTRL_PRESET_VAL_ENABLE)) { + /* + * We only need to set Driver Strength if the + * preset value enable is not set. + */ + ctrl_2 &= ~SDHCI_CTRL_DRV_TYPE_MASK; + if (ios->drv_type == MMC_SET_DRIVER_TYPE_A) + ctrl_2 |= SDHCI_CTRL_DRV_TYPE_A; + else if (ios->drv_type == MMC_SET_DRIVER_TYPE_C) + ctrl_2 |= SDHCI_CTRL_DRV_TYPE_C; + + sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); + } + } + /* * Some (ENE) controllers go apeshit on some ios operation, * signalling timeout and CRC errors even on CMD0. Resetting @@ -2086,6 +2105,14 @@ int sdhci_add_host(struct sdhci_host *host) if (caps[1] & SDHCI_SUPPORT_DDR50) mmc->caps |= MMC_CAP_UHS_DDR50; + /* Driver Type(s) (A, C, D) supported by the host */ + if (caps[1] & SDHCI_DRIVER_TYPE_A) + mmc->caps |= MMC_CAP_DRIVER_TYPE_A; + if (caps[1] & SDHCI_DRIVER_TYPE_C) + mmc->caps |= MMC_CAP_DRIVER_TYPE_C; + if (caps[1] & SDHCI_DRIVER_TYPE_D) + mmc->caps |= MMC_CAP_DRIVER_TYPE_D; + ocr_avail = 0; /* * According to SD Host Controller spec v3.00, if the Host System diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 5cba2fea46e0..667bf8874be7 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -71,7 +71,7 @@ #define SDHCI_DATA_LVL_MASK 0x00F00000 #define SDHCI_DATA_LVL_SHIFT 20 -#define SDHCI_HOST_CONTROL 0x28 +#define SDHCI_HOST_CONTROL 0x28 #define SDHCI_CTRL_LED 0x01 #define SDHCI_CTRL_4BITBUS 0x02 #define SDHCI_CTRL_HISPD 0x04 @@ -150,6 +150,12 @@ #define SDHCI_HOST_CONTROL2 0x3E #define SDHCI_CTRL_VDD_180 0x0008 +#define SDHCI_CTRL_DRV_TYPE_MASK 0x0030 +#define SDHCI_CTRL_DRV_TYPE_B 0x0000 +#define SDHCI_CTRL_DRV_TYPE_A 0x0010 +#define SDHCI_CTRL_DRV_TYPE_C 0x0020 +#define SDHCI_CTRL_DRV_TYPE_D 0x0030 +#define SDHCI_CTRL_PRESET_VAL_ENABLE 0x8000 #define SDHCI_CAPABILITIES 0x40 #define SDHCI_TIMEOUT_CLK_MASK 0x0000003F @@ -173,6 +179,9 @@ #define SDHCI_SUPPORT_SDR50 0x00000001 #define SDHCI_SUPPORT_SDR104 0x00000002 #define SDHCI_SUPPORT_DDR50 0x00000004 +#define SDHCI_DRIVER_TYPE_A 0x00000010 +#define SDHCI_DRIVER_TYPE_C 0x00000020 +#define SDHCI_DRIVER_TYPE_D 0x00000040 #define SDHCI_CAPABILITIES_1 0x44 diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 56f4d9234a66..539327260dc1 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -83,6 +83,10 @@ struct sd_switch_caps { unsigned int hs_max_dtr; unsigned int sd3_bus_mode; unsigned int sd3_drv_type; +#define SD_DRIVER_TYPE_B 0x01 +#define SD_DRIVER_TYPE_A 0x02 +#define SD_DRIVER_TYPE_C 0x04 +#define SD_DRIVER_TYPE_D 0x08 unsigned int sd3_curr_limit; }; diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index bde5a0b1c47e..949e4d525989 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -61,6 +61,13 @@ struct mmc_ios { #define MMC_SIGNAL_VOLTAGE_330 0 #define MMC_SIGNAL_VOLTAGE_180 1 + + unsigned char drv_type; /* driver type (A, B, C, D) */ + +#define MMC_SET_DRIVER_TYPE_B 0 +#define MMC_SET_DRIVER_TYPE_A 1 +#define MMC_SET_DRIVER_TYPE_C 2 +#define MMC_SET_DRIVER_TYPE_D 3 }; struct mmc_host_ops { @@ -188,6 +195,9 @@ struct mmc_host { #define MMC_CAP_SET_XPC_330 (1 << 20) /* Host supports >150mA current at 3.3V */ #define MMC_CAP_SET_XPC_300 (1 << 21) /* Host supports >150mA current at 3.0V */ #define MMC_CAP_SET_XPC_180 (1 << 22) /* Host supports >150mA current at 1.8V */ +#define MMC_CAP_DRIVER_TYPE_A (1 << 23) /* Host supports Driver Type A */ +#define MMC_CAP_DRIVER_TYPE_C (1 << 24) /* Host supports Driver Type C */ +#define MMC_CAP_DRIVER_TYPE_D (1 << 25) /* Host supports Driver Type D */ mmc_pm_flag_t pm_caps; /* supported pm features */ -- cgit From 49c468fcf878d2c86e31920cf54aa90c88418a66 Mon Sep 17 00:00:00 2001 From: Arindam Nath Date: Thu, 5 May 2011 12:19:01 +0530 Subject: mmc: sd: add support for uhs bus speed mode selection This patch adds support for setting UHS-I bus speed mode during UHS-I initialization procedure. Since both the host and card can support more than one bus speed, we select the highest speed based on both of their capabilities. First we set the bus speed mode for the card using CMD6 mode 1, and then we program the host controller to support the required speed mode. We also set High Speed Enable in case one of the UHS-I modes is selected. We take care to reset SD clock before setting UHS mode in the Host Control2 register, and then re-enable it as per the Host Controller spec v3.00. We then set the clock frequency for the UHS-I mode selected. Tested by Zhangfei Gao with a Toshiba uhs card and general hs card, on mmp2 in SDMA mode. Signed-off-by: Arindam Nath Reviewed-by: Philip Rakity Tested-by: Philip Rakity Acked-by: Zhangfei Gao Signed-off-by: Chris Ball --- drivers/mmc/core/sd.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++ drivers/mmc/host/sdhci.c | 40 ++++++++++++++++++++++++++--- drivers/mmc/host/sdhci.h | 6 +++++ include/linux/mmc/card.h | 19 ++++++++++++++ include/linux/mmc/host.h | 5 ++++ 5 files changed, 132 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 5b7c99855635..6970b82171f7 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -452,6 +452,66 @@ static int sd_select_driver_type(struct mmc_card *card, u8 *status) return 0; } +static int sd_set_bus_speed_mode(struct mmc_card *card, u8 *status) +{ + unsigned int bus_speed = 0, timing = 0; + int err; + + /* + * If the host doesn't support any of the UHS-I modes, fallback on + * default speed. + */ + if (!(card->host->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | + MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_DDR50))) + return 0; + + if ((card->host->caps & MMC_CAP_UHS_SDR104) && + (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR104)) { + bus_speed = UHS_SDR104_BUS_SPEED; + timing = MMC_TIMING_UHS_SDR104; + card->sw_caps.uhs_max_dtr = UHS_SDR104_MAX_DTR; + } else if ((card->host->caps & MMC_CAP_UHS_DDR50) && + (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_DDR50)) { + bus_speed = UHS_DDR50_BUS_SPEED; + timing = MMC_TIMING_UHS_DDR50; + card->sw_caps.uhs_max_dtr = UHS_DDR50_MAX_DTR; + } else if ((card->host->caps & (MMC_CAP_UHS_SDR104 | + MMC_CAP_UHS_SDR50)) && (card->sw_caps.sd3_bus_mode & + SD_MODE_UHS_SDR50)) { + bus_speed = UHS_SDR50_BUS_SPEED; + timing = MMC_TIMING_UHS_SDR50; + card->sw_caps.uhs_max_dtr = UHS_SDR50_MAX_DTR; + } else if ((card->host->caps & (MMC_CAP_UHS_SDR104 | + MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25)) && + (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR25)) { + bus_speed = UHS_SDR25_BUS_SPEED; + timing = MMC_TIMING_UHS_SDR25; + card->sw_caps.uhs_max_dtr = UHS_SDR25_MAX_DTR; + } else if ((card->host->caps & (MMC_CAP_UHS_SDR104 | + MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25 | + MMC_CAP_UHS_SDR12)) && (card->sw_caps.sd3_bus_mode & + SD_MODE_UHS_SDR12)) { + bus_speed = UHS_SDR12_BUS_SPEED; + timing = MMC_TIMING_UHS_SDR12; + card->sw_caps.uhs_max_dtr = UHS_SDR12_MAX_DTR; + } + + card->sd_bus_speed = bus_speed; + err = mmc_sd_switch(card, 1, 0, bus_speed, status); + if (err) + return err; + + if ((status[16] & 0xF) != bus_speed) + printk(KERN_WARNING "%s: Problem setting bus speed mode!\n", + mmc_hostname(card->host)); + else { + mmc_set_timing(card->host, timing); + mmc_set_clock(card->host, card->sw_caps.uhs_max_dtr); + } + + return 0; +} + /* * UHS-I specific initialization procedure */ @@ -485,6 +545,11 @@ static int mmc_sd_init_uhs_card(struct mmc_card *card) /* Set the driver strength for the card */ err = sd_select_driver_type(card, status); + if (err) + goto out; + + /* Set bus speed mode of the card */ + err = sd_set_bus_speed_mode(card, status); out: kfree(status); diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 409cde5970ae..8994493dd940 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1244,7 +1244,16 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) ctrl &= ~SDHCI_CTRL_HISPD; if (host->version >= SDHCI_SPEC_300) { - u16 ctrl_2; + u16 clk, ctrl_2; + unsigned int clock; + + /* In case of UHS-I modes, set High Speed Enable */ + if ((ios->timing == MMC_TIMING_UHS_SDR50) || + (ios->timing == MMC_TIMING_UHS_SDR104) || + (ios->timing == MMC_TIMING_UHS_DDR50) || + (ios->timing == MMC_TIMING_UHS_SDR25) || + (ios->timing == MMC_TIMING_UHS_SDR12)) + ctrl |= SDHCI_CTRL_HISPD; ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); if (!(ctrl_2 & SDHCI_CTRL_PRESET_VAL_ENABLE)) { @@ -1267,8 +1276,6 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) * need to reset SD Clock Enable before changing High * Speed Enable to avoid generating clock gliches. */ - u16 clk; - unsigned int clock; /* Reset SD Clock Enable */ clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); @@ -1282,6 +1289,33 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) host->clock = 0; sdhci_set_clock(host, clock); } + + ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); + + /* Select Bus Speed Mode for host */ + ctrl_2 &= ~SDHCI_CTRL_UHS_MASK; + if (ios->timing == MMC_TIMING_UHS_SDR12) + ctrl_2 |= SDHCI_CTRL_UHS_SDR12; + else if (ios->timing == MMC_TIMING_UHS_SDR25) + ctrl_2 |= SDHCI_CTRL_UHS_SDR25; + else if (ios->timing == MMC_TIMING_UHS_SDR50) + ctrl_2 |= SDHCI_CTRL_UHS_SDR50; + else if (ios->timing == MMC_TIMING_UHS_SDR104) + ctrl_2 |= SDHCI_CTRL_UHS_SDR104; + else if (ios->timing == MMC_TIMING_UHS_DDR50) + ctrl_2 |= SDHCI_CTRL_UHS_DDR50; + + /* Reset SD Clock Enable */ + clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); + clk &= ~SDHCI_CLOCK_CARD_EN; + sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); + + sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); + + /* Re-enable SD Clock */ + clock = host->clock; + host->clock = 0; + sdhci_set_clock(host, clock); } else sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 667bf8874be7..d96f6afcca1f 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -149,6 +149,12 @@ #define SDHCI_ACMD12_ERR 0x3C #define SDHCI_HOST_CONTROL2 0x3E +#define SDHCI_CTRL_UHS_MASK 0x0007 +#define SDHCI_CTRL_UHS_SDR12 0x0000 +#define SDHCI_CTRL_UHS_SDR25 0x0001 +#define SDHCI_CTRL_UHS_SDR50 0x0002 +#define SDHCI_CTRL_UHS_SDR104 0x0003 +#define SDHCI_CTRL_UHS_DDR50 0x0004 #define SDHCI_CTRL_VDD_180 0x0008 #define SDHCI_CTRL_DRV_TYPE_MASK 0x0030 #define SDHCI_CTRL_DRV_TYPE_B 0x0000 diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 539327260dc1..4ef6ded6347d 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -81,7 +81,24 @@ struct sd_ssr { struct sd_switch_caps { unsigned int hs_max_dtr; + unsigned int uhs_max_dtr; +#define UHS_SDR104_MAX_DTR 208000000 +#define UHS_SDR50_MAX_DTR 100000000 +#define UHS_DDR50_MAX_DTR 50000000 +#define UHS_SDR25_MAX_DTR UHS_DDR50_MAX_DTR +#define UHS_SDR12_MAX_DTR 25000000 unsigned int sd3_bus_mode; +#define UHS_SDR12_BUS_SPEED 0 +#define UHS_SDR25_BUS_SPEED 1 +#define UHS_SDR50_BUS_SPEED 2 +#define UHS_SDR104_BUS_SPEED 3 +#define UHS_DDR50_BUS_SPEED 4 + +#define SD_MODE_UHS_SDR12 (1 << UHS_SDR12_BUS_SPEED) +#define SD_MODE_UHS_SDR25 (1 << UHS_SDR25_BUS_SPEED) +#define SD_MODE_UHS_SDR50 (1 << UHS_SDR50_BUS_SPEED) +#define SD_MODE_UHS_SDR104 (1 << UHS_SDR104_BUS_SPEED) +#define SD_MODE_UHS_DDR50 (1 << UHS_DDR50_BUS_SPEED) unsigned int sd3_drv_type; #define SD_DRIVER_TYPE_B 0x01 #define SD_DRIVER_TYPE_A 0x02 @@ -166,6 +183,8 @@ struct mmc_card { const char **info; /* info strings */ struct sdio_func_tuple *tuples; /* unknown common tuples */ + unsigned int sd_bus_speed; /* Bus Speed Mode set for the card */ + struct dentry *debugfs_root; }; diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 949e4d525989..62375992bdd6 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -50,6 +50,11 @@ struct mmc_ios { #define MMC_TIMING_LEGACY 0 #define MMC_TIMING_MMC_HS 1 #define MMC_TIMING_SD_HS 2 +#define MMC_TIMING_UHS_SDR12 MMC_TIMING_LEGACY +#define MMC_TIMING_UHS_SDR25 MMC_TIMING_SD_HS +#define MMC_TIMING_UHS_SDR50 3 +#define MMC_TIMING_UHS_SDR104 4 +#define MMC_TIMING_UHS_DDR50 5 unsigned char ddr; /* dual data rate used */ -- cgit From 5371c927bcd06a5c9dd6785bab2d452b87d9abc6 Mon Sep 17 00:00:00 2001 From: Arindam Nath Date: Thu, 5 May 2011 12:19:02 +0530 Subject: mmc: sd: set current limit for uhs cards We decide on the current limit to be set for the card based on the Capability of Host Controller to provide current at 1.8V signalling, and the maximum current limit of the card as indicated by CMD6 mode 0. We then set the current limit for the card using CMD6 mode 1. As per the Physical Layer Spec v3.01, the current limit switch is only applicable for SDR50, SDR104, and DDR50 bus speed modes. For other UHS-I modes, we set the default current limit of 200mA. Tested by Zhangfei Gao with a Toshiba uhs card and general hs card, on mmp2 in SDMA mode. Signed-off-by: Arindam Nath Reviewed-by: Philip Rakity Tested-by: Philip Rakity Acked-by: Zhangfei Gao Signed-off-by: Chris Ball --- drivers/mmc/core/sd.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++ drivers/mmc/host/sdhci.c | 10 ++++++++ include/linux/mmc/card.h | 9 +++++++ include/linux/mmc/host.h | 4 +++ 4 files changed, 86 insertions(+) (limited to 'include/linux') diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 6970b82171f7..8e2d8012e4cb 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -512,6 +512,64 @@ static int sd_set_bus_speed_mode(struct mmc_card *card, u8 *status) return 0; } +static int sd_set_current_limit(struct mmc_card *card, u8 *status) +{ + int current_limit = 0; + int err; + + /* + * Current limit switch is only defined for SDR50, SDR104, and DDR50 + * bus speed modes. For other bus speed modes, we set the default + * current limit of 200mA. + */ + if ((card->sd_bus_speed == UHS_SDR50_BUS_SPEED) || + (card->sd_bus_speed == UHS_SDR104_BUS_SPEED) || + (card->sd_bus_speed == UHS_DDR50_BUS_SPEED)) { + if (card->host->caps & MMC_CAP_MAX_CURRENT_800) { + if (card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_800) + current_limit = SD_SET_CURRENT_LIMIT_800; + else if (card->sw_caps.sd3_curr_limit & + SD_MAX_CURRENT_600) + current_limit = SD_SET_CURRENT_LIMIT_600; + else if (card->sw_caps.sd3_curr_limit & + SD_MAX_CURRENT_400) + current_limit = SD_SET_CURRENT_LIMIT_400; + else if (card->sw_caps.sd3_curr_limit & + SD_MAX_CURRENT_200) + current_limit = SD_SET_CURRENT_LIMIT_200; + } else if (card->host->caps & MMC_CAP_MAX_CURRENT_600) { + if (card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_600) + current_limit = SD_SET_CURRENT_LIMIT_600; + else if (card->sw_caps.sd3_curr_limit & + SD_MAX_CURRENT_400) + current_limit = SD_SET_CURRENT_LIMIT_400; + else if (card->sw_caps.sd3_curr_limit & + SD_MAX_CURRENT_200) + current_limit = SD_SET_CURRENT_LIMIT_200; + } else if (card->host->caps & MMC_CAP_MAX_CURRENT_400) { + if (card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_400) + current_limit = SD_SET_CURRENT_LIMIT_400; + else if (card->sw_caps.sd3_curr_limit & + SD_MAX_CURRENT_200) + current_limit = SD_SET_CURRENT_LIMIT_200; + } else if (card->host->caps & MMC_CAP_MAX_CURRENT_200) { + if (card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_200) + current_limit = SD_SET_CURRENT_LIMIT_200; + } + } else + current_limit = SD_SET_CURRENT_LIMIT_200; + + err = mmc_sd_switch(card, 1, 3, current_limit, status); + if (err) + return err; + + if (((status[15] >> 4) & 0x0F) != current_limit) + printk(KERN_WARNING "%s: Problem setting current limit!\n", + mmc_hostname(card->host)); + + return 0; +} + /* * UHS-I specific initialization procedure */ @@ -550,6 +608,11 @@ static int mmc_sd_init_uhs_card(struct mmc_card *card) /* Set bus speed mode of the card */ err = sd_set_bus_speed_mode(card, status); + if (err) + goto out; + + /* Set current limit for the card */ + err = sd_set_current_limit(card, status); out: kfree(status); diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 8994493dd940..2a15aad2eba5 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -2216,6 +2216,16 @@ int sdhci_add_host(struct sdhci_host *host) if (max_current_180 > 150) mmc->caps |= MMC_CAP_SET_XPC_180; + + /* Maximum current capabilities of the host at 1.8V */ + if (max_current_180 >= 800) + mmc->caps |= MMC_CAP_MAX_CURRENT_800; + else if (max_current_180 >= 600) + mmc->caps |= MMC_CAP_MAX_CURRENT_600; + else if (max_current_180 >= 400) + mmc->caps |= MMC_CAP_MAX_CURRENT_400; + else + mmc->caps |= MMC_CAP_MAX_CURRENT_200; } mmc->ocr_avail = ocr_avail; diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 4ef6ded6347d..47b5ad3960b7 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -105,6 +105,15 @@ struct sd_switch_caps { #define SD_DRIVER_TYPE_C 0x04 #define SD_DRIVER_TYPE_D 0x08 unsigned int sd3_curr_limit; +#define SD_SET_CURRENT_LIMIT_200 0 +#define SD_SET_CURRENT_LIMIT_400 1 +#define SD_SET_CURRENT_LIMIT_600 2 +#define SD_SET_CURRENT_LIMIT_800 3 + +#define SD_MAX_CURRENT_200 (1 << SD_SET_CURRENT_LIMIT_200) +#define SD_MAX_CURRENT_400 (1 << SD_SET_CURRENT_LIMIT_400) +#define SD_MAX_CURRENT_600 (1 << SD_SET_CURRENT_LIMIT_600) +#define SD_MAX_CURRENT_800 (1 << SD_SET_CURRENT_LIMIT_800) }; struct sdio_cccr { diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 62375992bdd6..52b5dc914a8c 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -203,6 +203,10 @@ struct mmc_host { #define MMC_CAP_DRIVER_TYPE_A (1 << 23) /* Host supports Driver Type A */ #define MMC_CAP_DRIVER_TYPE_C (1 << 24) /* Host supports Driver Type C */ #define MMC_CAP_DRIVER_TYPE_D (1 << 25) /* Host supports Driver Type D */ +#define MMC_CAP_MAX_CURRENT_200 (1 << 26) /* Host max current limit is 200mA */ +#define MMC_CAP_MAX_CURRENT_400 (1 << 27) /* Host max current limit is 400mA */ +#define MMC_CAP_MAX_CURRENT_600 (1 << 28) /* Host max current limit is 600mA */ +#define MMC_CAP_MAX_CURRENT_800 (1 << 29) /* Host max current limit is 800mA */ mmc_pm_flag_t pm_caps; /* supported pm features */ -- cgit From 3a3035114307cd55e024662bb295a87b849f0bd4 Mon Sep 17 00:00:00 2001 From: Arindam Nath Date: Thu, 5 May 2011 12:19:03 +0530 Subject: mmc: sd: report correct speed and capacity of uhs cards Since only UHS-I cards respond with S18A set in response to ACMD41, we set the card as ultra-high-speed after successfull initialization. We need to decide whether a card is SDXC based on the C_SIZE field of CSDv2.0 register. According to Physical Layer spec v3.01, the minimum value of C_SIZE for SDXC card is 00FFFFh. Tested by Zhangfei Gao with a Toshiba uhs card and general hs card, on mmp2 in SDMA mode. Signed-off-by: Arindam Nath Reviewed-by: Philip Rakity Tested-by: Philip Rakity Acked-by: Zhangfei Gao Signed-off-by: Chris Ball --- drivers/mmc/core/bus.c | 11 ++++++++--- drivers/mmc/core/sd.c | 10 +++++++++- include/linux/mmc/card.h | 7 +++++++ 3 files changed, 24 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index d6d62fd07ee9..393d817ed040 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c @@ -274,8 +274,12 @@ int mmc_add_card(struct mmc_card *card) break; case MMC_TYPE_SD: type = "SD"; - if (mmc_card_blockaddr(card)) - type = "SDHC"; + if (mmc_card_blockaddr(card)) { + if (mmc_card_ext_capacity(card)) + type = "SDXC"; + else + type = "SDHC"; + } break; case MMC_TYPE_SDIO: type = "SDIO"; @@ -299,7 +303,8 @@ int mmc_add_card(struct mmc_card *card) } else { printk(KERN_INFO "%s: new %s%s%s card at address %04x\n", mmc_hostname(card->host), - mmc_card_highspeed(card) ? "high speed " : "", + mmc_sd_card_uhs(card) ? "ultra high speed " : + (mmc_card_highspeed(card) ? "high speed " : ""), mmc_card_ddr_mode(card) ? "DDR " : "", type, card->rca); } diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 8e2d8012e4cb..732c3171ceca 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -130,7 +130,7 @@ static int mmc_decode_csd(struct mmc_card *card) break; case 1: /* - * This is a block-addressed SDHC card. Most + * This is a block-addressed SDHC or SDXC card. Most * interesting fields are unused and have fixed * values. To avoid getting tripped by buggy cards, * we assume those fixed values ourselves. @@ -144,6 +144,11 @@ static int mmc_decode_csd(struct mmc_card *card) e = UNSTUFF_BITS(resp, 96, 3); csd->max_dtr = tran_exp[e] * tran_mant[m]; csd->cmdclass = UNSTUFF_BITS(resp, 84, 12); + csd->c_size = UNSTUFF_BITS(resp, 48, 22); + + /* SDXC cards have a minimum C_SIZE of 0x00FFFF */ + if (csd->c_size >= 0xFFFF) + mmc_card_set_ext_capacity(card); m = UNSTUFF_BITS(resp, 48, 22); csd->capacity = (1 + m) << 10; @@ -911,6 +916,9 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, err = mmc_sd_init_uhs_card(card); if (err) goto free_card; + + /* Card is an ultra-high-speed card */ + mmc_sd_card_set_uhs(card); } else { /* * Attempt to change to high-speed (if supported) diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 47b5ad3960b7..d8dffc992ce2 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -30,6 +30,7 @@ struct mmc_csd { unsigned short cmdclass; unsigned short tacc_clks; unsigned int tacc_ns; + unsigned int c_size; unsigned int r2w_factor; unsigned int max_dtr; unsigned int erase_size; /* In sectors */ @@ -158,6 +159,8 @@ struct mmc_card { #define MMC_STATE_HIGHSPEED (1<<2) /* card is in high speed mode */ #define MMC_STATE_BLOCKADDR (1<<3) /* card uses block-addressing */ #define MMC_STATE_HIGHSPEED_DDR (1<<4) /* card is in high speed mode */ +#define MMC_STATE_ULTRAHIGHSPEED (1<<5) /* card is in ultra high speed mode */ +#define MMC_CARD_SDXC (1<<6) /* card is SDXC */ unsigned int quirks; /* card quirks */ #define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */ #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */ @@ -293,12 +296,16 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data) #define mmc_card_highspeed(c) ((c)->state & MMC_STATE_HIGHSPEED) #define mmc_card_blockaddr(c) ((c)->state & MMC_STATE_BLOCKADDR) #define mmc_card_ddr_mode(c) ((c)->state & MMC_STATE_HIGHSPEED_DDR) +#define mmc_sd_card_uhs(c) ((c)->state & MMC_STATE_ULTRAHIGHSPEED) +#define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC) #define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT) #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY) #define mmc_card_set_highspeed(c) ((c)->state |= MMC_STATE_HIGHSPEED) #define mmc_card_set_blockaddr(c) ((c)->state |= MMC_STATE_BLOCKADDR) #define mmc_card_set_ddr_mode(c) ((c)->state |= MMC_STATE_HIGHSPEED_DDR) +#define mmc_sd_card_set_uhs(c) ((c)->state |= MMC_STATE_ULTRAHIGHSPEED) +#define mmc_card_set_ext_capacity(c) ((c)->state |= MMC_CARD_SDXC) static inline int mmc_card_lenient_fn0(const struct mmc_card *c) { -- cgit From b513ea250eb7c36a8afb3df938d632ca6b4df7cd Mon Sep 17 00:00:00 2001 From: Arindam Nath Date: Thu, 5 May 2011 12:19:04 +0530 Subject: mmc: sd: add support for tuning during uhs initialization Host Controller needs tuning during initialization to operate SDR50 and SDR104 UHS-I cards. Whether SDR50 mode actually needs tuning is indicated by bit 45 of the Host Controller Capabilities register. A new command CMD19 has been defined in the Physical Layer spec v3.01 to request the card to send tuning pattern. We enable Buffer Read Ready interrupt at the very begining of tuning procedure, because that is the only interrupt generated by the Host Controller during tuning. We program the block size to 64 in the Block Size register. We make sure that DMA Enable and Multi Block Select in the Transfer Mode register are set to 0 before actually sending CMD19. The tuning block is sent by the card to the Host Controller using DAT lines, so we set Data Present Select (bit 5) in the Command register. The Host Controller is responsible for doing the verfication of tuning block sent by the card at the hardware level. After sending CMD19, we wait for Buffer Read Ready interrupt. In case we don't receive an interrupt after the specified timeout value, we fall back on fixed sampling clock by setting Execute Tuning (bit 6) and Sampling Clock Select (bit 7) of Host Control2 register to 0. Before exiting the tuning procedure, we disable Buffer Read Ready interrupt and re-enable other interrupts. Tested by Zhangfei Gao with a Toshiba uhs card and general hs card, on mmp2 in SDMA mode. Signed-off-by: Arindam Nath Reviewed-by: Philip Rakity Tested-by: Philip Rakity Acked-by: Zhangfei Gao Signed-off-by: Chris Ball --- drivers/mmc/core/sd.c | 6 ++ drivers/mmc/host/sdhci.c | 168 +++++++++++++++++++++++++++++++++++++++++++++- drivers/mmc/host/sdhci.h | 3 + include/linux/mmc/host.h | 1 + include/linux/mmc/mmc.h | 1 + include/linux/mmc/sdhci.h | 4 ++ 6 files changed, 182 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 732c3171ceca..fc65475a26ee 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -618,6 +618,12 @@ static int mmc_sd_init_uhs_card(struct mmc_card *card) /* Set current limit for the card */ err = sd_set_current_limit(card, status); + if (err) + goto out; + + /* SPI mode doesn't define CMD19 */ + if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning) + err = card->host->ops->execute_tuning(card->host); out: kfree(status); diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 2a15aad2eba5..8a56eacea34d 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -38,6 +38,8 @@ #define SDHCI_USE_LEDS_CLASS #endif +#define MAX_TUNING_LOOP 40 + static unsigned int debug_quirks = 0; static void sdhci_finish_data(struct sdhci_host *); @@ -968,7 +970,9 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) flags |= SDHCI_CMD_CRC; if (cmd->flags & MMC_RSP_OPCODE) flags |= SDHCI_CMD_INDEX; - if (cmd->data) + + /* CMD19 is special in that the Data Present Select should be set */ + if (cmd->data || (cmd->opcode == MMC_SEND_TUNING_BLOCK)) flags |= SDHCI_CMD_DATA; sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND); @@ -1501,12 +1505,157 @@ static int sdhci_start_signal_voltage_switch(struct mmc_host *mmc, return 0; } +static int sdhci_execute_tuning(struct mmc_host *mmc) +{ + struct sdhci_host *host; + u16 ctrl; + u32 ier; + int tuning_loop_counter = MAX_TUNING_LOOP; + unsigned long timeout; + int err = 0; + + host = mmc_priv(mmc); + + disable_irq(host->irq); + spin_lock(&host->lock); + + ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); + + /* + * Host Controller needs tuning only in case of SDR104 mode + * and for SDR50 mode when Use Tuning for SDR50 is set in + * Capabilities register. + */ + if (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR104) || + (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR50) && + (host->flags & SDHCI_SDR50_NEEDS_TUNING))) + ctrl |= SDHCI_CTRL_EXEC_TUNING; + else { + spin_unlock(&host->lock); + enable_irq(host->irq); + return 0; + } + + sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); + + /* + * As per the Host Controller spec v3.00, tuning command + * generates Buffer Read Ready interrupt, so enable that. + * + * Note: The spec clearly says that when tuning sequence + * is being performed, the controller does not generate + * interrupts other than Buffer Read Ready interrupt. But + * to make sure we don't hit a controller bug, we _only_ + * enable Buffer Read Ready interrupt here. + */ + ier = sdhci_readl(host, SDHCI_INT_ENABLE); + sdhci_clear_set_irqs(host, ier, SDHCI_INT_DATA_AVAIL); + + /* + * Issue CMD19 repeatedly till Execute Tuning is set to 0 or the number + * of loops reaches 40 times or a timeout of 150ms occurs. + */ + timeout = 150; + do { + struct mmc_command cmd = {0}; + struct mmc_request mrq = {0}; + + if (!tuning_loop_counter && !timeout) + break; + + cmd.opcode = MMC_SEND_TUNING_BLOCK; + cmd.arg = 0; + cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; + cmd.retries = 0; + cmd.data = NULL; + cmd.error = 0; + + mrq.cmd = &cmd; + host->mrq = &mrq; + + /* + * In response to CMD19, the card sends 64 bytes of tuning + * block to the Host Controller. So we set the block size + * to 64 here. + */ + sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 64), SDHCI_BLOCK_SIZE); + + /* + * The tuning block is sent by the card to the host controller. + * So we set the TRNS_READ bit in the Transfer Mode register. + * This also takes care of setting DMA Enable and Multi Block + * Select in the same register to 0. + */ + sdhci_writew(host, SDHCI_TRNS_READ, SDHCI_TRANSFER_MODE); + + sdhci_send_command(host, &cmd); + + host->cmd = NULL; + host->mrq = NULL; + + spin_unlock(&host->lock); + enable_irq(host->irq); + + /* Wait for Buffer Read Ready interrupt */ + wait_event_interruptible_timeout(host->buf_ready_int, + (host->tuning_done == 1), + msecs_to_jiffies(50)); + disable_irq(host->irq); + spin_lock(&host->lock); + + if (!host->tuning_done) { + printk(KERN_INFO DRIVER_NAME ": Timeout waiting for " + "Buffer Read Ready interrupt during tuning " + "procedure, falling back to fixed sampling " + "clock\n"); + ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); + ctrl &= ~SDHCI_CTRL_TUNED_CLK; + ctrl &= ~SDHCI_CTRL_EXEC_TUNING; + sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); + + err = -EIO; + goto out; + } + + host->tuning_done = 0; + + ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); + tuning_loop_counter--; + timeout--; + mdelay(1); + } while (ctrl & SDHCI_CTRL_EXEC_TUNING); + + /* + * The Host Driver has exhausted the maximum number of loops allowed, + * so use fixed sampling frequency. + */ + if (!tuning_loop_counter || !timeout) { + ctrl &= ~SDHCI_CTRL_TUNED_CLK; + sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); + } else { + if (!(ctrl & SDHCI_CTRL_TUNED_CLK)) { + printk(KERN_INFO DRIVER_NAME ": Tuning procedure" + " failed, falling back to fixed sampling" + " clock\n"); + err = -EIO; + } + } + +out: + sdhci_clear_set_irqs(host, SDHCI_INT_DATA_AVAIL, ier); + spin_unlock(&host->lock); + enable_irq(host->irq); + + return err; +} + static const struct mmc_host_ops sdhci_ops = { .request = sdhci_request, .set_ios = sdhci_set_ios, .get_ro = sdhci_get_ro, .enable_sdio_irq = sdhci_enable_sdio_irq, .start_signal_voltage_switch = sdhci_start_signal_voltage_switch, + .execute_tuning = sdhci_execute_tuning, }; /*****************************************************************************\ @@ -1724,6 +1873,16 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) { BUG_ON(intmask == 0); + /* CMD19 generates _only_ Buffer Read Ready interrupt */ + if (intmask & SDHCI_INT_DATA_AVAIL) { + if (SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND)) == + MMC_SEND_TUNING_BLOCK) { + host->tuning_done = 1; + wake_up(&host->buf_ready_int); + return; + } + } + if (!host->data) { /* * The "data complete" interrupt is also used to @@ -2160,6 +2319,10 @@ int sdhci_add_host(struct sdhci_host *host) if (caps[1] & SDHCI_SUPPORT_DDR50) mmc->caps |= MMC_CAP_UHS_DDR50; + /* Does the host needs tuning for SDR50? */ + if (caps[1] & SDHCI_USE_SDR50_TUNING) + host->flags |= SDHCI_SDR50_NEEDS_TUNING; + /* Driver Type(s) (A, C, D) supported by the host */ if (caps[1] & SDHCI_DRIVER_TYPE_A) mmc->caps |= MMC_CAP_DRIVER_TYPE_A; @@ -2313,6 +2476,9 @@ int sdhci_add_host(struct sdhci_host *host) setup_timer(&host->timer, sdhci_timeout_timer, (unsigned long)host); + if (host->version >= SDHCI_SPEC_300) + init_waitqueue_head(&host->buf_ready_int); + ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED, mmc_hostname(mmc), host); if (ret) diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index d96f6afcca1f..e62367491eee 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -161,6 +161,8 @@ #define SDHCI_CTRL_DRV_TYPE_A 0x0010 #define SDHCI_CTRL_DRV_TYPE_C 0x0020 #define SDHCI_CTRL_DRV_TYPE_D 0x0030 +#define SDHCI_CTRL_EXEC_TUNING 0x0040 +#define SDHCI_CTRL_TUNED_CLK 0x0080 #define SDHCI_CTRL_PRESET_VAL_ENABLE 0x8000 #define SDHCI_CAPABILITIES 0x40 @@ -188,6 +190,7 @@ #define SDHCI_DRIVER_TYPE_A 0x00000010 #define SDHCI_DRIVER_TYPE_C 0x00000020 #define SDHCI_DRIVER_TYPE_D 0x00000040 +#define SDHCI_USE_SDR50_TUNING 0x00002000 #define SDHCI_CAPABILITIES_1 0x44 diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 52b5dc914a8c..ca7007fdb399 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -136,6 +136,7 @@ struct mmc_host_ops { void (*init_card)(struct mmc_host *host, struct mmc_card *card); int (*start_signal_voltage_switch)(struct mmc_host *host, struct mmc_ios *ios); + int (*execute_tuning)(struct mmc_host *host); }; struct mmc_card; diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index 373b2bf5e5b5..9fa5a73f393d 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -50,6 +50,7 @@ #define MMC_SET_BLOCKLEN 16 /* ac [31:0] block len R1 */ #define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */ #define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */ +#define MMC_SEND_TUNING_BLOCK 19 /* adtc R1 */ /* class 3 */ #define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */ diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h index 92e1c9ad126c..b74c8530e959 100644 --- a/include/linux/mmc/sdhci.h +++ b/include/linux/mmc/sdhci.h @@ -111,6 +111,7 @@ struct sdhci_host { #define SDHCI_USE_ADMA (1<<1) /* Host is ADMA capable */ #define SDHCI_REQ_USE_DMA (1<<2) /* Use DMA for this req. */ #define SDHCI_DEVICE_DEAD (1<<3) /* Device unresponsive */ +#define SDHCI_SDR50_NEEDS_TUNING (1<<4) /* SDR50 needs tuning */ unsigned int version; /* SDHCI spec. version */ @@ -147,6 +148,9 @@ struct sdhci_host { unsigned int ocr_avail_sd; unsigned int ocr_avail_mmc; + wait_queue_head_t buf_ready_int; /* Waitqueue for Buffer Read Ready interrupt */ + unsigned int tuning_done; /* Condition flag set when CMD19 succeeds */ + unsigned long private[0] ____cacheline_aligned; }; #endif /* __SDHCI_H */ -- cgit From 4d55c5a13a189a80d40383f02c8026f9a87d7c87 Mon Sep 17 00:00:00 2001 From: Arindam Nath Date: Thu, 5 May 2011 12:19:05 +0530 Subject: mmc: sdhci: enable preset value after uhs initialization According to the Host Controller spec v3.00, setting Preset Value Enable in the Host Control2 register lets SDCLK Frequency Select, Clock Generator Select and Driver Strength Select to be set automatically by the Host Controller based on the UHS-I mode set. This patch enables this feature. Since Preset Value Enable makes sense only for UHS-I cards, we enable this feature after successfull UHS-I initialization. We also reset Preset Value Enable next time before initialization. Tested by Zhangfei Gao with a Toshiba uhs card and general hs card, on mmp2 in SDMA mode. Signed-off-by: Arindam Nath Reviewed-by: Philip Rakity Tested-by: Philip Rakity Acked-by: Zhangfei Gao Signed-off-by: Chris Ball --- drivers/mmc/core/sd.c | 11 +++++++++++ drivers/mmc/host/sdhci.c | 32 ++++++++++++++++++++++++++++++++ include/linux/mmc/host.h | 1 + 3 files changed, 44 insertions(+) (limited to 'include/linux') diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index fc65475a26ee..b461b290ce25 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -925,6 +925,13 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, /* Card is an ultra-high-speed card */ mmc_sd_card_set_uhs(card); + + /* + * Since initialization is now complete, enable preset + * value registers for UHS-I cards. + */ + if (host->ops->enable_preset_value) + host->ops->enable_preset_value(host, true); } else { /* * Attempt to change to high-speed (if supported) @@ -1095,6 +1102,10 @@ int mmc_attach_sd(struct mmc_host *host) if (err) return err; + /* Disable preset value enable if already set since last time */ + if (host->ops->enable_preset_value) + host->ops->enable_preset_value(host, false); + err = mmc_send_app_op_cond(host, 0, &ocr); if (err) return err; diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 8a56eacea34d..a1ab22415883 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1649,6 +1649,37 @@ out: return err; } +static void sdhci_enable_preset_value(struct mmc_host *mmc, bool enable) +{ + struct sdhci_host *host; + u16 ctrl; + unsigned long flags; + + host = mmc_priv(mmc); + + /* Host Controller v3.00 defines preset value registers */ + if (host->version < SDHCI_SPEC_300) + return; + + spin_lock_irqsave(&host->lock, flags); + + ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); + + /* + * We only enable or disable Preset Value if they are not already + * enabled or disabled respectively. Otherwise, we bail out. + */ + if (enable && !(ctrl & SDHCI_CTRL_PRESET_VAL_ENABLE)) { + ctrl |= SDHCI_CTRL_PRESET_VAL_ENABLE; + sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); + } else if (!enable && (ctrl & SDHCI_CTRL_PRESET_VAL_ENABLE)) { + ctrl &= ~SDHCI_CTRL_PRESET_VAL_ENABLE; + sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); + } + + spin_unlock_irqrestore(&host->lock, flags); +} + static const struct mmc_host_ops sdhci_ops = { .request = sdhci_request, .set_ios = sdhci_set_ios, @@ -1656,6 +1687,7 @@ static const struct mmc_host_ops sdhci_ops = { .enable_sdio_irq = sdhci_enable_sdio_irq, .start_signal_voltage_switch = sdhci_start_signal_voltage_switch, .execute_tuning = sdhci_execute_tuning, + .enable_preset_value = sdhci_enable_preset_value, }; /*****************************************************************************\ diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index ca7007fdb399..6716bd12eccd 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -137,6 +137,7 @@ struct mmc_host_ops { int (*start_signal_voltage_switch)(struct mmc_host *host, struct mmc_ios *ios); int (*execute_tuning)(struct mmc_host *host); + void (*enable_preset_value)(struct mmc_host *host, bool enable); }; struct mmc_card; -- cgit From c3ed3877625f10d600b0eca2ca48a68c46aed660 Mon Sep 17 00:00:00 2001 From: Arindam Nath Date: Thu, 5 May 2011 12:19:06 +0530 Subject: mmc: sdhci: add support for programmable clock mode Host Controller v3.00 supports programmable clock mode as an optional feature. The support for this mode is indicated by non-zero value in bits 48-55 of the Capabilities register. If supported, the actual value of Clock Multiplier is one more than the value provided in the bit fields. We only set Clock Generator Select (bit 5) and SDCLK Frequency Select (bits 8-15) of the Clock Control register in case Preset Value Enable is not set, otherwise these fields are automatically set by the Host Controller based on the UHS mode selected. Also, since the maximum and minimum clock frequency in this mode can be (Base Clock * Clock Mul) and (Base Clock * Clock Mul)/1024 respectively, f_max and f_min have been recalculated to reflect this change. Tested by Zhangfei Gao with a Toshiba uhs card and general hs card, on mmp2 in SDMA mode. Signed-off-by: Arindam Nath Reviewed-by: Philip Rakity Tested-by: Philip Rakity Acked-by: Zhangfei Gao Signed-off-by: Chris Ball --- drivers/mmc/host/sdhci.c | 81 ++++++++++++++++++++++++++++++++++++++--------- drivers/mmc/host/sdhci.h | 3 ++ include/linux/mmc/sdhci.h | 1 + 3 files changed, 70 insertions(+), 15 deletions(-) (limited to 'include/linux') diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index a1ab22415883..07cca557c4b5 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1013,8 +1013,8 @@ static void sdhci_finish_command(struct sdhci_host *host) static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) { - int div; - u16 clk; + int div = 0; /* Initialized for compiler warning */ + u16 clk = 0; unsigned long timeout; if (clock == host->clock) @@ -1032,14 +1032,45 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) goto out; if (host->version >= SDHCI_SPEC_300) { - /* Version 3.00 divisors must be a multiple of 2. */ - if (host->max_clk <= clock) - div = 1; - else { - for (div = 2; div < SDHCI_MAX_DIV_SPEC_300; div += 2) { - if ((host->max_clk / div) <= clock) - break; + /* + * Check if the Host Controller supports Programmable Clock + * Mode. + */ + if (host->clk_mul) { + u16 ctrl; + + /* + * We need to figure out whether the Host Driver needs + * to select Programmable Clock Mode, or the value can + * be set automatically by the Host Controller based on + * the Preset Value registers. + */ + ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); + if (!(ctrl & SDHCI_CTRL_PRESET_VAL_ENABLE)) { + for (div = 1; div <= 1024; div++) { + if (((host->max_clk * host->clk_mul) / + div) <= clock) + break; + } + /* + * Set Programmable Clock Mode in the Clock + * Control register. + */ + clk = SDHCI_PROG_CLOCK_MODE; + div--; + } + } else { + /* Version 3.00 divisors must be a multiple of 2. */ + if (host->max_clk <= clock) + div = 1; + else { + for (div = 2; div < SDHCI_MAX_DIV_SPEC_300; + div += 2) { + if ((host->max_clk / div) <= clock) + break; + } } + div >>= 1; } } else { /* Version 2.00 divisors must be a power of 2. */ @@ -1047,10 +1078,10 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) if ((host->max_clk / div) <= clock) break; } + div >>= 1; } - div >>= 1; - clk = (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; + clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN) << SDHCI_DIVIDER_HI_SHIFT; clk |= SDHCI_CLOCK_INT_EN; @@ -2307,18 +2338,38 @@ int sdhci_add_host(struct sdhci_host *host) if (caps[0] & SDHCI_TIMEOUT_CLK_UNIT) host->timeout_clk *= 1000; + /* + * In case of Host Controller v3.00, find out whether clock + * multiplier is supported. + */ + host->clk_mul = (caps[1] & SDHCI_CLOCK_MUL_MASK) >> + SDHCI_CLOCK_MUL_SHIFT; + + /* + * In case the value in Clock Multiplier is 0, then programmable + * clock mode is not supported, otherwise the actual clock + * multiplier is one more than the value of Clock Multiplier + * in the Capabilities Register. + */ + if (host->clk_mul) + host->clk_mul += 1; + /* * Set host parameters. */ mmc->ops = &sdhci_ops; + mmc->f_max = host->max_clk; if (host->ops->get_min_clock) mmc->f_min = host->ops->get_min_clock(host); - else if (host->version >= SDHCI_SPEC_300) - mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_300; - else + else if (host->version >= SDHCI_SPEC_300) { + if (host->clk_mul) { + mmc->f_min = (host->max_clk * host->clk_mul) / 1024; + mmc->f_max = host->max_clk * host->clk_mul; + } else + mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_300; + } else mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_200; - mmc->f_max = host->max_clk; mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE; /* diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index e62367491eee..6b0a0ee9ac6e 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -101,6 +101,7 @@ #define SDHCI_DIV_MASK 0xFF #define SDHCI_DIV_MASK_LEN 8 #define SDHCI_DIV_HI_MASK 0x300 +#define SDHCI_PROG_CLOCK_MODE 0x0020 #define SDHCI_CLOCK_CARD_EN 0x0004 #define SDHCI_CLOCK_INT_STABLE 0x0002 #define SDHCI_CLOCK_INT_EN 0x0001 @@ -191,6 +192,8 @@ #define SDHCI_DRIVER_TYPE_C 0x00000020 #define SDHCI_DRIVER_TYPE_D 0x00000040 #define SDHCI_USE_SDR50_TUNING 0x00002000 +#define SDHCI_CLOCK_MUL_MASK 0x00FF0000 +#define SDHCI_CLOCK_MUL_SHIFT 16 #define SDHCI_CAPABILITIES_1 0x44 diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h index b74c8530e959..a88a799ed7c3 100644 --- a/include/linux/mmc/sdhci.h +++ b/include/linux/mmc/sdhci.h @@ -117,6 +117,7 @@ struct sdhci_host { unsigned int max_clk; /* Max possible freq (MHz) */ unsigned int timeout_clk; /* Timeout freq (KHz) */ + unsigned int clk_mul; /* Clock Muliplier value */ unsigned int clock; /* Current clock (MHz) */ u8 pwr; /* Current voltage */ -- cgit From cf2b5eea1ea0ff9b3184bc6771bcb93a9fdcd1d9 Mon Sep 17 00:00:00 2001 From: Arindam Nath Date: Thu, 5 May 2011 12:19:07 +0530 Subject: mmc: sdhci: add support for retuning mode 1 Host Controller v3.00 can support retuning modes 1,2 or 3 depending on the bits 46-47 of the Capabilities register. Also, the timer count for retuning is indicated by bits 40-43 of the same register. We initialize timer_list for retuning the first time we execute tuning procedure. This condition is indicated by SDHCI_NEEDS_RETUNING not being set. Since retuning mode 1 sets a limit of 4MB on the maximum data length, we set max_blk_count appropriately. Once the tuning timer expires, we set SDHCI_NEEDS_RETUNING flag, and if the flag is set, we execute tuning procedure before sending the next command. We need to restore mmc_request structure after executing retuning procedure since host->mrq is used inside the procedure to send CMD19. We also disable and re-enable this flag during suspend and resume respectively, as per the spec v3.00. Tested by Zhangfei Gao with a Toshiba uhs card and general hs card, on mmp2 in SDMA mode. Signed-off-by: Arindam Nath Reviewed-by: Philip Rakity Tested-by: Philip Rakity Acked-by: Zhangfei Gao Signed-off-by: Chris Ball --- drivers/mmc/host/sdhci.c | 109 +++++++++++++++++++++++++++++++++++++++++++++- drivers/mmc/host/sdhci.h | 6 ++- include/linux/mmc/sdhci.h | 6 +++ 3 files changed, 118 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 07cca557c4b5..fa3301644b15 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -46,6 +46,8 @@ static void sdhci_finish_data(struct sdhci_host *); static void sdhci_send_command(struct sdhci_host *, struct mmc_command *); static void sdhci_finish_command(struct sdhci_host *); +static int sdhci_execute_tuning(struct mmc_host *mmc); +static void sdhci_tuning_timer(unsigned long data); static void sdhci_dumpregs(struct sdhci_host *host) { @@ -1206,8 +1208,27 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) if (!present || host->flags & SDHCI_DEVICE_DEAD) { host->mrq->cmd->error = -ENOMEDIUM; tasklet_schedule(&host->finish_tasklet); - } else + } else { + u32 present_state; + + present_state = sdhci_readl(host, SDHCI_PRESENT_STATE); + /* + * Check if the re-tuning timer has already expired and there + * is no on-going data transfer. If so, we need to execute + * tuning procedure before sending command. + */ + if ((host->flags & SDHCI_NEEDS_RETUNING) && + !(present_state & (SDHCI_DOING_WRITE | SDHCI_DOING_READ))) { + spin_unlock_irqrestore(&host->lock, flags); + sdhci_execute_tuning(mmc); + spin_lock_irqsave(&host->lock, flags); + + /* Restore original mmc_request structure */ + host->mrq = mrq; + } + sdhci_send_command(host, mrq->cmd); + } mmiowb(); spin_unlock_irqrestore(&host->lock, flags); @@ -1673,6 +1694,37 @@ static int sdhci_execute_tuning(struct mmc_host *mmc) } out: + /* + * If this is the very first time we are here, we start the retuning + * timer. Since only during the first time, SDHCI_NEEDS_RETUNING + * flag won't be set, we check this condition before actually starting + * the timer. + */ + if (!(host->flags & SDHCI_NEEDS_RETUNING) && host->tuning_count && + (host->tuning_mode == SDHCI_TUNING_MODE_1)) { + mod_timer(&host->tuning_timer, jiffies + + host->tuning_count * HZ); + /* Tuning mode 1 limits the maximum data length to 4MB */ + mmc->max_blk_count = (4 * 1024 * 1024) / mmc->max_blk_size; + } else { + host->flags &= ~SDHCI_NEEDS_RETUNING; + /* Reload the new initial value for timer */ + if (host->tuning_mode == SDHCI_TUNING_MODE_1) + mod_timer(&host->tuning_timer, jiffies + + host->tuning_count * HZ); + } + + /* + * In case tuning fails, host controllers which support re-tuning can + * try tuning again at a later time, when the re-tuning timer expires. + * So for these controllers, we return 0. Since there might be other + * controllers who do not have this capability, we return error for + * them. + */ + if (err && host->tuning_count && + host->tuning_mode == SDHCI_TUNING_MODE_1) + err = 0; + sdhci_clear_set_irqs(host, SDHCI_INT_DATA_AVAIL, ier); spin_unlock(&host->lock); enable_irq(host->irq); @@ -1775,6 +1827,9 @@ static void sdhci_tasklet_finish(unsigned long param) del_timer(&host->timer); + if (host->version >= SDHCI_SPEC_300) + del_timer(&host->tuning_timer); + mrq = host->mrq; /* @@ -1848,6 +1903,20 @@ static void sdhci_timeout_timer(unsigned long data) spin_unlock_irqrestore(&host->lock, flags); } +static void sdhci_tuning_timer(unsigned long data) +{ + struct sdhci_host *host; + unsigned long flags; + + host = (struct sdhci_host *)data; + + spin_lock_irqsave(&host->lock, flags); + + host->flags |= SDHCI_NEEDS_RETUNING; + + spin_unlock_irqrestore(&host->lock, flags); +} + /*****************************************************************************\ * * * Interrupt handling * @@ -2122,6 +2191,14 @@ int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state) sdhci_disable_card_detection(host); + /* Disable tuning since we are suspending */ + if (host->version >= SDHCI_SPEC_300 && host->tuning_count && + host->tuning_mode == SDHCI_TUNING_MODE_1) { + host->flags &= ~SDHCI_NEEDS_RETUNING; + mod_timer(&host->tuning_timer, jiffies + + host->tuning_count * HZ); + } + ret = mmc_suspend_host(host->mmc); if (ret) return ret; @@ -2163,6 +2240,11 @@ int sdhci_resume_host(struct sdhci_host *host) ret = mmc_resume_host(host->mmc); sdhci_enable_card_detection(host); + /* Set the re-tuning expiration flag */ + if ((host->version >= SDHCI_SPEC_300) && host->tuning_count && + (host->tuning_mode == SDHCI_TUNING_MODE_1)) + host->flags |= SDHCI_NEEDS_RETUNING; + return ret; } @@ -2414,6 +2496,21 @@ int sdhci_add_host(struct sdhci_host *host) if (caps[1] & SDHCI_DRIVER_TYPE_D) mmc->caps |= MMC_CAP_DRIVER_TYPE_D; + /* Initial value for re-tuning timer count */ + host->tuning_count = (caps[1] & SDHCI_RETUNING_TIMER_COUNT_MASK) >> + SDHCI_RETUNING_TIMER_COUNT_SHIFT; + + /* + * In case Re-tuning Timer is not disabled, the actual value of + * re-tuning timer will be 2 ^ (n - 1). + */ + if (host->tuning_count) + host->tuning_count = 1 << (host->tuning_count - 1); + + /* Re-tuning mode supported by the Host Controller */ + host->tuning_mode = (caps[1] & SDHCI_RETUNING_MODE_MASK) >> + SDHCI_RETUNING_MODE_SHIFT; + ocr_avail = 0; /* * According to SD Host Controller spec v3.00, if the Host System @@ -2559,9 +2656,15 @@ int sdhci_add_host(struct sdhci_host *host) setup_timer(&host->timer, sdhci_timeout_timer, (unsigned long)host); - if (host->version >= SDHCI_SPEC_300) + if (host->version >= SDHCI_SPEC_300) { init_waitqueue_head(&host->buf_ready_int); + /* Initialize re-tuning timer */ + init_timer(&host->tuning_timer); + host->tuning_timer.data = (unsigned long)host; + host->tuning_timer.function = sdhci_tuning_timer; + } + ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED, mmc_hostname(mmc), host); if (ret) @@ -2655,6 +2758,8 @@ void sdhci_remove_host(struct sdhci_host *host, int dead) free_irq(host->irq, host); del_timer_sync(&host->timer); + if (host->version >= SDHCI_SPEC_300) + del_timer_sync(&host->tuning_timer); tasklet_kill(&host->card_tasklet); tasklet_kill(&host->finish_tasklet); diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 6b0a0ee9ac6e..8ea11b7cf89a 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -191,7 +191,11 @@ #define SDHCI_DRIVER_TYPE_A 0x00000010 #define SDHCI_DRIVER_TYPE_C 0x00000020 #define SDHCI_DRIVER_TYPE_D 0x00000040 -#define SDHCI_USE_SDR50_TUNING 0x00002000 +#define SDHCI_RETUNING_TIMER_COUNT_MASK 0x00000F00 +#define SDHCI_RETUNING_TIMER_COUNT_SHIFT 8 +#define SDHCI_USE_SDR50_TUNING 0x00002000 +#define SDHCI_RETUNING_MODE_MASK 0x0000C000 +#define SDHCI_RETUNING_MODE_SHIFT 14 #define SDHCI_CLOCK_MUL_MASK 0x00FF0000 #define SDHCI_CLOCK_MUL_SHIFT 16 diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h index a88a799ed7c3..e902618d68f4 100644 --- a/include/linux/mmc/sdhci.h +++ b/include/linux/mmc/sdhci.h @@ -112,6 +112,7 @@ struct sdhci_host { #define SDHCI_REQ_USE_DMA (1<<2) /* Use DMA for this req. */ #define SDHCI_DEVICE_DEAD (1<<3) /* Device unresponsive */ #define SDHCI_SDR50_NEEDS_TUNING (1<<4) /* SDR50 needs tuning */ +#define SDHCI_NEEDS_RETUNING (1<<5) /* Host needs retuning */ unsigned int version; /* SDHCI spec. version */ @@ -152,6 +153,11 @@ struct sdhci_host { wait_queue_head_t buf_ready_int; /* Waitqueue for Buffer Read Ready interrupt */ unsigned int tuning_done; /* Condition flag set when CMD19 succeeds */ + unsigned int tuning_count; /* Timer count for re-tuning */ + unsigned int tuning_mode; /* Re-tuning mode supported by host */ +#define SDHCI_TUNING_MODE_1 0 + struct timer_list tuning_timer; /* Timer for tuning */ + unsigned long private[0] ____cacheline_aligned; }; #endif /* __SDHCI_H */ -- cgit From 06e8935febe687e2a561707d4c7ca4245d261dbe Mon Sep 17 00:00:00 2001 From: Stefan Nilsson XK Date: Wed, 11 May 2011 17:48:05 +0200 Subject: mmc: sdio: optimized SDIO IRQ handling for single irq If there is only 1 function interrupt registered it is possible to improve performance by directly calling the irq handler and avoiding the overhead of reading the CCCR registers. Signed-off-by: Per Forlin Acked-by: Ulf Hansson Reviewed-by: Nicolas Pitre Signed-off-by: Chris Ball --- drivers/mmc/core/sdio_irq.c | 33 ++++++++++++++++++++++++++++++++- include/linux/mmc/card.h | 1 + 2 files changed, 33 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/drivers/mmc/core/sdio_irq.c b/drivers/mmc/core/sdio_irq.c index b3001617e67d..03ead028d2ce 100644 --- a/drivers/mmc/core/sdio_irq.c +++ b/drivers/mmc/core/sdio_irq.c @@ -31,6 +31,17 @@ static int process_sdio_pending_irqs(struct mmc_card *card) { int i, ret, count; unsigned char pending; + struct sdio_func *func; + + /* + * Optimization, if there is only 1 function interrupt registered + * call irq handler directly + */ + func = card->sdio_single_irq; + if (func) { + func->irq_handler(func); + return 1; + } ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_INTx, 0, &pending); if (ret) { @@ -42,7 +53,7 @@ static int process_sdio_pending_irqs(struct mmc_card *card) count = 0; for (i = 1; i <= 7; i++) { if (pending & (1 << i)) { - struct sdio_func *func = card->sdio_func[i - 1]; + func = card->sdio_func[i - 1]; if (!func) { printk(KERN_WARNING "%s: pending IRQ for " "non-existent function\n", @@ -186,6 +197,24 @@ static int sdio_card_irq_put(struct mmc_card *card) return 0; } +/* If there is only 1 function registered set sdio_single_irq */ +static void sdio_single_irq_set(struct mmc_card *card) +{ + struct sdio_func *func; + int i; + + card->sdio_single_irq = NULL; + if ((card->host->caps & MMC_CAP_SDIO_IRQ) && + card->host->sdio_irqs == 1) + for (i = 0; i < card->sdio_funcs; i++) { + func = card->sdio_func[i]; + if (func && func->irq_handler) { + card->sdio_single_irq = func; + break; + } + } +} + /** * sdio_claim_irq - claim the IRQ for a SDIO function * @func: SDIO function @@ -227,6 +256,7 @@ int sdio_claim_irq(struct sdio_func *func, sdio_irq_handler_t *handler) ret = sdio_card_irq_get(func->card); if (ret) func->irq_handler = NULL; + sdio_single_irq_set(func->card); return ret; } @@ -251,6 +281,7 @@ int sdio_release_irq(struct sdio_func *func) if (func->irq_handler) { func->irq_handler = NULL; sdio_card_irq_put(func->card); + sdio_single_irq_set(func->card); } ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IENx, 0, ®); diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index d8dffc992ce2..4910dec47bb7 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -191,6 +191,7 @@ struct mmc_card { struct sdio_cccr cccr; /* common card info */ struct sdio_cis cis; /* common tuple info */ struct sdio_func *sdio_func[SDIO_MAX_FUNCS]; /* SDIO functions (devices) */ + struct sdio_func *sdio_single_irq; /* SDIO function when only one IRQ active */ unsigned num_info; /* number of info strings */ const char **info; /* info strings */ struct sdio_func_tuple *tuples; /* unknown common tuples */ -- cgit From 7311bef0697bcfbbcb898c3c22e61e23f203ae9d Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 11 May 2011 16:51:11 +0000 Subject: mmc: tmio: runtime suspend the controller, where possible The TMIO MMC controller cannot be powered off to save power, when no card is plugged in, because then it will not be able to detect a new card-insertion event. On some implementations, however, it is possible to switch to using another source to detect card insertion. This patch adds support for such implementations. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Chris Ball --- drivers/mmc/host/tmio_mmc.h | 3 ++ drivers/mmc/host/tmio_mmc_pio.c | 64 +++++++++++++++++++++++++++++++++++++---- include/linux/mfd/tmio.h | 17 +++++++++++ 3 files changed, 78 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h index c6bf726c8f44..8260bc2c34e3 100644 --- a/drivers/mmc/host/tmio_mmc.h +++ b/drivers/mmc/host/tmio_mmc.h @@ -131,4 +131,7 @@ int tmio_mmc_host_resume(struct device *dev); #define tmio_mmc_host_resume NULL #endif +int tmio_mmc_host_runtime_suspend(struct device *dev); +int tmio_mmc_host_runtime_resume(struct device *dev); + #endif diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c index af5d4f6d2233..ad6347bb02dd 100644 --- a/drivers/mmc/host/tmio_mmc_pio.c +++ b/drivers/mmc/host/tmio_mmc_pio.c @@ -746,6 +746,7 @@ fail: static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) { struct tmio_mmc_host *host = mmc_priv(mmc); + struct tmio_mmc_data *pdata = host->pdata; unsigned long flags; spin_lock_irqsave(&host->lock, flags); @@ -775,13 +776,24 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) /* Power sequence - OFF -> UP -> ON */ if (ios->power_mode == MMC_POWER_UP) { + if ((pdata->flags & TMIO_MMC_HAS_COLD_CD) && !pdata->power) { + pm_runtime_get_sync(&host->pdev->dev); + pdata->power = true; + } /* power up SD bus */ if (host->set_pwr) host->set_pwr(host->pdev, 1); } else if (ios->power_mode == MMC_POWER_OFF || !ios->clock) { /* power down SD bus */ - if (ios->power_mode == MMC_POWER_OFF && host->set_pwr) - host->set_pwr(host->pdev, 0); + if (ios->power_mode == MMC_POWER_OFF) { + if (host->set_pwr) + host->set_pwr(host->pdev, 0); + if ((pdata->flags & TMIO_MMC_HAS_COLD_CD) && + pdata->power) { + pdata->power = false; + pm_runtime_put(&host->pdev->dev); + } + } tmio_mmc_clk_stop(host); } else { /* start bus clock */ @@ -853,6 +865,7 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host, if (!mmc) return -ENOMEM; + pdata->dev = &pdev->dev; _host = mmc_priv(mmc); _host->pdata = pdata; _host->mmc = mmc; @@ -886,6 +899,7 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host, else mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; + pdata->power = false; pm_runtime_enable(&pdev->dev); ret = pm_runtime_resume(&pdev->dev); if (ret < 0) @@ -907,7 +921,8 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host, tmio_mmc_request_dma(_host, pdata); /* We have to keep the device powered for its card detection to work */ - pm_runtime_get_noresume(&pdev->dev); + if (!(pdata->flags & TMIO_MMC_HAS_COLD_CD)) + pm_runtime_get_noresume(&pdev->dev); mmc_add_host(mmc); @@ -937,15 +952,25 @@ void tmio_mmc_host_remove(struct tmio_mmc_host *host) { struct platform_device *pdev = host->pdev; + /* + * We don't have to manipulate pdata->power here: if there is a card in + * the slot, the runtime PM is active and our .runtime_resume() will not + * be run. If there is no card in the slot and the platform can suspend + * the controller, the runtime PM is suspended and pdata->power == false, + * so, our .runtime_resume() will not try to detect a card in the slot. + */ + if (host->pdata->flags & TMIO_MMC_HAS_COLD_CD) + pm_runtime_get_sync(&pdev->dev); + mmc_remove_host(host->mmc); cancel_delayed_work_sync(&host->delayed_reset_work); tmio_mmc_release_dma(host); - iounmap(host->ctl); - mmc_free_host(host->mmc); - /* Compensate for pm_runtime_get_sync() in probe() above */ pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); + + iounmap(host->ctl); + mmc_free_host(host->mmc); } EXPORT_SYMBOL(tmio_mmc_host_remove); @@ -970,6 +995,9 @@ int tmio_mmc_host_resume(struct device *dev) struct mmc_host *mmc = dev_get_drvdata(dev); struct tmio_mmc_host *host = mmc_priv(mmc); + /* The MMC core will perform the complete set up */ + host->pdata->power = false; + if (!host->pm_error) pm_runtime_get_sync(dev); @@ -982,4 +1010,28 @@ EXPORT_SYMBOL(tmio_mmc_host_resume); #endif /* CONFIG_PM */ +int tmio_mmc_host_runtime_suspend(struct device *dev) +{ + return 0; +} +EXPORT_SYMBOL(tmio_mmc_host_runtime_suspend); + +int tmio_mmc_host_runtime_resume(struct device *dev) +{ + struct mmc_host *mmc = dev_get_drvdata(dev); + struct tmio_mmc_host *host = mmc_priv(mmc); + struct tmio_mmc_data *pdata = host->pdata; + + tmio_mmc_reset(host); + + if (pdata->power) { + /* Only entered after a card-insert interrupt */ + tmio_mmc_set_ios(mmc, &mmc->ios); + mmc_detect_change(mmc, msecs_to_jiffies(100)); + } + + return 0; +} +EXPORT_SYMBOL(tmio_mmc_host_runtime_resume); + MODULE_LICENSE("GPL v2"); diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h index 8e70310ee945..5a90266c3a5a 100644 --- a/include/linux/mfd/tmio.h +++ b/include/linux/mfd/tmio.h @@ -4,6 +4,7 @@ #include #include #include +#include #define tmio_ioread8(addr) readb(addr) #define tmio_ioread16(addr) readw(addr) @@ -61,6 +62,12 @@ * Some controllers can support SDIO IRQ signalling. */ #define TMIO_MMC_SDIO_IRQ (1 << 2) +/* + * Some platforms can detect card insertion events with controller powered + * down, in which case they have to call tmio_mmc_cd_wakeup() to power up the + * controller and report the event to the driver. + */ +#define TMIO_MMC_HAS_COLD_CD (1 << 3) int tmio_core_mmc_enable(void __iomem *cnf, int shift, unsigned long base); int tmio_core_mmc_resume(void __iomem *cnf, int shift, unsigned long base); @@ -82,11 +89,21 @@ struct tmio_mmc_data { unsigned long flags; u32 ocr_mask; /* available voltages */ struct tmio_mmc_dma *dma; + struct device *dev; + bool power; void (*set_pwr)(struct platform_device *host, int state); void (*set_clk_div)(struct platform_device *host, int state); int (*get_cd)(struct platform_device *host); }; +static inline void tmio_mmc_cd_wakeup(struct tmio_mmc_data *pdata) +{ + if (pdata && !pdata->power) { + pdata->power = true; + pm_runtime_get(pdata->dev); + } +} + /* * data for the NAND controller */ -- cgit From 2595880481ac894d390365092de9aaf92b44e147 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 11 May 2011 16:51:15 +0000 Subject: mmc: sdhi: allow powering down controller with no card inserted Supply a link to TMIO private data for platforms to implement their own card detection. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Chris Ball --- drivers/mmc/host/sh_mobile_sdhi.c | 6 ++++++ include/linux/mmc/sh_mobile_sdhi.h | 4 ++++ 2 files changed, 10 insertions(+) (limited to 'include/linux') diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c index d264bbeb529b..b3654293017b 100644 --- a/drivers/mmc/host/sh_mobile_sdhi.c +++ b/drivers/mmc/host/sh_mobile_sdhi.c @@ -71,6 +71,7 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev) } mmc_data = &priv->mmc_data; + p->pdata = mmc_data; snprintf(clk_name, sizeof(clk_name), "sdhi%d", pdev->id); priv->clk = clk_get(&pdev->dev, clk_name); @@ -159,8 +160,11 @@ static int sh_mobile_sdhi_remove(struct platform_device *pdev) struct mmc_host *mmc = platform_get_drvdata(pdev); struct tmio_mmc_host *host = mmc_priv(mmc); struct sh_mobile_sdhi *priv = container_of(host->pdata, struct sh_mobile_sdhi, mmc_data); + struct sh_mobile_sdhi_info *p = pdev->dev.platform_data; int i, irq; + p->pdata = NULL; + for (i = 0; i < 3; i++) { irq = platform_get_irq(pdev, i); if (irq >= 0) @@ -178,6 +182,8 @@ static int sh_mobile_sdhi_remove(struct platform_device *pdev) static const struct dev_pm_ops tmio_mmc_dev_pm_ops = { .suspend = tmio_mmc_host_suspend, .resume = tmio_mmc_host_resume, + .runtime_suspend = tmio_mmc_host_runtime_suspend, + .runtime_resume = tmio_mmc_host_runtime_resume, }; static struct platform_driver sh_mobile_sdhi_driver = { diff --git a/include/linux/mmc/sh_mobile_sdhi.h b/include/linux/mmc/sh_mobile_sdhi.h index c981b959760f..faf32b6ec185 100644 --- a/include/linux/mmc/sh_mobile_sdhi.h +++ b/include/linux/mmc/sh_mobile_sdhi.h @@ -3,12 +3,16 @@ #include +struct platform_device; +struct tmio_mmc_data; + struct sh_mobile_sdhi_info { int dma_slave_tx; int dma_slave_rx; unsigned long tmio_flags; unsigned long tmio_caps; u32 tmio_ocr_mask; /* available MMC voltages */ + struct tmio_mmc_data *pdata; void (*set_pwr)(struct platform_device *pdev, int state); int (*get_cd)(struct platform_device *pdev); }; -- cgit From 4c4cb171054230c2e58ed6574d7faa1871c75bbe Mon Sep 17 00:00:00 2001 From: Philip Rakity Date: Fri, 13 May 2011 11:17:18 +0530 Subject: mmc: core: add support for eMMC Dual Data Rate eMMC voltage change not required for 1.8V. 3.3V and 1.8V vcc are capable of doing DDR. vccq of 1.8v is not required. Signed-off-by: Philip Rakity Reviewed-by: Arindam Nath Signed-off-by: Chris Ball --- drivers/mmc/core/core.c | 14 ++------------ drivers/mmc/core/core.h | 2 -- drivers/mmc/core/mmc.c | 35 ++++++++++++++++++++++++++++++----- include/linux/mmc/host.h | 1 + 4 files changed, 33 insertions(+), 19 deletions(-) (limited to 'include/linux') diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 94c8d5a9ecae..7863eedf3d9a 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -717,23 +717,13 @@ void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode) mmc_set_ios(host); } -/* - * Change data bus width and DDR mode of a host. - */ -void mmc_set_bus_width_ddr(struct mmc_host *host, unsigned int width, - unsigned int ddr) -{ - host->ios.bus_width = width; - host->ios.ddr = ddr; - mmc_set_ios(host); -} - /* * Change data bus width of a host. */ void mmc_set_bus_width(struct mmc_host *host, unsigned int width) { - mmc_set_bus_width_ddr(host, width, MMC_SDR_MODE); + host->ios.bus_width = width; + mmc_set_ios(host); } /** diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index 53d23c240324..d9411ed2a39b 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h @@ -38,8 +38,6 @@ void mmc_ungate_clock(struct mmc_host *host); void mmc_set_ungated(struct mmc_host *host); void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode); void mmc_set_bus_width(struct mmc_host *host, unsigned int width); -void mmc_set_bus_width_ddr(struct mmc_host *host, unsigned int width, - unsigned int ddr); u32 mmc_select_voltage(struct mmc_host *host, u32 ocr); int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, bool cmd11); diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index a2c795e8f9dd..0433fe66cbad 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -20,6 +20,7 @@ #include "core.h" #include "bus.h" #include "mmc_ops.h" +#include "sd_ops.h" static const unsigned int tran_exp[] = { 10000, 100000, 1000000, 10000000, @@ -633,10 +634,14 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, */ if (mmc_card_highspeed(card)) { if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_8V) - && (host->caps & (MMC_CAP_1_8V_DDR))) + && ((host->caps & (MMC_CAP_1_8V_DDR | + MMC_CAP_UHS_DDR50)) + == (MMC_CAP_1_8V_DDR | MMC_CAP_UHS_DDR50))) ddr = MMC_1_8V_DDR_MODE; else if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_2V) - && (host->caps & (MMC_CAP_1_2V_DDR))) + && ((host->caps & (MMC_CAP_1_2V_DDR | + MMC_CAP_UHS_DDR50)) + == (MMC_CAP_1_2V_DDR | MMC_CAP_UHS_DDR50))) ddr = MMC_1_2V_DDR_MODE; } @@ -670,8 +675,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, ext_csd_bits[idx][0], 0); if (!err) { - mmc_set_bus_width_ddr(card->host, - bus_width, MMC_SDR_MODE); + mmc_set_bus_width(card->host, bus_width); /* * If controller can't handle bus width test, * use the highest bus width to maintain @@ -697,8 +701,29 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, 1 << bus_width, ddr); goto free_card; } else if (ddr) { + /* + * eMMC cards can support 3.3V to 1.2V i/o (vccq) + * signaling. + * + * EXT_CSD_CARD_TYPE_DDR_1_8V means 3.3V or 1.8V vccq. + * + * 1.8V vccq at 3.3V core voltage (vcc) is not required + * in the JEDEC spec for DDR. + * + * Do not force change in vccq since we are obviously + * working and no change to vccq is needed. + * + * WARNING: eMMC rules are NOT the same as SD DDR + */ + if (ddr == EXT_CSD_CARD_TYPE_DDR_1_2V) { + err = mmc_set_signal_voltage(host, + MMC_SIGNAL_VOLTAGE_120, 0); + if (err) + goto err; + } mmc_card_set_ddr_mode(card); - mmc_set_bus_width_ddr(card->host, bus_width, ddr); + mmc_set_timing(card->host, MMC_TIMING_UHS_DDR50); + mmc_set_bus_width(card->host, bus_width); } } diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 6716bd12eccd..de32e6aa018a 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -66,6 +66,7 @@ struct mmc_ios { #define MMC_SIGNAL_VOLTAGE_330 0 #define MMC_SIGNAL_VOLTAGE_180 1 +#define MMC_SIGNAL_VOLTAGE_120 2 unsigned char drv_type; /* driver type (A, B, C, D) */ -- cgit From c59de9287993b5c36f9005f745a3ce0b1008131d Mon Sep 17 00:00:00 2001 From: Andrei Warkentin Date: Mon, 23 May 2011 15:06:35 -0500 Subject: mmc: quirks: Add/remove quirks conditional support. Conditional add/remove quirks for MMC and SD. Signed-off-by: Andrei Warkentin Signed-off-by: Chris Ball --- include/linux/mmc/card.h | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 4910dec47bb7..7190aa2096f7 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -273,16 +273,14 @@ struct mmc_fixup { card->cid.month) /* - * This hook just adds a quirk unconditionally. + * Unconditionally quirk add/remove. */ + static inline void __maybe_unused add_quirk(struct mmc_card *card, int data) { card->quirks |= data; } -/* - * This hook just removes a quirk unconditionally. - */ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data) { card->quirks &= ~data; @@ -308,6 +306,40 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data) #define mmc_sd_card_set_uhs(c) ((c)->state |= MMC_STATE_ULTRAHIGHSPEED) #define mmc_card_set_ext_capacity(c) ((c)->state |= MMC_CARD_SDXC) +/* + * Quirk add/remove for MMC products. + */ + +static inline void __maybe_unused add_quirk_mmc(struct mmc_card *card, int data) +{ + if (mmc_card_mmc(card)) + card->quirks |= data; +} + +static inline void __maybe_unused remove_quirk_mmc(struct mmc_card *card, + int data) +{ + if (mmc_card_mmc(card)) + card->quirks &= ~data; +} + +/* + * Quirk add/remove for SD products. + */ + +static inline void __maybe_unused add_quirk_sd(struct mmc_card *card, int data) +{ + if (mmc_card_sd(card)) + card->quirks |= data; +} + +static inline void __maybe_unused remove_quirk_sd(struct mmc_card *card, + int data) +{ + if (mmc_card_sd(card)) + card->quirks &= ~data; +} + static inline int mmc_card_lenient_fn0(const struct mmc_card *c) { return c->quirks & MMC_QUIRK_LENIENT_FN0; -- cgit From aecb7b64dd9e2512c7a4c7e61dd781415d3dac5a Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 24 May 2011 14:04:09 +0530 Subject: dmaengine/dw_dmac: Update maintainer-ship Nobody is currently maintaining dw_dmac. We are using dw_dmac for SPEAr13xx and are currently maintaining it. After discussing with Vinod, sending this patch to update maintainer-ship of dw_dmac. Signed-off-by: Viresh Kumar Acked-by: Havard Skinnemoen Signed-off-by: Vinod Koul --- MAINTAINERS | 7 +++++++ drivers/dma/dw_dmac.c | 2 ++ drivers/dma/dw_dmac_regs.h | 1 + include/linux/dw_dmac.h | 1 + 4 files changed, 11 insertions(+) (limited to 'include/linux') diff --git a/MAINTAINERS b/MAINTAINERS index 6b4b9cdec370..8f4413014b2d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5401,6 +5401,13 @@ L: linux-serial@vger.kernel.org S: Maintained F: drivers/tty/serial +SYNOPSYS DESIGNWARE DMAC DRIVER +M: Viresh Kumar +S: Maintained +F: include/linux/dw_dmac.h +F: drivers/dma/dw_dmac_regs.h +F: drivers/dma/dw_dmac.c + TIMEKEEPING, NTP M: John Stultz M: Thomas Gleixner diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index eec675bf4f95..efd836dfb65a 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c @@ -3,6 +3,7 @@ * AVR32 systems.) * * Copyright (C) 2007-2008 Atmel Corporation + * Copyright (C) 2010-2011 ST Microelectronics * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -1575,3 +1576,4 @@ module_exit(dw_exit); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller driver"); MODULE_AUTHOR("Haavard Skinnemoen "); +MODULE_AUTHOR("Viresh Kumar "); diff --git a/drivers/dma/dw_dmac_regs.h b/drivers/dma/dw_dmac_regs.h index c968597c32ab..c3419518d701 100644 --- a/drivers/dma/dw_dmac_regs.h +++ b/drivers/dma/dw_dmac_regs.h @@ -2,6 +2,7 @@ * Driver for the Synopsys DesignWare AHB DMA Controller * * Copyright (C) 2005-2007 Atmel Corporation + * Copyright (C) 2010-2011 ST Microelectronics * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/include/linux/dw_dmac.h b/include/linux/dw_dmac.h index 6998d9376ef9..4bfe0a2f7d50 100644 --- a/include/linux/dw_dmac.h +++ b/include/linux/dw_dmac.h @@ -3,6 +3,7 @@ * AVR32 systems.) * * Copyright (C) 2007 Atmel Corporation + * Copyright (C) 2010-2011 ST Microelectronics * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as -- cgit From 7bf02ea22c6cdd09e2d3f1d3c3fe366b834ae9af Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Tue, 24 May 2011 17:11:16 -0700 Subject: arch, mm: filter disallowed nodes from arch specific show_mem functions Architectures that implement their own show_mem() function did not pass the filter argument to show_free_areas() to appropriately avoid emitting the state of nodes that are disallowed in the current context. This patch now passes the filter argument to show_free_areas() so those nodes are now avoided. This patch also removes the show_free_areas() wrapper around __show_free_areas() and converts existing callers to pass an empty filter. ia64 emits additional information for each node, so skip_free_areas_zone() must be made global to filter disallowed nodes and it is converted to use a nid argument rather than a zone for this use case. Signed-off-by: David Rientjes Cc: Russell King Cc: Tony Luck Cc: Fenghua Yu Cc: Kyle McMartin Cc: Helge Deller Cc: James Bottomley Cc: "David S. Miller" Cc: Guan Xuetao Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/arm/mm/init.c | 2 +- arch/ia64/mm/contig.c | 10 ++++++---- arch/ia64/mm/discontig.c | 10 ++++++---- arch/parisc/mm/init.c | 2 +- arch/sparc/kernel/setup_32.c | 2 +- arch/sparc/mm/init_32.c | 2 +- arch/unicore32/mm/init.c | 2 +- drivers/net/ioc3-eth.c | 2 +- drivers/tty/serial/68328serial.c | 2 +- include/linux/mm.h | 6 +++--- lib/show_mem.c | 2 +- mm/nommu.c | 6 +++--- mm/page_alloc.c | 22 ++++++++-------------- 13 files changed, 34 insertions(+), 36 deletions(-) (limited to 'include/linux') diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 76f82ae44efb..3f17ea146f0e 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -85,7 +85,7 @@ void show_mem(unsigned int filter) struct meminfo * mi = &meminfo; printk("Mem-info:\n"); - show_free_areas(); + show_free_areas(filter); for_each_bank (i, mi) { struct membank *bank = &mi->bank[i]; diff --git a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c index 9a018cde5d84..f114a3b14c6a 100644 --- a/arch/ia64/mm/contig.c +++ b/arch/ia64/mm/contig.c @@ -44,13 +44,16 @@ void show_mem(unsigned int filter) pg_data_t *pgdat; printk(KERN_INFO "Mem-info:\n"); - show_free_areas(); + show_free_areas(filter); printk(KERN_INFO "Node memory in pages:\n"); for_each_online_pgdat(pgdat) { unsigned long present; unsigned long flags; int shared = 0, cached = 0, reserved = 0; + int nid = pgdat->node_id; + if (skip_free_areas_node(filter, nid)) + continue; pgdat_resize_lock(pgdat, &flags); present = pgdat->node_present_pages; for(i = 0; i < pgdat->node_spanned_pages; i++) { @@ -64,8 +67,7 @@ void show_mem(unsigned int filter) if (max_gap < LARGE_GAP) continue; #endif - i = vmemmap_find_next_valid_pfn(pgdat->node_id, - i) - 1; + i = vmemmap_find_next_valid_pfn(nid, i) - 1; continue; } if (PageReserved(page)) @@ -81,7 +83,7 @@ void show_mem(unsigned int filter) total_cached += cached; total_shared += shared; printk(KERN_INFO "Node %4d: RAM: %11ld, rsvd: %8d, " - "shrd: %10d, swpd: %10d\n", pgdat->node_id, + "shrd: %10d, swpd: %10d\n", nid, present, reserved, shared, cached); } printk(KERN_INFO "%ld pages of RAM\n", total_present); diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c index 82ab1bc6afb1..c641333cd997 100644 --- a/arch/ia64/mm/discontig.c +++ b/arch/ia64/mm/discontig.c @@ -622,13 +622,16 @@ void show_mem(unsigned int filter) pg_data_t *pgdat; printk(KERN_INFO "Mem-info:\n"); - show_free_areas(); + show_free_areas(filter); printk(KERN_INFO "Node memory in pages:\n"); for_each_online_pgdat(pgdat) { unsigned long present; unsigned long flags; int shared = 0, cached = 0, reserved = 0; + int nid = pgdat->node_id; + if (skip_free_areas_node(filter, nid)) + continue; pgdat_resize_lock(pgdat, &flags); present = pgdat->node_present_pages; for(i = 0; i < pgdat->node_spanned_pages; i++) { @@ -638,8 +641,7 @@ void show_mem(unsigned int filter) if (pfn_valid(pgdat->node_start_pfn + i)) page = pfn_to_page(pgdat->node_start_pfn + i); else { - i = vmemmap_find_next_valid_pfn(pgdat->node_id, - i) - 1; + i = vmemmap_find_next_valid_pfn(nid, i) - 1; continue; } if (PageReserved(page)) @@ -655,7 +657,7 @@ void show_mem(unsigned int filter) total_cached += cached; total_shared += shared; printk(KERN_INFO "Node %4d: RAM: %11ld, rsvd: %8d, " - "shrd: %10d, swpd: %10d\n", pgdat->node_id, + "shrd: %10d, swpd: %10d\n", nid, present, reserved, shared, cached); } printk(KERN_INFO "%ld pages of RAM\n", total_present); diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index 5fa1e273006e..c5c9c65e502d 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c @@ -686,7 +686,7 @@ void show_mem(unsigned int filter) int shared = 0, cached = 0; printk(KERN_INFO "Mem-info:\n"); - show_free_areas(); + show_free_areas(filter); #ifndef CONFIG_DISCONTIGMEM i = max_mapnr; while (i-- > 0) { diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c index 3609bdee9ed2..3249d3f3234d 100644 --- a/arch/sparc/kernel/setup_32.c +++ b/arch/sparc/kernel/setup_32.c @@ -82,7 +82,7 @@ static void prom_sync_me(void) "nop\n\t" : : "r" (&trapbase)); prom_printf("PROM SYNC COMMAND...\n"); - show_free_areas(); + show_free_areas(0); if(current->pid != 0) { local_irq_enable(); sys_sync(); diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c index 4c31e2b6e71b..28c2cc81c9a9 100644 --- a/arch/sparc/mm/init_32.c +++ b/arch/sparc/mm/init_32.c @@ -78,7 +78,7 @@ void __init kmap_init(void) void show_mem(unsigned int filter) { printk("Mem-info:\n"); - show_free_areas(); + show_free_areas(filter); printk("Free swap: %6ldkB\n", nr_swap_pages << (PAGE_SHIFT-10)); printk("%ld pages of RAM\n", totalram_pages); diff --git a/arch/unicore32/mm/init.c b/arch/unicore32/mm/init.c index 1fc02633f700..2d3e7112d2a3 100644 --- a/arch/unicore32/mm/init.c +++ b/arch/unicore32/mm/init.c @@ -62,7 +62,7 @@ void show_mem(unsigned int filter) struct meminfo *mi = &meminfo; printk(KERN_DEFAULT "Mem-info:\n"); - show_free_areas(); + show_free_areas(filter); for_each_bank(i, mi) { struct membank *bank = &mi->bank[i]; diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c index 96c95617195f..32f07f868d89 100644 --- a/drivers/net/ioc3-eth.c +++ b/drivers/net/ioc3-eth.c @@ -915,7 +915,7 @@ static void ioc3_alloc_rings(struct net_device *dev) skb = ioc3_alloc_skb(RX_BUF_ALLOC_SIZE, GFP_ATOMIC); if (!skb) { - show_free_areas(); + show_free_areas(0); continue; } diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c index d5bfd41707e7..e0a77540b8ca 100644 --- a/drivers/tty/serial/68328serial.c +++ b/drivers/tty/serial/68328serial.c @@ -281,7 +281,7 @@ static void receive_chars(struct m68k_serial *info, unsigned short rx) #ifdef CONFIG_MAGIC_SYSRQ } else if (ch == 0x10) { /* ^P */ show_state(); - show_free_areas(); + show_free_areas(0); show_buffers(); /* show_net_buffers(); */ return; diff --git a/include/linux/mm.h b/include/linux/mm.h index 6507dde38b16..1746f67c33de 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -862,13 +862,13 @@ extern void pagefault_out_of_memory(void); #define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK) /* - * Flags passed to show_mem() and __show_free_areas() to suppress output in + * Flags passed to show_mem() and show_free_areas() to suppress output in * various contexts. */ #define SHOW_MEM_FILTER_NODES (0x0001u) /* filter disallowed nodes */ -extern void show_free_areas(void); -extern void __show_free_areas(unsigned int flags); +extern void show_free_areas(unsigned int flags); +extern bool skip_free_areas_node(unsigned int flags, int nid); int shmem_lock(struct file *file, int lock, struct user_struct *user); struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags); diff --git a/lib/show_mem.c b/lib/show_mem.c index 90cbe4bb5960..4407f8c9b1f7 100644 --- a/lib/show_mem.c +++ b/lib/show_mem.c @@ -16,7 +16,7 @@ void show_mem(unsigned int filter) nonshared = 0, highmem = 0; printk("Mem-Info:\n"); - __show_free_areas(filter); + show_free_areas(filter); for_each_online_pgdat(pgdat) { unsigned long i, flags; diff --git a/mm/nommu.c b/mm/nommu.c index c4c542c736a9..5afce48ce339 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -1235,7 +1235,7 @@ error_free: enomem: printk("Allocation of length %lu from process %d (%s) failed\n", len, current->pid, current->comm); - show_free_areas(); + show_free_areas(0); return -ENOMEM; } @@ -1468,14 +1468,14 @@ error_getting_vma: printk(KERN_WARNING "Allocation of vma for %lu byte allocation" " from process %d failed\n", len, current->pid); - show_free_areas(); + show_free_areas(0); return -ENOMEM; error_getting_region: printk(KERN_WARNING "Allocation of vm region for %lu byte allocation" " from process %d failed\n", len, current->pid); - show_free_areas(); + show_free_areas(0); return -ENOMEM; } EXPORT_SYMBOL(do_mmap_pgoff); diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 9d5498e2d0f5..b1447522d346 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -2473,10 +2473,10 @@ void si_meminfo_node(struct sysinfo *val, int nid) #endif /* - * Determine whether the zone's node should be displayed or not, depending on - * whether SHOW_MEM_FILTER_NODES was passed to __show_free_areas(). + * Determine whether the node should be displayed or not, depending on whether + * SHOW_MEM_FILTER_NODES was passed to show_free_areas(). */ -static bool skip_free_areas_zone(unsigned int flags, const struct zone *zone) +bool skip_free_areas_node(unsigned int flags, int nid) { bool ret = false; @@ -2484,8 +2484,7 @@ static bool skip_free_areas_zone(unsigned int flags, const struct zone *zone) goto out; get_mems_allowed(); - ret = !node_isset(zone->zone_pgdat->node_id, - cpuset_current_mems_allowed); + ret = !node_isset(nid, cpuset_current_mems_allowed); put_mems_allowed(); out: return ret; @@ -2500,13 +2499,13 @@ out: * Suppresses nodes that are not allowed by current's cpuset if * SHOW_MEM_FILTER_NODES is passed. */ -void __show_free_areas(unsigned int filter) +void show_free_areas(unsigned int filter) { int cpu; struct zone *zone; for_each_populated_zone(zone) { - if (skip_free_areas_zone(filter, zone)) + if (skip_free_areas_node(filter, zone_to_nid(zone))) continue; show_node(zone); printk("%s per-cpu:\n", zone->name); @@ -2549,7 +2548,7 @@ void __show_free_areas(unsigned int filter) for_each_populated_zone(zone) { int i; - if (skip_free_areas_zone(filter, zone)) + if (skip_free_areas_node(filter, zone_to_nid(zone))) continue; show_node(zone); printk("%s" @@ -2618,7 +2617,7 @@ void __show_free_areas(unsigned int filter) for_each_populated_zone(zone) { unsigned long nr[MAX_ORDER], flags, order, total = 0; - if (skip_free_areas_zone(filter, zone)) + if (skip_free_areas_node(filter, zone_to_nid(zone))) continue; show_node(zone); printk("%s: ", zone->name); @@ -2639,11 +2638,6 @@ void __show_free_areas(unsigned int filter) show_swap_cache_info(); } -void show_free_areas(void) -{ - __show_free_areas(0); -} - static void zoneref_set_zone(struct zone *zone, struct zoneref *zoneref) { zoneref->zone = zone; -- cgit From fa25c503dfa203b921199ea42c0046c89f2ed49f Mon Sep 17 00:00:00 2001 From: KOSAKI Motohiro Date: Tue, 24 May 2011 17:11:28 -0700 Subject: mm: per-node vmstat: show proper vmstats commit 2ac390370a ("writeback: add /sys/devices/system/node//vmstat") added vmstat entry. But strangely it only show nr_written and nr_dirtied. # cat /sys/devices/system/node/node20/vmstat nr_written 0 nr_dirtied 0 Of course, It's not adequate. With this patch, the vmstat show all vm stastics as /proc/vmstat. # cat /sys/devices/system/node/node0/vmstat nr_free_pages 899224 nr_inactive_anon 201 nr_active_anon 17380 nr_inactive_file 31572 nr_active_file 28277 nr_unevictable 0 nr_mlock 0 nr_anon_pages 17321 nr_mapped 8640 nr_file_pages 60107 nr_dirty 33 nr_writeback 0 nr_slab_reclaimable 6850 nr_slab_unreclaimable 7604 nr_page_table_pages 3105 nr_kernel_stack 175 nr_unstable 0 nr_bounce 0 nr_vmscan_write 0 nr_writeback_temp 0 nr_isolated_anon 0 nr_isolated_file 0 nr_shmem 260 nr_dirtied 1050 nr_written 938 numa_hit 962872 numa_miss 0 numa_foreign 0 numa_interleave 8617 numa_local 962872 numa_other 0 nr_anon_transparent_hugepages 0 [akpm@linux-foundation.org: no externs in .c files] Signed-off-by: KOSAKI Motohiro Cc: Michael Rubin Cc: Wu Fengguang Acked-by: David Rientjes Cc: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/base/node.c | 14 ++- include/linux/vmstat.h | 4 +- mm/vmstat.c | 261 +++++++++++++++++++++++++------------------------ 3 files changed, 144 insertions(+), 135 deletions(-) (limited to 'include/linux') diff --git a/drivers/base/node.c b/drivers/base/node.c index b3b72d64e805..793f796c4da3 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -179,11 +180,14 @@ static ssize_t node_read_vmstat(struct sys_device *dev, struct sysdev_attribute *attr, char *buf) { int nid = dev->id; - return sprintf(buf, - "nr_written %lu\n" - "nr_dirtied %lu\n", - node_page_state(nid, NR_WRITTEN), - node_page_state(nid, NR_DIRTIED)); + int i; + int n = 0; + + for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++) + n += sprintf(buf+n, "%s %lu\n", vmstat_text[i], + node_page_state(nid, i)); + + return n; } static SYSDEV_ATTR(vmstat, S_IRUGO, node_read_vmstat, NULL); diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h index 2b3831b58aa4..e73d1030f2f7 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h @@ -313,6 +313,8 @@ static inline void __dec_zone_page_state(struct page *page, #define set_pgdat_percpu_threshold(pgdat, callback) { } static inline void refresh_cpu_vm_stats(int cpu) { } -#endif +#endif /* CONFIG_SMP */ + +extern const char * const vmstat_text[]; #endif /* _LINUX_VMSTAT_H */ diff --git a/mm/vmstat.c b/mm/vmstat.c index 897ea9e88238..209546a8bdd5 100644 --- a/mm/vmstat.c +++ b/mm/vmstat.c @@ -659,6 +659,138 @@ static void walk_zones_in_node(struct seq_file *m, pg_data_t *pgdat, } #endif +#if defined(CONFIG_PROC_FS) || defined(CONFIG_SYSFS) +#ifdef CONFIG_ZONE_DMA +#define TEXT_FOR_DMA(xx) xx "_dma", +#else +#define TEXT_FOR_DMA(xx) +#endif + +#ifdef CONFIG_ZONE_DMA32 +#define TEXT_FOR_DMA32(xx) xx "_dma32", +#else +#define TEXT_FOR_DMA32(xx) +#endif + +#ifdef CONFIG_HIGHMEM +#define TEXT_FOR_HIGHMEM(xx) xx "_high", +#else +#define TEXT_FOR_HIGHMEM(xx) +#endif + +#define TEXTS_FOR_ZONES(xx) TEXT_FOR_DMA(xx) TEXT_FOR_DMA32(xx) xx "_normal", \ + TEXT_FOR_HIGHMEM(xx) xx "_movable", + +const char * const vmstat_text[] = { + /* Zoned VM counters */ + "nr_free_pages", + "nr_inactive_anon", + "nr_active_anon", + "nr_inactive_file", + "nr_active_file", + "nr_unevictable", + "nr_mlock", + "nr_anon_pages", + "nr_mapped", + "nr_file_pages", + "nr_dirty", + "nr_writeback", + "nr_slab_reclaimable", + "nr_slab_unreclaimable", + "nr_page_table_pages", + "nr_kernel_stack", + "nr_unstable", + "nr_bounce", + "nr_vmscan_write", + "nr_writeback_temp", + "nr_isolated_anon", + "nr_isolated_file", + "nr_shmem", + "nr_dirtied", + "nr_written", + +#ifdef CONFIG_NUMA + "numa_hit", + "numa_miss", + "numa_foreign", + "numa_interleave", + "numa_local", + "numa_other", +#endif + "nr_anon_transparent_hugepages", + "nr_dirty_threshold", + "nr_dirty_background_threshold", + +#ifdef CONFIG_VM_EVENT_COUNTERS + "pgpgin", + "pgpgout", + "pswpin", + "pswpout", + + TEXTS_FOR_ZONES("pgalloc") + + "pgfree", + "pgactivate", + "pgdeactivate", + + "pgfault", + "pgmajfault", + + TEXTS_FOR_ZONES("pgrefill") + TEXTS_FOR_ZONES("pgsteal") + TEXTS_FOR_ZONES("pgscan_kswapd") + TEXTS_FOR_ZONES("pgscan_direct") + +#ifdef CONFIG_NUMA + "zone_reclaim_failed", +#endif + "pginodesteal", + "slabs_scanned", + "kswapd_steal", + "kswapd_inodesteal", + "kswapd_low_wmark_hit_quickly", + "kswapd_high_wmark_hit_quickly", + "kswapd_skip_congestion_wait", + "pageoutrun", + "allocstall", + + "pgrotated", + +#ifdef CONFIG_COMPACTION + "compact_blocks_moved", + "compact_pages_moved", + "compact_pagemigrate_failed", + "compact_stall", + "compact_fail", + "compact_success", +#endif + +#ifdef CONFIG_HUGETLB_PAGE + "htlb_buddy_alloc_success", + "htlb_buddy_alloc_fail", +#endif + "unevictable_pgs_culled", + "unevictable_pgs_scanned", + "unevictable_pgs_rescued", + "unevictable_pgs_mlocked", + "unevictable_pgs_munlocked", + "unevictable_pgs_cleared", + "unevictable_pgs_stranded", + "unevictable_pgs_mlockfreed", + +#ifdef CONFIG_TRANSPARENT_HUGEPAGE + "thp_fault_alloc", + "thp_fault_fallback", + "thp_collapse_alloc", + "thp_collapse_alloc_failed", + "thp_split", +#endif + +#endif /* CONFIG_VM_EVENTS_COUNTERS */ +}; +#endif /* CONFIG_PROC_FS || CONFIG_SYSFS */ + + #ifdef CONFIG_PROC_FS static void frag_show_print(struct seq_file *m, pg_data_t *pgdat, struct zone *zone) @@ -831,135 +963,6 @@ static const struct file_operations pagetypeinfo_file_ops = { .release = seq_release, }; -#ifdef CONFIG_ZONE_DMA -#define TEXT_FOR_DMA(xx) xx "_dma", -#else -#define TEXT_FOR_DMA(xx) -#endif - -#ifdef CONFIG_ZONE_DMA32 -#define TEXT_FOR_DMA32(xx) xx "_dma32", -#else -#define TEXT_FOR_DMA32(xx) -#endif - -#ifdef CONFIG_HIGHMEM -#define TEXT_FOR_HIGHMEM(xx) xx "_high", -#else -#define TEXT_FOR_HIGHMEM(xx) -#endif - -#define TEXTS_FOR_ZONES(xx) TEXT_FOR_DMA(xx) TEXT_FOR_DMA32(xx) xx "_normal", \ - TEXT_FOR_HIGHMEM(xx) xx "_movable", - -static const char * const vmstat_text[] = { - /* Zoned VM counters */ - "nr_free_pages", - "nr_inactive_anon", - "nr_active_anon", - "nr_inactive_file", - "nr_active_file", - "nr_unevictable", - "nr_mlock", - "nr_anon_pages", - "nr_mapped", - "nr_file_pages", - "nr_dirty", - "nr_writeback", - "nr_slab_reclaimable", - "nr_slab_unreclaimable", - "nr_page_table_pages", - "nr_kernel_stack", - "nr_unstable", - "nr_bounce", - "nr_vmscan_write", - "nr_writeback_temp", - "nr_isolated_anon", - "nr_isolated_file", - "nr_shmem", - "nr_dirtied", - "nr_written", - -#ifdef CONFIG_NUMA - "numa_hit", - "numa_miss", - "numa_foreign", - "numa_interleave", - "numa_local", - "numa_other", -#endif - "nr_anon_transparent_hugepages", - "nr_dirty_threshold", - "nr_dirty_background_threshold", - -#ifdef CONFIG_VM_EVENT_COUNTERS - "pgpgin", - "pgpgout", - "pswpin", - "pswpout", - - TEXTS_FOR_ZONES("pgalloc") - - "pgfree", - "pgactivate", - "pgdeactivate", - - "pgfault", - "pgmajfault", - - TEXTS_FOR_ZONES("pgrefill") - TEXTS_FOR_ZONES("pgsteal") - TEXTS_FOR_ZONES("pgscan_kswapd") - TEXTS_FOR_ZONES("pgscan_direct") - -#ifdef CONFIG_NUMA - "zone_reclaim_failed", -#endif - "pginodesteal", - "slabs_scanned", - "kswapd_steal", - "kswapd_inodesteal", - "kswapd_low_wmark_hit_quickly", - "kswapd_high_wmark_hit_quickly", - "kswapd_skip_congestion_wait", - "pageoutrun", - "allocstall", - - "pgrotated", - -#ifdef CONFIG_COMPACTION - "compact_blocks_moved", - "compact_pages_moved", - "compact_pagemigrate_failed", - "compact_stall", - "compact_fail", - "compact_success", -#endif - -#ifdef CONFIG_HUGETLB_PAGE - "htlb_buddy_alloc_success", - "htlb_buddy_alloc_fail", -#endif - "unevictable_pgs_culled", - "unevictable_pgs_scanned", - "unevictable_pgs_rescued", - "unevictable_pgs_mlocked", - "unevictable_pgs_munlocked", - "unevictable_pgs_cleared", - "unevictable_pgs_stranded", - "unevictable_pgs_mlockfreed", - -#ifdef CONFIG_TRANSPARENT_HUGEPAGE - "thp_fault_alloc", - "thp_fault_fallback", - "thp_collapse_alloc", - "thp_collapse_alloc_failed", - "thp_split", -#endif - -#endif /* CONFIG_VM_EVENTS_COUNTERS */ -}; - static void zoneinfo_show_print(struct seq_file *m, pg_data_t *pgdat, struct zone *zone) { -- cgit From f62e00cc3a00bfbd394a79fc22b334c31f91bd5f Mon Sep 17 00:00:00 2001 From: KOSAKI Motohiro Date: Tue, 24 May 2011 17:11:29 -0700 Subject: mm: introduce wait_on_page_locked_killable() commit 2687a356 ("Add lock_page_killable") introduced killable lock_page(). Similarly this patch introdues killable wait_on_page_locked(). Signed-off-by: KOSAKI Motohiro Acked-by: KAMEZAWA Hiroyuki Reviewed-by: Minchan Kim Cc: Matthew Wilcox Cc: Ingo Molnar Cc: Thomas Gleixner Cc: "H. Peter Anvin" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/pagemap.h | 9 +++++++++ mm/filemap.c | 11 +++++++++++ 2 files changed, 20 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index c11950652646..ea268080380d 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -357,6 +357,15 @@ static inline int lock_page_or_retry(struct page *page, struct mm_struct *mm, */ extern void wait_on_page_bit(struct page *page, int bit_nr); +extern int wait_on_page_bit_killable(struct page *page, int bit_nr); + +static inline int wait_on_page_locked_killable(struct page *page) +{ + if (PageLocked(page)) + return wait_on_page_bit_killable(page, PG_locked); + return 0; +} + /* * Wait for a page to be unlocked. * diff --git a/mm/filemap.c b/mm/filemap.c index c641edf553a9..dea8a38bb2bb 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -562,6 +562,17 @@ void wait_on_page_bit(struct page *page, int bit_nr) } EXPORT_SYMBOL(wait_on_page_bit); +int wait_on_page_bit_killable(struct page *page, int bit_nr) +{ + DEFINE_WAIT_BIT(wait, &page->flags, bit_nr); + + if (!test_bit(bit_nr, &page->flags)) + return 0; + + return __wait_on_bit(page_waitqueue(page), &wait, + sleep_on_page_killable, TASK_KILLABLE); +} + /** * add_page_wait_queue - Add an arbitrary waiter to a page's wait queue * @page: Page defining the wait queue of interest -- cgit From 37b23e0525d393d48a7d59f870b3bc061a30ccdb Mon Sep 17 00:00:00 2001 From: KOSAKI Motohiro Date: Tue, 24 May 2011 17:11:30 -0700 Subject: x86,mm: make pagefault killable When an oom killing occurs, almost all processes are getting stuck at the following two points. 1) __alloc_pages_nodemask 2) __lock_page_or_retry 1) is not very problematic because TIF_MEMDIE leads to an allocation failure and getting out from page allocator. 2) is more problematic. In an OOM situation, zones typically don't have page cache at all and memory starvation might lead to greatly reduced IO performance. When a fork bomb occurs, TIF_MEMDIE tasks don't die quickly, meaning that a fork bomb may create new process quickly rather than the oom-killer killing it. Then, the system may become livelocked. This patch makes the pagefault interruptible by SIGKILL. Signed-off-by: KOSAKI Motohiro Reviewed-by: KAMEZAWA Hiroyuki Cc: Minchan Kim Cc: Matthew Wilcox Cc: Ingo Molnar Cc: Thomas Gleixner Cc: "H. Peter Anvin" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86/mm/fault.c | 12 +++++++++++- include/linux/mm.h | 1 + mm/filemap.c | 31 ++++++++++++++++++++++++------- 3 files changed, 36 insertions(+), 8 deletions(-) (limited to 'include/linux') diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index bcb394dfbb35..f7a2a054a3c0 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -965,7 +965,7 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code) struct mm_struct *mm; int fault; int write = error_code & PF_WRITE; - unsigned int flags = FAULT_FLAG_ALLOW_RETRY | + unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | (write ? FAULT_FLAG_WRITE : 0); tsk = current; @@ -1138,6 +1138,16 @@ good_area: return; } + /* + * Pagefault was interrupted by SIGKILL. We have no reason to + * continue pagefault. + */ + if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) { + if (!(error_code & PF_USER)) + no_context(regs, error_code, address); + return; + } + /* * Major/minor page fault accounting is only done on the * initial attempt. If we go through a retry, it is extremely diff --git a/include/linux/mm.h b/include/linux/mm.h index 1746f67c33de..57d3d5fade16 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -153,6 +153,7 @@ extern pgprot_t protection_map[16]; #define FAULT_FLAG_MKWRITE 0x04 /* Fault was mkwrite of existing pte */ #define FAULT_FLAG_ALLOW_RETRY 0x08 /* Retry fault if blocking */ #define FAULT_FLAG_RETRY_NOWAIT 0x10 /* Don't drop mmap_sem and wait when retrying */ +#define FAULT_FLAG_KILLABLE 0x20 /* The fault task is in SIGKILL killable region */ /* * This interface is used by x86 PAT code to identify a pfn mapping that is diff --git a/mm/filemap.c b/mm/filemap.c index dea8a38bb2bb..8144f87dcbb4 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -654,15 +654,32 @@ EXPORT_SYMBOL_GPL(__lock_page_killable); int __lock_page_or_retry(struct page *page, struct mm_struct *mm, unsigned int flags) { - if (!(flags & FAULT_FLAG_ALLOW_RETRY)) { - __lock_page(page); - return 1; - } else { - if (!(flags & FAULT_FLAG_RETRY_NOWAIT)) { - up_read(&mm->mmap_sem); + if (flags & FAULT_FLAG_ALLOW_RETRY) { + /* + * CAUTION! In this case, mmap_sem is not released + * even though return 0. + */ + if (flags & FAULT_FLAG_RETRY_NOWAIT) + return 0; + + up_read(&mm->mmap_sem); + if (flags & FAULT_FLAG_KILLABLE) + wait_on_page_locked_killable(page); + else wait_on_page_locked(page); - } return 0; + } else { + if (flags & FAULT_FLAG_KILLABLE) { + int ret; + + ret = __lock_page_killable(page); + if (ret) { + up_read(&mm->mmap_sem); + return 0; + } + } else + __lock_page(page); + return 1; } } -- cgit From 1b79acc91115ba47e744b70bb166b77bd94f5855 Mon Sep 17 00:00:00 2001 From: KOSAKI Motohiro Date: Tue, 24 May 2011 17:11:32 -0700 Subject: mm, mem-hotplug: recalculate lowmem_reserve when memory hotplug occurs Currently, memory hotplug calls setup_per_zone_wmarks() and calculate_zone_inactive_ratio(), but doesn't call setup_per_zone_lowmem_reserve(). It means the number of reserved pages aren't updated even if memory hot plug occur. This patch fixes it. Signed-off-by: KOSAKI Motohiro Reviewed-by: KAMEZAWA Hiroyuki Acked-by: Mel Gorman Reviewed-by: Minchan Kim Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mm.h | 2 +- mm/memory_hotplug.c | 9 +++++---- mm/page_alloc.c | 4 ++-- 3 files changed, 8 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mm.h b/include/linux/mm.h index 57d3d5fade16..e173cd297d88 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1381,7 +1381,7 @@ extern void set_dma_reserve(unsigned long new_dma_reserve); extern void memmap_init_zone(unsigned long, int, unsigned long, unsigned long, enum memmap_context); extern void setup_per_zone_wmarks(void); -extern void calculate_zone_inactive_ratio(struct zone *zone); +extern int __meminit init_per_zone_wmark_min(void); extern void mem_init(void); extern void __init mmap_init(void); extern void show_mem(unsigned int flags); diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 2c4edc459fb0..59ac18fefd65 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -459,8 +459,9 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages) zone_pcp_update(zone); mutex_unlock(&zonelists_mutex); - setup_per_zone_wmarks(); - calculate_zone_inactive_ratio(zone); + + init_per_zone_wmark_min(); + if (onlined_pages) { kswapd_run(zone_to_nid(zone)); node_set_state(zone_to_nid(zone), N_HIGH_MEMORY); @@ -893,8 +894,8 @@ repeat: zone->zone_pgdat->node_present_pages -= offlined_pages; totalram_pages -= offlined_pages; - setup_per_zone_wmarks(); - calculate_zone_inactive_ratio(zone); + init_per_zone_wmark_min(); + if (!node_present_pages(node)) { node_clear_state(node, N_HIGH_MEMORY); kswapd_stop(node); diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 56d0be36be9d..e133cea36932 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -5094,7 +5094,7 @@ void setup_per_zone_wmarks(void) * 1TB 101 10GB * 10TB 320 32GB */ -void __meminit calculate_zone_inactive_ratio(struct zone *zone) +static void __meminit calculate_zone_inactive_ratio(struct zone *zone) { unsigned int gb, ratio; @@ -5140,7 +5140,7 @@ static void __meminit setup_per_zone_inactive_ratio(void) * 8192MB: 11584k * 16384MB: 16384k */ -static int __init init_per_zone_wmark_min(void) +int __meminit init_per_zone_wmark_min(void) { unsigned long lowmem_kbytes; -- cgit From a6cccdc36c966e51fd969560d870cfd37afbfa9c Mon Sep 17 00:00:00 2001 From: KOSAKI Motohiro Date: Tue, 24 May 2011 17:11:33 -0700 Subject: mm, mem-hotplug: update pcp->stat_threshold when memory hotplug occur Currently, cpu hotplug updates pcp->stat_threshold, but memory hotplug doesn't. There is no reason for this. [akpm@linux-foundation.org: fix CONFIG_SMP=n build] Signed-off-by: KOSAKI Motohiro Reviewed-by: KAMEZAWA Hiroyuki Acked-by: Mel Gorman Acked-by: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/vmstat.h | 3 +++ mm/page_alloc.c | 2 ++ mm/vmstat.c | 3 +-- 3 files changed, 6 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h index e73d1030f2f7..51359837511a 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h @@ -261,6 +261,7 @@ extern void dec_zone_state(struct zone *, enum zone_stat_item); extern void __dec_zone_state(struct zone *, enum zone_stat_item); void refresh_cpu_vm_stats(int); +void refresh_zone_stat_thresholds(void); int calculate_pressure_threshold(struct zone *zone); int calculate_normal_threshold(struct zone *zone); @@ -313,6 +314,8 @@ static inline void __dec_zone_page_state(struct page *page, #define set_pgdat_percpu_threshold(pgdat, callback) { } static inline void refresh_cpu_vm_stats(int cpu) { } +static inline void refresh_zone_stat_thresholds(void) { } + #endif /* CONFIG_SMP */ extern const char * const vmstat_text[]; diff --git a/mm/page_alloc.c b/mm/page_alloc.c index e133cea36932..77773329aa72 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -5152,6 +5153,7 @@ int __meminit init_per_zone_wmark_min(void) if (min_free_kbytes > 65536) min_free_kbytes = 65536; setup_per_zone_wmarks(); + refresh_zone_stat_thresholds(); setup_per_zone_lowmem_reserve(); setup_per_zone_inactive_ratio(); return 0; diff --git a/mm/vmstat.c b/mm/vmstat.c index 209546a8bdd5..20c18b7694b2 100644 --- a/mm/vmstat.c +++ b/mm/vmstat.c @@ -157,7 +157,7 @@ int calculate_normal_threshold(struct zone *zone) /* * Refresh the thresholds for each zone. */ -static void refresh_zone_stat_thresholds(void) +void refresh_zone_stat_thresholds(void) { struct zone *zone; int cpu; @@ -1201,7 +1201,6 @@ static int __init setup_vmstat(void) #ifdef CONFIG_SMP int cpu; - refresh_zone_stat_thresholds(); register_cpu_notifier(&vmstat_notifier); for_each_online_cpu(cpu) -- cgit From 72788c385604523422592249c19cba0187021e9b Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Tue, 24 May 2011 17:11:40 -0700 Subject: oom: replace PF_OOM_ORIGIN with toggling oom_score_adj There's a kernel-wide shortage of per-process flags, so it's always helpful to trim one when possible without incurring a significant penalty. It's even more important when you're planning on adding a per- process flag yourself, which I plan to do shortly for transparent hugepages. PF_OOM_ORIGIN is used by ksm and swapoff to prefer current since it has a tendency to allocate large amounts of memory and should be preferred for killing over other tasks. We'd rather immediately kill the task making the errant syscall rather than penalizing an innocent task. This patch removes PF_OOM_ORIGIN since its behavior is equivalent to setting the process's oom_score_adj to OOM_SCORE_ADJ_MAX. The process's old oom_score_adj is stored and then set to OOM_SCORE_ADJ_MAX during the time it used to have PF_OOM_ORIGIN. The old value is then reinstated when the process should no longer be considered a high priority for oom killing. Signed-off-by: David Rientjes Reviewed-by: KOSAKI Motohiro Reviewed-by: Minchan Kim Cc: Hugh Dickins Cc: Izik Eidus Cc: KAMEZAWA Hiroyuki Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/oom.h | 2 ++ include/linux/sched.h | 1 - mm/ksm.c | 7 +++++-- mm/oom_kill.c | 36 +++++++++++++++++++++++++++--------- mm/swapfile.c | 6 ++++-- 5 files changed, 38 insertions(+), 14 deletions(-) (limited to 'include/linux') diff --git a/include/linux/oom.h b/include/linux/oom.h index 5e3aa8311c5e..4952fb874ad3 100644 --- a/include/linux/oom.h +++ b/include/linux/oom.h @@ -40,6 +40,8 @@ enum oom_constraint { CONSTRAINT_MEMCG, }; +extern int test_set_oom_score_adj(int new_val); + extern unsigned int oom_badness(struct task_struct *p, struct mem_cgroup *mem, const nodemask_t *nodemask, unsigned long totalpages); extern int try_set_zonelist_oom(struct zonelist *zonelist, gfp_t gfp_flags); diff --git a/include/linux/sched.h b/include/linux/sched.h index aaf71e08222c..44b8faaac7c0 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1753,7 +1753,6 @@ extern void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t * #define PF_FROZEN 0x00010000 /* frozen for system suspend */ #define PF_FSTRANS 0x00020000 /* inside a filesystem transaction */ #define PF_KSWAPD 0x00040000 /* I am kswapd */ -#define PF_OOM_ORIGIN 0x00080000 /* Allocating much memory to others */ #define PF_LESS_THROTTLE 0x00100000 /* Throttle me less: I clean memory */ #define PF_KTHREAD 0x00200000 /* I am a kernel thread */ #define PF_RANDOMIZE 0x00400000 /* randomize virtual address space */ diff --git a/mm/ksm.c b/mm/ksm.c index 942dfc73a2ff..d708b3ef2260 100644 --- a/mm/ksm.c +++ b/mm/ksm.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include "internal.h" @@ -1894,9 +1895,11 @@ static ssize_t run_store(struct kobject *kobj, struct kobj_attribute *attr, if (ksm_run != flags) { ksm_run = flags; if (flags & KSM_RUN_UNMERGE) { - current->flags |= PF_OOM_ORIGIN; + int oom_score_adj; + + oom_score_adj = test_set_oom_score_adj(OOM_SCORE_ADJ_MAX); err = unmerge_and_remove_all_rmap_items(); - current->flags &= ~PF_OOM_ORIGIN; + test_set_oom_score_adj(oom_score_adj); if (err) { ksm_run = KSM_RUN_STOP; count = err; diff --git a/mm/oom_kill.c b/mm/oom_kill.c index f52e85c80e8d..e4b0991ca351 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -38,6 +38,33 @@ int sysctl_oom_kill_allocating_task; int sysctl_oom_dump_tasks = 1; static DEFINE_SPINLOCK(zone_scan_lock); +/** + * test_set_oom_score_adj() - set current's oom_score_adj and return old value + * @new_val: new oom_score_adj value + * + * Sets the oom_score_adj value for current to @new_val with proper + * synchronization and returns the old value. Usually used to temporarily + * set a value, save the old value in the caller, and then reinstate it later. + */ +int test_set_oom_score_adj(int new_val) +{ + struct sighand_struct *sighand = current->sighand; + int old_val; + + spin_lock_irq(&sighand->siglock); + old_val = current->signal->oom_score_adj; + if (new_val != old_val) { + if (new_val == OOM_SCORE_ADJ_MIN) + atomic_inc(¤t->mm->oom_disable_count); + else if (old_val == OOM_SCORE_ADJ_MIN) + atomic_dec(¤t->mm->oom_disable_count); + current->signal->oom_score_adj = new_val; + } + spin_unlock_irq(&sighand->siglock); + + return old_val; +} + #ifdef CONFIG_NUMA /** * has_intersects_mems_allowed() - check task eligiblity for kill @@ -154,15 +181,6 @@ unsigned int oom_badness(struct task_struct *p, struct mem_cgroup *mem, return 0; } - /* - * When the PF_OOM_ORIGIN bit is set, it indicates the task should have - * priority for oom killing. - */ - if (p->flags & PF_OOM_ORIGIN) { - task_unlock(p); - return 1000; - } - /* * The memory controller may have a limit of 0 bytes, so avoid a divide * by zero, if necessary. diff --git a/mm/swapfile.c b/mm/swapfile.c index 8c6b3ce38f09..d537d29e9b7b 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -1555,6 +1556,7 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) struct address_space *mapping; struct inode *inode; char *pathname; + int oom_score_adj; int i, type, prev; int err; @@ -1613,9 +1615,9 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) p->flags &= ~SWP_WRITEOK; spin_unlock(&swap_lock); - current->flags |= PF_OOM_ORIGIN; + oom_score_adj = test_set_oom_score_adj(OOM_SCORE_ADJ_MAX); err = try_to_unuse(type); - current->flags &= ~PF_OOM_ORIGIN; + test_set_oom_score_adj(oom_score_adj); if (err) { /* -- cgit From 15fa8f425557a0d698f933627771f520ef4ae34b Mon Sep 17 00:00:00 2001 From: Dave Hansen Date: Tue, 24 May 2011 17:11:41 -0700 Subject: include/linux/gfp.h: work around apparent sparse confusion Running sparse on page_alloc.c today, it errors out: include/linux/gfp.h:254:17: error: bad constant expression include/linux/gfp.h:254:17: error: cannot size expression which is a line in gfp_zone(): BUILD_BUG_ON((GFP_ZONE_BAD >> bit) & 1); That's really unfortunate, because it ends up hiding all of the other legitimate sparse messages like this: mm/page_alloc.c:5315:59: warning: incorrect type in argument 1 (different base types) mm/page_alloc.c:5315:59: expected unsigned long [unsigned] [usertype] size mm/page_alloc.c:5315:59: got restricted gfp_t [usertype] ... Having sparse be able to catch these very oopsable bugs is a lot more important than keeping a BUILD_BUG_ON(). Kill the BUILD_BUG_ON(). Compiles on x86_64 with and without CONFIG_DEBUG_VM=y. defconfig boots fine for me. Signed-off-by: Dave Hansen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/gfp.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 56d8fc87fbbc..7e8f5d863c76 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -249,14 +249,9 @@ static inline enum zone_type gfp_zone(gfp_t flags) z = (GFP_ZONE_TABLE >> (bit * ZONES_SHIFT)) & ((1 << ZONES_SHIFT) - 1); - - if (__builtin_constant_p(bit)) - BUILD_BUG_ON((GFP_ZONE_BAD >> bit) & 1); - else { #ifdef CONFIG_DEBUG_VM - BUG_ON((GFP_ZONE_BAD >> bit) & 1); + BUG_ON((GFP_ZONE_BAD >> bit) & 1); #endif - } return z; } -- cgit From 82d4b5779a75887750748609f3415f01c1bb9f81 Mon Sep 17 00:00:00 2001 From: Dave Hansen Date: Tue, 24 May 2011 17:11:42 -0700 Subject: include/linux/gfp.h: convert BUG_ON() into VM_BUG_ON() VM_BUG_ON() if effectively a BUG_ON() undef #ifdef CONFIG_DEBUG_VM. That is exactly what we have here now, and two different folks have suggested doing it this way. Signed-off-by: Dave Hansen Cc: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/gfp.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 7e8f5d863c76..cb4089254f01 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -249,9 +249,7 @@ static inline enum zone_type gfp_zone(gfp_t flags) z = (GFP_ZONE_TABLE >> (bit * ZONES_SHIFT)) & ((1 << ZONES_SHIFT) - 1); -#ifdef CONFIG_DEBUG_VM - BUG_ON((GFP_ZONE_BAD >> bit) & 1); -#endif + VM_BUG_ON((GFP_ZONE_BAD >> bit) & 1); return z; } -- cgit From d05f3169c0fbca16132ec7c2be71685c6de638b5 Mon Sep 17 00:00:00 2001 From: Michal Hocko Date: Tue, 24 May 2011 17:11:44 -0700 Subject: mm: make expand_downwards() symmetrical with expand_upwards() Currently we have expand_upwards exported while expand_downwards is accessible only via expand_stack or expand_stack_downwards. check_stack_guard_page is a nice example of the asymmetry. It uses expand_stack for VM_GROWSDOWN while expand_upwards is called for VM_GROWSUP case. Let's clean this up by exporting both functions and make those names consistent. Let's use expand_{upwards,downwards} because expanding doesn't always involve stack manipulation (an example is ia64_do_page_fault which uses expand_upwards for registers backing store expansion). expand_downwards has to be defined for both CONFIG_STACK_GROWS{UP,DOWN} because get_arg_page calls the downwards version in the early process initialization phase for growsup configuration. Signed-off-by: Michal Hocko Acked-by: Hugh Dickins Cc: James Bottomley Cc: "Luck, Tony" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/exec.c | 2 +- include/linux/mm.h | 8 +++++--- mm/memory.c | 2 +- mm/mmap.c | 7 +------ 4 files changed, 8 insertions(+), 11 deletions(-) (limited to 'include/linux') diff --git a/fs/exec.c b/fs/exec.c index c1cf372f17a7..e276d5e0abb9 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -200,7 +200,7 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, #ifdef CONFIG_STACK_GROWSUP if (write) { - ret = expand_stack_downwards(bprm->vma, pos); + ret = expand_downwards(bprm->vma, pos); if (ret < 0) return NULL; } diff --git a/include/linux/mm.h b/include/linux/mm.h index e173cd297d88..d2948af126ca 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1518,15 +1518,17 @@ unsigned long ra_submit(struct file_ra_state *ra, struct address_space *mapping, struct file *filp); -/* Do stack extension */ +/* Generic expand stack which grows the stack according to GROWS{UP,DOWN} */ extern int expand_stack(struct vm_area_struct *vma, unsigned long address); + +/* CONFIG_STACK_GROWSUP still needs to to grow downwards at some places */ +extern int expand_downwards(struct vm_area_struct *vma, + unsigned long address); #if VM_GROWSUP extern int expand_upwards(struct vm_area_struct *vma, unsigned long address); #else #define expand_upwards(vma, address) do { } while (0) #endif -extern int expand_stack_downwards(struct vm_area_struct *vma, - unsigned long address); /* Look up the first VMA which satisfies addr < vm_end, NULL if none. */ extern struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr); diff --git a/mm/memory.c b/mm/memory.c index 61e66f026563..4c6ea10f3d18 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -2966,7 +2966,7 @@ static inline int check_stack_guard_page(struct vm_area_struct *vma, unsigned lo if (prev && prev->vm_end == address) return prev->vm_flags & VM_GROWSDOWN ? 0 : -ENOMEM; - expand_stack(vma, address - PAGE_SIZE); + expand_downwards(vma, address - PAGE_SIZE); } if ((vma->vm_flags & VM_GROWSUP) && address + PAGE_SIZE == vma->vm_end) { struct vm_area_struct *next = vma->vm_next; diff --git a/mm/mmap.c b/mm/mmap.c index e76f8d752884..adb12527fd0e 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1774,7 +1774,7 @@ int expand_upwards(struct vm_area_struct *vma, unsigned long address) /* * vma is the first one with address < vma->vm_start. Have to extend vma. */ -static int expand_downwards(struct vm_area_struct *vma, +int expand_downwards(struct vm_area_struct *vma, unsigned long address) { int error; @@ -1821,11 +1821,6 @@ static int expand_downwards(struct vm_area_struct *vma, return error; } -int expand_stack_downwards(struct vm_area_struct *vma, unsigned long address) -{ - return expand_downwards(vma, address); -} - #ifdef CONFIG_STACK_GROWSUP int expand_stack(struct vm_area_struct *vma, unsigned long address) { -- cgit From d16dfc550f5326a4000f3322582a7c05dec91d7a Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 24 May 2011 17:11:45 -0700 Subject: mm: mmu_gather rework Rework the existing mmu_gather infrastructure. The direct purpose of these patches was to allow preemptible mmu_gather, but even without that I think these patches provide an improvement to the status quo. The first 9 patches rework the mmu_gather infrastructure. For review purpose I've split them into generic and per-arch patches with the last of those a generic cleanup. The next patch provides generic RCU page-table freeing, and the followup is a patch converting s390 to use this. I've also got 4 patches from DaveM lined up (not included in this series) that uses this to implement gup_fast() for sparc64. Then there is one patch that extends the generic mmu_gather batching. After that follow the mm preemptibility patches, these make part of the mm a lot more preemptible. It converts i_mmap_lock and anon_vma->lock to mutexes which together with the mmu_gather rework makes mmu_gather preemptible as well. Making i_mmap_lock a mutex also enables a clean-up of the truncate code. This also allows for preemptible mmu_notifiers, something that XPMEM I think wants. Furthermore, it removes the new and universially detested unmap_mutex. This patch: Remove the first obstacle towards a fully preemptible mmu_gather. The current scheme assumes mmu_gather is always done with preemption disabled and uses per-cpu storage for the page batches. Change this to try and allocate a page for batching and in case of failure, use a small on-stack array to make some progress. Preemptible mmu_gather is desired in general and usable once i_mmap_lock becomes a mutex. Doing it before the mutex conversion saves us from having to rework the code by moving the mmu_gather bits inside the pte_lock. Also avoid flushing the tlb batches from under the pte lock, this is useful even without the i_mmap_lock conversion as it significantly reduces pte lock hold times. [akpm@linux-foundation.org: fix comment tpyo] Signed-off-by: Peter Zijlstra Cc: Benjamin Herrenschmidt Cc: David Miller Cc: Martin Schwidefsky Cc: Russell King Cc: Paul Mundt Cc: Jeff Dike Cc: Richard Weinberger Cc: Tony Luck Reviewed-by: KAMEZAWA Hiroyuki Acked-by: Hugh Dickins Acked-by: Mel Gorman Cc: KOSAKI Motohiro Cc: Nick Piggin Cc: Namhyung Kim Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/exec.c | 10 ++--- include/asm-generic/tlb.h | 96 ++++++++++++++++++++++++++++++++++------------- include/linux/mm.h | 2 +- mm/memory.c | 46 +++++++++++------------ mm/mmap.c | 18 ++++----- 5 files changed, 107 insertions(+), 65 deletions(-) (limited to 'include/linux') diff --git a/fs/exec.c b/fs/exec.c index e276d5e0abb9..936f5776655c 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -600,7 +600,7 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift) unsigned long length = old_end - old_start; unsigned long new_start = old_start - shift; unsigned long new_end = old_end - shift; - struct mmu_gather *tlb; + struct mmu_gather tlb; BUG_ON(new_start > new_end); @@ -626,12 +626,12 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift) return -ENOMEM; lru_add_drain(); - tlb = tlb_gather_mmu(mm, 0); + tlb_gather_mmu(&tlb, mm, 0); if (new_end > old_start) { /* * when the old and new regions overlap clear from new_end. */ - free_pgd_range(tlb, new_end, old_end, new_end, + free_pgd_range(&tlb, new_end, old_end, new_end, vma->vm_next ? vma->vm_next->vm_start : 0); } else { /* @@ -640,10 +640,10 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift) * have constraints on va-space that make this illegal (IA64) - * for the others its just a little faster. */ - free_pgd_range(tlb, old_start, old_end, new_end, + free_pgd_range(&tlb, old_start, old_end, new_end, vma->vm_next ? vma->vm_next->vm_start : 0); } - tlb_finish_mmu(tlb, new_end, old_end); + tlb_finish_mmu(&tlb, new_end, old_end); /* * Shrink the vma to just the new range. Always succeeds. diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h index e43f9766259f..2d3547c84235 100644 --- a/include/asm-generic/tlb.h +++ b/include/asm-generic/tlb.h @@ -5,6 +5,8 @@ * Copyright 2001 Red Hat, Inc. * Based on code from mm/memory.c Copyright Linus Torvalds and others. * + * Copyright 2011 Red Hat, Inc., Peter Zijlstra + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version @@ -22,51 +24,71 @@ * and page free order so much.. */ #ifdef CONFIG_SMP - #ifdef ARCH_FREE_PTR_NR - #define FREE_PTR_NR ARCH_FREE_PTR_NR - #else - #define FREE_PTE_NR 506 - #endif #define tlb_fast_mode(tlb) ((tlb)->nr == ~0U) #else - #define FREE_PTE_NR 1 #define tlb_fast_mode(tlb) 1 #endif +/* + * If we can't allocate a page to make a big batch of page pointers + * to work on, then just handle a few from the on-stack structure. + */ +#define MMU_GATHER_BUNDLE 8 + /* struct mmu_gather is an opaque type used by the mm code for passing around * any data needed by arch specific code for tlb_remove_page. */ struct mmu_gather { struct mm_struct *mm; unsigned int nr; /* set to ~0U means fast mode */ + unsigned int max; /* nr < max */ unsigned int need_flush;/* Really unmapped some ptes? */ unsigned int fullmm; /* non-zero means full mm flush */ - struct page * pages[FREE_PTE_NR]; +#ifdef HAVE_ARCH_MMU_GATHER + struct arch_mmu_gather arch; +#endif + struct page **pages; + struct page *local[MMU_GATHER_BUNDLE]; }; -/* Users of the generic TLB shootdown code must declare this storage space. */ -DECLARE_PER_CPU(struct mmu_gather, mmu_gathers); +static inline void __tlb_alloc_page(struct mmu_gather *tlb) +{ + unsigned long addr = __get_free_pages(GFP_NOWAIT | __GFP_NOWARN, 0); + + if (addr) { + tlb->pages = (void *)addr; + tlb->max = PAGE_SIZE / sizeof(struct page *); + } +} /* tlb_gather_mmu - * Return a pointer to an initialized struct mmu_gather. + * Called to initialize an (on-stack) mmu_gather structure for page-table + * tear-down from @mm. The @fullmm argument is used when @mm is without + * users and we're going to destroy the full address space (exit/execve). */ -static inline struct mmu_gather * -tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush) +static inline void +tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, bool fullmm) { - struct mmu_gather *tlb = &get_cpu_var(mmu_gathers); - tlb->mm = mm; - /* Use fast mode if only one CPU is online */ - tlb->nr = num_online_cpus() > 1 ? 0U : ~0U; + tlb->max = ARRAY_SIZE(tlb->local); + tlb->pages = tlb->local; + + if (num_online_cpus() > 1) { + tlb->nr = 0; + __tlb_alloc_page(tlb); + } else /* Use fast mode if only one CPU is online */ + tlb->nr = ~0U; - tlb->fullmm = full_mm_flush; + tlb->fullmm = fullmm; - return tlb; +#ifdef HAVE_ARCH_MMU_GATHER + tlb->arch = ARCH_MMU_GATHER_INIT; +#endif } static inline void -tlb_flush_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end) +tlb_flush_mmu(struct mmu_gather *tlb) { if (!tlb->need_flush) return; @@ -75,6 +97,13 @@ tlb_flush_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end) if (!tlb_fast_mode(tlb)) { free_pages_and_swap_cache(tlb->pages, tlb->nr); tlb->nr = 0; + /* + * If we are using the local on-stack array of pages for MMU + * gather, try allocating an off-stack array again as we have + * recently freed pages. + */ + if (tlb->pages == tlb->local) + __tlb_alloc_page(tlb); } } @@ -85,29 +114,42 @@ tlb_flush_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end) static inline void tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end) { - tlb_flush_mmu(tlb, start, end); + tlb_flush_mmu(tlb); /* keep the page table cache within bounds */ check_pgt_cache(); - put_cpu_var(mmu_gathers); + if (tlb->pages != tlb->local) + free_pages((unsigned long)tlb->pages, 0); } -/* tlb_remove_page +/* __tlb_remove_page * Must perform the equivalent to __free_pte(pte_get_and_clear(ptep)), while * handling the additional races in SMP caused by other CPUs caching valid - * mappings in their TLBs. + * mappings in their TLBs. Returns the number of free page slots left. + * When out of page slots we must call tlb_flush_mmu(). */ -static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page) +static inline int __tlb_remove_page(struct mmu_gather *tlb, struct page *page) { tlb->need_flush = 1; if (tlb_fast_mode(tlb)) { free_page_and_swap_cache(page); - return; + return 1; /* avoid calling tlb_flush_mmu() */ } tlb->pages[tlb->nr++] = page; - if (tlb->nr >= FREE_PTE_NR) - tlb_flush_mmu(tlb, 0, 0); + VM_BUG_ON(tlb->nr > tlb->max); + + return tlb->max - tlb->nr; +} + +/* tlb_remove_page + * Similar to __tlb_remove_page but will call tlb_flush_mmu() itself when + * required. + */ +static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page) +{ + if (!__tlb_remove_page(tlb, page)) + tlb_flush_mmu(tlb); } /** diff --git a/include/linux/mm.h b/include/linux/mm.h index d2948af126ca..ffcce9bf2b54 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -906,7 +906,7 @@ int zap_vma_ptes(struct vm_area_struct *vma, unsigned long address, unsigned long size); unsigned long zap_page_range(struct vm_area_struct *vma, unsigned long address, unsigned long size, struct zap_details *); -unsigned long unmap_vmas(struct mmu_gather **tlb, +unsigned long unmap_vmas(struct mmu_gather *tlb, struct vm_area_struct *start_vma, unsigned long start_addr, unsigned long end_addr, unsigned long *nr_accounted, struct zap_details *); diff --git a/mm/memory.c b/mm/memory.c index 4c6ea10f3d18..19b2d44de9f0 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -912,12 +912,13 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb, long *zap_work, struct zap_details *details) { struct mm_struct *mm = tlb->mm; + int force_flush = 0; pte_t *pte; spinlock_t *ptl; int rss[NR_MM_COUNTERS]; init_rss_vec(rss); - +again: pte = pte_offset_map_lock(mm, pmd, addr, &ptl); arch_enter_lazy_mmu_mode(); do { @@ -974,7 +975,9 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb, page_remove_rmap(page); if (unlikely(page_mapcount(page) < 0)) print_bad_pte(vma, addr, ptent, page); - tlb_remove_page(tlb, page); + force_flush = !__tlb_remove_page(tlb, page); + if (force_flush) + break; continue; } /* @@ -1001,6 +1004,18 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb, arch_leave_lazy_mmu_mode(); pte_unmap_unlock(pte - 1, ptl); + /* + * mmu_gather ran out of room to batch pages, we break out of + * the PTE lock to avoid doing the potential expensive TLB invalidate + * and page-free while holding it. + */ + if (force_flush) { + force_flush = 0; + tlb_flush_mmu(tlb); + if (addr != end) + goto again; + } + return addr; } @@ -1121,17 +1136,14 @@ static unsigned long unmap_page_range(struct mmu_gather *tlb, * ensure that any thus-far unmapped pages are flushed before unmap_vmas() * drops the lock and schedules. */ -unsigned long unmap_vmas(struct mmu_gather **tlbp, +unsigned long unmap_vmas(struct mmu_gather *tlb, struct vm_area_struct *vma, unsigned long start_addr, unsigned long end_addr, unsigned long *nr_accounted, struct zap_details *details) { long zap_work = ZAP_BLOCK_SIZE; - unsigned long tlb_start = 0; /* For tlb_finish_mmu */ - int tlb_start_valid = 0; unsigned long start = start_addr; spinlock_t *i_mmap_lock = details? details->i_mmap_lock: NULL; - int fullmm = (*tlbp)->fullmm; struct mm_struct *mm = vma->vm_mm; mmu_notifier_invalidate_range_start(mm, start_addr, end_addr); @@ -1152,11 +1164,6 @@ unsigned long unmap_vmas(struct mmu_gather **tlbp, untrack_pfn_vma(vma, 0, 0); while (start != end) { - if (!tlb_start_valid) { - tlb_start = start; - tlb_start_valid = 1; - } - if (unlikely(is_vm_hugetlb_page(vma))) { /* * It is undesirable to test vma->vm_file as it @@ -1177,7 +1184,7 @@ unsigned long unmap_vmas(struct mmu_gather **tlbp, start = end; } else - start = unmap_page_range(*tlbp, vma, + start = unmap_page_range(tlb, vma, start, end, &zap_work, details); if (zap_work > 0) { @@ -1185,19 +1192,13 @@ unsigned long unmap_vmas(struct mmu_gather **tlbp, break; } - tlb_finish_mmu(*tlbp, tlb_start, start); - if (need_resched() || (i_mmap_lock && spin_needbreak(i_mmap_lock))) { - if (i_mmap_lock) { - *tlbp = NULL; + if (i_mmap_lock) goto out; - } cond_resched(); } - *tlbp = tlb_gather_mmu(vma->vm_mm, fullmm); - tlb_start_valid = 0; zap_work = ZAP_BLOCK_SIZE; } } @@ -1217,16 +1218,15 @@ unsigned long zap_page_range(struct vm_area_struct *vma, unsigned long address, unsigned long size, struct zap_details *details) { struct mm_struct *mm = vma->vm_mm; - struct mmu_gather *tlb; + struct mmu_gather tlb; unsigned long end = address + size; unsigned long nr_accounted = 0; lru_add_drain(); - tlb = tlb_gather_mmu(mm, 0); + tlb_gather_mmu(&tlb, mm, 0); update_hiwater_rss(mm); end = unmap_vmas(&tlb, vma, address, end, &nr_accounted, details); - if (tlb) - tlb_finish_mmu(tlb, address, end); + tlb_finish_mmu(&tlb, address, end); return end; } diff --git a/mm/mmap.c b/mm/mmap.c index adb12527fd0e..40d49986e714 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1903,17 +1903,17 @@ static void unmap_region(struct mm_struct *mm, unsigned long start, unsigned long end) { struct vm_area_struct *next = prev? prev->vm_next: mm->mmap; - struct mmu_gather *tlb; + struct mmu_gather tlb; unsigned long nr_accounted = 0; lru_add_drain(); - tlb = tlb_gather_mmu(mm, 0); + tlb_gather_mmu(&tlb, mm, 0); update_hiwater_rss(mm); unmap_vmas(&tlb, vma, start, end, &nr_accounted, NULL); vm_unacct_memory(nr_accounted); - free_pgtables(tlb, vma, prev? prev->vm_end: FIRST_USER_ADDRESS, - next? next->vm_start: 0); - tlb_finish_mmu(tlb, start, end); + free_pgtables(&tlb, vma, prev ? prev->vm_end : FIRST_USER_ADDRESS, + next ? next->vm_start : 0); + tlb_finish_mmu(&tlb, start, end); } /* @@ -2255,7 +2255,7 @@ EXPORT_SYMBOL(do_brk); /* Release all mmaps. */ void exit_mmap(struct mm_struct *mm) { - struct mmu_gather *tlb; + struct mmu_gather tlb; struct vm_area_struct *vma; unsigned long nr_accounted = 0; unsigned long end; @@ -2280,14 +2280,14 @@ void exit_mmap(struct mm_struct *mm) lru_add_drain(); flush_cache_mm(mm); - tlb = tlb_gather_mmu(mm, 1); + tlb_gather_mmu(&tlb, mm, 1); /* update_hiwater_rss(mm) here? but nobody should be looking */ /* Use -1 here to ensure all VMAs in the mm are unmapped */ end = unmap_vmas(&tlb, vma, 0, -1, &nr_accounted, NULL); vm_unacct_memory(nr_accounted); - free_pgtables(tlb, vma, FIRST_USER_ADDRESS, 0); - tlb_finish_mmu(tlb, 0, end); + free_pgtables(&tlb, vma, FIRST_USER_ADDRESS, 0); + tlb_finish_mmu(&tlb, 0, end); /* * Walk the list again, actually closing and freeing it, -- cgit From e4c70a6629f9c74c4b0de258a3951890e9047c82 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 24 May 2011 17:12:03 -0700 Subject: lockdep, mutex: provide mutex_lock_nest_lock In order to convert i_mmap_lock to a mutex we need a mutex equivalent to spin_lock_nest_lock(), thus provide the mutex_lock_nest_lock() annotation. As with spin_lock_nest_lock(), mutex_lock_nest_lock() allows annotation of the locking pattern where an outer lock serializes the acquisition order of nested locks. That is, if every time you lock multiple locks A, say A1 and A2 you first acquire N, the order of acquiring A1 and A2 is irrelevant. Signed-off-by: Peter Zijlstra Cc: Benjamin Herrenschmidt Cc: David Miller Cc: Martin Schwidefsky Cc: Russell King Cc: Paul Mundt Cc: Jeff Dike Cc: Richard Weinberger Cc: Tony Luck Cc: KAMEZAWA Hiroyuki Cc: Hugh Dickins Cc: Mel Gorman Cc: KOSAKI Motohiro Cc: Nick Piggin Cc: Namhyung Kim Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/lockdep.h | 3 +++ include/linux/mutex.h | 9 +++++++++ kernel/mutex.c | 25 +++++++++++++++++-------- 3 files changed, 29 insertions(+), 8 deletions(-) (limited to 'include/linux') diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h index 4aef1dda6406..ef820a3c378b 100644 --- a/include/linux/lockdep.h +++ b/include/linux/lockdep.h @@ -487,12 +487,15 @@ static inline void print_irqtrace_events(struct task_struct *curr) #ifdef CONFIG_DEBUG_LOCK_ALLOC # ifdef CONFIG_PROVE_LOCKING # define mutex_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 2, NULL, i) +# define mutex_acquire_nest(l, s, t, n, i) lock_acquire(l, s, t, 0, 2, n, i) # else # define mutex_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 1, NULL, i) +# define mutex_acquire_nest(l, s, t, n, i) lock_acquire(l, s, t, 0, 1, n, i) # endif # define mutex_release(l, n, i) lock_release(l, n, i) #else # define mutex_acquire(l, s, t, i) do { } while (0) +# define mutex_acquire_nest(l, s, t, n, i) do { } while (0) # define mutex_release(l, n, i) do { } while (0) #endif diff --git a/include/linux/mutex.h b/include/linux/mutex.h index c75471db576e..a940fe435aca 100644 --- a/include/linux/mutex.h +++ b/include/linux/mutex.h @@ -132,6 +132,7 @@ static inline int mutex_is_locked(struct mutex *lock) */ #ifdef CONFIG_DEBUG_LOCK_ALLOC extern void mutex_lock_nested(struct mutex *lock, unsigned int subclass); +extern void _mutex_lock_nest_lock(struct mutex *lock, struct lockdep_map *nest_lock); extern int __must_check mutex_lock_interruptible_nested(struct mutex *lock, unsigned int subclass); extern int __must_check mutex_lock_killable_nested(struct mutex *lock, @@ -140,6 +141,13 @@ extern int __must_check mutex_lock_killable_nested(struct mutex *lock, #define mutex_lock(lock) mutex_lock_nested(lock, 0) #define mutex_lock_interruptible(lock) mutex_lock_interruptible_nested(lock, 0) #define mutex_lock_killable(lock) mutex_lock_killable_nested(lock, 0) + +#define mutex_lock_nest_lock(lock, nest_lock) \ +do { \ + typecheck(struct lockdep_map *, &(nest_lock)->dep_map); \ + _mutex_lock_nest_lock(lock, &(nest_lock)->dep_map); \ +} while (0) + #else extern void mutex_lock(struct mutex *lock); extern int __must_check mutex_lock_interruptible(struct mutex *lock); @@ -148,6 +156,7 @@ extern int __must_check mutex_lock_killable(struct mutex *lock); # define mutex_lock_nested(lock, subclass) mutex_lock(lock) # define mutex_lock_interruptible_nested(lock, subclass) mutex_lock_interruptible(lock) # define mutex_lock_killable_nested(lock, subclass) mutex_lock_killable(lock) +# define mutex_lock_nest_lock(lock, nest_lock) mutex_lock(lock) #endif /* diff --git a/kernel/mutex.c b/kernel/mutex.c index 2c938e2337cd..d607ed5dd441 100644 --- a/kernel/mutex.c +++ b/kernel/mutex.c @@ -131,14 +131,14 @@ EXPORT_SYMBOL(mutex_unlock); */ static inline int __sched __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, - unsigned long ip) + struct lockdep_map *nest_lock, unsigned long ip) { struct task_struct *task = current; struct mutex_waiter waiter; unsigned long flags; preempt_disable(); - mutex_acquire(&lock->dep_map, subclass, 0, ip); + mutex_acquire_nest(&lock->dep_map, subclass, 0, nest_lock, ip); #ifdef CONFIG_MUTEX_SPIN_ON_OWNER /* @@ -269,16 +269,25 @@ void __sched mutex_lock_nested(struct mutex *lock, unsigned int subclass) { might_sleep(); - __mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, subclass, _RET_IP_); + __mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, subclass, NULL, _RET_IP_); } EXPORT_SYMBOL_GPL(mutex_lock_nested); +void __sched +_mutex_lock_nest_lock(struct mutex *lock, struct lockdep_map *nest) +{ + might_sleep(); + __mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, 0, nest, _RET_IP_); +} + +EXPORT_SYMBOL_GPL(_mutex_lock_nest_lock); + int __sched mutex_lock_killable_nested(struct mutex *lock, unsigned int subclass) { might_sleep(); - return __mutex_lock_common(lock, TASK_KILLABLE, subclass, _RET_IP_); + return __mutex_lock_common(lock, TASK_KILLABLE, subclass, NULL, _RET_IP_); } EXPORT_SYMBOL_GPL(mutex_lock_killable_nested); @@ -287,7 +296,7 @@ mutex_lock_interruptible_nested(struct mutex *lock, unsigned int subclass) { might_sleep(); return __mutex_lock_common(lock, TASK_INTERRUPTIBLE, - subclass, _RET_IP_); + subclass, NULL, _RET_IP_); } EXPORT_SYMBOL_GPL(mutex_lock_interruptible_nested); @@ -393,7 +402,7 @@ __mutex_lock_slowpath(atomic_t *lock_count) { struct mutex *lock = container_of(lock_count, struct mutex, count); - __mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, 0, _RET_IP_); + __mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, 0, NULL, _RET_IP_); } static noinline int __sched @@ -401,7 +410,7 @@ __mutex_lock_killable_slowpath(atomic_t *lock_count) { struct mutex *lock = container_of(lock_count, struct mutex, count); - return __mutex_lock_common(lock, TASK_KILLABLE, 0, _RET_IP_); + return __mutex_lock_common(lock, TASK_KILLABLE, 0, NULL, _RET_IP_); } static noinline int __sched @@ -409,7 +418,7 @@ __mutex_lock_interruptible_slowpath(atomic_t *lock_count) { struct mutex *lock = container_of(lock_count, struct mutex, count); - return __mutex_lock_common(lock, TASK_INTERRUPTIBLE, 0, _RET_IP_); + return __mutex_lock_common(lock, TASK_INTERRUPTIBLE, 0, NULL, _RET_IP_); } #endif -- cgit From 97a894136f29802da19a15541de3c019e1ca147e Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 24 May 2011 17:12:04 -0700 Subject: mm: Remove i_mmap_lock lockbreak Hugh says: "The only significant loser, I think, would be page reclaim (when concurrent with truncation): could spin for a long time waiting for the i_mmap_mutex it expects would soon be dropped? " Counter points: - cpu contention makes the spin stop (need_resched()) - zap pages should be freeing pages at a higher rate than reclaim ever can I think the simplification of the truncate code is definitely worth it. Effectively reverts: 2aa15890f3c ("mm: prevent concurrent unmap_mapping_range() on the same inode") and takes out the code that caused its problem. Signed-off-by: Peter Zijlstra Reviewed-by: KAMEZAWA Hiroyuki Cc: Hugh Dickins Cc: Benjamin Herrenschmidt Cc: David Miller Cc: Martin Schwidefsky Cc: Russell King Cc: Paul Mundt Cc: Jeff Dike Cc: Richard Weinberger Cc: Tony Luck Cc: Mel Gorman Cc: KOSAKI Motohiro Cc: Nick Piggin Cc: Namhyung Kim Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/inode.c | 1 - include/linux/fs.h | 2 - include/linux/mm.h | 2 - include/linux/mm_types.h | 1 - kernel/fork.c | 1 - mm/memory.c | 195 +++++++---------------------------------------- mm/mmap.c | 13 +--- mm/mremap.c | 1 - 8 files changed, 28 insertions(+), 188 deletions(-) (limited to 'include/linux') diff --git a/fs/inode.c b/fs/inode.c index 05f4fa521325..7a7284c71abd 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -331,7 +331,6 @@ void address_space_init_once(struct address_space *mapping) spin_lock_init(&mapping->private_lock); INIT_RAW_PRIO_TREE_ROOT(&mapping->i_mmap); INIT_LIST_HEAD(&mapping->i_mmap_nonlinear); - mutex_init(&mapping->unmap_mutex); } EXPORT_SYMBOL(address_space_init_once); diff --git a/include/linux/fs.h b/include/linux/fs.h index cdf9495df204..5d2c86bdf5ba 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -635,7 +635,6 @@ struct address_space { struct prio_tree_root i_mmap; /* tree of private and shared mappings */ struct list_head i_mmap_nonlinear;/*list VM_NONLINEAR mappings */ spinlock_t i_mmap_lock; /* protect tree, count, list */ - unsigned int truncate_count; /* Cover race condition with truncate */ unsigned long nrpages; /* number of total pages */ pgoff_t writeback_index;/* writeback starts here */ const struct address_space_operations *a_ops; /* methods */ @@ -644,7 +643,6 @@ struct address_space { spinlock_t private_lock; /* for use by the address_space */ struct list_head private_list; /* ditto */ struct address_space *assoc_mapping; /* ditto */ - struct mutex unmap_mutex; /* to protect unmapping */ } __attribute__((aligned(sizeof(long)))); /* * On most architectures that alignment is already the case; but diff --git a/include/linux/mm.h b/include/linux/mm.h index ffcce9bf2b54..2ad0ac8c3f32 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -895,8 +895,6 @@ struct zap_details { struct address_space *check_mapping; /* Check page->mapping if set */ pgoff_t first_index; /* Lowest page->index to unmap */ pgoff_t last_index; /* Highest page->index to unmap */ - spinlock_t *i_mmap_lock; /* For unmap_mapping_range: */ - unsigned long truncate_count; /* Compare vm_truncate_count */ }; struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr, diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 02aa5619709b..201998e5b530 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -175,7 +175,6 @@ struct vm_area_struct { units, *not* PAGE_CACHE_SIZE */ struct file * vm_file; /* File we map to (can be NULL). */ void * vm_private_data; /* was vm_pte (shared mem) */ - unsigned long vm_truncate_count;/* truncate_count or restart_addr */ #ifndef CONFIG_MMU struct vm_region *vm_region; /* NOMMU mapping region */ diff --git a/kernel/fork.c b/kernel/fork.c index 2b44d82b8237..4eef925477fc 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -386,7 +386,6 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) spin_lock(&mapping->i_mmap_lock); if (tmp->vm_flags & VM_SHARED) mapping->i_mmap_writable++; - tmp->vm_truncate_count = mpnt->vm_truncate_count; flush_dcache_mmap_lock(mapping); /* insert tmp into the share list, just after mpnt */ vma_prio_tree_add(tmp, mpnt); diff --git a/mm/memory.c b/mm/memory.c index 17193d74f302..18655878b9f8 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -986,13 +986,13 @@ int copy_page_range(struct mm_struct *dst_mm, struct mm_struct *src_mm, static unsigned long zap_pte_range(struct mmu_gather *tlb, struct vm_area_struct *vma, pmd_t *pmd, unsigned long addr, unsigned long end, - long *zap_work, struct zap_details *details) + struct zap_details *details) { struct mm_struct *mm = tlb->mm; int force_flush = 0; - pte_t *pte; - spinlock_t *ptl; int rss[NR_MM_COUNTERS]; + spinlock_t *ptl; + pte_t *pte; again: init_rss_vec(rss); @@ -1001,12 +1001,9 @@ again: do { pte_t ptent = *pte; if (pte_none(ptent)) { - (*zap_work)--; continue; } - (*zap_work) -= PAGE_SIZE; - if (pte_present(ptent)) { struct page *page; @@ -1075,7 +1072,7 @@ again: print_bad_pte(vma, addr, ptent, NULL); } pte_clear_not_present_full(mm, addr, pte, tlb->fullmm); - } while (pte++, addr += PAGE_SIZE, (addr != end && *zap_work > 0)); + } while (pte++, addr += PAGE_SIZE, addr != end); add_mm_rss_vec(mm, rss); arch_leave_lazy_mmu_mode(); @@ -1099,7 +1096,7 @@ again: static inline unsigned long zap_pmd_range(struct mmu_gather *tlb, struct vm_area_struct *vma, pud_t *pud, unsigned long addr, unsigned long end, - long *zap_work, struct zap_details *details) + struct zap_details *details) { pmd_t *pmd; unsigned long next; @@ -1111,19 +1108,15 @@ static inline unsigned long zap_pmd_range(struct mmu_gather *tlb, if (next-addr != HPAGE_PMD_SIZE) { VM_BUG_ON(!rwsem_is_locked(&tlb->mm->mmap_sem)); split_huge_page_pmd(vma->vm_mm, pmd); - } else if (zap_huge_pmd(tlb, vma, pmd)) { - (*zap_work)--; + } else if (zap_huge_pmd(tlb, vma, pmd)) continue; - } /* fall through */ } - if (pmd_none_or_clear_bad(pmd)) { - (*zap_work)--; + if (pmd_none_or_clear_bad(pmd)) continue; - } - next = zap_pte_range(tlb, vma, pmd, addr, next, - zap_work, details); - } while (pmd++, addr = next, (addr != end && *zap_work > 0)); + next = zap_pte_range(tlb, vma, pmd, addr, next, details); + cond_resched(); + } while (pmd++, addr = next, addr != end); return addr; } @@ -1131,7 +1124,7 @@ static inline unsigned long zap_pmd_range(struct mmu_gather *tlb, static inline unsigned long zap_pud_range(struct mmu_gather *tlb, struct vm_area_struct *vma, pgd_t *pgd, unsigned long addr, unsigned long end, - long *zap_work, struct zap_details *details) + struct zap_details *details) { pud_t *pud; unsigned long next; @@ -1139,13 +1132,10 @@ static inline unsigned long zap_pud_range(struct mmu_gather *tlb, pud = pud_offset(pgd, addr); do { next = pud_addr_end(addr, end); - if (pud_none_or_clear_bad(pud)) { - (*zap_work)--; + if (pud_none_or_clear_bad(pud)) continue; - } - next = zap_pmd_range(tlb, vma, pud, addr, next, - zap_work, details); - } while (pud++, addr = next, (addr != end && *zap_work > 0)); + next = zap_pmd_range(tlb, vma, pud, addr, next, details); + } while (pud++, addr = next, addr != end); return addr; } @@ -1153,7 +1143,7 @@ static inline unsigned long zap_pud_range(struct mmu_gather *tlb, static unsigned long unmap_page_range(struct mmu_gather *tlb, struct vm_area_struct *vma, unsigned long addr, unsigned long end, - long *zap_work, struct zap_details *details) + struct zap_details *details) { pgd_t *pgd; unsigned long next; @@ -1167,13 +1157,10 @@ static unsigned long unmap_page_range(struct mmu_gather *tlb, pgd = pgd_offset(vma->vm_mm, addr); do { next = pgd_addr_end(addr, end); - if (pgd_none_or_clear_bad(pgd)) { - (*zap_work)--; + if (pgd_none_or_clear_bad(pgd)) continue; - } - next = zap_pud_range(tlb, vma, pgd, addr, next, - zap_work, details); - } while (pgd++, addr = next, (addr != end && *zap_work > 0)); + next = zap_pud_range(tlb, vma, pgd, addr, next, details); + } while (pgd++, addr = next, addr != end); tlb_end_vma(tlb, vma); mem_cgroup_uncharge_end(); @@ -1218,9 +1205,7 @@ unsigned long unmap_vmas(struct mmu_gather *tlb, unsigned long end_addr, unsigned long *nr_accounted, struct zap_details *details) { - long zap_work = ZAP_BLOCK_SIZE; unsigned long start = start_addr; - spinlock_t *i_mmap_lock = details? details->i_mmap_lock: NULL; struct mm_struct *mm = vma->vm_mm; mmu_notifier_invalidate_range_start(mm, start_addr, end_addr); @@ -1253,33 +1238,15 @@ unsigned long unmap_vmas(struct mmu_gather *tlb, * Since no pte has actually been setup, it is * safe to do nothing in this case. */ - if (vma->vm_file) { + if (vma->vm_file) unmap_hugepage_range(vma, start, end, NULL); - zap_work -= (end - start) / - pages_per_huge_page(hstate_vma(vma)); - } start = end; } else - start = unmap_page_range(tlb, vma, - start, end, &zap_work, details); - - if (zap_work > 0) { - BUG_ON(start != end); - break; - } - - if (need_resched() || - (i_mmap_lock && spin_needbreak(i_mmap_lock))) { - if (i_mmap_lock) - goto out; - cond_resched(); - } - - zap_work = ZAP_BLOCK_SIZE; + start = unmap_page_range(tlb, vma, start, end, details); } } -out: + mmu_notifier_invalidate_range_end(mm, start_addr, end_addr); return start; /* which is now the end (or restart) address */ } @@ -2612,96 +2579,11 @@ unwritable_page: return ret; } -/* - * Helper functions for unmap_mapping_range(). - * - * __ Notes on dropping i_mmap_lock to reduce latency while unmapping __ - * - * We have to restart searching the prio_tree whenever we drop the lock, - * since the iterator is only valid while the lock is held, and anyway - * a later vma might be split and reinserted earlier while lock dropped. - * - * The list of nonlinear vmas could be handled more efficiently, using - * a placeholder, but handle it in the same way until a need is shown. - * It is important to search the prio_tree before nonlinear list: a vma - * may become nonlinear and be shifted from prio_tree to nonlinear list - * while the lock is dropped; but never shifted from list to prio_tree. - * - * In order to make forward progress despite restarting the search, - * vm_truncate_count is used to mark a vma as now dealt with, so we can - * quickly skip it next time around. Since the prio_tree search only - * shows us those vmas affected by unmapping the range in question, we - * can't efficiently keep all vmas in step with mapping->truncate_count: - * so instead reset them all whenever it wraps back to 0 (then go to 1). - * mapping->truncate_count and vma->vm_truncate_count are protected by - * i_mmap_lock. - * - * In order to make forward progress despite repeatedly restarting some - * large vma, note the restart_addr from unmap_vmas when it breaks out: - * and restart from that address when we reach that vma again. It might - * have been split or merged, shrunk or extended, but never shifted: so - * restart_addr remains valid so long as it remains in the vma's range. - * unmap_mapping_range forces truncate_count to leap over page-aligned - * values so we can save vma's restart_addr in its truncate_count field. - */ -#define is_restart_addr(truncate_count) (!((truncate_count) & ~PAGE_MASK)) - -static void reset_vma_truncate_counts(struct address_space *mapping) -{ - struct vm_area_struct *vma; - struct prio_tree_iter iter; - - vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, 0, ULONG_MAX) - vma->vm_truncate_count = 0; - list_for_each_entry(vma, &mapping->i_mmap_nonlinear, shared.vm_set.list) - vma->vm_truncate_count = 0; -} - -static int unmap_mapping_range_vma(struct vm_area_struct *vma, +static void unmap_mapping_range_vma(struct vm_area_struct *vma, unsigned long start_addr, unsigned long end_addr, struct zap_details *details) { - unsigned long restart_addr; - int need_break; - - /* - * files that support invalidating or truncating portions of the - * file from under mmaped areas must have their ->fault function - * return a locked page (and set VM_FAULT_LOCKED in the return). - * This provides synchronisation against concurrent unmapping here. - */ - -again: - restart_addr = vma->vm_truncate_count; - if (is_restart_addr(restart_addr) && start_addr < restart_addr) { - start_addr = restart_addr; - if (start_addr >= end_addr) { - /* Top of vma has been split off since last time */ - vma->vm_truncate_count = details->truncate_count; - return 0; - } - } - - restart_addr = zap_page_range(vma, start_addr, - end_addr - start_addr, details); - need_break = need_resched() || spin_needbreak(details->i_mmap_lock); - - if (restart_addr >= end_addr) { - /* We have now completed this vma: mark it so */ - vma->vm_truncate_count = details->truncate_count; - if (!need_break) - return 0; - } else { - /* Note restart_addr in vma's truncate_count field */ - vma->vm_truncate_count = restart_addr; - if (!need_break) - goto again; - } - - spin_unlock(details->i_mmap_lock); - cond_resched(); - spin_lock(details->i_mmap_lock); - return -EINTR; + zap_page_range(vma, start_addr, end_addr - start_addr, details); } static inline void unmap_mapping_range_tree(struct prio_tree_root *root, @@ -2711,12 +2593,8 @@ static inline void unmap_mapping_range_tree(struct prio_tree_root *root, struct prio_tree_iter iter; pgoff_t vba, vea, zba, zea; -restart: vma_prio_tree_foreach(vma, &iter, root, details->first_index, details->last_index) { - /* Skip quickly over those we have already dealt with */ - if (vma->vm_truncate_count == details->truncate_count) - continue; vba = vma->vm_pgoff; vea = vba + ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) - 1; @@ -2728,11 +2606,10 @@ restart: if (zea > vea) zea = vea; - if (unmap_mapping_range_vma(vma, + unmap_mapping_range_vma(vma, ((zba - vba) << PAGE_SHIFT) + vma->vm_start, ((zea - vba + 1) << PAGE_SHIFT) + vma->vm_start, - details) < 0) - goto restart; + details); } } @@ -2747,15 +2624,9 @@ static inline void unmap_mapping_range_list(struct list_head *head, * across *all* the pages in each nonlinear VMA, not just the pages * whose virtual address lies outside the file truncation point. */ -restart: list_for_each_entry(vma, head, shared.vm_set.list) { - /* Skip quickly over those we have already dealt with */ - if (vma->vm_truncate_count == details->truncate_count) - continue; details->nonlinear_vma = vma; - if (unmap_mapping_range_vma(vma, vma->vm_start, - vma->vm_end, details) < 0) - goto restart; + unmap_mapping_range_vma(vma, vma->vm_start, vma->vm_end, details); } } @@ -2794,26 +2665,14 @@ void unmap_mapping_range(struct address_space *mapping, details.last_index = hba + hlen - 1; if (details.last_index < details.first_index) details.last_index = ULONG_MAX; - details.i_mmap_lock = &mapping->i_mmap_lock; - mutex_lock(&mapping->unmap_mutex); - spin_lock(&mapping->i_mmap_lock); - - /* Protect against endless unmapping loops */ - mapping->truncate_count++; - if (unlikely(is_restart_addr(mapping->truncate_count))) { - if (mapping->truncate_count == 0) - reset_vma_truncate_counts(mapping); - mapping->truncate_count++; - } - details.truncate_count = mapping->truncate_count; + spin_lock(&mapping->i_mmap_lock); if (unlikely(!prio_tree_empty(&mapping->i_mmap))) unmap_mapping_range_tree(&mapping->i_mmap, &details); if (unlikely(!list_empty(&mapping->i_mmap_nonlinear))) unmap_mapping_range_list(&mapping->i_mmap_nonlinear, &details); spin_unlock(&mapping->i_mmap_lock); - mutex_unlock(&mapping->unmap_mutex); } EXPORT_SYMBOL(unmap_mapping_range); diff --git a/mm/mmap.c b/mm/mmap.c index 40d49986e714..50cb04bb56bf 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -445,10 +445,8 @@ static void vma_link(struct mm_struct *mm, struct vm_area_struct *vma, if (vma->vm_file) mapping = vma->vm_file->f_mapping; - if (mapping) { + if (mapping) spin_lock(&mapping->i_mmap_lock); - vma->vm_truncate_count = mapping->truncate_count; - } __vma_link(mm, vma, prev, rb_link, rb_parent); __vma_link_file(vma); @@ -558,16 +556,7 @@ again: remove_next = 1 + (end > next->vm_end); if (!(vma->vm_flags & VM_NONLINEAR)) root = &mapping->i_mmap; spin_lock(&mapping->i_mmap_lock); - if (importer && - vma->vm_truncate_count != next->vm_truncate_count) { - /* - * unmap_mapping_range might be in progress: - * ensure that the expanding vma is rescanned. - */ - importer->vm_truncate_count = 0; - } if (insert) { - insert->vm_truncate_count = vma->vm_truncate_count; /* * Put into prio_tree now, so instantiated pages * are visible to arm/parisc __flush_dcache_page diff --git a/mm/mremap.c b/mm/mremap.c index a7c1f9f9b941..909e1e1e99b1 100644 --- a/mm/mremap.c +++ b/mm/mremap.c @@ -94,7 +94,6 @@ static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd, */ mapping = vma->vm_file->f_mapping; spin_lock(&mapping->i_mmap_lock); - new_vma->vm_truncate_count = 0; } /* -- cgit From 3d48ae45e72390ddf8cc5256ac32ed6f7a19cbea Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 24 May 2011 17:12:06 -0700 Subject: mm: Convert i_mmap_lock to a mutex Straightforward conversion of i_mmap_lock to a mutex. Signed-off-by: Peter Zijlstra Acked-by: Hugh Dickins Cc: Benjamin Herrenschmidt Cc: David Miller Cc: Martin Schwidefsky Cc: Russell King Cc: Paul Mundt Cc: Jeff Dike Cc: Richard Weinberger Cc: Tony Luck Cc: KAMEZAWA Hiroyuki Cc: Mel Gorman Cc: KOSAKI Motohiro Cc: Nick Piggin Cc: Namhyung Kim Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/lockstat.txt | 2 +- Documentation/vm/locking | 2 +- arch/x86/mm/hugetlbpage.c | 4 ++-- fs/hugetlbfs/inode.c | 4 ++-- fs/inode.c | 2 +- include/linux/fs.h | 2 +- include/linux/mmu_notifier.h | 2 +- kernel/fork.c | 4 ++-- mm/filemap.c | 10 +++++----- mm/filemap_xip.c | 4 ++-- mm/fremap.c | 4 ++-- mm/hugetlb.c | 14 +++++++------- mm/memory-failure.c | 4 ++-- mm/memory.c | 4 ++-- mm/mmap.c | 22 +++++++++++----------- mm/mremap.c | 4 ++-- mm/rmap.c | 28 ++++++++++++++-------------- 17 files changed, 58 insertions(+), 58 deletions(-) (limited to 'include/linux') diff --git a/Documentation/lockstat.txt b/Documentation/lockstat.txt index 65f4c795015d..9c0a80d17a23 100644 --- a/Documentation/lockstat.txt +++ b/Documentation/lockstat.txt @@ -136,7 +136,7 @@ View the top contending locks: dcache_lock: 1037 1161 0.38 45.32 774.51 6611 243371 0.15 306.48 77387.24 &inode->i_mutex: 161 286 18446744073709 62882.54 1244614.55 3653 20598 18446744073709 62318.60 1693822.74 &zone->lru_lock: 94 94 0.53 7.33 92.10 4366 32690 0.29 59.81 16350.06 - &inode->i_data.i_mmap_lock: 79 79 0.40 3.77 53.03 11779 87755 0.28 116.93 29898.44 + &inode->i_data.i_mmap_mutex: 79 79 0.40 3.77 53.03 11779 87755 0.28 116.93 29898.44 &q->__queue_lock: 48 50 0.52 31.62 86.31 774 13131 0.17 113.08 12277.52 &rq->rq_lock_key: 43 47 0.74 68.50 170.63 3706 33929 0.22 107.99 17460.62 &rq->rq_lock_key#2: 39 46 0.75 6.68 49.03 2979 32292 0.17 125.17 17137.63 diff --git a/Documentation/vm/locking b/Documentation/vm/locking index 25fadb448760..f61228bd6395 100644 --- a/Documentation/vm/locking +++ b/Documentation/vm/locking @@ -66,7 +66,7 @@ in some cases it is not really needed. Eg, vm_start is modified by expand_stack(), it is hard to come up with a destructive scenario without having the vmlist protection in this case. -The page_table_lock nests with the inode i_mmap_lock and the kmem cache +The page_table_lock nests with the inode i_mmap_mutex and the kmem cache c_spinlock spinlocks. This is okay, since the kmem code asks for pages after dropping c_spinlock. The page_table_lock also nests with pagecache_lock and pagemap_lru_lock spinlocks, and no code asks for memory with these locks diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c index d4203988504a..f581a18c0d4d 100644 --- a/arch/x86/mm/hugetlbpage.c +++ b/arch/x86/mm/hugetlbpage.c @@ -72,7 +72,7 @@ static void huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud) if (!vma_shareable(vma, addr)) return; - spin_lock(&mapping->i_mmap_lock); + mutex_lock(&mapping->i_mmap_mutex); vma_prio_tree_foreach(svma, &iter, &mapping->i_mmap, idx, idx) { if (svma == vma) continue; @@ -97,7 +97,7 @@ static void huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud) put_page(virt_to_page(spte)); spin_unlock(&mm->page_table_lock); out: - spin_unlock(&mapping->i_mmap_lock); + mutex_unlock(&mapping->i_mmap_mutex); } /* diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index b9eeb1cd03ff..e7a035781b7d 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -412,10 +412,10 @@ static int hugetlb_vmtruncate(struct inode *inode, loff_t offset) pgoff = offset >> PAGE_SHIFT; i_size_write(inode, offset); - spin_lock(&mapping->i_mmap_lock); + mutex_lock(&mapping->i_mmap_mutex); if (!prio_tree_empty(&mapping->i_mmap)) hugetlb_vmtruncate_list(&mapping->i_mmap, pgoff); - spin_unlock(&mapping->i_mmap_lock); + mutex_unlock(&mapping->i_mmap_mutex); truncate_hugepages(inode, offset); return 0; } diff --git a/fs/inode.c b/fs/inode.c index 7a7284c71abd..88aa3bcc7681 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -326,7 +326,7 @@ void address_space_init_once(struct address_space *mapping) memset(mapping, 0, sizeof(*mapping)); INIT_RADIX_TREE(&mapping->page_tree, GFP_ATOMIC); spin_lock_init(&mapping->tree_lock); - spin_lock_init(&mapping->i_mmap_lock); + mutex_init(&mapping->i_mmap_mutex); INIT_LIST_HEAD(&mapping->private_list); spin_lock_init(&mapping->private_lock); INIT_RAW_PRIO_TREE_ROOT(&mapping->i_mmap); diff --git a/include/linux/fs.h b/include/linux/fs.h index 5d2c86bdf5ba..5bb9e826019b 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -634,7 +634,7 @@ struct address_space { unsigned int i_mmap_writable;/* count VM_SHARED mappings */ struct prio_tree_root i_mmap; /* tree of private and shared mappings */ struct list_head i_mmap_nonlinear;/*list VM_NONLINEAR mappings */ - spinlock_t i_mmap_lock; /* protect tree, count, list */ + struct mutex i_mmap_mutex; /* protect tree, count, list */ unsigned long nrpages; /* number of total pages */ pgoff_t writeback_index;/* writeback starts here */ const struct address_space_operations *a_ops; /* methods */ diff --git a/include/linux/mmu_notifier.h b/include/linux/mmu_notifier.h index cc2e7dfea9d7..a877dfc243eb 100644 --- a/include/linux/mmu_notifier.h +++ b/include/linux/mmu_notifier.h @@ -150,7 +150,7 @@ struct mmu_notifier_ops { * Therefore notifier chains can only be traversed when either * * 1. mmap_sem is held. - * 2. One of the reverse map locks is held (i_mmap_lock or anon_vma->lock). + * 2. One of the reverse map locks is held (i_mmap_mutex or anon_vma->lock). * 3. No other concurrent thread can access the list (release) */ struct mmu_notifier { diff --git a/kernel/fork.c b/kernel/fork.c index 4eef925477fc..927692734bcf 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -383,14 +383,14 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) get_file(file); if (tmp->vm_flags & VM_DENYWRITE) atomic_dec(&inode->i_writecount); - spin_lock(&mapping->i_mmap_lock); + mutex_lock(&mapping->i_mmap_mutex); if (tmp->vm_flags & VM_SHARED) mapping->i_mmap_writable++; flush_dcache_mmap_lock(mapping); /* insert tmp into the share list, just after mpnt */ vma_prio_tree_add(tmp, mpnt); flush_dcache_mmap_unlock(mapping); - spin_unlock(&mapping->i_mmap_lock); + mutex_unlock(&mapping->i_mmap_mutex); } /* diff --git a/mm/filemap.c b/mm/filemap.c index 8144f87dcbb4..88354ae0b1fd 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -58,16 +58,16 @@ /* * Lock ordering: * - * ->i_mmap_lock (truncate_pagecache) + * ->i_mmap_mutex (truncate_pagecache) * ->private_lock (__free_pte->__set_page_dirty_buffers) * ->swap_lock (exclusive_swap_page, others) * ->mapping->tree_lock * * ->i_mutex - * ->i_mmap_lock (truncate->unmap_mapping_range) + * ->i_mmap_mutex (truncate->unmap_mapping_range) * * ->mmap_sem - * ->i_mmap_lock + * ->i_mmap_mutex * ->page_table_lock or pte_lock (various, mainly in memory.c) * ->mapping->tree_lock (arch-dependent flush_dcache_mmap_lock) * @@ -84,7 +84,7 @@ * sb_lock (fs/fs-writeback.c) * ->mapping->tree_lock (__sync_single_inode) * - * ->i_mmap_lock + * ->i_mmap_mutex * ->anon_vma.lock (vma_adjust) * * ->anon_vma.lock @@ -106,7 +106,7 @@ * * (code doesn't rely on that order, so you could switch it around) * ->tasklist_lock (memory_failure, collect_procs_ao) - * ->i_mmap_lock + * ->i_mmap_mutex */ /* diff --git a/mm/filemap_xip.c b/mm/filemap_xip.c index 83364df74a33..93356cd12828 100644 --- a/mm/filemap_xip.c +++ b/mm/filemap_xip.c @@ -183,7 +183,7 @@ __xip_unmap (struct address_space * mapping, return; retry: - spin_lock(&mapping->i_mmap_lock); + mutex_lock(&mapping->i_mmap_mutex); vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) { mm = vma->vm_mm; address = vma->vm_start + @@ -201,7 +201,7 @@ retry: page_cache_release(page); } } - spin_unlock(&mapping->i_mmap_lock); + mutex_unlock(&mapping->i_mmap_mutex); if (locked) { mutex_unlock(&xip_sparse_mutex); diff --git a/mm/fremap.c b/mm/fremap.c index ec520c7b28df..7f4123056e06 100644 --- a/mm/fremap.c +++ b/mm/fremap.c @@ -211,13 +211,13 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, } goto out; } - spin_lock(&mapping->i_mmap_lock); + mutex_lock(&mapping->i_mmap_mutex); flush_dcache_mmap_lock(mapping); vma->vm_flags |= VM_NONLINEAR; vma_prio_tree_remove(vma, &mapping->i_mmap); vma_nonlinear_insert(vma, &mapping->i_mmap_nonlinear); flush_dcache_mmap_unlock(mapping); - spin_unlock(&mapping->i_mmap_lock); + mutex_unlock(&mapping->i_mmap_mutex); } if (vma->vm_flags & VM_LOCKED) { diff --git a/mm/hugetlb.c b/mm/hugetlb.c index bbb4a5bbb958..5fd68b95c671 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -2205,7 +2205,7 @@ void __unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start, unsigned long sz = huge_page_size(h); /* - * A page gathering list, protected by per file i_mmap_lock. The + * A page gathering list, protected by per file i_mmap_mutex. The * lock is used to avoid list corruption from multiple unmapping * of the same page since we are using page->lru. */ @@ -2274,9 +2274,9 @@ void __unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start, void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start, unsigned long end, struct page *ref_page) { - spin_lock(&vma->vm_file->f_mapping->i_mmap_lock); + mutex_lock(&vma->vm_file->f_mapping->i_mmap_mutex); __unmap_hugepage_range(vma, start, end, ref_page); - spin_unlock(&vma->vm_file->f_mapping->i_mmap_lock); + mutex_unlock(&vma->vm_file->f_mapping->i_mmap_mutex); } /* @@ -2308,7 +2308,7 @@ static int unmap_ref_private(struct mm_struct *mm, struct vm_area_struct *vma, * this mapping should be shared between all the VMAs, * __unmap_hugepage_range() is called as the lock is already held */ - spin_lock(&mapping->i_mmap_lock); + mutex_lock(&mapping->i_mmap_mutex); vma_prio_tree_foreach(iter_vma, &iter, &mapping->i_mmap, pgoff, pgoff) { /* Do not unmap the current VMA */ if (iter_vma == vma) @@ -2326,7 +2326,7 @@ static int unmap_ref_private(struct mm_struct *mm, struct vm_area_struct *vma, address, address + huge_page_size(h), page); } - spin_unlock(&mapping->i_mmap_lock); + mutex_unlock(&mapping->i_mmap_mutex); return 1; } @@ -2810,7 +2810,7 @@ void hugetlb_change_protection(struct vm_area_struct *vma, BUG_ON(address >= end); flush_cache_range(vma, address, end); - spin_lock(&vma->vm_file->f_mapping->i_mmap_lock); + mutex_lock(&vma->vm_file->f_mapping->i_mmap_mutex); spin_lock(&mm->page_table_lock); for (; address < end; address += huge_page_size(h)) { ptep = huge_pte_offset(mm, address); @@ -2825,7 +2825,7 @@ void hugetlb_change_protection(struct vm_area_struct *vma, } } spin_unlock(&mm->page_table_lock); - spin_unlock(&vma->vm_file->f_mapping->i_mmap_lock); + mutex_unlock(&vma->vm_file->f_mapping->i_mmap_mutex); flush_tlb_range(vma, start, end); } diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 2b9a5eef39e0..12178ec32ab5 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -429,7 +429,7 @@ static void collect_procs_file(struct page *page, struct list_head *to_kill, */ read_lock(&tasklist_lock); - spin_lock(&mapping->i_mmap_lock); + mutex_lock(&mapping->i_mmap_mutex); for_each_process(tsk) { pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT); @@ -449,7 +449,7 @@ static void collect_procs_file(struct page *page, struct list_head *to_kill, add_to_kill(tsk, page, vma, to_kill, tkc); } } - spin_unlock(&mapping->i_mmap_lock); + mutex_unlock(&mapping->i_mmap_mutex); read_unlock(&tasklist_lock); } diff --git a/mm/memory.c b/mm/memory.c index 18655878b9f8..7bbe4d3df756 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -2667,12 +2667,12 @@ void unmap_mapping_range(struct address_space *mapping, details.last_index = ULONG_MAX; - spin_lock(&mapping->i_mmap_lock); + mutex_lock(&mapping->i_mmap_mutex); if (unlikely(!prio_tree_empty(&mapping->i_mmap))) unmap_mapping_range_tree(&mapping->i_mmap, &details); if (unlikely(!list_empty(&mapping->i_mmap_nonlinear))) unmap_mapping_range_list(&mapping->i_mmap_nonlinear, &details); - spin_unlock(&mapping->i_mmap_lock); + mutex_unlock(&mapping->i_mmap_mutex); } EXPORT_SYMBOL(unmap_mapping_range); diff --git a/mm/mmap.c b/mm/mmap.c index 50cb04bb56bf..26efbfca0b20 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -194,7 +194,7 @@ error: } /* - * Requires inode->i_mapping->i_mmap_lock + * Requires inode->i_mapping->i_mmap_mutex */ static void __remove_shared_vm_struct(struct vm_area_struct *vma, struct file *file, struct address_space *mapping) @@ -222,9 +222,9 @@ void unlink_file_vma(struct vm_area_struct *vma) if (file) { struct address_space *mapping = file->f_mapping; - spin_lock(&mapping->i_mmap_lock); + mutex_lock(&mapping->i_mmap_mutex); __remove_shared_vm_struct(vma, file, mapping); - spin_unlock(&mapping->i_mmap_lock); + mutex_unlock(&mapping->i_mmap_mutex); } } @@ -446,13 +446,13 @@ static void vma_link(struct mm_struct *mm, struct vm_area_struct *vma, mapping = vma->vm_file->f_mapping; if (mapping) - spin_lock(&mapping->i_mmap_lock); + mutex_lock(&mapping->i_mmap_mutex); __vma_link(mm, vma, prev, rb_link, rb_parent); __vma_link_file(vma); if (mapping) - spin_unlock(&mapping->i_mmap_lock); + mutex_unlock(&mapping->i_mmap_mutex); mm->map_count++; validate_mm(mm); @@ -555,7 +555,7 @@ again: remove_next = 1 + (end > next->vm_end); mapping = file->f_mapping; if (!(vma->vm_flags & VM_NONLINEAR)) root = &mapping->i_mmap; - spin_lock(&mapping->i_mmap_lock); + mutex_lock(&mapping->i_mmap_mutex); if (insert) { /* * Put into prio_tree now, so instantiated pages @@ -622,7 +622,7 @@ again: remove_next = 1 + (end > next->vm_end); if (anon_vma) anon_vma_unlock(anon_vma); if (mapping) - spin_unlock(&mapping->i_mmap_lock); + mutex_unlock(&mapping->i_mmap_mutex); if (remove_next) { if (file) { @@ -2290,7 +2290,7 @@ void exit_mmap(struct mm_struct *mm) /* Insert vm structure into process list sorted by address * and into the inode's i_mmap tree. If vm_file is non-NULL - * then i_mmap_lock is taken here. + * then i_mmap_mutex is taken here. */ int insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma) { @@ -2532,7 +2532,7 @@ static void vm_lock_mapping(struct mm_struct *mm, struct address_space *mapping) */ if (test_and_set_bit(AS_MM_ALL_LOCKS, &mapping->flags)) BUG(); - spin_lock_nest_lock(&mapping->i_mmap_lock, &mm->mmap_sem); + mutex_lock_nest_lock(&mapping->i_mmap_mutex, &mm->mmap_sem); } } @@ -2559,7 +2559,7 @@ static void vm_lock_mapping(struct mm_struct *mm, struct address_space *mapping) * vma in this mm is backed by the same anon_vma or address_space. * * We can take all the locks in random order because the VM code - * taking i_mmap_lock or anon_vma->lock outside the mmap_sem never + * taking i_mmap_mutex or anon_vma->lock outside the mmap_sem never * takes more than one of them in a row. Secondly we're protected * against a concurrent mm_take_all_locks() by the mm_all_locks_mutex. * @@ -2631,7 +2631,7 @@ static void vm_unlock_mapping(struct address_space *mapping) * AS_MM_ALL_LOCKS can't change to 0 from under us * because we hold the mm_all_locks_mutex. */ - spin_unlock(&mapping->i_mmap_lock); + mutex_unlock(&mapping->i_mmap_mutex); if (!test_and_clear_bit(AS_MM_ALL_LOCKS, &mapping->flags)) BUG(); diff --git a/mm/mremap.c b/mm/mremap.c index 909e1e1e99b1..506fa44403df 100644 --- a/mm/mremap.c +++ b/mm/mremap.c @@ -93,7 +93,7 @@ static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd, * and we propagate stale pages into the dst afterward. */ mapping = vma->vm_file->f_mapping; - spin_lock(&mapping->i_mmap_lock); + mutex_lock(&mapping->i_mmap_mutex); } /* @@ -122,7 +122,7 @@ static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd, pte_unmap(new_pte - 1); pte_unmap_unlock(old_pte - 1, old_ptl); if (mapping) - spin_unlock(&mapping->i_mmap_lock); + mutex_unlock(&mapping->i_mmap_mutex); mmu_notifier_invalidate_range_end(vma->vm_mm, old_start, old_end); } diff --git a/mm/rmap.c b/mm/rmap.c index 522e4a93cadd..f0ef7ea5423a 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -24,7 +24,7 @@ * inode->i_alloc_sem (vmtruncate_range) * mm->mmap_sem * page->flags PG_locked (lock_page) - * mapping->i_mmap_lock + * mapping->i_mmap_mutex * anon_vma->lock * mm->page_table_lock or pte_lock * zone->lru_lock (in mark_page_accessed, isolate_lru_page) @@ -646,14 +646,14 @@ static int page_referenced_file(struct page *page, * The page lock not only makes sure that page->mapping cannot * suddenly be NULLified by truncation, it makes sure that the * structure at mapping cannot be freed and reused yet, - * so we can safely take mapping->i_mmap_lock. + * so we can safely take mapping->i_mmap_mutex. */ BUG_ON(!PageLocked(page)); - spin_lock(&mapping->i_mmap_lock); + mutex_lock(&mapping->i_mmap_mutex); /* - * i_mmap_lock does not stabilize mapcount at all, but mapcount + * i_mmap_mutex does not stabilize mapcount at all, but mapcount * is more likely to be accurate if we note it after spinning. */ mapcount = page_mapcount(page); @@ -675,7 +675,7 @@ static int page_referenced_file(struct page *page, break; } - spin_unlock(&mapping->i_mmap_lock); + mutex_unlock(&mapping->i_mmap_mutex); return referenced; } @@ -762,7 +762,7 @@ static int page_mkclean_file(struct address_space *mapping, struct page *page) BUG_ON(PageAnon(page)); - spin_lock(&mapping->i_mmap_lock); + mutex_lock(&mapping->i_mmap_mutex); vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) { if (vma->vm_flags & VM_SHARED) { unsigned long address = vma_address(page, vma); @@ -771,7 +771,7 @@ static int page_mkclean_file(struct address_space *mapping, struct page *page) ret += page_mkclean_one(page, vma, address); } } - spin_unlock(&mapping->i_mmap_lock); + mutex_unlock(&mapping->i_mmap_mutex); return ret; } @@ -1119,7 +1119,7 @@ out_mlock: /* * We need mmap_sem locking, Otherwise VM_LOCKED check makes * unstable result and race. Plus, We can't wait here because - * we now hold anon_vma->lock or mapping->i_mmap_lock. + * we now hold anon_vma->lock or mapping->i_mmap_mutex. * if trylock failed, the page remain in evictable lru and later * vmscan could retry to move the page to unevictable lru if the * page is actually mlocked. @@ -1345,7 +1345,7 @@ static int try_to_unmap_file(struct page *page, enum ttu_flags flags) unsigned long max_nl_size = 0; unsigned int mapcount; - spin_lock(&mapping->i_mmap_lock); + mutex_lock(&mapping->i_mmap_mutex); vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) { unsigned long address = vma_address(page, vma); if (address == -EFAULT) @@ -1391,7 +1391,7 @@ static int try_to_unmap_file(struct page *page, enum ttu_flags flags) mapcount = page_mapcount(page); if (!mapcount) goto out; - cond_resched_lock(&mapping->i_mmap_lock); + cond_resched(); max_nl_size = (max_nl_size + CLUSTER_SIZE - 1) & CLUSTER_MASK; if (max_nl_cursor == 0) @@ -1413,7 +1413,7 @@ static int try_to_unmap_file(struct page *page, enum ttu_flags flags) } vma->vm_private_data = (void *) max_nl_cursor; } - cond_resched_lock(&mapping->i_mmap_lock); + cond_resched(); max_nl_cursor += CLUSTER_SIZE; } while (max_nl_cursor <= max_nl_size); @@ -1425,7 +1425,7 @@ static int try_to_unmap_file(struct page *page, enum ttu_flags flags) list_for_each_entry(vma, &mapping->i_mmap_nonlinear, shared.vm_set.list) vma->vm_private_data = NULL; out: - spin_unlock(&mapping->i_mmap_lock); + mutex_unlock(&mapping->i_mmap_mutex); return ret; } @@ -1544,7 +1544,7 @@ static int rmap_walk_file(struct page *page, int (*rmap_one)(struct page *, if (!mapping) return ret; - spin_lock(&mapping->i_mmap_lock); + mutex_lock(&mapping->i_mmap_mutex); vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) { unsigned long address = vma_address(page, vma); if (address == -EFAULT) @@ -1558,7 +1558,7 @@ static int rmap_walk_file(struct page *page, int (*rmap_one)(struct page *, * never contain migration ptes. Decide what to do about this * limitation to linear when we need rmap_walk() on nonlinear. */ - spin_unlock(&mapping->i_mmap_lock); + mutex_unlock(&mapping->i_mmap_mutex); return ret; } -- cgit From 25aeeb046e695c3093a86aa9386128ffb3b1bc32 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 24 May 2011 17:12:07 -0700 Subject: mm: revert page_lock_anon_vma() lock annotation Its beyond ugly and gets in the way. Signed-off-by: Peter Zijlstra Acked-by: Hugh Dickins Cc: Benjamin Herrenschmidt Cc: David Miller Cc: Martin Schwidefsky Cc: Russell King Cc: Paul Mundt Cc: Jeff Dike Cc: Richard Weinberger Cc: Tony Luck Cc: KAMEZAWA Hiroyuki Cc: Mel Gorman Cc: Namhyung Kim Cc: KOSAKI Motohiro Cc: Nick Piggin Cc: Namhyung Kim Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/rmap.h | 15 +-------------- mm/rmap.c | 4 +--- 2 files changed, 2 insertions(+), 17 deletions(-) (limited to 'include/linux') diff --git a/include/linux/rmap.h b/include/linux/rmap.h index 830e65dc01ee..590c291a8cd9 100644 --- a/include/linux/rmap.h +++ b/include/linux/rmap.h @@ -218,20 +218,7 @@ int try_to_munlock(struct page *); /* * Called by memory-failure.c to kill processes. */ -struct anon_vma *__page_lock_anon_vma(struct page *page); - -static inline struct anon_vma *page_lock_anon_vma(struct page *page) -{ - struct anon_vma *anon_vma; - - __cond_lock(RCU, anon_vma = __page_lock_anon_vma(page)); - - /* (void) is needed to make gcc happy */ - (void) __cond_lock(&anon_vma->root->lock, anon_vma); - - return anon_vma; -} - +struct anon_vma *page_lock_anon_vma(struct page *page); void page_unlock_anon_vma(struct anon_vma *anon_vma); int page_mapped_in_vma(struct page *page, struct vm_area_struct *vma); diff --git a/mm/rmap.c b/mm/rmap.c index f0ef7ea5423a..c6044761617e 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -323,7 +323,7 @@ void __init anon_vma_init(void) * Getting a lock on a stable anon_vma from a page off the LRU is * tricky: page_lock_anon_vma rely on RCU to guard against the races. */ -struct anon_vma *__page_lock_anon_vma(struct page *page) +struct anon_vma *page_lock_anon_vma(struct page *page) { struct anon_vma *anon_vma, *root_anon_vma; unsigned long anon_mapping; @@ -357,8 +357,6 @@ out: } void page_unlock_anon_vma(struct anon_vma *anon_vma) - __releases(&anon_vma->root->lock) - __releases(RCU) { anon_vma_unlock(anon_vma); rcu_read_unlock(); -- cgit From 2b575eb64f7a9c701fb4bfdb12388ac547f6c2b6 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 24 May 2011 17:12:11 -0700 Subject: mm: convert anon_vma->lock to a mutex Straightforward conversion of anon_vma->lock to a mutex. Signed-off-by: Peter Zijlstra Acked-by: Hugh Dickins Reviewed-by: KOSAKI Motohiro Cc: Benjamin Herrenschmidt Cc: David Miller Cc: Martin Schwidefsky Cc: Russell King Cc: Paul Mundt Cc: Jeff Dike Cc: Richard Weinberger Cc: Tony Luck Cc: KAMEZAWA Hiroyuki Cc: Mel Gorman Cc: Nick Piggin Cc: Namhyung Kim Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/huge_mm.h | 8 ++------ include/linux/mmu_notifier.h | 2 +- include/linux/rmap.h | 14 +++++++------- mm/huge_memory.c | 4 ++-- mm/mmap.c | 10 +++++----- mm/rmap.c | 8 ++++---- 6 files changed, 21 insertions(+), 25 deletions(-) (limited to 'include/linux') diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h index 8847c8c29791..48c32ebf65a7 100644 --- a/include/linux/huge_mm.h +++ b/include/linux/huge_mm.h @@ -92,12 +92,8 @@ extern void __split_huge_page_pmd(struct mm_struct *mm, pmd_t *pmd); #define wait_split_huge_page(__anon_vma, __pmd) \ do { \ pmd_t *____pmd = (__pmd); \ - spin_unlock_wait(&(__anon_vma)->root->lock); \ - /* \ - * spin_unlock_wait() is just a loop in C and so the \ - * CPU can reorder anything around it. \ - */ \ - smp_mb(); \ + anon_vma_lock(__anon_vma); \ + anon_vma_unlock(__anon_vma); \ BUG_ON(pmd_trans_splitting(*____pmd) || \ pmd_trans_huge(*____pmd)); \ } while (0) diff --git a/include/linux/mmu_notifier.h b/include/linux/mmu_notifier.h index a877dfc243eb..1d1b1e13f79f 100644 --- a/include/linux/mmu_notifier.h +++ b/include/linux/mmu_notifier.h @@ -150,7 +150,7 @@ struct mmu_notifier_ops { * Therefore notifier chains can only be traversed when either * * 1. mmap_sem is held. - * 2. One of the reverse map locks is held (i_mmap_mutex or anon_vma->lock). + * 2. One of the reverse map locks is held (i_mmap_mutex or anon_vma->mutex). * 3. No other concurrent thread can access the list (release) */ struct mmu_notifier { diff --git a/include/linux/rmap.h b/include/linux/rmap.h index 590c291a8cd9..2148b122779b 100644 --- a/include/linux/rmap.h +++ b/include/linux/rmap.h @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include /* @@ -26,7 +26,7 @@ */ struct anon_vma { struct anon_vma *root; /* Root of this anon_vma tree */ - spinlock_t lock; /* Serialize access to vma list */ + struct mutex mutex; /* Serialize access to vma list */ /* * The refcount is taken on an anon_vma when there is no * guarantee that the vma of page tables will exist for @@ -64,7 +64,7 @@ struct anon_vma_chain { struct vm_area_struct *vma; struct anon_vma *anon_vma; struct list_head same_vma; /* locked by mmap_sem & page_table_lock */ - struct list_head same_anon_vma; /* locked by anon_vma->lock */ + struct list_head same_anon_vma; /* locked by anon_vma->mutex */ }; #ifdef CONFIG_MMU @@ -93,24 +93,24 @@ static inline void vma_lock_anon_vma(struct vm_area_struct *vma) { struct anon_vma *anon_vma = vma->anon_vma; if (anon_vma) - spin_lock(&anon_vma->root->lock); + mutex_lock(&anon_vma->root->mutex); } static inline void vma_unlock_anon_vma(struct vm_area_struct *vma) { struct anon_vma *anon_vma = vma->anon_vma; if (anon_vma) - spin_unlock(&anon_vma->root->lock); + mutex_unlock(&anon_vma->root->mutex); } static inline void anon_vma_lock(struct anon_vma *anon_vma) { - spin_lock(&anon_vma->root->lock); + mutex_lock(&anon_vma->root->mutex); } static inline void anon_vma_unlock(struct anon_vma *anon_vma) { - spin_unlock(&anon_vma->root->lock); + mutex_unlock(&anon_vma->root->mutex); } /* diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 83326ad66d9b..90eef404ec2e 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -1139,7 +1139,7 @@ static int __split_huge_page_splitting(struct page *page, * We can't temporarily set the pmd to null in order * to split it, the pmd must remain marked huge at all * times or the VM won't take the pmd_trans_huge paths - * and it won't wait on the anon_vma->root->lock to + * and it won't wait on the anon_vma->root->mutex to * serialize against split_huge_page*. */ pmdp_splitting_flush_notify(vma, address, pmd); @@ -1333,7 +1333,7 @@ static int __split_huge_page_map(struct page *page, return ret; } -/* must be called with anon_vma->root->lock hold */ +/* must be called with anon_vma->root->mutex hold */ static void __split_huge_page(struct page *page, struct anon_vma *anon_vma) { diff --git a/mm/mmap.c b/mm/mmap.c index 26efbfca0b20..ac2631b7477f 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -2502,15 +2502,15 @@ static void vm_lock_anon_vma(struct mm_struct *mm, struct anon_vma *anon_vma) * The LSB of head.next can't change from under us * because we hold the mm_all_locks_mutex. */ - spin_lock_nest_lock(&anon_vma->root->lock, &mm->mmap_sem); + mutex_lock_nest_lock(&anon_vma->root->mutex, &mm->mmap_sem); /* * We can safely modify head.next after taking the - * anon_vma->root->lock. If some other vma in this mm shares + * anon_vma->root->mutex. If some other vma in this mm shares * the same anon_vma we won't take it again. * * No need of atomic instructions here, head.next * can't change from under us thanks to the - * anon_vma->root->lock. + * anon_vma->root->mutex. */ if (__test_and_set_bit(0, (unsigned long *) &anon_vma->root->head.next)) @@ -2559,7 +2559,7 @@ static void vm_lock_mapping(struct mm_struct *mm, struct address_space *mapping) * vma in this mm is backed by the same anon_vma or address_space. * * We can take all the locks in random order because the VM code - * taking i_mmap_mutex or anon_vma->lock outside the mmap_sem never + * taking i_mmap_mutex or anon_vma->mutex outside the mmap_sem never * takes more than one of them in a row. Secondly we're protected * against a concurrent mm_take_all_locks() by the mm_all_locks_mutex. * @@ -2615,7 +2615,7 @@ static void vm_unlock_anon_vma(struct anon_vma *anon_vma) * * No need of atomic instructions here, head.next * can't change from under us until we release the - * anon_vma->root->lock. + * anon_vma->root->mutex. */ if (!__test_and_clear_bit(0, (unsigned long *) &anon_vma->root->head.next)) diff --git a/mm/rmap.c b/mm/rmap.c index d271845d7d15..ce29d405d093 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -25,7 +25,7 @@ * mm->mmap_sem * page->flags PG_locked (lock_page) * mapping->i_mmap_mutex - * anon_vma->lock + * anon_vma->mutex * mm->page_table_lock or pte_lock * zone->lru_lock (in mark_page_accessed, isolate_lru_page) * swap_lock (in swap_duplicate, swap_info_get) @@ -40,7 +40,7 @@ * * (code doesn't rely on that order so it could be switched around) * ->tasklist_lock - * anon_vma->lock (memory_failure, collect_procs_anon) + * anon_vma->mutex (memory_failure, collect_procs_anon) * pte map lock */ @@ -307,7 +307,7 @@ static void anon_vma_ctor(void *data) { struct anon_vma *anon_vma = data; - spin_lock_init(&anon_vma->lock); + mutex_init(&anon_vma->mutex); atomic_set(&anon_vma->refcount, 0); INIT_LIST_HEAD(&anon_vma->head); } @@ -1143,7 +1143,7 @@ out_mlock: /* * We need mmap_sem locking, Otherwise VM_LOCKED check makes * unstable result and race. Plus, We can't wait here because - * we now hold anon_vma->lock or mapping->i_mmap_mutex. + * we now hold anon_vma->mutex or mapping->i_mmap_mutex. * if trylock failed, the page remain in evictable lru and later * vmscan could retry to move the page to unevictable lru if the * page is actually mlocked. -- cgit From de03c72cfce5b263a674d04348b58475ec50163c Mon Sep 17 00:00:00 2001 From: KOSAKI Motohiro Date: Tue, 24 May 2011 17:12:15 -0700 Subject: mm: convert mm->cpu_vm_cpumask into cpumask_var_t cpumask_t is very big struct and cpu_vm_mask is placed wrong position. It might lead to reduce cache hit ratio. This patch has two change. 1) Move the place of cpumask into last of mm_struct. Because usually cpumask is accessed only front bits when the system has cpu-hotplug capability 2) Convert cpu_vm_mask into cpumask_var_t. It may help to reduce memory footprint if cpumask_size() will use nr_cpumask_bits properly in future. In addition, this patch change the name of cpu_vm_mask with cpu_vm_mask_var. It may help to detect out of tree cpu_vm_mask users. This patch has no functional change. [akpm@linux-foundation.org: build fix] [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: KOSAKI Motohiro Cc: David Howells Cc: Koichi Yasutake Cc: Hugh Dickins Cc: Chris Metcalf Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/cachetlb.txt | 2 +- arch/x86/kernel/tboot.c | 1 - include/linux/mm_types.h | 9 ++++++--- include/linux/sched.h | 1 + init/main.c | 2 ++ kernel/fork.c | 37 ++++++++++++++++++++++++++++++++++--- mm/init-mm.c | 1 - 7 files changed, 44 insertions(+), 9 deletions(-) (limited to 'include/linux') diff --git a/Documentation/cachetlb.txt b/Documentation/cachetlb.txt index 9164ae3b83bc..9b728dc17535 100644 --- a/Documentation/cachetlb.txt +++ b/Documentation/cachetlb.txt @@ -16,7 +16,7 @@ on all processors in the system. Don't let this scare you into thinking SMP cache/tlb flushing must be so inefficient, this is in fact an area where many optimizations are possible. For example, if it can be proven that a user address space has never executed -on a cpu (see vma->cpu_vm_mask), one need not perform a flush +on a cpu (see mm_cpumask()), one need not perform a flush for this address space on that cpu. First, the TLB flushing interfaces, since they are the simplest. The diff --git a/arch/x86/kernel/tboot.c b/arch/x86/kernel/tboot.c index 998e972f3b1a..30ac65df7d4e 100644 --- a/arch/x86/kernel/tboot.c +++ b/arch/x86/kernel/tboot.c @@ -110,7 +110,6 @@ static struct mm_struct tboot_mm = { .mmap_sem = __RWSEM_INITIALIZER(init_mm.mmap_sem), .page_table_lock = __SPIN_LOCK_UNLOCKED(init_mm.page_table_lock), .mmlist = LIST_HEAD_INIT(init_mm.mmlist), - .cpu_vm_mask = CPU_MASK_ALL, }; static inline void switch_to_tboot_pt(void) diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 201998e5b530..c2f9ea7922f4 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -265,8 +265,6 @@ struct mm_struct { struct linux_binfmt *binfmt; - cpumask_t cpu_vm_mask; - /* Architecture-specific MM context */ mm_context_t context; @@ -316,9 +314,14 @@ struct mm_struct { #ifdef CONFIG_TRANSPARENT_HUGEPAGE pgtable_t pmd_huge_pte; /* protected by page_table_lock */ #endif + + cpumask_var_t cpu_vm_mask_var; }; /* Future-safe accessor for struct mm_struct's cpu_vm_mask. */ -#define mm_cpumask(mm) (&(mm)->cpu_vm_mask) +static inline cpumask_t *mm_cpumask(struct mm_struct *mm) +{ + return mm->cpu_vm_mask_var; +} #endif /* _LINUX_MM_TYPES_H */ diff --git a/include/linux/sched.h b/include/linux/sched.h index 44b8faaac7c0..f18300eddfcb 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -2176,6 +2176,7 @@ static inline void mmdrop(struct mm_struct * mm) if (unlikely(atomic_dec_and_test(&mm->mm_count))) __mmdrop(mm); } +extern int mm_init_cpumask(struct mm_struct *mm, struct mm_struct *oldmm); /* mmput gets rid of the mappings and all user-space */ extern void mmput(struct mm_struct *); diff --git a/init/main.c b/init/main.c index 48df882d51d2..22da33918aef 100644 --- a/init/main.c +++ b/init/main.c @@ -509,6 +509,8 @@ asmlinkage void __init start_kernel(void) sort_main_extable(); trap_init(); mm_init(); + BUG_ON(mm_init_cpumask(&init_mm, 0)); + /* * Set up the scheduler prior starting any interrupts (such as the * timer interrupt). Full topology setup happens at smp_init() diff --git a/kernel/fork.c b/kernel/fork.c index 927692734bcf..8e7e135d0817 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -485,6 +485,20 @@ static void mm_init_aio(struct mm_struct *mm) #endif } +int mm_init_cpumask(struct mm_struct *mm, struct mm_struct *oldmm) +{ +#ifdef CONFIG_CPUMASK_OFFSTACK + if (!alloc_cpumask_var(&mm->cpu_vm_mask_var, GFP_KERNEL)) + return -ENOMEM; + + if (oldmm) + cpumask_copy(mm_cpumask(mm), mm_cpumask(oldmm)); + else + memset(mm_cpumask(mm), 0, cpumask_size()); +#endif + return 0; +} + static struct mm_struct * mm_init(struct mm_struct * mm, struct task_struct *p) { atomic_set(&mm->mm_users, 1); @@ -521,10 +535,20 @@ struct mm_struct * mm_alloc(void) struct mm_struct * mm; mm = allocate_mm(); - if (mm) { - memset(mm, 0, sizeof(*mm)); - mm = mm_init(mm, current); + if (!mm) + return NULL; + + memset(mm, 0, sizeof(*mm)); + mm = mm_init(mm, current); + if (!mm) + return NULL; + + if (mm_init_cpumask(mm, NULL)) { + mm_free_pgd(mm); + free_mm(mm); + return NULL; } + return mm; } @@ -536,6 +560,7 @@ struct mm_struct * mm_alloc(void) void __mmdrop(struct mm_struct *mm) { BUG_ON(mm == &init_mm); + free_cpumask_var(mm->cpu_vm_mask_var); mm_free_pgd(mm); destroy_context(mm); mmu_notifier_mm_destroy(mm); @@ -690,6 +715,9 @@ struct mm_struct *dup_mm(struct task_struct *tsk) if (!mm_init(mm, tsk)) goto fail_nomem; + if (mm_init_cpumask(mm, oldmm)) + goto fail_nocpumask; + if (init_new_context(tsk, mm)) goto fail_nocontext; @@ -716,6 +744,9 @@ fail_nomem: return NULL; fail_nocontext: + free_cpumask_var(mm->cpu_vm_mask_var); + +fail_nocpumask: /* * If init_new_context() failed, we cannot use mmput() to free the mm * because it calls destroy_context() diff --git a/mm/init-mm.c b/mm/init-mm.c index 1d29cdfe8ebb..4019979b2637 100644 --- a/mm/init-mm.c +++ b/mm/init-mm.c @@ -21,6 +21,5 @@ struct mm_struct init_mm = { .mmap_sem = __RWSEM_INITIALIZER(init_mm.mmap_sem), .page_table_lock = __SPIN_LOCK_UNLOCKED(init_mm.page_table_lock), .mmlist = LIST_HEAD_INIT(init_mm.mmlist), - .cpu_vm_mask = CPU_MASK_ALL, INIT_MM_CONTEXT(init_mm) }; -- cgit From a238ab5b0239575c179f4976064192c3f7409dad Mon Sep 17 00:00:00 2001 From: Dave Hansen Date: Tue, 24 May 2011 17:12:16 -0700 Subject: mm: break out page allocation warning code This originally started as a simple patch to give vmalloc() some more verbose output on failure on top of the plain page allocator messages. Johannes suggested that it might be nicer to lead with the vmalloc() info _before_ the page allocator messages. But, I do think there's a lot of value in what __alloc_pages_slowpath() does with its filtering and so forth. This patch creates a new function which other allocators can call instead of relying on the internal page allocator warnings. It also gives this function private rate-limiting which separates it from other printk_ratelimit() users. Signed-off-by: Dave Hansen Cc: Johannes Weiner Cc: David Rientjes Cc: Michal Nazarewicz Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mm.h | 2 ++ mm/page_alloc.c | 62 ++++++++++++++++++++++++++++++++++++------------------ 2 files changed, 43 insertions(+), 21 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mm.h b/include/linux/mm.h index 2ad0ac8c3f32..8e2f2cd821f7 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1387,6 +1387,8 @@ extern void si_meminfo(struct sysinfo * val); extern void si_meminfo_node(struct sysinfo *val, int nid); extern int after_bootmem; +extern void warn_alloc_failed(gfp_t gfp_mask, int order, const char *fmt, ...); + extern void setup_per_cpu_pageset(void); extern void zone_pcp_update(struct zone *zone); diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 83eaa2eb72f8..44019da9632e 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -1736,6 +1737,45 @@ static inline bool should_suppress_show_mem(void) return ret; } +static DEFINE_RATELIMIT_STATE(nopage_rs, + DEFAULT_RATELIMIT_INTERVAL, + DEFAULT_RATELIMIT_BURST); + +void warn_alloc_failed(gfp_t gfp_mask, int order, const char *fmt, ...) +{ + va_list args; + unsigned int filter = SHOW_MEM_FILTER_NODES; + + if ((gfp_mask & __GFP_NOWARN) || !__ratelimit(&nopage_rs)) + return; + + /* + * This documents exceptions given to allocations in certain + * contexts that are allowed to allocate outside current's set + * of allowed nodes. + */ + if (!(gfp_mask & __GFP_NOMEMALLOC)) + if (test_thread_flag(TIF_MEMDIE) || + (current->flags & (PF_MEMALLOC | PF_EXITING))) + filter &= ~SHOW_MEM_FILTER_NODES; + if (in_interrupt() || !(gfp_mask & __GFP_WAIT)) + filter &= ~SHOW_MEM_FILTER_NODES; + + if (fmt) { + printk(KERN_WARNING); + va_start(args, fmt); + vprintk(fmt, args); + va_end(args); + } + + pr_warning("%s: page allocation failure: order:%d, mode:0x%x\n", + current->comm, order, gfp_mask); + + dump_stack(); + if (!should_suppress_show_mem()) + show_mem(filter); +} + static inline int should_alloc_retry(gfp_t gfp_mask, unsigned int order, unsigned long pages_reclaimed) @@ -2178,27 +2218,7 @@ rebalance: } nopage: - if (!(gfp_mask & __GFP_NOWARN) && printk_ratelimit()) { - unsigned int filter = SHOW_MEM_FILTER_NODES; - - /* - * This documents exceptions given to allocations in certain - * contexts that are allowed to allocate outside current's set - * of allowed nodes. - */ - if (!(gfp_mask & __GFP_NOMEMALLOC)) - if (test_thread_flag(TIF_MEMDIE) || - (current->flags & (PF_MEMALLOC | PF_EXITING))) - filter &= ~SHOW_MEM_FILTER_NODES; - if (in_interrupt() || !wait) - filter &= ~SHOW_MEM_FILTER_NODES; - - pr_warning("%s: page allocation failure. order:%d, mode:0x%x\n", - current->comm, order, gfp_mask); - dump_stack(); - if (!should_suppress_show_mem()) - show_mem(filter); - } + warn_alloc_failed(gfp_mask, order, NULL); return page; got_pg: if (kmemcheck_enabled) -- cgit From 7b1de5868b124d8f399d8791ed30a9b679d64d4d Mon Sep 17 00:00:00 2001 From: Wu Fengguang Date: Tue, 24 May 2011 17:12:25 -0700 Subject: readahead: readahead page allocations are OK to fail Pass __GFP_NORETRY|__GFP_NOWARN for readahead page allocations. readahead page allocations are completely optional. They are OK to fail and in particular shall not trigger OOM on themselves. Reported-by: Dave Young Reviewed-by: KOSAKI Motohiro Signed-off-by: Wu Fengguang Reviewed-by: Minchan Kim Reviewed-by: Pekka Enberg Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/pagemap.h | 6 ++++++ mm/readahead.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index ea268080380d..716875e53520 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -219,6 +219,12 @@ static inline struct page *page_cache_alloc_cold(struct address_space *x) return __page_cache_alloc(mapping_gfp_mask(x)|__GFP_COLD); } +static inline struct page *page_cache_alloc_readahead(struct address_space *x) +{ + return __page_cache_alloc(mapping_gfp_mask(x) | + __GFP_COLD | __GFP_NORETRY | __GFP_NOWARN); +} + typedef int filler_t(void *, struct page *); extern struct page * find_get_page(struct address_space *mapping, diff --git a/mm/readahead.c b/mm/readahead.c index 2c0cc489e288..867f9dd82dcd 100644 --- a/mm/readahead.c +++ b/mm/readahead.c @@ -180,7 +180,7 @@ __do_page_cache_readahead(struct address_space *mapping, struct file *filp, if (page) continue; - page = page_cache_alloc_cold(mapping); + page = page_cache_alloc_readahead(mapping); if (!page) break; page->index = page_offset; -- cgit From a09ed5e00084448453c8bada4dcd31e5fbfc2f21 Mon Sep 17 00:00:00 2001 From: Ying Han Date: Tue, 24 May 2011 17:12:26 -0700 Subject: vmscan: change shrink_slab() interfaces by passing shrink_control Consolidate the existing parameters to shrink_slab() into a new shrink_control struct. This is needed later to pass the same struct to shrinkers. Signed-off-by: Ying Han Cc: KOSAKI Motohiro Cc: Minchan Kim Acked-by: Pavel Emelyanov Cc: KAMEZAWA Hiroyuki Cc: Mel Gorman Acked-by: Rik van Riel Cc: Johannes Weiner Cc: Hugh Dickins Cc: Dave Hansen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/drop_caches.c | 6 +++++- include/linux/mm.h | 13 +++++++++++-- mm/memory-failure.c | 7 ++++++- mm/vmscan.c | 46 +++++++++++++++++++++++++++++++++------------- 4 files changed, 55 insertions(+), 17 deletions(-) (limited to 'include/linux') diff --git a/fs/drop_caches.c b/fs/drop_caches.c index 98b77c89494c..440999c24353 100644 --- a/fs/drop_caches.c +++ b/fs/drop_caches.c @@ -40,9 +40,13 @@ static void drop_pagecache_sb(struct super_block *sb, void *unused) static void drop_slab(void) { int nr_objects; + struct shrink_control shrink = { + .gfp_mask = GFP_KERNEL, + .nr_scanned = 1000, + }; do { - nr_objects = shrink_slab(1000, GFP_KERNEL, 1000); + nr_objects = shrink_slab(&shrink, 1000); } while (nr_objects > 10); } diff --git a/include/linux/mm.h b/include/linux/mm.h index 8e2f2cd821f7..32cfa9602d00 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1161,6 +1161,15 @@ static inline void sync_mm_rss(struct task_struct *task, struct mm_struct *mm) } #endif +/* + * This struct is used to pass information from page reclaim to the shrinkers. + * We consolidate the values for easier extention later. + */ +struct shrink_control { + unsigned long nr_scanned; + gfp_t gfp_mask; +}; + /* * A callback you can register to apply pressure to ageable caches. * @@ -1630,8 +1639,8 @@ int in_gate_area_no_mm(unsigned long addr); int drop_caches_sysctl_handler(struct ctl_table *, int, void __user *, size_t *, loff_t *); -unsigned long shrink_slab(unsigned long scanned, gfp_t gfp_mask, - unsigned long lru_pages); +unsigned long shrink_slab(struct shrink_control *shrink, + unsigned long lru_pages); #ifndef CONFIG_MMU #define randomize_va_space 0 diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 369b80e81416..341341b2b47b 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -239,7 +239,12 @@ void shake_page(struct page *p, int access) if (access) { int nr; do { - nr = shrink_slab(1000, GFP_KERNEL, 1000); + struct shrink_control shrink = { + .gfp_mask = GFP_KERNEL, + .nr_scanned = 1000, + }; + + nr = shrink_slab(&shrink, 1000); if (page_count(p) == 1) break; } while (nr > 10); diff --git a/mm/vmscan.c b/mm/vmscan.c index 890f54184d9a..e4e245ed1a5b 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -222,11 +222,13 @@ EXPORT_SYMBOL(unregister_shrinker); * * Returns the number of slab objects which we shrunk. */ -unsigned long shrink_slab(unsigned long scanned, gfp_t gfp_mask, - unsigned long lru_pages) +unsigned long shrink_slab(struct shrink_control *shrink, + unsigned long lru_pages) { struct shrinker *shrinker; unsigned long ret = 0; + unsigned long scanned = shrink->nr_scanned; + gfp_t gfp_mask = shrink->gfp_mask; if (scanned == 0) scanned = SWAP_CLUSTER_MAX; @@ -2035,7 +2037,8 @@ static bool all_unreclaimable(struct zonelist *zonelist, * else, the number of pages reclaimed */ static unsigned long do_try_to_free_pages(struct zonelist *zonelist, - struct scan_control *sc) + struct scan_control *sc, + struct shrink_control *shrink) { int priority; unsigned long total_scanned = 0; @@ -2069,7 +2072,8 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist, lru_pages += zone_reclaimable_pages(zone); } - shrink_slab(sc->nr_scanned, sc->gfp_mask, lru_pages); + shrink->nr_scanned = sc->nr_scanned; + shrink_slab(shrink, lru_pages); if (reclaim_state) { sc->nr_reclaimed += reclaim_state->reclaimed_slab; reclaim_state->reclaimed_slab = 0; @@ -2141,12 +2145,15 @@ unsigned long try_to_free_pages(struct zonelist *zonelist, int order, .mem_cgroup = NULL, .nodemask = nodemask, }; + struct shrink_control shrink = { + .gfp_mask = sc.gfp_mask, + }; trace_mm_vmscan_direct_reclaim_begin(order, sc.may_writepage, gfp_mask); - nr_reclaimed = do_try_to_free_pages(zonelist, &sc); + nr_reclaimed = do_try_to_free_pages(zonelist, &sc, &shrink); trace_mm_vmscan_direct_reclaim_end(nr_reclaimed); @@ -2206,17 +2213,20 @@ unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem_cont, .order = 0, .mem_cgroup = mem_cont, .nodemask = NULL, /* we don't care the placement */ + .gfp_mask = (gfp_mask & GFP_RECLAIM_MASK) | + (GFP_HIGHUSER_MOVABLE & ~GFP_RECLAIM_MASK), + }; + struct shrink_control shrink = { + .gfp_mask = sc.gfp_mask, }; - sc.gfp_mask = (gfp_mask & GFP_RECLAIM_MASK) | - (GFP_HIGHUSER_MOVABLE & ~GFP_RECLAIM_MASK); zonelist = NODE_DATA(numa_node_id())->node_zonelists; trace_mm_vmscan_memcg_reclaim_begin(0, sc.may_writepage, sc.gfp_mask); - nr_reclaimed = do_try_to_free_pages(zonelist, &sc); + nr_reclaimed = do_try_to_free_pages(zonelist, &sc, &shrink); trace_mm_vmscan_memcg_reclaim_end(nr_reclaimed); @@ -2344,6 +2354,9 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order, .order = order, .mem_cgroup = NULL, }; + struct shrink_control shrink = { + .gfp_mask = sc.gfp_mask, + }; loop_again: total_scanned = 0; sc.nr_reclaimed = 0; @@ -2443,8 +2456,8 @@ loop_again: end_zone, 0)) shrink_zone(priority, zone, &sc); reclaim_state->reclaimed_slab = 0; - nr_slab = shrink_slab(sc.nr_scanned, GFP_KERNEL, - lru_pages); + shrink.nr_scanned = sc.nr_scanned; + nr_slab = shrink_slab(&shrink, lru_pages); sc.nr_reclaimed += reclaim_state->reclaimed_slab; total_scanned += sc.nr_scanned; @@ -2796,7 +2809,10 @@ unsigned long shrink_all_memory(unsigned long nr_to_reclaim) .swappiness = vm_swappiness, .order = 0, }; - struct zonelist * zonelist = node_zonelist(numa_node_id(), sc.gfp_mask); + struct shrink_control shrink = { + .gfp_mask = sc.gfp_mask, + }; + struct zonelist *zonelist = node_zonelist(numa_node_id(), sc.gfp_mask); struct task_struct *p = current; unsigned long nr_reclaimed; @@ -2805,7 +2821,7 @@ unsigned long shrink_all_memory(unsigned long nr_to_reclaim) reclaim_state.reclaimed_slab = 0; p->reclaim_state = &reclaim_state; - nr_reclaimed = do_try_to_free_pages(zonelist, &sc); + nr_reclaimed = do_try_to_free_pages(zonelist, &sc, &shrink); p->reclaim_state = NULL; lockdep_clear_current_reclaim_state(); @@ -2980,6 +2996,9 @@ static int __zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) .swappiness = vm_swappiness, .order = order, }; + struct shrink_control shrink = { + .gfp_mask = sc.gfp_mask, + }; unsigned long nr_slab_pages0, nr_slab_pages1; cond_resched(); @@ -3006,6 +3025,7 @@ static int __zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) } nr_slab_pages0 = zone_page_state(zone, NR_SLAB_RECLAIMABLE); + shrink.nr_scanned = sc.nr_scanned; if (nr_slab_pages0 > zone->min_slab_pages) { /* * shrink_slab() does not currently allow us to determine how @@ -3021,7 +3041,7 @@ static int __zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) unsigned long lru_pages = zone_reclaimable_pages(zone); /* No reclaimable slab or very low memory pressure */ - if (!shrink_slab(sc.nr_scanned, gfp_mask, lru_pages)) + if (!shrink_slab(&shrink, lru_pages)) break; /* Freed enough memory */ -- cgit From 1495f230fa7750479c79e3656286b9183d662077 Mon Sep 17 00:00:00 2001 From: Ying Han Date: Tue, 24 May 2011 17:12:27 -0700 Subject: vmscan: change shrinker API by passing shrink_control struct Change each shrinker's API by consolidating the existing parameters into shrink_control struct. This will simplify any further features added w/o touching each file of shrinker. [akpm@linux-foundation.org: fix build] [akpm@linux-foundation.org: fix warning] [kosaki.motohiro@jp.fujitsu.com: fix up new shrinker API] [akpm@linux-foundation.org: fix xfs warning] [akpm@linux-foundation.org: update gfs2] Signed-off-by: Ying Han Cc: KOSAKI Motohiro Cc: Minchan Kim Acked-by: Pavel Emelyanov Cc: KAMEZAWA Hiroyuki Cc: Mel Gorman Acked-by: Rik van Riel Cc: Johannes Weiner Cc: Hugh Dickins Cc: Dave Hansen Cc: Steven Whitehouse Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86/kvm/mmu.c | 3 ++- drivers/gpu/drm/i915/i915_gem.c | 9 +++------ drivers/gpu/drm/ttm/ttm_page_alloc.c | 4 +++- drivers/staging/zcache/zcache.c | 5 ++++- fs/dcache.c | 8 ++++++-- fs/drop_caches.c | 3 +-- fs/gfs2/glock.c | 5 ++++- fs/gfs2/quota.c | 12 +++++++----- fs/gfs2/quota.h | 4 +++- fs/inode.c | 6 +++++- fs/mbcache.c | 10 ++++++---- fs/nfs/dir.c | 5 ++++- fs/nfs/internal.h | 2 +- fs/quota/dquot.c | 5 ++++- fs/xfs/linux-2.6/xfs_buf.c | 4 ++-- fs/xfs/linux-2.6/xfs_sync.c | 5 +++-- fs/xfs/quota/xfs_qm.c | 6 +++--- include/linux/mm.h | 19 +++++++++++-------- mm/memory-failure.c | 3 +-- mm/vmscan.c | 34 +++++++++++++++++++--------------- net/sunrpc/auth.c | 4 +++- 21 files changed, 95 insertions(+), 61 deletions(-) (limited to 'include/linux') diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 28418054b880..bd14bb4c8594 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -3545,10 +3545,11 @@ static int kvm_mmu_remove_some_alloc_mmu_pages(struct kvm *kvm, return kvm_mmu_prepare_zap_page(kvm, page, invalid_list); } -static int mmu_shrink(struct shrinker *shrink, int nr_to_scan, gfp_t gfp_mask) +static int mmu_shrink(struct shrinker *shrink, struct shrink_control *sc) { struct kvm *kvm; struct kvm *kvm_freed = NULL; + int nr_to_scan = sc->nr_to_scan; if (nr_to_scan == 0) goto out; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index c6289034e29a..0b2e167d2bce 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -56,9 +56,7 @@ static int i915_gem_phys_pwrite(struct drm_device *dev, static void i915_gem_free_object_tail(struct drm_i915_gem_object *obj); static int i915_gem_inactive_shrink(struct shrinker *shrinker, - int nr_to_scan, - gfp_t gfp_mask); - + struct shrink_control *sc); /* some bookkeeping */ static void i915_gem_info_add_obj(struct drm_i915_private *dev_priv, @@ -4092,9 +4090,7 @@ i915_gpu_is_active(struct drm_device *dev) } static int -i915_gem_inactive_shrink(struct shrinker *shrinker, - int nr_to_scan, - gfp_t gfp_mask) +i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc) { struct drm_i915_private *dev_priv = container_of(shrinker, @@ -4102,6 +4098,7 @@ i915_gem_inactive_shrink(struct shrinker *shrinker, mm.inactive_shrinker); struct drm_device *dev = dev_priv->dev; struct drm_i915_gem_object *obj, *next; + int nr_to_scan = sc->nr_to_scan; int cnt; if (!mutex_trylock(&dev->struct_mutex)) diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c index 9d9d92945f8c..d948575717bf 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c @@ -395,12 +395,14 @@ static int ttm_pool_get_num_unused_pages(void) /** * Callback for mm to request pool to reduce number of page held. */ -static int ttm_pool_mm_shrink(struct shrinker *shrink, int shrink_pages, gfp_t gfp_mask) +static int ttm_pool_mm_shrink(struct shrinker *shrink, + struct shrink_control *sc) { static atomic_t start_pool = ATOMIC_INIT(0); unsigned i; unsigned pool_offset = atomic_add_return(1, &start_pool); struct ttm_page_pool *pool; + int shrink_pages = sc->nr_to_scan; pool_offset = pool_offset % NUM_POOLS; /* select start pool in round robin fashion */ diff --git a/drivers/staging/zcache/zcache.c b/drivers/staging/zcache/zcache.c index b8a2b30a1572..77ac2d4d3ef1 100644 --- a/drivers/staging/zcache/zcache.c +++ b/drivers/staging/zcache/zcache.c @@ -1181,9 +1181,12 @@ static bool zcache_freeze; /* * zcache shrinker interface (only useful for ephemeral pages, so zbud only) */ -static int shrink_zcache_memory(struct shrinker *shrink, int nr, gfp_t gfp_mask) +static int shrink_zcache_memory(struct shrinker *shrink, + struct shrink_control *sc) { int ret = -1; + int nr = sc->nr_to_scan; + gfp_t gfp_mask = sc->gfp_mask; if (nr >= 0) { if (!(gfp_mask & __GFP_FS)) diff --git a/fs/dcache.c b/fs/dcache.c index 18b2a1f10ed8..37f72ee5bf7c 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1220,7 +1220,7 @@ void shrink_dcache_parent(struct dentry * parent) EXPORT_SYMBOL(shrink_dcache_parent); /* - * Scan `nr' dentries and return the number which remain. + * Scan `sc->nr_slab_to_reclaim' dentries and return the number which remain. * * We need to avoid reentering the filesystem if the caller is performing a * GFP_NOFS allocation attempt. One example deadlock is: @@ -1231,8 +1231,12 @@ EXPORT_SYMBOL(shrink_dcache_parent); * * In this case we return -1 to tell the caller that we baled. */ -static int shrink_dcache_memory(struct shrinker *shrink, int nr, gfp_t gfp_mask) +static int shrink_dcache_memory(struct shrinker *shrink, + struct shrink_control *sc) { + int nr = sc->nr_to_scan; + gfp_t gfp_mask = sc->gfp_mask; + if (nr) { if (!(gfp_mask & __GFP_FS)) return -1; diff --git a/fs/drop_caches.c b/fs/drop_caches.c index 440999c24353..c00e055b6282 100644 --- a/fs/drop_caches.c +++ b/fs/drop_caches.c @@ -42,11 +42,10 @@ static void drop_slab(void) int nr_objects; struct shrink_control shrink = { .gfp_mask = GFP_KERNEL, - .nr_scanned = 1000, }; do { - nr_objects = shrink_slab(&shrink, 1000); + nr_objects = shrink_slab(&shrink, 1000, 1000); } while (nr_objects > 10); } diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index a2a6abbccc07..2792a790e50b 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -1346,11 +1346,14 @@ void gfs2_glock_complete(struct gfs2_glock *gl, int ret) } -static int gfs2_shrink_glock_memory(struct shrinker *shrink, int nr, gfp_t gfp_mask) +static int gfs2_shrink_glock_memory(struct shrinker *shrink, + struct shrink_control *sc) { struct gfs2_glock *gl; int may_demote; int nr_skipped = 0; + int nr = sc->nr_to_scan; + gfp_t gfp_mask = sc->gfp_mask; LIST_HEAD(skipped); if (nr == 0) diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index e23d9864c418..42e8d23bc047 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c @@ -38,6 +38,7 @@ #include #include +#include #include #include #include @@ -77,19 +78,20 @@ static LIST_HEAD(qd_lru_list); static atomic_t qd_lru_count = ATOMIC_INIT(0); static DEFINE_SPINLOCK(qd_lru_lock); -int gfs2_shrink_qd_memory(struct shrinker *shrink, int nr, gfp_t gfp_mask) +int gfs2_shrink_qd_memory(struct shrinker *shrink, struct shrink_control *sc) { struct gfs2_quota_data *qd; struct gfs2_sbd *sdp; + int nr_to_scan = sc->nr_to_scan; - if (nr == 0) + if (nr_to_scan == 0) goto out; - if (!(gfp_mask & __GFP_FS)) + if (!(sc->gfp_mask & __GFP_FS)) return -1; spin_lock(&qd_lru_lock); - while (nr && !list_empty(&qd_lru_list)) { + while (nr_to_scan && !list_empty(&qd_lru_list)) { qd = list_entry(qd_lru_list.next, struct gfs2_quota_data, qd_reclaim); sdp = qd->qd_gl->gl_sbd; @@ -110,7 +112,7 @@ int gfs2_shrink_qd_memory(struct shrinker *shrink, int nr, gfp_t gfp_mask) spin_unlock(&qd_lru_lock); kmem_cache_free(gfs2_quotad_cachep, qd); spin_lock(&qd_lru_lock); - nr--; + nr_to_scan--; } spin_unlock(&qd_lru_lock); diff --git a/fs/gfs2/quota.h b/fs/gfs2/quota.h index e7d236ca48bd..90bf1c302a98 100644 --- a/fs/gfs2/quota.h +++ b/fs/gfs2/quota.h @@ -12,6 +12,7 @@ struct gfs2_inode; struct gfs2_sbd; +struct shrink_control; #define NO_QUOTA_CHANGE ((u32)-1) @@ -51,7 +52,8 @@ static inline int gfs2_quota_lock_check(struct gfs2_inode *ip) return ret; } -extern int gfs2_shrink_qd_memory(struct shrinker *shrink, int nr, gfp_t gfp_mask); +extern int gfs2_shrink_qd_memory(struct shrinker *shrink, + struct shrink_control *sc); extern const struct quotactl_ops gfs2_quotactl_ops; #endif /* __QUOTA_DOT_H__ */ diff --git a/fs/inode.c b/fs/inode.c index 88aa3bcc7681..990d284877a1 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -751,8 +751,12 @@ static void prune_icache(int nr_to_scan) * This function is passed the number of inodes to scan, and it returns the * total number of remaining possibly-reclaimable inodes. */ -static int shrink_icache_memory(struct shrinker *shrink, int nr, gfp_t gfp_mask) +static int shrink_icache_memory(struct shrinker *shrink, + struct shrink_control *sc) { + int nr = sc->nr_to_scan; + gfp_t gfp_mask = sc->gfp_mask; + if (nr) { /* * Nasty deadlock avoidance. We may hold various FS locks, diff --git a/fs/mbcache.c b/fs/mbcache.c index 2f174be06555..8c32ef3ba88e 100644 --- a/fs/mbcache.c +++ b/fs/mbcache.c @@ -90,7 +90,8 @@ static DEFINE_SPINLOCK(mb_cache_spinlock); * What the mbcache registers as to get shrunk dynamically. */ -static int mb_cache_shrink_fn(struct shrinker *shrink, int nr_to_scan, gfp_t gfp_mask); +static int mb_cache_shrink_fn(struct shrinker *shrink, + struct shrink_control *sc); static struct shrinker mb_cache_shrinker = { .shrink = mb_cache_shrink_fn, @@ -156,18 +157,19 @@ forget: * gets low. * * @shrink: (ignored) - * @nr_to_scan: Number of objects to scan - * @gfp_mask: (ignored) + * @sc: shrink_control passed from reclaim * * Returns the number of objects which are present in the cache. */ static int -mb_cache_shrink_fn(struct shrinker *shrink, int nr_to_scan, gfp_t gfp_mask) +mb_cache_shrink_fn(struct shrinker *shrink, struct shrink_control *sc) { LIST_HEAD(free_list); struct mb_cache *cache; struct mb_cache_entry *entry, *tmp; int count = 0; + int nr_to_scan = sc->nr_to_scan; + gfp_t gfp_mask = sc->gfp_mask; mb_debug("trying to free %d entries", nr_to_scan); spin_lock(&mb_cache_spinlock); diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 7237672216c8..424e47773a84 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -2042,11 +2042,14 @@ static void nfs_access_free_list(struct list_head *head) } } -int nfs_access_cache_shrinker(struct shrinker *shrink, int nr_to_scan, gfp_t gfp_mask) +int nfs_access_cache_shrinker(struct shrinker *shrink, + struct shrink_control *sc) { LIST_HEAD(head); struct nfs_inode *nfsi, *next; struct nfs_access_entry *cache; + int nr_to_scan = sc->nr_to_scan; + gfp_t gfp_mask = sc->gfp_mask; if ((gfp_mask & GFP_KERNEL) != GFP_KERNEL) return (nr_to_scan == 0) ? 0 : -1; diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index ce118ce885dd..2df6ca7b5898 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -234,7 +234,7 @@ extern int nfs_init_client(struct nfs_client *clp, /* dir.c */ extern int nfs_access_cache_shrinker(struct shrinker *shrink, - int nr_to_scan, gfp_t gfp_mask); + struct shrink_control *sc); /* inode.c */ extern struct workqueue_struct *nfsiod_workqueue; diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index d3c032f5fa0a..5b572c89e6c4 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -691,8 +691,11 @@ static void prune_dqcache(int count) * This is called from kswapd when we think we need some * more memory */ -static int shrink_dqcache_memory(struct shrinker *shrink, int nr, gfp_t gfp_mask) +static int shrink_dqcache_memory(struct shrinker *shrink, + struct shrink_control *sc) { + int nr = sc->nr_to_scan; + if (nr) { spin_lock(&dq_list_lock); prune_dqcache(nr); diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index 52b2b5da566e..5e68099db2a5 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c @@ -1422,12 +1422,12 @@ restart: int xfs_buftarg_shrink( struct shrinker *shrink, - int nr_to_scan, - gfp_t mask) + struct shrink_control *sc) { struct xfs_buftarg *btp = container_of(shrink, struct xfs_buftarg, bt_shrinker); struct xfs_buf *bp; + int nr_to_scan = sc->nr_to_scan; LIST_HEAD(dispose); if (!nr_to_scan) diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c index cb1bb2080e44..8ecad5ff9f9b 100644 --- a/fs/xfs/linux-2.6/xfs_sync.c +++ b/fs/xfs/linux-2.6/xfs_sync.c @@ -1032,13 +1032,14 @@ xfs_reclaim_inodes( static int xfs_reclaim_inode_shrink( struct shrinker *shrink, - int nr_to_scan, - gfp_t gfp_mask) + struct shrink_control *sc) { struct xfs_mount *mp; struct xfs_perag *pag; xfs_agnumber_t ag; int reclaimable; + int nr_to_scan = sc->nr_to_scan; + gfp_t gfp_mask = sc->gfp_mask; mp = container_of(shrink, struct xfs_mount, m_inode_shrink); if (nr_to_scan) { diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index 69228aa8605a..b94dace4e785 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c @@ -60,7 +60,7 @@ STATIC void xfs_qm_list_destroy(xfs_dqlist_t *); STATIC int xfs_qm_init_quotainos(xfs_mount_t *); STATIC int xfs_qm_init_quotainfo(xfs_mount_t *); -STATIC int xfs_qm_shake(struct shrinker *, int, gfp_t); +STATIC int xfs_qm_shake(struct shrinker *, struct shrink_control *); static struct shrinker xfs_qm_shaker = { .shrink = xfs_qm_shake, @@ -2009,10 +2009,10 @@ xfs_qm_shake_freelist( STATIC int xfs_qm_shake( struct shrinker *shrink, - int nr_to_scan, - gfp_t gfp_mask) + struct shrink_control *sc) { int ndqused, nfree, n; + gfp_t gfp_mask = sc->gfp_mask; if (!kmem_shake_allow(gfp_mask)) return 0; diff --git a/include/linux/mm.h b/include/linux/mm.h index 32cfa9602d00..5cbbf78eaac7 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1166,18 +1166,20 @@ static inline void sync_mm_rss(struct task_struct *task, struct mm_struct *mm) * We consolidate the values for easier extention later. */ struct shrink_control { - unsigned long nr_scanned; gfp_t gfp_mask; + + /* How many slab objects shrinker() should scan and try to reclaim */ + unsigned long nr_to_scan; }; /* * A callback you can register to apply pressure to ageable caches. * - * 'shrink' is passed a count 'nr_to_scan' and a 'gfpmask'. It should - * look through the least-recently-used 'nr_to_scan' entries and - * attempt to free them up. It should return the number of objects - * which remain in the cache. If it returns -1, it means it cannot do - * any scanning at this time (eg. there is a risk of deadlock). + * 'sc' is passed shrink_control which includes a count 'nr_to_scan' + * and a 'gfpmask'. It should look through the least-recently-used + * 'nr_to_scan' entries and attempt to free them up. It should return + * the number of objects which remain in the cache. If it returns -1, it means + * it cannot do any scanning at this time (eg. there is a risk of deadlock). * * The 'gfpmask' refers to the allocation we are currently trying to * fulfil. @@ -1186,7 +1188,7 @@ struct shrink_control { * querying the cache size, so a fastpath for that case is appropriate. */ struct shrinker { - int (*shrink)(struct shrinker *, int nr_to_scan, gfp_t gfp_mask); + int (*shrink)(struct shrinker *, struct shrink_control *sc); int seeks; /* seeks to recreate an obj */ /* These are for internal use */ @@ -1640,7 +1642,8 @@ int in_gate_area_no_mm(unsigned long addr); int drop_caches_sysctl_handler(struct ctl_table *, int, void __user *, size_t *, loff_t *); unsigned long shrink_slab(struct shrink_control *shrink, - unsigned long lru_pages); + unsigned long nr_pages_scanned, + unsigned long lru_pages); #ifndef CONFIG_MMU #define randomize_va_space 0 diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 341341b2b47b..5c8f7e08928d 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -241,10 +241,9 @@ void shake_page(struct page *p, int access) do { struct shrink_control shrink = { .gfp_mask = GFP_KERNEL, - .nr_scanned = 1000, }; - nr = shrink_slab(&shrink, 1000); + nr = shrink_slab(&shrink, 1000, 1000); if (page_count(p) == 1) break; } while (nr > 10); diff --git a/mm/vmscan.c b/mm/vmscan.c index e4e245ed1a5b..7e0116150dc7 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -202,6 +202,14 @@ void unregister_shrinker(struct shrinker *shrinker) } EXPORT_SYMBOL(unregister_shrinker); +static inline int do_shrinker_shrink(struct shrinker *shrinker, + struct shrink_control *sc, + unsigned long nr_to_scan) +{ + sc->nr_to_scan = nr_to_scan; + return (*shrinker->shrink)(shrinker, sc); +} + #define SHRINK_BATCH 128 /* * Call the shrink functions to age shrinkable caches @@ -223,15 +231,14 @@ EXPORT_SYMBOL(unregister_shrinker); * Returns the number of slab objects which we shrunk. */ unsigned long shrink_slab(struct shrink_control *shrink, + unsigned long nr_pages_scanned, unsigned long lru_pages) { struct shrinker *shrinker; unsigned long ret = 0; - unsigned long scanned = shrink->nr_scanned; - gfp_t gfp_mask = shrink->gfp_mask; - if (scanned == 0) - scanned = SWAP_CLUSTER_MAX; + if (nr_pages_scanned == 0) + nr_pages_scanned = SWAP_CLUSTER_MAX; if (!down_read_trylock(&shrinker_rwsem)) { /* Assume we'll be able to shrink next time */ @@ -244,8 +251,8 @@ unsigned long shrink_slab(struct shrink_control *shrink, unsigned long total_scan; unsigned long max_pass; - max_pass = (*shrinker->shrink)(shrinker, 0, gfp_mask); - delta = (4 * scanned) / shrinker->seeks; + max_pass = do_shrinker_shrink(shrinker, shrink, 0); + delta = (4 * nr_pages_scanned) / shrinker->seeks; delta *= max_pass; do_div(delta, lru_pages + 1); shrinker->nr += delta; @@ -272,9 +279,9 @@ unsigned long shrink_slab(struct shrink_control *shrink, int shrink_ret; int nr_before; - nr_before = (*shrinker->shrink)(shrinker, 0, gfp_mask); - shrink_ret = (*shrinker->shrink)(shrinker, this_scan, - gfp_mask); + nr_before = do_shrinker_shrink(shrinker, shrink, 0); + shrink_ret = do_shrinker_shrink(shrinker, shrink, + this_scan); if (shrink_ret == -1) break; if (shrink_ret < nr_before) @@ -2072,8 +2079,7 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist, lru_pages += zone_reclaimable_pages(zone); } - shrink->nr_scanned = sc->nr_scanned; - shrink_slab(shrink, lru_pages); + shrink_slab(shrink, sc->nr_scanned, lru_pages); if (reclaim_state) { sc->nr_reclaimed += reclaim_state->reclaimed_slab; reclaim_state->reclaimed_slab = 0; @@ -2456,8 +2462,7 @@ loop_again: end_zone, 0)) shrink_zone(priority, zone, &sc); reclaim_state->reclaimed_slab = 0; - shrink.nr_scanned = sc.nr_scanned; - nr_slab = shrink_slab(&shrink, lru_pages); + nr_slab = shrink_slab(&shrink, sc.nr_scanned, lru_pages); sc.nr_reclaimed += reclaim_state->reclaimed_slab; total_scanned += sc.nr_scanned; @@ -3025,7 +3030,6 @@ static int __zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) } nr_slab_pages0 = zone_page_state(zone, NR_SLAB_RECLAIMABLE); - shrink.nr_scanned = sc.nr_scanned; if (nr_slab_pages0 > zone->min_slab_pages) { /* * shrink_slab() does not currently allow us to determine how @@ -3041,7 +3045,7 @@ static int __zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) unsigned long lru_pages = zone_reclaimable_pages(zone); /* No reclaimable slab or very low memory pressure */ - if (!shrink_slab(&shrink, lru_pages)) + if (!shrink_slab(&shrink, sc.nr_scanned, lru_pages)) break; /* Freed enough memory */ diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index 67e31276682a..cd6e4aa19dbf 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c @@ -326,10 +326,12 @@ rpcauth_prune_expired(struct list_head *free, int nr_to_scan) * Run memory cache shrinker. */ static int -rpcauth_cache_shrinker(struct shrinker *shrink, int nr_to_scan, gfp_t gfp_mask) +rpcauth_cache_shrinker(struct shrinker *shrink, struct shrink_control *sc) { LIST_HEAD(free); int res; + int nr_to_scan = sc->nr_to_scan; + gfp_t gfp_mask = sc->gfp_mask; if ((gfp_mask & GFP_KERNEL) != GFP_KERNEL) return (nr_to_scan == 0) ? 0 : -1; -- cgit From bf4e8902ee5080f5d2c810b639e7e778c8082b52 Mon Sep 17 00:00:00 2001 From: Daniel Kiper Date: Tue, 24 May 2011 17:12:32 -0700 Subject: mm: enable set_page_section() only if CONFIG_SPARSEMEM and !CONFIG_SPARSEMEM_VMEMMAP set_page_section() is meaningful only in CONFIG_SPARSEMEM and !CONFIG_SPARSEMEM_VMEMMAP context. Move it to proper place and amend accordingly functions which are using it. Signed-off-by: Daniel Kiper Acked-by: Dave Hansen Acked-by: David Rientjes Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mm.h | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mm.h b/include/linux/mm.h index 5cbbf78eaac7..6702171f8d0a 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -682,6 +682,12 @@ static inline struct zone *page_zone(struct page *page) } #if defined(CONFIG_SPARSEMEM) && !defined(CONFIG_SPARSEMEM_VMEMMAP) +static inline void set_page_section(struct page *page, unsigned long section) +{ + page->flags &= ~(SECTIONS_MASK << SECTIONS_PGSHIFT); + page->flags |= (section & SECTIONS_MASK) << SECTIONS_PGSHIFT; +} + static inline unsigned long page_to_section(struct page *page) { return (page->flags >> SECTIONS_PGSHIFT) & SECTIONS_MASK; @@ -700,18 +706,14 @@ static inline void set_page_node(struct page *page, unsigned long node) page->flags |= (node & NODES_MASK) << NODES_PGSHIFT; } -static inline void set_page_section(struct page *page, unsigned long section) -{ - page->flags &= ~(SECTIONS_MASK << SECTIONS_PGSHIFT); - page->flags |= (section & SECTIONS_MASK) << SECTIONS_PGSHIFT; -} - static inline void set_page_links(struct page *page, enum zone_type zone, unsigned long node, unsigned long pfn) { set_page_zone(page, zone); set_page_node(page, node); +#if defined(CONFIG_SPARSEMEM) && !defined(CONFIG_SPARSEMEM_VMEMMAP) set_page_section(page, pfn_to_section_nr(pfn)); +#endif } /* -- cgit From e3c40f379a144f35e53864a2cd970e238071afd7 Mon Sep 17 00:00:00 2001 From: Daniel Kiper Date: Tue, 24 May 2011 17:12:33 -0700 Subject: mm: pfn_to_section_nr()/section_nr_to_pfn() is valid only in CONFIG_SPARSEMEM context pfn_to_section_nr()/section_nr_to_pfn() is valid only in CONFIG_SPARSEMEM context. Move it to proper place. Signed-off-by: Daniel Kiper Cc: Dave Hansen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mmzone.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index e56f835274c9..d7152002e18d 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -928,9 +928,6 @@ static inline unsigned long early_pfn_to_nid(unsigned long pfn) #define pfn_to_nid(pfn) (0) #endif -#define pfn_to_section_nr(pfn) ((pfn) >> PFN_SECTION_SHIFT) -#define section_nr_to_pfn(sec) ((sec) << PFN_SECTION_SHIFT) - #ifdef CONFIG_SPARSEMEM /* @@ -956,6 +953,9 @@ static inline unsigned long early_pfn_to_nid(unsigned long pfn) #error Allocator MAX_ORDER exceeds SECTION_SIZE #endif +#define pfn_to_section_nr(pfn) ((pfn) >> PFN_SECTION_SHIFT) +#define section_nr_to_pfn(sec) ((sec) << PFN_SECTION_SHIFT) + struct page; struct page_cgroup; struct mem_section { -- cgit From ba93fa81b5f2bf0076407a3a777fff122ce16220 Mon Sep 17 00:00:00 2001 From: Daniel Kiper Date: Tue, 24 May 2011 17:12:34 -0700 Subject: mm: do not define PFN_SECTION_SHIFT if !CONFIG_SPARSEMEM Do not define PFN_SECTION_SHIFT if !CONFIG_SPARSEMEM. Signed-off-by: Daniel Kiper Acked-by: Dave Hansen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mm.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mm.h b/include/linux/mm.h index 6702171f8d0a..32309f6542e8 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -605,10 +605,6 @@ static inline pte_t maybe_mkwrite(pte_t pte, struct vm_area_struct *vma) #define NODE_NOT_IN_PAGE_FLAGS #endif -#ifndef PFN_SECTION_SHIFT -#define PFN_SECTION_SHIFT 0 -#endif - /* * Define the bit shifts to access each section. For non-existent * sections we define the shift as 0; that plus a 0 mask ensures -- cgit From 172703b08cd05e2d5196ac13e94cc186f629d58b Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Tue, 24 May 2011 17:12:36 -0700 Subject: mm: delete non-atomic mm counter implementation The problem with having two different types of counters is that developers adding new code need to keep in mind whether it's safe to use both the atomic and non-atomic implementations. For example, when adding new callers of the *_mm_counter() functions a developer needs to ensure that those paths are always executed with page_table_lock held, in case we're using the non-atomic implementation of mm counters. Hugh Dickins introduced the atomic mm counters in commit f412ac08c986 ("[PATCH] mm: fix rss and mmlist locking"). When asked why he left the non-atomic counters around he said, | The only reason was to avoid adding costly atomic operations into a | configuration that had no need for them there: the page_table_lock | sufficed. | | Certainly it would be simpler just to delete the non-atomic variant. | | And I think it's fair to say that any configuration on which we're | measuring performance to that degree (rather than "does it boot fast?" | type measurements), would already be going the split ptlocks route. Removing the non-atomic counters eases the maintenance burden because developers no longer have to mindful of the two implementations when using *_mm_counter(). Note that all architectures provide a means of atomically updating atomic_long_t variables, even if they have to revert to the generic spinlock implementation because they don't support 64-bit atomic instructions (see lib/atomic64.c). Signed-off-by: Matt Fleming Acked-by: Dave Hansen Acked-by: KAMEZAWA Hiroyuki Cc: Hugh Dickins Cc: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mm.h | 44 +++++++------------------------------------- include/linux/mm_types.h | 9 +++------ 2 files changed, 10 insertions(+), 43 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mm.h b/include/linux/mm.h index 32309f6542e8..48e458190d88 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1053,65 +1053,35 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write, /* * per-process(per-mm_struct) statistics. */ -#if defined(SPLIT_RSS_COUNTING) -/* - * The mm counters are not protected by its page_table_lock, - * so must be incremented atomically. - */ static inline void set_mm_counter(struct mm_struct *mm, int member, long value) { atomic_long_set(&mm->rss_stat.count[member], value); } +#if defined(SPLIT_RSS_COUNTING) unsigned long get_mm_counter(struct mm_struct *mm, int member); - -static inline void add_mm_counter(struct mm_struct *mm, int member, long value) -{ - atomic_long_add(value, &mm->rss_stat.count[member]); -} - -static inline void inc_mm_counter(struct mm_struct *mm, int member) -{ - atomic_long_inc(&mm->rss_stat.count[member]); -} - -static inline void dec_mm_counter(struct mm_struct *mm, int member) -{ - atomic_long_dec(&mm->rss_stat.count[member]); -} - -#else /* !USE_SPLIT_PTLOCKS */ -/* - * The mm counters are protected by its page_table_lock, - * so can be incremented directly. - */ -static inline void set_mm_counter(struct mm_struct *mm, int member, long value) -{ - mm->rss_stat.count[member] = value; -} - +#else static inline unsigned long get_mm_counter(struct mm_struct *mm, int member) { - return mm->rss_stat.count[member]; + return atomic_long_read(&mm->rss_stat.count[member]); } +#endif static inline void add_mm_counter(struct mm_struct *mm, int member, long value) { - mm->rss_stat.count[member] += value; + atomic_long_add(value, &mm->rss_stat.count[member]); } static inline void inc_mm_counter(struct mm_struct *mm, int member) { - mm->rss_stat.count[member]++; + atomic_long_inc(&mm->rss_stat.count[member]); } static inline void dec_mm_counter(struct mm_struct *mm, int member) { - mm->rss_stat.count[member]--; + atomic_long_dec(&mm->rss_stat.count[member]); } -#endif /* !USE_SPLIT_PTLOCKS */ - static inline unsigned long get_mm_rss(struct mm_struct *mm) { return get_mm_counter(mm, MM_FILEPAGES) + diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index c2f9ea7922f4..071d459e866b 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -204,19 +204,16 @@ enum { #if USE_SPLIT_PTLOCKS && defined(CONFIG_MMU) #define SPLIT_RSS_COUNTING -struct mm_rss_stat { - atomic_long_t count[NR_MM_COUNTERS]; -}; /* per-thread cached information, */ struct task_rss_stat { int events; /* for synchronization threshold */ int count[NR_MM_COUNTERS]; }; -#else /* !USE_SPLIT_PTLOCKS */ +#endif /* USE_SPLIT_PTLOCKS */ + struct mm_rss_stat { - unsigned long count[NR_MM_COUNTERS]; + atomic_long_t count[NR_MM_COUNTERS]; }; -#endif /* !USE_SPLIT_PTLOCKS */ struct mm_struct { struct vm_area_struct * mmap; /* list of VMAs */ -- cgit From 8bba154ef29e16331e578029e9050c74b87b7ff9 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 24 May 2011 17:12:37 -0700 Subject: memblock/nobootmem: allow alloc_bootmem() to take 0 as low limit The bootmem wrapper with memblock supports top-down now, so we do not need to set the low limit to __pa(MAX_DMA_ADDRESS). The logic should be: good to allocate above __pa(MAX_DMA_ADDRESS), but it is ok if we can not find memory above 16M on system that has a small amount of RAM. Signed-off-by: Yinghai LU Cc: Ingo Molnar Cc: "H. Peter Anvin" Cc: Olaf Hering Cc: Tejun Heo Cc: Lucas De Marchi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/bootmem.h | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'include/linux') diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h index 01eca1794e14..ab344a521105 100644 --- a/include/linux/bootmem.h +++ b/include/linux/bootmem.h @@ -99,24 +99,31 @@ extern void *__alloc_bootmem_low_node(pg_data_t *pgdat, unsigned long align, unsigned long goal); +#ifdef CONFIG_NO_BOOTMEM +/* We are using top down, so it is safe to use 0 here */ +#define BOOTMEM_LOW_LIMIT 0 +#else +#define BOOTMEM_LOW_LIMIT __pa(MAX_DMA_ADDRESS) +#endif + #define alloc_bootmem(x) \ - __alloc_bootmem(x, SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS)) + __alloc_bootmem(x, SMP_CACHE_BYTES, BOOTMEM_LOW_LIMIT) #define alloc_bootmem_align(x, align) \ - __alloc_bootmem(x, align, __pa(MAX_DMA_ADDRESS)) + __alloc_bootmem(x, align, BOOTMEM_LOW_LIMIT) #define alloc_bootmem_nopanic(x) \ - __alloc_bootmem_nopanic(x, SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS)) + __alloc_bootmem_nopanic(x, SMP_CACHE_BYTES, BOOTMEM_LOW_LIMIT) #define alloc_bootmem_pages(x) \ - __alloc_bootmem(x, PAGE_SIZE, __pa(MAX_DMA_ADDRESS)) + __alloc_bootmem(x, PAGE_SIZE, BOOTMEM_LOW_LIMIT) #define alloc_bootmem_pages_nopanic(x) \ - __alloc_bootmem_nopanic(x, PAGE_SIZE, __pa(MAX_DMA_ADDRESS)) + __alloc_bootmem_nopanic(x, PAGE_SIZE, BOOTMEM_LOW_LIMIT) #define alloc_bootmem_node(pgdat, x) \ - __alloc_bootmem_node(pgdat, x, SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS)) + __alloc_bootmem_node(pgdat, x, SMP_CACHE_BYTES, BOOTMEM_LOW_LIMIT) #define alloc_bootmem_node_nopanic(pgdat, x) \ - __alloc_bootmem_node_nopanic(pgdat, x, SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS)) + __alloc_bootmem_node_nopanic(pgdat, x, SMP_CACHE_BYTES, BOOTMEM_LOW_LIMIT) #define alloc_bootmem_pages_node(pgdat, x) \ - __alloc_bootmem_node(pgdat, x, PAGE_SIZE, __pa(MAX_DMA_ADDRESS)) + __alloc_bootmem_node(pgdat, x, PAGE_SIZE, BOOTMEM_LOW_LIMIT) #define alloc_bootmem_pages_node_nopanic(pgdat, x) \ - __alloc_bootmem_node_nopanic(pgdat, x, PAGE_SIZE, __pa(MAX_DMA_ADDRESS)) + __alloc_bootmem_node_nopanic(pgdat, x, PAGE_SIZE, BOOTMEM_LOW_LIMIT) #define alloc_bootmem_low(x) \ __alloc_bootmem_low(x, SMP_CACHE_BYTES, 0) -- cgit From b09e0fa4b4ea66266058eead43350bd7d55fec67 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Tue, 24 May 2011 17:12:39 -0700 Subject: tmpfs: implement generic xattr support Implement generic xattrs for tmpfs filesystems. The Feodra project, while trying to replace suid apps with file capabilities, realized that tmpfs, which is used on the build systems, does not support file capabilities and thus cannot be used to build packages which use file capabilities. Xattrs are also needed for overlayfs. The xattr interface is a bit odd. If a filesystem does not implement any {get,set,list}xattr functions the VFS will call into some random LSM hooks and the running LSM can then implement some method for handling xattrs. SELinux for example provides a method to support security.selinux but no other security.* xattrs. As it stands today when one enables CONFIG_TMPFS_POSIX_ACL tmpfs will have xattr handler routines specifically to handle acls. Because of this tmpfs would loose the VFS/LSM helpers to support the running LSM. To make up for that tmpfs had stub functions that did nothing but call into the LSM hooks which implement the helpers. This new patch does not use the LSM fallback functions and instead just implements a native get/set/list xattr feature for the full security.* and trusted.* namespace like a normal filesystem. This means that tmpfs can now support both security.selinux and security.capability, which was not previously possible. The basic implementation is that I attach a: struct shmem_xattr { struct list_head list; /* anchored by shmem_inode_info->xattr_list */ char *name; size_t size; char value[0]; }; Into the struct shmem_inode_info for each xattr that is set. This implementation could easily support the user.* namespace as well, except some care needs to be taken to prevent large amounts of unswappable memory being allocated for unprivileged users. [mszeredi@suse.cz: new config option, suport trusted.*, support symlinks] Signed-off-by: Eric Paris Signed-off-by: Miklos Szeredi Acked-by: Serge Hallyn Tested-by: Serge Hallyn Cc: Kyle McMartin Acked-by: Hugh Dickins Tested-by: Jordi Pujol Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/Kconfig | 18 ++- include/linux/shmem_fs.h | 8 +- mm/shmem.c | 320 +++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 290 insertions(+), 56 deletions(-) (limited to 'include/linux') diff --git a/fs/Kconfig b/fs/Kconfig index f3aa9b08b228..979992dcb386 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -121,9 +121,25 @@ config TMPFS See for details. +config TMPFS_XATTR + bool "Tmpfs extended attributes" + depends on TMPFS + default n + help + Extended attributes are name:value pairs associated with inodes by + the kernel or by users (see the attr(5) manual page, or visit + for details). + + Currently this enables support for the trusted.* and + security.* namespaces. + + If unsure, say N. + + You need this for POSIX ACL support on tmpfs. + config TMPFS_POSIX_ACL bool "Tmpfs POSIX Access Control Lists" - depends on TMPFS + depends on TMPFS_XATTR select GENERIC_ACL help POSIX Access Control Lists (ACLs) support permissions for users and diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h index 399be5ad2f99..2b7fec840517 100644 --- a/include/linux/shmem_fs.h +++ b/include/linux/shmem_fs.h @@ -9,6 +9,8 @@ #define SHMEM_NR_DIRECT 16 +#define SHMEM_SYMLINK_INLINE_LEN (SHMEM_NR_DIRECT * sizeof(swp_entry_t)) + struct shmem_inode_info { spinlock_t lock; unsigned long flags; @@ -17,8 +19,12 @@ struct shmem_inode_info { unsigned long next_index; /* highest alloced index + 1 */ struct shared_policy policy; /* NUMA memory alloc policy */ struct page *i_indirect; /* top indirect blocks page */ - swp_entry_t i_direct[SHMEM_NR_DIRECT]; /* first blocks */ + union { + swp_entry_t i_direct[SHMEM_NR_DIRECT]; /* first blocks */ + char inline_symlink[SHMEM_SYMLINK_INLINE_LEN]; + }; struct list_head swaplist; /* chain of maybes on swap */ + struct list_head xattr_list; /* list of shmem_xattr */ struct inode vfs_inode; }; diff --git a/mm/shmem.c b/mm/shmem.c index ba4ad28b7db6..69edb45a9f28 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -99,6 +99,13 @@ static struct vfsmount *shm_mnt; /* Pretend that each entry is of this size in directory's i_size */ #define BOGO_DIRENT_SIZE 20 +struct shmem_xattr { + struct list_head list; /* anchored by shmem_inode_info->xattr_list */ + char *name; /* xattr name */ + size_t size; + char value[0]; +}; + /* Flag allocation requirements to shmem_getpage and shmem_swp_alloc */ enum sgp_type { SGP_READ, /* don't exceed i_size, don't allocate page */ @@ -822,6 +829,7 @@ static int shmem_notify_change(struct dentry *dentry, struct iattr *attr) static void shmem_evict_inode(struct inode *inode) { struct shmem_inode_info *info = SHMEM_I(inode); + struct shmem_xattr *xattr, *nxattr; if (inode->i_mapping->a_ops == &shmem_aops) { truncate_inode_pages(inode->i_mapping, 0); @@ -834,6 +842,11 @@ static void shmem_evict_inode(struct inode *inode) mutex_unlock(&shmem_swaplist_mutex); } } + + list_for_each_entry_safe(xattr, nxattr, &info->xattr_list, list) { + kfree(xattr->name); + kfree(xattr); + } BUG_ON(inode->i_blocks); shmem_free_inode(inode->i_sb); end_writeback(inode); @@ -1615,6 +1628,7 @@ static struct inode *shmem_get_inode(struct super_block *sb, const struct inode spin_lock_init(&info->lock); info->flags = flags & VM_NORESERVE; INIT_LIST_HEAD(&info->swaplist); + INIT_LIST_HEAD(&info->xattr_list); cache_no_acl(inode); switch (mode & S_IFMT) { @@ -2014,9 +2028,9 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s info = SHMEM_I(inode); inode->i_size = len-1; - if (len <= (char *)inode - (char *)info) { + if (len <= SHMEM_SYMLINK_INLINE_LEN) { /* do it inline */ - memcpy(info, symname, len); + memcpy(info->inline_symlink, symname, len); inode->i_op = &shmem_symlink_inline_operations; } else { error = shmem_getpage(inode, 0, &page, SGP_WRITE, NULL); @@ -2042,7 +2056,7 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s static void *shmem_follow_link_inline(struct dentry *dentry, struct nameidata *nd) { - nd_set_link(nd, (char *)SHMEM_I(dentry->d_inode)); + nd_set_link(nd, SHMEM_I(dentry->d_inode)->inline_symlink); return NULL; } @@ -2066,63 +2080,253 @@ static void shmem_put_link(struct dentry *dentry, struct nameidata *nd, void *co } } -static const struct inode_operations shmem_symlink_inline_operations = { - .readlink = generic_readlink, - .follow_link = shmem_follow_link_inline, -}; - -static const struct inode_operations shmem_symlink_inode_operations = { - .readlink = generic_readlink, - .follow_link = shmem_follow_link, - .put_link = shmem_put_link, -}; - -#ifdef CONFIG_TMPFS_POSIX_ACL +#ifdef CONFIG_TMPFS_XATTR /* - * Superblocks without xattr inode operations will get security.* xattr - * support from the VFS "for free". As soon as we have any other xattrs + * Superblocks without xattr inode operations may get some security.* xattr + * support from the LSM "for free". As soon as we have any other xattrs * like ACLs, we also need to implement the security.* handlers at * filesystem level, though. */ -static size_t shmem_xattr_security_list(struct dentry *dentry, char *list, - size_t list_len, const char *name, - size_t name_len, int handler_flags) +static int shmem_xattr_get(struct dentry *dentry, const char *name, + void *buffer, size_t size) { - return security_inode_listsecurity(dentry->d_inode, list, list_len); -} + struct shmem_inode_info *info; + struct shmem_xattr *xattr; + int ret = -ENODATA; -static int shmem_xattr_security_get(struct dentry *dentry, const char *name, - void *buffer, size_t size, int handler_flags) -{ - if (strcmp(name, "") == 0) - return -EINVAL; - return xattr_getsecurity(dentry->d_inode, name, buffer, size); + info = SHMEM_I(dentry->d_inode); + + spin_lock(&info->lock); + list_for_each_entry(xattr, &info->xattr_list, list) { + if (strcmp(name, xattr->name)) + continue; + + ret = xattr->size; + if (buffer) { + if (size < xattr->size) + ret = -ERANGE; + else + memcpy(buffer, xattr->value, xattr->size); + } + break; + } + spin_unlock(&info->lock); + return ret; } -static int shmem_xattr_security_set(struct dentry *dentry, const char *name, - const void *value, size_t size, int flags, int handler_flags) +static int shmem_xattr_set(struct dentry *dentry, const char *name, + const void *value, size_t size, int flags) { - if (strcmp(name, "") == 0) - return -EINVAL; - return security_inode_setsecurity(dentry->d_inode, name, value, - size, flags); + struct inode *inode = dentry->d_inode; + struct shmem_inode_info *info = SHMEM_I(inode); + struct shmem_xattr *xattr; + struct shmem_xattr *new_xattr = NULL; + size_t len; + int err = 0; + + /* value == NULL means remove */ + if (value) { + /* wrap around? */ + len = sizeof(*new_xattr) + size; + if (len <= sizeof(*new_xattr)) + return -ENOMEM; + + new_xattr = kmalloc(len, GFP_KERNEL); + if (!new_xattr) + return -ENOMEM; + + new_xattr->name = kstrdup(name, GFP_KERNEL); + if (!new_xattr->name) { + kfree(new_xattr); + return -ENOMEM; + } + + new_xattr->size = size; + memcpy(new_xattr->value, value, size); + } + + spin_lock(&info->lock); + list_for_each_entry(xattr, &info->xattr_list, list) { + if (!strcmp(name, xattr->name)) { + if (flags & XATTR_CREATE) { + xattr = new_xattr; + err = -EEXIST; + } else if (new_xattr) { + list_replace(&xattr->list, &new_xattr->list); + } else { + list_del(&xattr->list); + } + goto out; + } + } + if (flags & XATTR_REPLACE) { + xattr = new_xattr; + err = -ENODATA; + } else { + list_add(&new_xattr->list, &info->xattr_list); + xattr = NULL; + } +out: + spin_unlock(&info->lock); + if (xattr) + kfree(xattr->name); + kfree(xattr); + return err; } -static const struct xattr_handler shmem_xattr_security_handler = { - .prefix = XATTR_SECURITY_PREFIX, - .list = shmem_xattr_security_list, - .get = shmem_xattr_security_get, - .set = shmem_xattr_security_set, -}; static const struct xattr_handler *shmem_xattr_handlers[] = { +#ifdef CONFIG_TMPFS_POSIX_ACL &generic_acl_access_handler, &generic_acl_default_handler, - &shmem_xattr_security_handler, +#endif NULL }; + +static int shmem_xattr_validate(const char *name) +{ + struct { const char *prefix; size_t len; } arr[] = { + { XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN }, + { XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN } + }; + int i; + + for (i = 0; i < ARRAY_SIZE(arr); i++) { + size_t preflen = arr[i].len; + if (strncmp(name, arr[i].prefix, preflen) == 0) { + if (!name[preflen]) + return -EINVAL; + return 0; + } + } + return -EOPNOTSUPP; +} + +static ssize_t shmem_getxattr(struct dentry *dentry, const char *name, + void *buffer, size_t size) +{ + int err; + + /* + * If this is a request for a synthetic attribute in the system.* + * namespace use the generic infrastructure to resolve a handler + * for it via sb->s_xattr. + */ + if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) + return generic_getxattr(dentry, name, buffer, size); + + err = shmem_xattr_validate(name); + if (err) + return err; + + return shmem_xattr_get(dentry, name, buffer, size); +} + +static int shmem_setxattr(struct dentry *dentry, const char *name, + const void *value, size_t size, int flags) +{ + int err; + + /* + * If this is a request for a synthetic attribute in the system.* + * namespace use the generic infrastructure to resolve a handler + * for it via sb->s_xattr. + */ + if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) + return generic_setxattr(dentry, name, value, size, flags); + + err = shmem_xattr_validate(name); + if (err) + return err; + + if (size == 0) + value = ""; /* empty EA, do not remove */ + + return shmem_xattr_set(dentry, name, value, size, flags); + +} + +static int shmem_removexattr(struct dentry *dentry, const char *name) +{ + int err; + + /* + * If this is a request for a synthetic attribute in the system.* + * namespace use the generic infrastructure to resolve a handler + * for it via sb->s_xattr. + */ + if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) + return generic_removexattr(dentry, name); + + err = shmem_xattr_validate(name); + if (err) + return err; + + return shmem_xattr_set(dentry, name, NULL, 0, XATTR_REPLACE); +} + +static bool xattr_is_trusted(const char *name) +{ + return !strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN); +} + +static ssize_t shmem_listxattr(struct dentry *dentry, char *buffer, size_t size) +{ + bool trusted = capable(CAP_SYS_ADMIN); + struct shmem_xattr *xattr; + struct shmem_inode_info *info; + size_t used = 0; + + info = SHMEM_I(dentry->d_inode); + + spin_lock(&info->lock); + list_for_each_entry(xattr, &info->xattr_list, list) { + size_t len; + + /* skip "trusted." attributes for unprivileged callers */ + if (!trusted && xattr_is_trusted(xattr->name)) + continue; + + len = strlen(xattr->name) + 1; + used += len; + if (buffer) { + if (size < used) { + used = -ERANGE; + break; + } + memcpy(buffer, xattr->name, len); + buffer += len; + } + } + spin_unlock(&info->lock); + + return used; +} +#endif /* CONFIG_TMPFS_XATTR */ + +static const struct inode_operations shmem_symlink_inline_operations = { + .readlink = generic_readlink, + .follow_link = shmem_follow_link_inline, +#ifdef CONFIG_TMPFS_XATTR + .setxattr = shmem_setxattr, + .getxattr = shmem_getxattr, + .listxattr = shmem_listxattr, + .removexattr = shmem_removexattr, +#endif +}; + +static const struct inode_operations shmem_symlink_inode_operations = { + .readlink = generic_readlink, + .follow_link = shmem_follow_link, + .put_link = shmem_put_link, +#ifdef CONFIG_TMPFS_XATTR + .setxattr = shmem_setxattr, + .getxattr = shmem_getxattr, + .listxattr = shmem_listxattr, + .removexattr = shmem_removexattr, #endif +}; static struct dentry *shmem_get_parent(struct dentry *child) { @@ -2402,8 +2606,10 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent) sb->s_magic = TMPFS_MAGIC; sb->s_op = &shmem_ops; sb->s_time_gran = 1; -#ifdef CONFIG_TMPFS_POSIX_ACL +#ifdef CONFIG_TMPFS_XATTR sb->s_xattr = shmem_xattr_handlers; +#endif +#ifdef CONFIG_TMPFS_POSIX_ACL sb->s_flags |= MS_POSIXACL; #endif @@ -2501,11 +2707,13 @@ static const struct file_operations shmem_file_operations = { static const struct inode_operations shmem_inode_operations = { .setattr = shmem_notify_change, .truncate_range = shmem_truncate_range, +#ifdef CONFIG_TMPFS_XATTR + .setxattr = shmem_setxattr, + .getxattr = shmem_getxattr, + .listxattr = shmem_listxattr, + .removexattr = shmem_removexattr, +#endif #ifdef CONFIG_TMPFS_POSIX_ACL - .setxattr = generic_setxattr, - .getxattr = generic_getxattr, - .listxattr = generic_listxattr, - .removexattr = generic_removexattr, .check_acl = generic_check_acl, #endif @@ -2523,23 +2731,27 @@ static const struct inode_operations shmem_dir_inode_operations = { .mknod = shmem_mknod, .rename = shmem_rename, #endif +#ifdef CONFIG_TMPFS_XATTR + .setxattr = shmem_setxattr, + .getxattr = shmem_getxattr, + .listxattr = shmem_listxattr, + .removexattr = shmem_removexattr, +#endif #ifdef CONFIG_TMPFS_POSIX_ACL .setattr = shmem_notify_change, - .setxattr = generic_setxattr, - .getxattr = generic_getxattr, - .listxattr = generic_listxattr, - .removexattr = generic_removexattr, .check_acl = generic_check_acl, #endif }; static const struct inode_operations shmem_special_inode_operations = { +#ifdef CONFIG_TMPFS_XATTR + .setxattr = shmem_setxattr, + .getxattr = shmem_getxattr, + .listxattr = shmem_listxattr, + .removexattr = shmem_removexattr, +#endif #ifdef CONFIG_TMPFS_POSIX_ACL .setattr = shmem_notify_change, - .setxattr = generic_setxattr, - .getxattr = generic_getxattr, - .listxattr = generic_listxattr, - .removexattr = generic_removexattr, .check_acl = generic_check_acl, #endif }; -- cgit From c856507f2b2b47a49d8587afb58930b463f6bff4 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Tue, 24 May 2011 17:12:40 -0700 Subject: mm: remove last trace of shmem_get_unmapped_area Remove noMMU declaration of shmem_get_unmapped_area() from mm.h: it fell out of use in 2.6.21 and ceased to exist in 2.6.29. Signed-off-by: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mm.h | 8 -------- 1 file changed, 8 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mm.h b/include/linux/mm.h index 48e458190d88..8eb969ebf904 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -873,14 +873,6 @@ int shmem_lock(struct file *file, int lock, struct user_struct *user); struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags); int shmem_zero_setup(struct vm_area_struct *); -#ifndef CONFIG_MMU -extern unsigned long shmem_get_unmapped_area(struct file *file, - unsigned long addr, - unsigned long len, - unsigned long pgoff, - unsigned long flags); -#endif - extern int can_do_mlock(void); extern int user_shm_lock(size_t, struct user_struct *); extern void user_shm_unlock(size_t, struct user_struct *); -- cgit From d98f6cb67fb5b9376d4957d7ba9f32eac35c2e08 Mon Sep 17 00:00:00 2001 From: Stephen Wilson Date: Tue, 24 May 2011 17:12:41 -0700 Subject: mm: export get_vma_policy() In commit 48fce3429d ("mempolicies: unexport get_vma_policy()") get_vma_policy() was marked static as all clients were local to mempolicy.c. However, the decision to generate /proc/pid/numa_maps in the numa memory policy code and outside the procfs subsystem introduces an artificial interdependency between the two systems. Exporting get_vma_policy() once again is the first step to clean up this interdependency. Signed-off-by: Stephen Wilson Reviewed-by: KOSAKI Motohiro Cc: Hugh Dickins Cc: David Rientjes Cc: Lee Schermerhorn Cc: Alexey Dobriyan Cc: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mempolicy.h | 3 +++ mm/mempolicy.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h index 31ac26ca4acf..c2f603218fbc 100644 --- a/include/linux/mempolicy.h +++ b/include/linux/mempolicy.h @@ -199,6 +199,9 @@ void mpol_free_shared_policy(struct shared_policy *p); struct mempolicy *mpol_shared_policy_lookup(struct shared_policy *sp, unsigned long idx); +struct mempolicy *get_vma_policy(struct task_struct *tsk, + struct vm_area_struct *vma, unsigned long addr); + extern void numa_default_policy(void); extern void numa_policy_init(void); extern void mpol_rebind_task(struct task_struct *tsk, const nodemask_t *new, diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 959a8b8c7350..5bfb03ef3cb0 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -1489,7 +1489,7 @@ asmlinkage long compat_sys_mbind(compat_ulong_t start, compat_ulong_t len, * freeing by another task. It is the caller's responsibility to free the * extra reference for shared policies. */ -static struct mempolicy *get_vma_policy(struct task_struct *task, +struct mempolicy *get_vma_policy(struct task_struct *task, struct vm_area_struct *vma, unsigned long addr) { struct mempolicy *pol = task->mempolicy; -- cgit From 13057efb0a0063eb8042d99093ec88a52c4f1593 Mon Sep 17 00:00:00 2001 From: Stephen Wilson Date: Tue, 24 May 2011 17:12:46 -0700 Subject: mm: declare mpol_to_str() when CONFIG_TMPFS=n When CONFIG_TMPFS=n mpol_to_str() is not declared in mempolicy.h. However, in the NUMA case, the definition is always compiled. Since it is not strictly true that tmpfs is the only client, and since the symbol was always lurking around anyways, export mpol_to_str() unconditionally. Furthermore, this will allow us to move show_numa_map() out of mempolicy.c and into the procfs subsystem. Signed-off-by: Stephen Wilson Cc: KOSAKI Motohiro Cc: Hugh Dickins Cc: David Rientjes Cc: Lee Schermerhorn Cc: Alexey Dobriyan Cc: Christoph Lameter Cc: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mempolicy.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h index c2f603218fbc..7978eec1b7d9 100644 --- a/include/linux/mempolicy.h +++ b/include/linux/mempolicy.h @@ -231,10 +231,10 @@ int do_migrate_pages(struct mm_struct *mm, #ifdef CONFIG_TMPFS extern int mpol_parse_str(char *str, struct mempolicy **mpol, int no_context); +#endif extern int mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol, int no_context); -#endif /* Check if a vma is migratable */ static inline int vma_migratable(struct vm_area_struct *vma) @@ -371,13 +371,13 @@ static inline int mpol_parse_str(char *str, struct mempolicy **mpol, { return 1; /* error */ } +#endif static inline int mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol, int no_context) { return 0; } -#endif #endif /* CONFIG_NUMA */ #endif /* __KERNEL__ */ -- cgit From f2beb7983613ecca20a61604f01ab50cc7a797e6 Mon Sep 17 00:00:00 2001 From: Stephen Wilson Date: Tue, 24 May 2011 17:12:48 -0700 Subject: proc: make struct proc_maps_private truly private Now that mm/mempolicy.c is no longer implementing /proc/pid/numa_maps there is no need to export struct proc_maps_private to the world. Move it to fs/proc/internal.h instead. Signed-off-by: Stephen Wilson Reviewed-by: KOSAKI Motohiro Cc: Hugh Dickins Cc: David Rientjes Cc: Lee Schermerhorn Cc: Alexey Dobriyan Cc: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/proc/internal.h | 8 ++++++++ include/linux/proc_fs.h | 8 -------- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'include/linux') diff --git a/fs/proc/internal.h b/fs/proc/internal.h index c03e8d3a3a5b..3763b436e69d 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h @@ -61,6 +61,14 @@ extern const struct file_operations proc_pagemap_operations; extern const struct file_operations proc_net_operations; extern const struct inode_operations proc_net_inode_operations; +struct proc_maps_private { + struct pid *pid; + struct task_struct *task; +#ifdef CONFIG_MMU + struct vm_area_struct *tail_vma; +#endif +}; + void proc_init_inodecache(void); static inline struct pid *proc_pid(struct inode *inode) diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index eaf4350c0f90..3686cd6c9aca 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -288,12 +288,4 @@ static inline struct net *PDE_NET(struct proc_dir_entry *pde) return pde->parent->data; } -struct proc_maps_private { - struct pid *pid; - struct task_struct *task; -#ifdef CONFIG_MMU - struct vm_area_struct *tail_vma; -#endif -}; - #endif /* _LINUX_PROC_FS_H */ -- cgit From a539f3533b78e39a22723d6d3e1e11b6c14454d9 Mon Sep 17 00:00:00 2001 From: Daniel Kiper Date: Tue, 24 May 2011 17:12:51 -0700 Subject: mm: add SECTION_ALIGN_UP() and SECTION_ALIGN_DOWN() macro Add SECTION_ALIGN_UP() and SECTION_ALIGN_DOWN() macro which aligns given pfn to upper section and lower section boundary accordingly. Required for the latest memory hotplug support for the Xen balloon driver. Signed-off-by: Daniel Kiper Reviewed-by: Konrad Rzeszutek Wilk David Rientjes Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mmzone.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index d7152002e18d..217bcf6bca77 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -956,6 +956,9 @@ static inline unsigned long early_pfn_to_nid(unsigned long pfn) #define pfn_to_section_nr(pfn) ((pfn) >> PFN_SECTION_SHIFT) #define section_nr_to_pfn(sec) ((sec) << PFN_SECTION_SHIFT) +#define SECTION_ALIGN_UP(pfn) (((pfn) + PAGES_PER_SECTION - 1) & PAGE_SECTION_MASK) +#define SECTION_ALIGN_DOWN(pfn) ((pfn) & PAGE_SECTION_MASK) + struct page; struct page_cgroup; struct mem_section { -- cgit From 0ac1ee0bfec2a4ad118f907ce586d0dfd8db7641 Mon Sep 17 00:00:00 2001 From: Tim Gardner Date: Tue, 24 May 2011 17:13:05 -0700 Subject: ulimit: raise default hard ulimit on number of files to 4096 Apps are increasingly using more than 1024 file descriptors. See discussion in several distro bug trackers, e.g. BugLink: http://bugs.launchpad.net/bugs/663090 https://issues.rpath.com/browse/RPL-2054 You don't want to raise the default soft limit, since that might break apps that use select(), but it's safe to raise the default hard limit; that way, apps that know they need lots of file descriptors can raise their soft limit without needing root, and without user intervention. Ubuntu is doing this with a kernel change because they have a policy of not changing kernel defaults in userland. While 4096 might not be enough for *all* apps, it seems to be plenty for the apps I've seen lately that are unhappy with 1024. Signed-off-by: Tim Gardner Cc: Dan Kegel Cc: Al Viro Cc: Christoph Hellwig Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-generic/resource.h | 2 +- include/linux/fs.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/asm-generic/resource.h b/include/asm-generic/resource.h index 587566f95f6c..61fa862fe08d 100644 --- a/include/asm-generic/resource.h +++ b/include/asm-generic/resource.h @@ -78,7 +78,7 @@ [RLIMIT_CORE] = { 0, RLIM_INFINITY }, \ [RLIMIT_RSS] = { RLIM_INFINITY, RLIM_INFINITY }, \ [RLIMIT_NPROC] = { 0, 0 }, \ - [RLIMIT_NOFILE] = { INR_OPEN, INR_OPEN }, \ + [RLIMIT_NOFILE] = { INR_OPEN_CUR, INR_OPEN_MAX }, \ [RLIMIT_MEMLOCK] = { MLOCK_LIMIT, MLOCK_LIMIT }, \ [RLIMIT_AS] = { RLIM_INFINITY, RLIM_INFINITY }, \ [RLIMIT_LOCKS] = { RLIM_INFINITY, RLIM_INFINITY }, \ diff --git a/include/linux/fs.h b/include/linux/fs.h index 5bb9e826019b..3f9d3251790d 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -23,7 +23,8 @@ /* Fixed constants first: */ #undef NR_OPEN -#define INR_OPEN 1024 /* Initial setting for nfile rlimits */ +#define INR_OPEN_CUR 1024 /* Initial setting for nfile rlimits */ +#define INR_OPEN_MAX 4096 /* Hard limit for nfile rlimits */ #define BLOCK_SIZE_BITS 10 #define BLOCK_SIZE (1< Date: Tue, 24 May 2011 17:13:06 -0700 Subject: include/linux/c2port.h: remove wrong and never used macros The macro to_class_dev() uses the deprecated structure class_device, and the c2port_device has no member named class in the definition of the macro to_c2port_device. Signed-off-by: Wanlong Gao Cc: Rodolfo Giometti Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/c2port.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/c2port.h b/include/linux/c2port.h index 2a5cd867c365..a2f7d7413f30 100644 --- a/include/linux/c2port.h +++ b/include/linux/c2port.h @@ -60,9 +60,6 @@ struct c2port_ops { * Exported functions */ -#define to_class_dev(obj) container_of((obj), struct class_device, kobj) -#define to_c2port_device(obj) container_of((obj), struct c2port_device, class) - extern struct c2port_device *c2port_device_register(char *name, struct c2port_ops *ops, void *devdata); extern void c2port_device_unregister(struct c2port_device *dev); -- cgit From e50c1f609c63223adaa38f5a79b18759a00adf72 Mon Sep 17 00:00:00 2001 From: Amerigo Wang Date: Tue, 24 May 2011 17:13:11 -0700 Subject: fscache: remove dead code under CONFIG_WORKQUEUE_DEBUGFS There is no CONFIG_WORKQUEUE_DEBUGFS any more, so this code is dead. Signed-off-by: WANG Cong Cc: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/fscache/operation.c | 10 ---------- fs/fscache/page.c | 13 ------------- include/linux/fscache-cache.h | 12 ------------ 3 files changed, 35 deletions(-) (limited to 'include/linux') diff --git a/fs/fscache/operation.c b/fs/fscache/operation.c index 48a18f184d50..30afdfa7aec7 100644 --- a/fs/fscache/operation.c +++ b/fs/fscache/operation.c @@ -33,8 +33,6 @@ void fscache_enqueue_operation(struct fscache_operation *op) _enter("{OBJ%x OP%x,%u}", op->object->debug_id, op->debug_id, atomic_read(&op->usage)); - fscache_set_op_state(op, "EnQ"); - ASSERT(list_empty(&op->pend_link)); ASSERT(op->processor != NULL); ASSERTCMP(op->object->state, >=, FSCACHE_OBJECT_AVAILABLE); @@ -66,8 +64,6 @@ EXPORT_SYMBOL(fscache_enqueue_operation); static void fscache_run_op(struct fscache_object *object, struct fscache_operation *op) { - fscache_set_op_state(op, "Run"); - object->n_in_progress++; if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags)) wake_up_bit(&op->flags, FSCACHE_OP_WAITING); @@ -88,8 +84,6 @@ int fscache_submit_exclusive_op(struct fscache_object *object, _enter("{OBJ%x OP%x},", object->debug_id, op->debug_id); - fscache_set_op_state(op, "SubmitX"); - spin_lock(&object->lock); ASSERTCMP(object->n_ops, >=, object->n_in_progress); ASSERTCMP(object->n_ops, >=, object->n_exclusive); @@ -194,8 +188,6 @@ int fscache_submit_op(struct fscache_object *object, ASSERTCMP(atomic_read(&op->usage), >, 0); - fscache_set_op_state(op, "Submit"); - spin_lock(&object->lock); ASSERTCMP(object->n_ops, >=, object->n_in_progress); ASSERTCMP(object->n_ops, >=, object->n_exclusive); @@ -335,8 +327,6 @@ void fscache_put_operation(struct fscache_operation *op) if (!atomic_dec_and_test(&op->usage)) return; - fscache_set_op_state(op, "Put"); - _debug("PUT OP"); if (test_and_set_bit(FSCACHE_OP_DEAD, &op->flags)) BUG(); diff --git a/fs/fscache/page.c b/fs/fscache/page.c index 41c441c2058d..a2a5d19ece6a 100644 --- a/fs/fscache/page.c +++ b/fs/fscache/page.c @@ -155,11 +155,9 @@ static void fscache_attr_changed_op(struct fscache_operation *op) fscache_stat(&fscache_n_attr_changed_calls); if (fscache_object_is_active(object)) { - fscache_set_op_state(op, "CallFS"); fscache_stat(&fscache_n_cop_attr_changed); ret = object->cache->ops->attr_changed(object); fscache_stat_d(&fscache_n_cop_attr_changed); - fscache_set_op_state(op, "Done"); if (ret < 0) fscache_abort_object(object); } @@ -190,7 +188,6 @@ int __fscache_attr_changed(struct fscache_cookie *cookie) fscache_operation_init(op, fscache_attr_changed_op, NULL); op->flags = FSCACHE_OP_ASYNC | (1 << FSCACHE_OP_EXCLUSIVE); - fscache_set_op_name(op, "Attr"); spin_lock(&cookie->lock); @@ -257,7 +254,6 @@ static struct fscache_retrieval *fscache_alloc_retrieval( op->context = context; op->start_time = jiffies; INIT_LIST_HEAD(&op->to_do); - fscache_set_op_name(&op->op, "Retr"); return op; } @@ -368,7 +364,6 @@ int __fscache_read_or_alloc_page(struct fscache_cookie *cookie, _leave(" = -ENOMEM"); return -ENOMEM; } - fscache_set_op_name(&op->op, "RetrRA1"); spin_lock(&cookie->lock); @@ -487,7 +482,6 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie, op = fscache_alloc_retrieval(mapping, end_io_func, context); if (!op) return -ENOMEM; - fscache_set_op_name(&op->op, "RetrRAN"); spin_lock(&cookie->lock); @@ -589,7 +583,6 @@ int __fscache_alloc_page(struct fscache_cookie *cookie, op = fscache_alloc_retrieval(page->mapping, NULL, NULL); if (!op) return -ENOMEM; - fscache_set_op_name(&op->op, "RetrAL1"); spin_lock(&cookie->lock); @@ -662,8 +655,6 @@ static void fscache_write_op(struct fscache_operation *_op) _enter("{OP%x,%d}", op->op.debug_id, atomic_read(&op->op.usage)); - fscache_set_op_state(&op->op, "GetPage"); - spin_lock(&object->lock); cookie = object->cookie; @@ -698,15 +689,12 @@ static void fscache_write_op(struct fscache_operation *_op) spin_unlock(&cookie->stores_lock); spin_unlock(&object->lock); - fscache_set_op_state(&op->op, "Store"); fscache_stat(&fscache_n_store_pages); fscache_stat(&fscache_n_cop_write_page); ret = object->cache->ops->write_page(op, page); fscache_stat_d(&fscache_n_cop_write_page); - fscache_set_op_state(&op->op, "EndWrite"); fscache_end_page_write(object, page); if (ret < 0) { - fscache_set_op_state(&op->op, "Abort"); fscache_abort_object(object); } else { fscache_enqueue_operation(&op->op); @@ -778,7 +766,6 @@ int __fscache_write_page(struct fscache_cookie *cookie, fscache_operation_init(&op->op, fscache_write_op, fscache_release_write_op); op->op.flags = FSCACHE_OP_ASYNC | (1 << FSCACHE_OP_WAITING); - fscache_set_op_name(&op->op, "Write1"); ret = radix_tree_preload(gfp & ~__GFP_HIGHMEM); if (ret < 0) diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h index 76427e688d15..af095b54502e 100644 --- a/include/linux/fscache-cache.h +++ b/include/linux/fscache-cache.h @@ -100,17 +100,6 @@ struct fscache_operation { /* operation releaser */ fscache_operation_release_t release; - -#ifdef CONFIG_WORKQUEUE_DEBUGFS - struct work_struct put_work; /* work to delay operation put */ - const char *name; /* operation name */ - const char *state; /* operation state */ -#define fscache_set_op_name(OP, N) do { (OP)->name = (N); } while(0) -#define fscache_set_op_state(OP, S) do { (OP)->state = (S); } while(0) -#else -#define fscache_set_op_name(OP, N) do { } while(0) -#define fscache_set_op_state(OP, S) do { } while(0) -#endif }; extern atomic_t fscache_op_debug_id; @@ -137,7 +126,6 @@ static inline void fscache_operation_init(struct fscache_operation *op, op->processor = processor; op->release = release; INIT_LIST_HEAD(&op->pend_link); - fscache_set_op_state(op, "Init"); } /* -- cgit From 4b060420a596095869a6d7849caa798d23839cd1 Mon Sep 17 00:00:00 2001 From: Mike Travis Date: Tue, 24 May 2011 17:13:12 -0700 Subject: bitmap, irq: add smp_affinity_list interface to /proc/irq Manually adjusting the smp_affinity for IRQ's becomes unwieldy when the cpu count is large. Setting smp affinity to cpus 256 to 263 would be: echo 000000ff,00000000,00000000,00000000,00000000,00000000,00000000,00000000 > smp_affinity instead of: echo 256-263 > smp_affinity_list Think about what it looks like for cpus around say, 4088 to 4095. We already have many alternate "list" interfaces: /sys/devices/system/cpu/cpuX/indexY/shared_cpu_list /sys/devices/system/cpu/cpuX/topology/thread_siblings_list /sys/devices/system/cpu/cpuX/topology/core_siblings_list /sys/devices/system/node/nodeX/cpulist /sys/devices/pci***/***/local_cpulist Add a companion interface, smp_affinity_list to use cpu lists instead of cpu maps. This conforms to other companion interfaces where both a map and a list interface exists. This required adding a bitmap_parselist_user() function in a manner similar to the bitmap_parse_user() function. [akpm@linux-foundation.org: make __bitmap_parselist() static] Signed-off-by: Mike Travis Cc: Thomas Gleixner Cc: Jack Steiner Cc: Lee Schermerhorn Cc: Andy Shevchenko Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/IRQ-affinity.txt | 17 ++++-- Documentation/filesystems/proc.txt | 11 +++- include/linux/bitmap.h | 5 +- include/linux/cpumask.h | 15 +++++ kernel/irq/proc.c | 54 ++++++++++++++++-- lib/bitmap.c | 109 +++++++++++++++++++++++++++++++++---- 6 files changed, 188 insertions(+), 23 deletions(-) (limited to 'include/linux') diff --git a/Documentation/IRQ-affinity.txt b/Documentation/IRQ-affinity.txt index b4a615b78403..7890fae18529 100644 --- a/Documentation/IRQ-affinity.txt +++ b/Documentation/IRQ-affinity.txt @@ -4,10 +4,11 @@ ChangeLog: SMP IRQ affinity -/proc/irq/IRQ#/smp_affinity specifies which target CPUs are permitted -for a given IRQ source. It's a bitmask of allowed CPUs. It's not allowed -to turn off all CPUs, and if an IRQ controller does not support IRQ -affinity then the value will not change from the default 0xffffffff. +/proc/irq/IRQ#/smp_affinity and /proc/irq/IRQ#/smp_affinity_list specify +which target CPUs are permitted for a given IRQ source. It's a bitmask +(smp_affinity) or cpu list (smp_affinity_list) of allowed CPUs. It's not +allowed to turn off all CPUs, and if an IRQ controller does not support +IRQ affinity then the value will not change from the default of all cpus. /proc/irq/default_smp_affinity specifies default affinity mask that applies to all non-active IRQs. Once IRQ is allocated/activated its affinity bitmask @@ -54,3 +55,11 @@ round-trip min/avg/max = 0.1/0.5/585.4 ms This time around IRQ44 was delivered only to the last four processors. i.e counters for the CPU0-3 did not change. +Here is an example of limiting that same irq (44) to cpus 1024 to 1031: + +[root@moon 44]# echo 1024-1031 > smp_affinity +[root@moon 44]# cat smp_affinity +1024-1031 + +Note that to do this with a bitmask would require 32 bitmasks of zero +to follow the pertinent one. diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index 60740e8ecb37..f48178024067 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt @@ -574,6 +574,12 @@ The contents of each smp_affinity file is the same by default: > cat /proc/irq/0/smp_affinity ffffffff +There is an alternate interface, smp_affinity_list which allows specifying +a cpu range instead of a bitmask: + + > cat /proc/irq/0/smp_affinity_list + 1024-1031 + The default_smp_affinity mask applies to all non-active IRQs, which are the IRQs which have not yet been allocated/activated, and hence which lack a /proc/irq/[0-9]* directory. @@ -583,12 +589,13 @@ reports itself as being attached. This hardware locality information does not include information about any possible driver locality preference. prof_cpu_mask specifies which CPUs are to be profiled by the system wide -profiler. Default value is ffffffff (all cpus). +profiler. Default value is ffffffff (all cpus if there are only 32 of them). The way IRQs are routed is handled by the IO-APIC, and it's Round Robin between all the CPUs which are allowed to handle it. As usual the kernel has more info than you and does a better job than you, so the defaults are the -best choice for almost everyone. +best choice for almost everyone. [Note this applies only to those IO-APIC's +that support "Round Robin" interrupt distribution.] There are three more important subdirectories in /proc: net, scsi, and sys. The general rule is that the contents, or even the existence of these diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h index daf8c480c786..dcafe0bf0005 100644 --- a/include/linux/bitmap.h +++ b/include/linux/bitmap.h @@ -55,7 +55,8 @@ * bitmap_parse(buf, buflen, dst, nbits) Parse bitmap dst from kernel buf * bitmap_parse_user(ubuf, ulen, dst, nbits) Parse bitmap dst from user buf * bitmap_scnlistprintf(buf, len, src, nbits) Print bitmap src as list to buf - * bitmap_parselist(buf, dst, nbits) Parse bitmap dst from list + * bitmap_parselist(buf, dst, nbits) Parse bitmap dst from kernel buf + * bitmap_parselist_user(buf, dst, nbits) Parse bitmap dst from user buf * bitmap_find_free_region(bitmap, bits, order) Find and allocate bit region * bitmap_release_region(bitmap, pos, order) Free specified bit region * bitmap_allocate_region(bitmap, pos, order) Allocate specified bit region @@ -129,6 +130,8 @@ extern int bitmap_scnlistprintf(char *buf, unsigned int len, const unsigned long *src, int nbits); extern int bitmap_parselist(const char *buf, unsigned long *maskp, int nmaskbits); +extern int bitmap_parselist_user(const char __user *ubuf, unsigned int ulen, + unsigned long *dst, int nbits); extern void bitmap_remap(unsigned long *dst, const unsigned long *src, const unsigned long *old, const unsigned long *new, int bits); extern int bitmap_bitremap(int oldbit, diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index bae6fe24d1f9..b24ac56477b4 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -546,6 +546,21 @@ static inline int cpumask_parse_user(const char __user *buf, int len, return bitmap_parse_user(buf, len, cpumask_bits(dstp), nr_cpumask_bits); } +/** + * cpumask_parselist_user - extract a cpumask from a user string + * @buf: the buffer to extract from + * @len: the length of the buffer + * @dstp: the cpumask to set. + * + * Returns -errno, or 0 for success. + */ +static inline int cpumask_parselist_user(const char __user *buf, int len, + struct cpumask *dstp) +{ + return bitmap_parselist_user(buf, len, cpumask_bits(dstp), + nr_cpumask_bits); +} + /** * cpulist_scnprintf - print a cpumask into a string as comma-separated list * @buf: the buffer to sprintf into diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c index 834899f2500f..64e3df6ab1ef 100644 --- a/kernel/irq/proc.c +++ b/kernel/irq/proc.c @@ -19,7 +19,7 @@ static struct proc_dir_entry *root_irq_dir; #ifdef CONFIG_SMP -static int irq_affinity_proc_show(struct seq_file *m, void *v) +static int show_irq_affinity(int type, struct seq_file *m, void *v) { struct irq_desc *desc = irq_to_desc((long)m->private); const struct cpumask *mask = desc->irq_data.affinity; @@ -28,7 +28,10 @@ static int irq_affinity_proc_show(struct seq_file *m, void *v) if (irqd_is_setaffinity_pending(&desc->irq_data)) mask = desc->pending_mask; #endif - seq_cpumask(m, mask); + if (type) + seq_cpumask_list(m, mask); + else + seq_cpumask(m, mask); seq_putc(m, '\n'); return 0; } @@ -59,7 +62,18 @@ static int irq_affinity_hint_proc_show(struct seq_file *m, void *v) #endif int no_irq_affinity; -static ssize_t irq_affinity_proc_write(struct file *file, +static int irq_affinity_proc_show(struct seq_file *m, void *v) +{ + return show_irq_affinity(0, m, v); +} + +static int irq_affinity_list_proc_show(struct seq_file *m, void *v) +{ + return show_irq_affinity(1, m, v); +} + + +static ssize_t write_irq_affinity(int type, struct file *file, const char __user *buffer, size_t count, loff_t *pos) { unsigned int irq = (int)(long)PDE(file->f_path.dentry->d_inode)->data; @@ -72,7 +86,10 @@ static ssize_t irq_affinity_proc_write(struct file *file, if (!alloc_cpumask_var(&new_value, GFP_KERNEL)) return -ENOMEM; - err = cpumask_parse_user(buffer, count, new_value); + if (type) + err = cpumask_parselist_user(buffer, count, new_value); + else + err = cpumask_parse_user(buffer, count, new_value); if (err) goto free_cpumask; @@ -100,11 +117,28 @@ free_cpumask: return err; } +static ssize_t irq_affinity_proc_write(struct file *file, + const char __user *buffer, size_t count, loff_t *pos) +{ + return write_irq_affinity(0, file, buffer, count, pos); +} + +static ssize_t irq_affinity_list_proc_write(struct file *file, + const char __user *buffer, size_t count, loff_t *pos) +{ + return write_irq_affinity(1, file, buffer, count, pos); +} + static int irq_affinity_proc_open(struct inode *inode, struct file *file) { return single_open(file, irq_affinity_proc_show, PDE(inode)->data); } +static int irq_affinity_list_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, irq_affinity_list_proc_show, PDE(inode)->data); +} + static int irq_affinity_hint_proc_open(struct inode *inode, struct file *file) { return single_open(file, irq_affinity_hint_proc_show, PDE(inode)->data); @@ -125,6 +159,14 @@ static const struct file_operations irq_affinity_hint_proc_fops = { .release = single_release, }; +static const struct file_operations irq_affinity_list_proc_fops = { + .open = irq_affinity_list_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = irq_affinity_list_proc_write, +}; + static int default_affinity_show(struct seq_file *m, void *v) { seq_cpumask(m, irq_default_affinity); @@ -289,6 +331,10 @@ void register_irq_proc(unsigned int irq, struct irq_desc *desc) proc_create_data("affinity_hint", 0400, desc->dir, &irq_affinity_hint_proc_fops, (void *)(long)irq); + /* create /proc/irq//smp_affinity_list */ + proc_create_data("smp_affinity_list", 0600, desc->dir, + &irq_affinity_list_proc_fops, (void *)(long)irq); + proc_create_data("node", 0444, desc->dir, &irq_node_proc_fops, (void *)(long)irq); #endif diff --git a/lib/bitmap.c b/lib/bitmap.c index 91e0ccfdb424..41baf02924e6 100644 --- a/lib/bitmap.c +++ b/lib/bitmap.c @@ -571,8 +571,11 @@ int bitmap_scnlistprintf(char *buf, unsigned int buflen, EXPORT_SYMBOL(bitmap_scnlistprintf); /** - * bitmap_parselist - convert list format ASCII string to bitmap + * __bitmap_parselist - convert list format ASCII string to bitmap * @bp: read nul-terminated user string from this buffer + * @buflen: buffer size in bytes. If string is smaller than this + * then it must be terminated with a \0. + * @is_user: location of buffer, 0 indicates kernel space * @maskp: write resulting mask here * @nmaskbits: number of bits in mask to be written * @@ -587,20 +590,63 @@ EXPORT_SYMBOL(bitmap_scnlistprintf); * %-EINVAL: invalid character in string * %-ERANGE: bit number specified too large for mask */ -int bitmap_parselist(const char *bp, unsigned long *maskp, int nmaskbits) +static int __bitmap_parselist(const char *buf, unsigned int buflen, + int is_user, unsigned long *maskp, + int nmaskbits) { unsigned a, b; + int c, old_c, totaldigits; + const char __user *ubuf = buf; + int exp_digit, in_range; + totaldigits = c = 0; bitmap_zero(maskp, nmaskbits); do { - if (!isdigit(*bp)) - return -EINVAL; - b = a = simple_strtoul(bp, (char **)&bp, BASEDEC); - if (*bp == '-') { - bp++; - if (!isdigit(*bp)) + exp_digit = 1; + in_range = 0; + a = b = 0; + + /* Get the next cpu# or a range of cpu#'s */ + while (buflen) { + old_c = c; + if (is_user) { + if (__get_user(c, ubuf++)) + return -EFAULT; + } else + c = *buf++; + buflen--; + if (isspace(c)) + continue; + + /* + * If the last character was a space and the current + * character isn't '\0', we've got embedded whitespace. + * This is a no-no, so throw an error. + */ + if (totaldigits && c && isspace(old_c)) + return -EINVAL; + + /* A '\0' or a ',' signal the end of a cpu# or range */ + if (c == '\0' || c == ',') + break; + + if (c == '-') { + if (exp_digit || in_range) + return -EINVAL; + b = 0; + in_range = 1; + exp_digit = 1; + continue; + } + + if (!isdigit(c)) return -EINVAL; - b = simple_strtoul(bp, (char **)&bp, BASEDEC); + + b = b * 10 + (c - '0'); + if (!in_range) + a = b; + exp_digit = 0; + totaldigits++; } if (!(a <= b)) return -EINVAL; @@ -610,13 +656,52 @@ int bitmap_parselist(const char *bp, unsigned long *maskp, int nmaskbits) set_bit(a, maskp); a++; } - if (*bp == ',') - bp++; - } while (*bp != '\0' && *bp != '\n'); + } while (buflen && c == ','); return 0; } + +int bitmap_parselist(const char *bp, unsigned long *maskp, int nmaskbits) +{ + char *nl = strchr(bp, '\n'); + int len; + + if (nl) + len = nl - bp; + else + len = strlen(bp); + + return __bitmap_parselist(bp, len, 0, maskp, nmaskbits); +} EXPORT_SYMBOL(bitmap_parselist); + +/** + * bitmap_parselist_user() + * + * @ubuf: pointer to user buffer containing string. + * @ulen: buffer size in bytes. If string is smaller than this + * then it must be terminated with a \0. + * @maskp: pointer to bitmap array that will contain result. + * @nmaskbits: size of bitmap, in bits. + * + * Wrapper for bitmap_parselist(), providing it with user buffer. + * + * We cannot have this as an inline function in bitmap.h because it needs + * linux/uaccess.h to get the access_ok() declaration and this causes + * cyclic dependencies. + */ +int bitmap_parselist_user(const char __user *ubuf, + unsigned int ulen, unsigned long *maskp, + int nmaskbits) +{ + if (!access_ok(VERIFY_READ, ubuf, ulen)) + return -EFAULT; + return __bitmap_parselist((const char *)ubuf, + ulen, 1, maskp, nmaskbits); +} +EXPORT_SYMBOL(bitmap_parselist_user); + + /** * bitmap_pos_to_ord - find ordinal of set bit at given position in bitmap * @buf: pointer to a bitmap -- cgit From 1dbe39424a43e56a6c9aed12661192af51dcdb9f Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Tue, 24 May 2011 17:13:13 -0700 Subject: xattr.h: expose string defines to userspace MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit af4f136056c9 ("security: move LSM xattrnames to xattr.h") moved the XATTR_CAPS_SUFFIX define from capability.h to xattr.h. This makes sense except it was previously exports to userspace but xattr.h does not export it to userspace. This patch exports these headers to userspace to fix the ABI regression. There is some slight possibility that this will cause problems in other applications which used these #defines differently (wrongly) and I could JUST export the capabilities xattr name that we broke. Does anyonehave an idea how exposing these headers could cause a problem? Below is what is being exposed to userspace, included here since it isn't clear exactly what is going to be made available from the patch. /* Namespaces */ #define XATTR_OS2_PREFIX "os2." #define XATTR_OS2_PREFIX_LEN (sizeof (XATTR_OS2_PREFIX) - 1) #define XATTR_SECURITY_PREFIX "security." #define XATTR_SECURITY_PREFIX_LEN (sizeof (XATTR_SECURITY_PREFIX) - 1) #define XATTR_SYSTEM_PREFIX "system." #define XATTR_SYSTEM_PREFIX_LEN (sizeof (XATTR_SYSTEM_PREFIX) - 1) #define XATTR_TRUSTED_PREFIX "trusted." #define XATTR_TRUSTED_PREFIX_LEN (sizeof (XATTR_TRUSTED_PREFIX) - 1) #define XATTR_USER_PREFIX "user." #define XATTR_USER_PREFIX_LEN (sizeof (XATTR_USER_PREFIX) - 1) /* Security namespace */ #define XATTR_SELINUX_SUFFIX "selinux" #define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX #define XATTR_SMACK_SUFFIX "SMACK64" #define XATTR_SMACK_IPIN "SMACK64IPIN" #define XATTR_SMACK_IPOUT "SMACK64IPOUT" #define XATTR_NAME_SMACK XATTR_SECURITY_PREFIX XATTR_SMACK_SUFFIX #define XATTR_NAME_SMACKIPIN XATTR_SECURITY_PREFIX XATTR_SMACK_IPIN #define XATTR_NAME_SMACKIPOUT XATTR_SECURITY_PREFIX XATTR_SMACK_IPOUT #define XATTR_CAPS_SUFFIX "capability" #define XATTR_NAME_CAPS XATTR_SECURITY_PREFIX XATTR_CAPS_SUFFIX Reported-by: Ozan Çaglayan Signed-off-by: Eric Paris Cc: Mimi Zohar Cc: Serge Hallyn Cc: James Morris Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/xattr.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/xattr.h b/include/linux/xattr.h index 6050783005bd..aed54c50aa66 100644 --- a/include/linux/xattr.h +++ b/include/linux/xattr.h @@ -13,10 +13,6 @@ #define XATTR_CREATE 0x1 /* set value, fail if attr already exists */ #define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */ -#ifdef __KERNEL__ - -#include - /* Namespaces */ #define XATTR_OS2_PREFIX "os2." #define XATTR_OS2_PREFIX_LEN (sizeof (XATTR_OS2_PREFIX) - 1) @@ -53,6 +49,10 @@ #define XATTR_CAPS_SUFFIX "capability" #define XATTR_NAME_CAPS XATTR_SECURITY_PREFIX XATTR_CAPS_SUFFIX +#ifdef __KERNEL__ + +#include + struct inode; struct dentry; -- cgit From 903c0c7cdc21f2ccb7562a7bbc70289c0c2b16ad Mon Sep 17 00:00:00 2001 From: KOSAKI Motohiro Date: Tue, 24 May 2011 17:13:16 -0700 Subject: sparse: define dummy BUILD_BUG_ON definition for sparse BUILD_BUG_ON() causes a syntax error to detect coding errors. So it causes sparse to detect an error too. This reduces sparse's usefulness. This patch makes a dummy BUILD_BUG_ON() definition for sparse. Signed-off-by: KOSAKI Motohiro Cc: Dave Hansen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/kernel.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include/linux') diff --git a/include/linux/kernel.h b/include/linux/kernel.h index f37ba716ef8b..22295244de18 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -638,6 +638,13 @@ struct sysinfo { char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding: libc5 uses this.. */ }; +#ifdef __CHECKER__ +#define BUILD_BUG_ON_NOT_POWER_OF_2(n) +#define BUILD_BUG_ON_ZERO(e) +#define BUILD_BUG_ON_NULL(e) +#define BUILD_BUG_ON(condition) +#else /* __CHECKER__ */ + /* Force a compilation error if a constant expression is not a power of 2 */ #define BUILD_BUG_ON_NOT_POWER_OF_2(n) \ BUILD_BUG_ON((n) == 0 || (((n) & ((n) - 1)) != 0)) @@ -674,6 +681,7 @@ extern int __build_bug_on_failed; if (condition) __build_bug_on_failed = 1; \ } while(0) #endif +#endif /* __CHECKER__ */ /* Trap pasters of __FUNCTION__ at compile-time */ #define __FUNCTION__ (__func__) -- cgit From 5bd7e6a30e1eb38f58f0046c0cd42dfc38e90d64 Mon Sep 17 00:00:00 2001 From: KOSAKI Motohiro Date: Tue, 24 May 2011 17:13:17 -0700 Subject: sparse: define __must_be_array() for __CHECKER__ commit c5e631cf65f ("ARRAY_SIZE: check for type") added __must_be_array(). But sparse can't parse this gcc extention. Now make C=2 makes following sparse errors a lot. kernel/futex.c:2699:25: error: No right hand side of '+'-expression Because __must_be_array() is used for ARRAY_SIZE() macro and it is used very widely. This patch fixes it. Signed-off-by: KOSAKI Motohiro Cc: Dave Hansen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/compiler-gcc.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h index cb4c1eb7778e..59e4028e833d 100644 --- a/include/linux/compiler-gcc.h +++ b/include/linux/compiler-gcc.h @@ -34,8 +34,12 @@ __asm__ ("" : "=r"(__ptr) : "0"(ptr)); \ (typeof(ptr)) (__ptr + (off)); }) +#ifdef __CHECKER__ +#define __must_be_array(arr) 0 +#else /* &a[0] degrades to a pointer: a different type from an array */ #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) +#endif /* * Force always-inline if the user requests it so via the .config, -- cgit From 746a2a838deec3ef86ef6b7c3edd4207b9a351aa Mon Sep 17 00:00:00 2001 From: KOSAKI Motohiro Date: Tue, 24 May 2011 17:13:17 -0700 Subject: sparse: Undef __compiletime_{warning,error} if __CHECKER__ is defined sparse can't parse warning and error attribute. then they should be hidden from sparse. Signed-off-by: KOSAKI Motohiro Cc: Arjan van de Ven Cc: Dave Hansen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/compiler-gcc4.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h index 64b7c003fd7a..dfadc96e9d63 100644 --- a/include/linux/compiler-gcc4.h +++ b/include/linux/compiler-gcc4.h @@ -51,7 +51,7 @@ #if __GNUC_MINOR__ > 0 #define __compiletime_object_size(obj) __builtin_object_size(obj, 0) #endif -#if __GNUC_MINOR__ >= 4 +#if __GNUC_MINOR__ >= 4 && !defined(__CHECKER__) #define __compiletime_warning(message) __attribute__((warning(message))) #define __compiletime_error(message) __attribute__((error(message))) #endif -- cgit From 95dde501907b06e7203c74f8435acfdab9eb2659 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 24 May 2011 17:13:19 -0700 Subject: memblock: add error return when CONFIG_HAVE_MEMBLOCK is not set On larger systems, information in the kernel log is lost because there is so much early text printed, that it overflows the static log buffer before the log_buf_len kernel parameter can be processed, and a bigger log buffer allocated. Distros are relunctant to increase memory usage by increasing the size of the static log buffer, so minimize the problem by allocating the new log buffer as early as possible. This patch: Add an error return if CONFIG_HAVE_MEMBLOCK is not set instead of having to add #ifdef CONFIG_HAVE_MEMBLOCK around blocks of code calling that function. Signed-off-by: Mike Travis Cc: Yinghai Lu Cc: "H. Peter Anvin" Cc: Jack Steiner Cc: Thomas Gleixner Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memblock.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/memblock.h b/include/linux/memblock.h index 62a10c2a11f2..7525e38c434d 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -2,6 +2,8 @@ #define _LINUX_MEMBLOCK_H #ifdef __KERNEL__ +#define MEMBLOCK_ERROR 0 + #ifdef CONFIG_HAVE_MEMBLOCK /* * Logical memory blocks. @@ -20,7 +22,6 @@ #include #define INIT_MEMBLOCK_REGIONS 128 -#define MEMBLOCK_ERROR 0 struct memblock_region { phys_addr_t base; @@ -160,6 +161,12 @@ static inline unsigned long memblock_region_reserved_end_pfn(const struct memblo #define __initdata_memblock #endif +#else +static inline phys_addr_t memblock_alloc(phys_addr_t size, phys_addr_t align) +{ + return MEMBLOCK_ERROR; +} + #endif /* CONFIG_HAVE_MEMBLOCK */ #endif /* __KERNEL__ */ -- cgit From 162a7e7500f9664636e649ba59defe541b7c2c60 Mon Sep 17 00:00:00 2001 From: Mike Travis Date: Tue, 24 May 2011 17:13:20 -0700 Subject: printk: allocate kernel log buffer earlier On larger systems, because of the numerous ACPI, Bootmem and EFI messages, the static log buffer overflows before the larger one specified by the log_buf_len param is allocated. Minimize the overflow by allocating the new log buffer as soon as possible. On kernels without memblock, a later call to setup_log_buf from kernel/init.c is the fallback. [akpm@linux-foundation.org: coding-style fixes] [akpm@linux-foundation.org: fix CONFIG_PRINTK=n build] Signed-off-by: Mike Travis Cc: Yinghai Lu Cc: "H. Peter Anvin" Cc: Jack Steiner Cc: Thomas Gleixner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86/kernel/setup.c | 2 ++ include/linux/printk.h | 7 ++++ init/main.c | 1 + kernel/printk.c | 87 ++++++++++++++++++++++++++++++++----------------- 4 files changed, 68 insertions(+), 29 deletions(-) (limited to 'include/linux') diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 605e5ae19c7f..a3e5948670c2 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -946,6 +946,8 @@ void __init setup_arch(char **cmdline_p) if (init_ohci1394_dma_early) init_ohci1394_dma_on_all_controllers(); #endif + /* Allocate bigger log buffer */ + setup_log_buf(1); reserve_initrd(); diff --git a/include/linux/printk.h b/include/linux/printk.h index ee048e77e1ae..0101d55d9651 100644 --- a/include/linux/printk.h +++ b/include/linux/printk.h @@ -1,6 +1,8 @@ #ifndef __KERNEL_PRINTK__ #define __KERNEL_PRINTK__ +#include + extern const char linux_banner[]; extern const char linux_proc_banner[]; @@ -113,6 +115,7 @@ extern int dmesg_restrict; extern int kptr_restrict; void log_buf_kexec_setup(void); +void __init setup_log_buf(int early); #else static inline __attribute__ ((format (printf, 1, 0))) int vprintk(const char *s, va_list args) @@ -137,6 +140,10 @@ static inline bool printk_timed_ratelimit(unsigned long *caller_jiffies, static inline void log_buf_kexec_setup(void) { } + +static inline void setup_log_buf(int early) +{ +} #endif extern void dump_stack(void) __cold; diff --git a/init/main.c b/init/main.c index 22da33918aef..d2f1e086bf33 100644 --- a/init/main.c +++ b/init/main.c @@ -504,6 +504,7 @@ asmlinkage void __init start_kernel(void) * These use large bootmem allocations and must precede * kmem_cache_init() */ + setup_log_buf(0); pidhash_init(); vfs_caches_init_early(); sort_main_extable(); diff --git a/kernel/printk.c b/kernel/printk.c index da8ca817eae3..35185392173f 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -167,46 +168,74 @@ void log_buf_kexec_setup(void) } #endif +/* requested log_buf_len from kernel cmdline */ +static unsigned long __initdata new_log_buf_len; + +/* save requested log_buf_len since it's too early to process it */ static int __init log_buf_len_setup(char *str) { unsigned size = memparse(str, &str); - unsigned long flags; if (size) size = roundup_pow_of_two(size); - if (size > log_buf_len) { - unsigned start, dest_idx, offset; - char *new_log_buf; + if (size > log_buf_len) + new_log_buf_len = size; - new_log_buf = alloc_bootmem(size); - if (!new_log_buf) { - printk(KERN_WARNING "log_buf_len: allocation failed\n"); - goto out; - } + return 0; +} +early_param("log_buf_len", log_buf_len_setup); - spin_lock_irqsave(&logbuf_lock, flags); - log_buf_len = size; - log_buf = new_log_buf; - - offset = start = min(con_start, log_start); - dest_idx = 0; - while (start != log_end) { - log_buf[dest_idx] = __log_buf[start & (__LOG_BUF_LEN - 1)]; - start++; - dest_idx++; - } - log_start -= offset; - con_start -= offset; - log_end -= offset; - spin_unlock_irqrestore(&logbuf_lock, flags); +void __init setup_log_buf(int early) +{ + unsigned long flags; + unsigned start, dest_idx, offset; + char *new_log_buf; + int free; + + if (!new_log_buf_len) + return; + + if (early) { + unsigned long mem; - printk(KERN_NOTICE "log_buf_len: %d\n", log_buf_len); + mem = memblock_alloc(new_log_buf_len, PAGE_SIZE); + if (mem == MEMBLOCK_ERROR) + return; + new_log_buf = __va(mem); + } else { + new_log_buf = alloc_bootmem_nopanic(new_log_buf_len); } -out: - return 1; -} -__setup("log_buf_len=", log_buf_len_setup); + if (unlikely(!new_log_buf)) { + pr_err("log_buf_len: %ld bytes not available\n", + new_log_buf_len); + return; + } + + spin_lock_irqsave(&logbuf_lock, flags); + log_buf_len = new_log_buf_len; + log_buf = new_log_buf; + new_log_buf_len = 0; + free = __LOG_BUF_LEN - log_end; + + offset = start = min(con_start, log_start); + dest_idx = 0; + while (start != log_end) { + unsigned log_idx_mask = start & (__LOG_BUF_LEN - 1); + + log_buf[dest_idx] = __log_buf[log_idx_mask]; + start++; + dest_idx++; + } + log_start -= offset; + con_start -= offset; + log_end -= offset; + spin_unlock_irqrestore(&logbuf_lock, flags); + + pr_info("log_buf_len: %d\n", log_buf_len); + pr_info("early log buf free: %d(%d%%)\n", + free, (free * 100) / __LOG_BUF_LEN); +} #ifdef CONFIG_BOOT_PRINTK_DELAY -- cgit From 3c1ab50d0a31b27bb4e55168f4901dd91e6e5ea4 Mon Sep 17 00:00:00 2001 From: Joachim Eastwood Date: Tue, 24 May 2011 17:13:23 -0700 Subject: drivers/leds/leds-pca9532.c: add gpio capability Allow unused leds on pca9532 to be used as gpio. The board I am working on now has no less than 6 pca9532 chips. One chips is used for only leds, one has 14 leds and 2 gpio and the rest of the chips are gpio only. There is also one board in mainline which could use this capabilty; arch/arm/mach-iop32x/n2100.c 232 { .type = PCA9532_TYPE_NONE }, /* power OFF gpio */ 233 { .type = PCA9532_TYPE_NONE }, /* reset gpio */ This patch defines a new pin type, PCA9532_TYPE_GPIO, and registers a gpiochip if any pin has this type set. The gpio will registers all chip pins but will filter on gpio_request. [randy.dunlap@oracle.com: fix build when GPIOLIB is not enabled] Signed-off-by: Joachim Eastwood Reviewed-by: Wolfram Sang Reviewed-by: H Hartley Sweeten Cc: Richard Purdie Cc: Grant Likely Signed-off-by: Randy Dunlap Cc: Jan Weitzel Cc: Juergen Kilb Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/leds/Kconfig | 10 ++++ drivers/leds/leds-pca9532.c | 113 +++++++++++++++++++++++++++++++++++++++++-- include/linux/leds-pca9532.h | 3 +- 3 files changed, 122 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 9bec8699b8a3..09de8dac8a73 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -162,6 +162,16 @@ config LEDS_PCA9532 LED controller. It is generally only useful as a platform driver +config LEDS_PCA9532_GPIO + bool "Enable GPIO support for PCA9532" + depends on LEDS_PCA9532 + depends on GPIOLIB + help + Allow unused pins on PCA9532 to be used as gpio. + + To use a pin as gpio pca9532_type in pca9532_platform data needs to + set to PCA9532_TYPE_GPIO. + config LEDS_GPIO tristate "LED Support for GPIO connected LEDs" depends on LEDS_CLASS diff --git a/drivers/leds/leds-pca9532.c b/drivers/leds/leds-pca9532.c index 5bf63af09ddf..ebea85603f43 100644 --- a/drivers/leds/leds-pca9532.c +++ b/drivers/leds/leds-pca9532.c @@ -19,7 +19,9 @@ #include #include #include +#include +#define PCA9532_REG_INPUT(i) ((i)/8) #define PCA9532_REG_PSC(i) (0x2+(i)*2) #define PCA9532_REG_PWM(i) (0x3+(i)*2) #define PCA9532_REG_LS0 0x6 @@ -34,6 +36,9 @@ struct pca9532_data { struct mutex update_lock; struct input_dev *idev; struct work_struct work; +#ifdef CONFIG_LEDS_PCA9532_GPIO + struct gpio_chip gpio; +#endif u8 pwm[2]; u8 psc[2]; }; @@ -200,16 +205,68 @@ static void pca9532_led_work(struct work_struct *work) pca9532_setled(led); } -static void pca9532_destroy_devices(struct pca9532_data *data, int n_devs) +#ifdef CONFIG_LEDS_PCA9532_GPIO +static int pca9532_gpio_request_pin(struct gpio_chip *gc, unsigned offset) +{ + struct pca9532_data *data = container_of(gc, struct pca9532_data, gpio); + struct pca9532_led *led = &data->leds[offset]; + + if (led->type == PCA9532_TYPE_GPIO) + return 0; + + return -EBUSY; +} + +static void pca9532_gpio_set_value(struct gpio_chip *gc, unsigned offset, int val) +{ + struct pca9532_data *data = container_of(gc, struct pca9532_data, gpio); + struct pca9532_led *led = &data->leds[offset]; + + if (val) + led->state = PCA9532_ON; + else + led->state = PCA9532_OFF; + + pca9532_setled(led); +} + +static int pca9532_gpio_get_value(struct gpio_chip *gc, unsigned offset) +{ + struct pca9532_data *data = container_of(gc, struct pca9532_data, gpio); + unsigned char reg; + + reg = i2c_smbus_read_byte_data(data->client, PCA9532_REG_INPUT(offset)); + + return !!(reg & (1 << (offset % 8))); +} + +static int pca9532_gpio_direction_input(struct gpio_chip *gc, unsigned offset) +{ + /* To use as input ensure pin is not driven */ + pca9532_gpio_set_value(gc, offset, 0); + + return 0; +} + +static int pca9532_gpio_direction_output(struct gpio_chip *gc, unsigned offset, int val) +{ + pca9532_gpio_set_value(gc, offset, val); + + return 0; +} +#endif /* CONFIG_LEDS_PCA9532_GPIO */ + +static int pca9532_destroy_devices(struct pca9532_data *data, int n_devs) { int i = n_devs; if (!data) - return; + return -EINVAL; while (--i >= 0) { switch (data->leds[i].type) { case PCA9532_TYPE_NONE: + case PCA9532_TYPE_GPIO: break; case PCA9532_TYPE_LED: led_classdev_unregister(&data->leds[i].ldev); @@ -224,12 +281,26 @@ static void pca9532_destroy_devices(struct pca9532_data *data, int n_devs) break; } } + +#ifdef CONFIG_LEDS_PCA9532_GPIO + if (data->gpio.dev) { + int err = gpiochip_remove(&data->gpio); + if (err) { + dev_err(&data->client->dev, "%s failed, %d\n", + "gpiochip_remove()", err); + return err; + } + } +#endif + + return 0; } static int pca9532_configure(struct i2c_client *client, struct pca9532_data *data, struct pca9532_platform_data *pdata) { int i, err = 0; + int gpios = 0; for (i = 0; i < 2; i++) { data->pwm[i] = pdata->pwm[i]; @@ -249,6 +320,9 @@ static int pca9532_configure(struct i2c_client *client, switch (led->type) { case PCA9532_TYPE_NONE: break; + case PCA9532_TYPE_GPIO: + gpios++; + break; case PCA9532_TYPE_LED: led->state = pled->state; led->name = pled->name; @@ -297,6 +371,34 @@ static int pca9532_configure(struct i2c_client *client, break; } } + +#ifdef CONFIG_LEDS_PCA9532_GPIO + if (gpios) { + data->gpio.label = "gpio-pca9532"; + data->gpio.direction_input = pca9532_gpio_direction_input; + data->gpio.direction_output = pca9532_gpio_direction_output; + data->gpio.set = pca9532_gpio_set_value; + data->gpio.get = pca9532_gpio_get_value; + data->gpio.request = pca9532_gpio_request_pin; + data->gpio.can_sleep = 1; + data->gpio.base = pdata->gpio_base; + data->gpio.ngpio = 16; + data->gpio.dev = &client->dev; + data->gpio.owner = THIS_MODULE; + + err = gpiochip_add(&data->gpio); + if (err) { + /* Use data->gpio.dev as a flag for freeing gpiochip */ + data->gpio.dev = NULL; + dev_warn(&client->dev, "could not add gpiochip\n"); + } else { + dev_info(&client->dev, "gpios %i...%i\n", + data->gpio.base, data->gpio.base + + data->gpio.ngpio - 1); + } + } +#endif + return 0; exit: @@ -337,7 +439,12 @@ static int pca9532_probe(struct i2c_client *client, static int pca9532_remove(struct i2c_client *client) { struct pca9532_data *data = i2c_get_clientdata(client); - pca9532_destroy_devices(data, 16); + int err; + + err = pca9532_destroy_devices(data, 16); + if (err) + return err; + kfree(data); return 0; } diff --git a/include/linux/leds-pca9532.h b/include/linux/leds-pca9532.h index f158eb1149aa..b8d6fffed4d8 100644 --- a/include/linux/leds-pca9532.h +++ b/include/linux/leds-pca9532.h @@ -25,7 +25,7 @@ enum pca9532_state { }; enum pca9532_type { PCA9532_TYPE_NONE, PCA9532_TYPE_LED, - PCA9532_TYPE_N2100_BEEP }; + PCA9532_TYPE_N2100_BEEP, PCA9532_TYPE_GPIO }; struct pca9532_led { u8 id; @@ -41,6 +41,7 @@ struct pca9532_platform_data { struct pca9532_led leds[16]; u8 pwm[2]; u8 psc[2]; + int gpio_base; }; #endif /* __LINUX_PCA9532_H */ -- cgit From 4440673a95e63ad888a41db596edaa0c55d3a332 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Tue, 24 May 2011 17:13:29 -0700 Subject: leds: provide helper to register "leds-gpio" devices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This function makes a deep copy of the platform data to allow it to live in init memory. For a kernel that supports several machines and so includes the definition for several leds-gpio devices this saves quite some memory because all but one definition can be free'd after boot. As the function is used by arch code it must be builtin and so cannot go into leds-gpio.c. [akpm@linux-foundation.org: s/CONFIG_LED_REGISTER_GPIO/CONFIG_LEDS_REGISTER_GPIO/] Signed-off-by: Uwe Kleine-König Cc: Russell King Acked-by: Richard Purdie Cc: Fabio Estevam Cc: Sascha Hauer Tested-by: H Hartley Sweeten Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/Makefile | 2 +- drivers/leds/Kconfig | 7 +++++++ drivers/leds/Makefile | 1 + drivers/leds/leds-gpio-register.c | 42 +++++++++++++++++++++++++++++++++++++++ include/linux/leds.h | 2 ++ 5 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 drivers/leds/leds-gpio-register.c (limited to 'include/linux') diff --git a/drivers/Makefile b/drivers/Makefile index 145aeadb6c03..bceb60c85c01 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -94,7 +94,7 @@ obj-$(CONFIG_CPU_IDLE) += cpuidle/ obj-$(CONFIG_DMA_ENGINE) += dma/ obj-$(CONFIG_MMC) += mmc/ obj-$(CONFIG_MEMSTICK) += memstick/ -obj-$(CONFIG_NEW_LEDS) += leds/ +obj-y += leds/ obj-$(CONFIG_INFINIBAND) += infiniband/ obj-$(CONFIG_SGI_SN) += sn/ obj-y += firmware/ diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index a4a77734ab6e..1d027b475b22 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -14,6 +14,13 @@ config LEDS_CLASS This option enables the led sysfs class in /sys/class/leds. You'll need this to do anything useful with LEDs. If unsure, say N. +config LEDS_GPIO_REGISTER + bool + help + This option provides the function gpio_led_register_device. + As this function is used by arch code it must not be compiled as a + module. + if NEW_LEDS comment "LED drivers" diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index 0b6ad375bfdb..bccb96c9bb45 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -21,6 +21,7 @@ obj-$(CONFIG_LEDS_COBALT_QUBE) += leds-cobalt-qube.o obj-$(CONFIG_LEDS_COBALT_RAQ) += leds-cobalt-raq.o obj-$(CONFIG_LEDS_SUNFIRE) += leds-sunfire.o obj-$(CONFIG_LEDS_PCA9532) += leds-pca9532.o +obj-$(CONFIG_LEDS_GPIO_REGISTER) += leds-gpio-register.o obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o obj-$(CONFIG_LEDS_LP3944) += leds-lp3944.o obj-$(CONFIG_LEDS_LP5521) += leds-lp5521.o diff --git a/drivers/leds/leds-gpio-register.c b/drivers/leds/leds-gpio-register.c new file mode 100644 index 000000000000..1c4ed5510f35 --- /dev/null +++ b/drivers/leds/leds-gpio-register.c @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2011 Pengutronix + * Uwe Kleine-Koenig + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. + */ +#include +#include +#include +#include + +/** + * gpio_led_register_device - register a gpio-led device + * @pdata: the platform data used for the new device + * + * Makes a copy of pdata and pdata->leds and registers a new leds-gpio device + * with the result. This allows to have pdata and pdata-leds in .init.rodata + * and so saves some bytes compared to a static struct platform_device with + * static platform data. + * + * Returns the registered device or an error pointer. + */ +struct platform_device *__init gpio_led_register_device( + int id, const struct gpio_led_platform_data *pdata) +{ + struct platform_device *ret; + struct gpio_led_platform_data _pdata = *pdata; + + _pdata.leds = kmemdup(pdata->leds, + pdata->num_leds * sizeof(*pdata->leds), GFP_KERNEL); + if (!_pdata.leds) + return ERR_PTR(-ENOMEM); + + ret = platform_device_register_resndata(NULL, "leds-gpio", id, + NULL, 0, &_pdata, sizeof(_pdata)); + if (IS_ERR(ret)) + kfree(_pdata.leds); + + return ret; +} diff --git a/include/linux/leds.h b/include/linux/leds.h index 61e0340a4b77..5884def15a24 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -207,5 +207,7 @@ struct gpio_led_platform_data { unsigned long *delay_off); }; +struct platform_device *gpio_led_register_device( + int id, const struct gpio_led_platform_data *pdata); #endif /* __LINUX_LEDS_H_INCLUDED */ -- cgit From c196e32a111b0ee356d67acceb938ae0b5e63ef0 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Tue, 24 May 2011 17:13:31 -0700 Subject: lib: add kstrto*_from_user() There is quite a lot of code which does copy_from_user() + strict_strto*() or simple_strto*() combo in slightly different ways. Before doing conversions all over tree, let's get final API correct. Enter kstrtoull_from_user() and friends. Typical code which uses them looks very simple: TYPE val; int rv; rv = kstrtoTYPE_from_user(buf, count, 0, &val); if (rv < 0) return rv; [use val] return count; There is a tiny semantic difference from the plain kstrto*() API -- the latter allows any amount of leading zeroes, while the former copies data into buffer on stack and thus allows leading zeroes as long as it fits into buffer. This shouldn't be a problem for typical usecase "echo 42 > /proc/x". The point is to make reading one integer from userspace _very_ simple and very bug free. Signed-off-by: Alexey Dobriyan Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/kernel.h | 31 +++++++++++++++++++++++++++++++ lib/kstrtox.c | 26 ++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) (limited to 'include/linux') diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 22295244de18..fb0e7329fee1 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -248,6 +248,37 @@ int __must_check kstrtos16(const char *s, unsigned int base, s16 *res); int __must_check kstrtou8(const char *s, unsigned int base, u8 *res); int __must_check kstrtos8(const char *s, unsigned int base, s8 *res); +int __must_check kstrtoull_from_user(const char __user *s, size_t count, unsigned int base, unsigned long long *res); +int __must_check kstrtoll_from_user(const char __user *s, size_t count, unsigned int base, long long *res); +int __must_check kstrtoul_from_user(const char __user *s, size_t count, unsigned int base, unsigned long *res); +int __must_check kstrtol_from_user(const char __user *s, size_t count, unsigned int base, long *res); +int __must_check kstrtouint_from_user(const char __user *s, size_t count, unsigned int base, unsigned int *res); +int __must_check kstrtoint_from_user(const char __user *s, size_t count, unsigned int base, int *res); +int __must_check kstrtou16_from_user(const char __user *s, size_t count, unsigned int base, u16 *res); +int __must_check kstrtos16_from_user(const char __user *s, size_t count, unsigned int base, s16 *res); +int __must_check kstrtou8_from_user(const char __user *s, size_t count, unsigned int base, u8 *res); +int __must_check kstrtos8_from_user(const char __user *s, size_t count, unsigned int base, s8 *res); + +static inline int __must_check kstrtou64_from_user(const char __user *s, size_t count, unsigned int base, u64 *res) +{ + return kstrtoull_from_user(s, count, base, res); +} + +static inline int __must_check kstrtos64_from_user(const char __user *s, size_t count, unsigned int base, s64 *res) +{ + return kstrtoll_from_user(s, count, base, res); +} + +static inline int __must_check kstrtou32_from_user(const char __user *s, size_t count, unsigned int base, u32 *res) +{ + return kstrtouint_from_user(s, count, base, res); +} + +static inline int __must_check kstrtos32_from_user(const char __user *s, size_t count, unsigned int base, s32 *res) +{ + return kstrtoint_from_user(s, count, base, res); +} + extern unsigned long simple_strtoul(const char *,char **,unsigned int); extern long simple_strtol(const char *,char **,unsigned int); extern unsigned long long simple_strtoull(const char *,char **,unsigned int); diff --git a/lib/kstrtox.c b/lib/kstrtox.c index a235f3cc471c..2dbae88090ac 100644 --- a/lib/kstrtox.c +++ b/lib/kstrtox.c @@ -17,6 +17,7 @@ #include #include #include +#include static inline char _tolower(const char c) { @@ -222,3 +223,28 @@ int kstrtos8(const char *s, unsigned int base, s8 *res) return 0; } EXPORT_SYMBOL(kstrtos8); + +#define kstrto_from_user(f, g, type) \ +int f(const char __user *s, size_t count, unsigned int base, type *res) \ +{ \ + /* sign, base 2 representation, newline, terminator */ \ + char buf[1 + sizeof(type) * 8 + 1 + 1]; \ + \ + count = min(count, sizeof(buf) - 1); \ + if (copy_from_user(buf, s, count)) \ + return -EFAULT; \ + buf[count] = '\0'; \ + return g(buf, base, res); \ +} \ +EXPORT_SYMBOL(f) + +kstrto_from_user(kstrtoull_from_user, kstrtoull, unsigned long long); +kstrto_from_user(kstrtoll_from_user, kstrtoll, long long); +kstrto_from_user(kstrtoul_from_user, kstrtoul, unsigned long); +kstrto_from_user(kstrtol_from_user, kstrtol, long); +kstrto_from_user(kstrtouint_from_user, kstrtouint, unsigned int); +kstrto_from_user(kstrtoint_from_user, kstrtoint, int); +kstrto_from_user(kstrtou16_from_user, kstrtou16, u16); +kstrto_from_user(kstrtos16_from_user, kstrtos16, s16); +kstrto_from_user(kstrtou8_from_user, kstrtou8, u8); +kstrto_from_user(kstrtos8_from_user, kstrtos8, s8); -- cgit From 6aae6e0304d33e537298867dafb2703ec58c2e4f Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Tue, 24 May 2011 17:13:33 -0700 Subject: include/linux/genalloc.h: add multiple-inclusion guards Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Cc: Nicolas Ferre Cc: Patrice VILCHEZ Cc: Jes Sorensen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/genalloc.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/genalloc.h b/include/linux/genalloc.h index 9869ef3674ac..b1c70f10c42b 100644 --- a/include/linux/genalloc.h +++ b/include/linux/genalloc.h @@ -9,6 +9,8 @@ */ +#ifndef __GENALLOC_H__ +#define __GENALLOC_H__ /* * General purpose special memory pool descriptor. */ @@ -34,3 +36,4 @@ extern int gen_pool_add(struct gen_pool *, unsigned long, size_t, int); extern void gen_pool_destroy(struct gen_pool *); extern unsigned long gen_pool_alloc(struct gen_pool *, size_t); extern void gen_pool_free(struct gen_pool *, unsigned long, size_t); +#endif /* __GENALLOC_H__ */ -- cgit From 3c8f370ded3483b27f1218ff0051fcf0c7a2facd Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Tue, 24 May 2011 17:13:34 -0700 Subject: lib/genalloc.c: add support for specifying the physical address So we can specify the virtual address as the base of the pool chunk and then get physical addresses for hardware IP. For example on at91 we will use this on spi, uart or macb Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Cc: Nicolas Ferre Cc: Patrice VILCHEZ Cc: Jes Sorensen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/genalloc.h | 22 +++++++++++++++++++++- lib/genalloc.c | 45 +++++++++++++++++++++++++++++++++++++-------- 2 files changed, 58 insertions(+), 9 deletions(-) (limited to 'include/linux') diff --git a/include/linux/genalloc.h b/include/linux/genalloc.h index b1c70f10c42b..5bbebda78b02 100644 --- a/include/linux/genalloc.h +++ b/include/linux/genalloc.h @@ -26,13 +26,33 @@ struct gen_pool { struct gen_pool_chunk { spinlock_t lock; struct list_head next_chunk; /* next chunk in pool */ + phys_addr_t phys_addr; /* physical starting address of memory chunk */ unsigned long start_addr; /* starting address of memory chunk */ unsigned long end_addr; /* ending address of memory chunk */ unsigned long bits[0]; /* bitmap for allocating memory chunk */ }; extern struct gen_pool *gen_pool_create(int, int); -extern int gen_pool_add(struct gen_pool *, unsigned long, size_t, int); +extern phys_addr_t gen_pool_virt_to_phys(struct gen_pool *pool, unsigned long); +extern int gen_pool_add_virt(struct gen_pool *, unsigned long, phys_addr_t, + size_t, int); +/** + * gen_pool_add - add a new chunk of special memory to the pool + * @pool: pool to add new memory chunk to + * @addr: starting address of memory chunk to add to pool + * @size: size in bytes of the memory chunk to add to pool + * @nid: node id of the node the chunk structure and bitmap should be + * allocated on, or -1 + * + * Add a new chunk of special memory to the specified pool. + * + * Returns 0 on success or a -ve errno on failure. + */ +static inline int gen_pool_add(struct gen_pool *pool, unsigned long addr, + size_t size, int nid) +{ + return gen_pool_add_virt(pool, addr, -1, size, nid); +} extern void gen_pool_destroy(struct gen_pool *); extern unsigned long gen_pool_alloc(struct gen_pool *, size_t); extern void gen_pool_free(struct gen_pool *, unsigned long, size_t); diff --git a/lib/genalloc.c b/lib/genalloc.c index 1923f1490e72..577ddf805975 100644 --- a/lib/genalloc.c +++ b/lib/genalloc.c @@ -39,17 +39,20 @@ struct gen_pool *gen_pool_create(int min_alloc_order, int nid) EXPORT_SYMBOL(gen_pool_create); /** - * gen_pool_add - add a new chunk of special memory to the pool + * gen_pool_add_virt - add a new chunk of special memory to the pool * @pool: pool to add new memory chunk to - * @addr: starting address of memory chunk to add to pool + * @virt: virtual starting address of memory chunk to add to pool + * @phys: physical starting address of memory chunk to add to pool * @size: size in bytes of the memory chunk to add to pool * @nid: node id of the node the chunk structure and bitmap should be * allocated on, or -1 * * Add a new chunk of special memory to the specified pool. + * + * Returns 0 on success or a -ve errno on failure. */ -int gen_pool_add(struct gen_pool *pool, unsigned long addr, size_t size, - int nid) +int gen_pool_add_virt(struct gen_pool *pool, unsigned long virt, phys_addr_t phys, + size_t size, int nid) { struct gen_pool_chunk *chunk; int nbits = size >> pool->min_alloc_order; @@ -58,11 +61,12 @@ int gen_pool_add(struct gen_pool *pool, unsigned long addr, size_t size, chunk = kmalloc_node(nbytes, GFP_KERNEL | __GFP_ZERO, nid); if (unlikely(chunk == NULL)) - return -1; + return -ENOMEM; spin_lock_init(&chunk->lock); - chunk->start_addr = addr; - chunk->end_addr = addr + size; + chunk->phys_addr = phys; + chunk->start_addr = virt; + chunk->end_addr = virt + size; write_lock(&pool->lock); list_add(&chunk->next_chunk, &pool->chunks); @@ -70,7 +74,32 @@ int gen_pool_add(struct gen_pool *pool, unsigned long addr, size_t size, return 0; } -EXPORT_SYMBOL(gen_pool_add); +EXPORT_SYMBOL(gen_pool_add_virt); + +/** + * gen_pool_virt_to_phys - return the physical address of memory + * @pool: pool to allocate from + * @addr: starting address of memory + * + * Returns the physical address on success, or -1 on error. + */ +phys_addr_t gen_pool_virt_to_phys(struct gen_pool *pool, unsigned long addr) +{ + struct list_head *_chunk; + struct gen_pool_chunk *chunk; + + read_lock(&pool->lock); + list_for_each(_chunk, &pool->chunks) { + chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk); + + if (addr >= chunk->start_addr && addr < chunk->end_addr) + return chunk->phys_addr + addr - chunk->start_addr; + } + read_unlock(&pool->lock); + + return -1; +} +EXPORT_SYMBOL(gen_pool_virt_to_phys); /** * gen_pool_destroy - destroy a special memory pool -- cgit From c84598bbfa756b7d042da31aa4e198ae866a6c7d Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Tue, 24 May 2011 17:13:35 -0700 Subject: percpu_counter: change return value and add comments The percpu_counter_*_positive() API in UP case doesn't check if return value is positive. Add comments to explain why we don't. Also if count < 0, returns 0 instead of 1 for *read_positive(). [akpm@linux-foundation.org: tweak comment] Signed-off-by: Shaohua Li Acked-by: Eric Dumazet Cc: Tejun Heo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/percpu_counter.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/percpu_counter.h b/include/linux/percpu_counter.h index 46f6ba56fa91..5edc9014263a 100644 --- a/include/linux/percpu_counter.h +++ b/include/linux/percpu_counter.h @@ -75,7 +75,7 @@ static inline s64 percpu_counter_read_positive(struct percpu_counter *fbc) barrier(); /* Prevent reloads of fbc->count */ if (ret >= 0) return ret; - return 1; + return 0; } static inline int percpu_counter_initialized(struct percpu_counter *fbc) @@ -133,6 +133,10 @@ static inline s64 percpu_counter_read(struct percpu_counter *fbc) return fbc->count; } +/* + * percpu_counter is intended to track positive numbers. In the UP case the + * number should never be negative. + */ static inline s64 percpu_counter_read_positive(struct percpu_counter *fbc) { return fbc->count; -- cgit From 774466add7c810fd7e4c8bcf41995b6799608880 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 25 May 2011 20:43:32 +0200 Subject: hwmon: (jc42) Change detection class While the JC42-compatible chips are temperature sensors, I2C_CLASS_SPD makes more sense because these chips always live on memory modules. Signed-off-by: Jean Delvare Cc: Guenter Roeck --- drivers/hwmon/jc42.c | 2 +- include/linux/i2c.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c index 934991237061..02cebb74e206 100644 --- a/drivers/hwmon/jc42.c +++ b/drivers/hwmon/jc42.c @@ -213,7 +213,7 @@ static const struct dev_pm_ops jc42_dev_pm_ops = { /* This is the driver that will be inserted */ static struct i2c_driver jc42_driver = { - .class = I2C_CLASS_HWMON, + .class = I2C_CLASS_SPD, .driver = { .name = "jc42", .pm = JC42_DEV_PM_OPS, diff --git a/include/linux/i2c.h b/include/linux/i2c.h index f1e3ff5880a9..a6c652ef516d 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -409,7 +409,7 @@ void i2c_unlock_adapter(struct i2c_adapter *); /* i2c adapter classes (bitmask) */ #define I2C_CLASS_HWMON (1<<0) /* lm_sensors, ... */ #define I2C_CLASS_DDC (1<<3) /* DDC bus on graphics adapters */ -#define I2C_CLASS_SPD (1<<7) /* SPD EEPROMs and similar */ +#define I2C_CLASS_SPD (1<<7) /* Memory modules */ /* Internal numbers to terminate lists */ #define I2C_CLIENT_END 0xfffeU -- cgit From d0c97cfb81ebc5b416c0f92fa2fc18d2773e3023 Mon Sep 17 00:00:00 2001 From: Andrei Warkentin Date: Mon, 23 May 2011 15:06:36 -0500 Subject: mmc: core: Use CMD23 for multiblock transfers when we can. CMD23-prefixed instead of open-ended multiblock transfers have a performance advantage on some MMC cards. Signed-off-by: Andrei Warkentin Signed-off-by: Chris Ball --- drivers/mmc/card/block.c | 108 ++++++++++++++++++++++++++++++++++------------- include/linux/mmc/card.h | 1 + include/linux/mmc/core.h | 1 + include/linux/mmc/host.h | 6 +++ include/linux/mmc/mmc.h | 6 +++ 5 files changed, 93 insertions(+), 29 deletions(-) (limited to 'include/linux') diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 126c7f41c5a3..a380accaba9a 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -59,10 +59,6 @@ MODULE_ALIAS("mmc:block"); #define INAND_CMD38_ARG_SECTRIM1 0x81 #define INAND_CMD38_ARG_SECTRIM2 0x88 -#define REL_WRITES_SUPPORTED(card) (mmc_card_mmc((card)) && \ - (((card)->ext_csd.rel_param & EXT_CSD_WR_REL_PARAM_EN) || \ - ((card)->ext_csd.rel_sectors))) - static DEFINE_MUTEX(block_mutex); /* @@ -90,6 +86,10 @@ struct mmc_blk_data { struct mmc_queue queue; struct list_head part; + unsigned int flags; +#define MMC_BLK_CMD23 (1 << 0) /* Can do SET_BLOCK_COUNT for multiblock */ +#define MMC_BLK_REL_WR (1 << 1) /* MMC Reliable write support */ + unsigned int usage; unsigned int read_only; unsigned int part_type; @@ -429,6 +429,7 @@ static const struct block_device_operations mmc_bdops = { struct mmc_blk_request { struct mmc_request mrq; + struct mmc_command sbc; struct mmc_command cmd; struct mmc_command stop; struct mmc_data data; @@ -652,13 +653,10 @@ static int mmc_blk_issue_flush(struct mmc_queue *mq, struct request *req) * reliable write can handle, thus finish the request in * partial completions. */ -static inline int mmc_apply_rel_rw(struct mmc_blk_request *brq, - struct mmc_card *card, - struct request *req) +static inline void mmc_apply_rel_rw(struct mmc_blk_request *brq, + struct mmc_card *card, + struct request *req) { - int err; - struct mmc_command set_count = {0}; - if (!(card->ext_csd.rel_param & EXT_CSD_WR_REL_PARAM_EN)) { /* Legacy mode imposes restrictions on transfers. */ if (!IS_ALIGNED(brq->cmd.arg, card->ext_csd.rel_sectors)) @@ -669,15 +667,6 @@ static inline int mmc_apply_rel_rw(struct mmc_blk_request *brq, else if (brq->data.blocks < card->ext_csd.rel_sectors) brq->data.blocks = 1; } - - set_count.opcode = MMC_SET_BLOCK_COUNT; - set_count.arg = brq->data.blocks | (1 << 31); - set_count.flags = MMC_RSP_R1 | MMC_CMD_AC; - err = mmc_wait_for_cmd(card->host, &set_count, 0); - if (err) - printk(KERN_ERR "%s: error %d SET_BLOCK_COUNT\n", - req->rq_disk->disk_name, err); - return err; } static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) @@ -694,7 +683,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) bool do_rel_wr = ((req->cmd_flags & REQ_FUA) || (req->cmd_flags & REQ_META)) && (rq_data_dir(req) == WRITE) && - REL_WRITES_SUPPORTED(card); + (md->flags & MMC_BLK_REL_WR); do { struct mmc_command cmd = {0}; @@ -732,11 +721,9 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) if (brq.data.blocks > 1 || do_rel_wr) { /* SPI multiblock writes terminate using a special - * token, not a STOP_TRANSMISSION request. Reliable - * writes use SET_BLOCK_COUNT and do not use a - * STOP_TRANSMISSION request either. + * token, not a STOP_TRANSMISSION request. */ - if ((!mmc_host_is_spi(card->host) && !do_rel_wr) || + if (!mmc_host_is_spi(card->host) || rq_data_dir(req) == READ) brq.mrq.stop = &brq.stop; readcmd = MMC_READ_MULTIPLE_BLOCK; @@ -754,8 +741,37 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) brq.data.flags |= MMC_DATA_WRITE; } - if (do_rel_wr && mmc_apply_rel_rw(&brq, card, req)) - goto cmd_err; + if (do_rel_wr) + mmc_apply_rel_rw(&brq, card, req); + + /* + * Pre-defined multi-block transfers are preferable to + * open ended-ones (and necessary for reliable writes). + * However, it is not sufficient to just send CMD23, + * and avoid the final CMD12, as on an error condition + * CMD12 (stop) needs to be sent anyway. This, coupled + * with Auto-CMD23 enhancements provided by some + * hosts, means that the complexity of dealing + * with this is best left to the host. If CMD23 is + * supported by card and host, we'll fill sbc in and let + * the host deal with handling it correctly. This means + * that for hosts that don't expose MMC_CAP_CMD23, no + * change of behavior will be observed. + * + * N.B: Some MMC cards experience perf degradation. + * We'll avoid using CMD23-bounded multiblock writes for + * these, while retaining features like reliable writes. + */ + + if ((md->flags & MMC_BLK_CMD23) && + mmc_op_multi(brq.cmd.opcode) && + (do_rel_wr || !(card->quirks & MMC_QUIRK_BLK_NO_CMD23))) { + brq.sbc.opcode = MMC_SET_BLOCK_COUNT; + brq.sbc.arg = brq.data.blocks | + (do_rel_wr ? (1 << 31) : 0); + brq.sbc.flags = MMC_RSP_R1 | MMC_CMD_AC; + brq.mrq.sbc = &brq.sbc; + } mmc_set_data_timeout(&brq.data, card); @@ -792,7 +808,8 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) * until later as we need to wait for the card to leave * programming mode even when things go wrong. */ - if (brq.cmd.error || brq.data.error || brq.stop.error) { + if (brq.sbc.error || brq.cmd.error || + brq.data.error || brq.stop.error) { if (brq.data.blocks > 1 && rq_data_dir(req) == READ) { /* Redo read one sector at a time */ printk(KERN_WARNING "%s: retrying using single " @@ -803,6 +820,13 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) status = get_card_status(card, req); } + if (brq.sbc.error) { + printk(KERN_ERR "%s: error %d sending SET_BLOCK_COUNT " + "command, response %#x, card status %#x\n", + req->rq_disk->disk_name, brq.sbc.error, + brq.sbc.resp[0], status); + } + if (brq.cmd.error) { printk(KERN_ERR "%s: error %d sending read/write " "command, response %#x, card status %#x\n", @@ -1014,8 +1038,6 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, md->disk->queue = md->queue.queue; md->disk->driverfs_dev = parent; set_disk_ro(md->disk, md->read_only || default_ro); - if (REL_WRITES_SUPPORTED(card)) - blk_queue_flush(md->queue.queue, REQ_FLUSH | REQ_FUA); /* * As discussed on lkml, GENHD_FL_REMOVABLE should: @@ -1034,6 +1056,19 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, blk_queue_logical_block_size(md->queue.queue, 512); set_capacity(md->disk, size); + + if (mmc_host_cmd23(card->host) && + mmc_card_mmc(card)) + md->flags |= MMC_BLK_CMD23; + + if (mmc_card_mmc(card) && + md->flags & MMC_BLK_CMD23 && + ((card->ext_csd.rel_param & EXT_CSD_WR_REL_PARAM_EN) || + card->ext_csd.rel_sectors)) { + md->flags |= MMC_BLK_REL_WR; + blk_queue_flush(md->queue.queue, REQ_FLUSH | REQ_FUA); + } + return md; err_putdisk: @@ -1189,6 +1224,21 @@ static const struct mmc_fixup blk_fixups[] = MMC_FIXUP("SEM08G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38), MMC_FIXUP("SEM16G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38), MMC_FIXUP("SEM32G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38), + + /* + * Some MMC cards experience performance degradation with CMD23 + * instead of CMD12-bounded multiblock transfers. For now we'll + * black list what's bad... + * - Certain Toshiba cards. + * + * N.B. This doesn't affect SD cards. + */ + MMC_FIXUP("MMC08G", 0x11, CID_OEMID_ANY, add_quirk_mmc, + MMC_QUIRK_BLK_NO_CMD23), + MMC_FIXUP("MMC16G", 0x11, CID_OEMID_ANY, add_quirk_mmc, + MMC_QUIRK_BLK_NO_CMD23), + MMC_FIXUP("MMC32G", 0x11, CID_OEMID_ANY, add_quirk_mmc, + MMC_QUIRK_BLK_NO_CMD23), END_FIXUP }; diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 7190aa2096f7..4a0e27baaea0 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -171,6 +171,7 @@ struct mmc_card { #define MMC_QUIRK_NONSTD_FUNC_IF (1<<4) /* SDIO card has nonstd function interfaces */ #define MMC_QUIRK_DISABLE_CD (1<<5) /* disconnect CD/DAT[3] resistor */ #define MMC_QUIRK_INAND_CMD38 (1<<6) /* iNAND devices have broken CMD38 */ +#define MMC_QUIRK_BLK_NO_CMD23 (1<<7) /* Avoid CMD23 for regular multiblock */ unsigned int erase_size; /* erase size in sectors */ unsigned int erase_shift; /* if erase unit is power 2 */ diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index cbe8d55f64c4..b6718e549a51 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -120,6 +120,7 @@ struct mmc_data { }; struct mmc_request { + struct mmc_command *sbc; /* SET_BLOCK_COUNT for multiblock */ struct mmc_command *cmd; struct mmc_data *data; struct mmc_command *stop; diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index de32e6aa018a..e946bd10fe3f 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -210,6 +210,7 @@ struct mmc_host { #define MMC_CAP_MAX_CURRENT_400 (1 << 27) /* Host max current limit is 400mA */ #define MMC_CAP_MAX_CURRENT_600 (1 << 28) /* Host max current limit is 600mA */ #define MMC_CAP_MAX_CURRENT_800 (1 << 29) /* Host max current limit is 800mA */ +#define MMC_CAP_CMD23 (1 << 30) /* CMD23 supported. */ mmc_pm_flag_t pm_caps; /* supported pm features */ @@ -366,5 +367,10 @@ static inline int mmc_card_wake_sdio_irq(struct mmc_host *host) { return host->pm_flags & MMC_PM_WAKE_SDIO_IRQ; } + +static inline int mmc_host_cmd23(struct mmc_host *host) +{ + return host->caps & MMC_CAP_CMD23; +} #endif diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index 9fa5a73f393d..ac26a685cca8 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -83,6 +83,12 @@ #define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */ #define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1 */ +static inline bool mmc_op_multi(u32 opcode) +{ + return opcode == MMC_WRITE_MULTIPLE_BLOCK || + opcode == MMC_READ_MULTIPLE_BLOCK; +} + /* * MMC_SWITCH argument format: * -- cgit From e89d456fcdde2df008c032bf928e69e628e07a28 Mon Sep 17 00:00:00 2001 From: Andrei Warkentin Date: Mon, 23 May 2011 15:06:37 -0500 Subject: mmc: sdhci: Implement MMC_CAP_CMD23 for SDHCI. Implements support for multiblock transfers bounded by SET_BLOCK_COUNT (CMD23). Signed-off-by: Andrei Warkentin Signed-off-by: Chris Ball --- drivers/mmc/host/sdhci.c | 63 +++++++++++++++++++++++++++++++++++------------ drivers/mmc/host/sdhci.h | 2 +- include/linux/mmc/sdhci.h | 1 + 3 files changed, 49 insertions(+), 17 deletions(-) (limited to 'include/linux') diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index cc63f5ed2310..b9ed66307ac3 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -838,9 +838,10 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd) } static void sdhci_set_transfer_mode(struct sdhci_host *host, - struct mmc_data *data) + struct mmc_command *cmd) { u16 mode; + struct mmc_data *data = cmd->data; if (data == NULL) return; @@ -848,11 +849,14 @@ static void sdhci_set_transfer_mode(struct sdhci_host *host, WARN_ON(!host->data); mode = SDHCI_TRNS_BLK_CNT_EN; - if (data->blocks > 1) { - if (host->quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12) - mode |= SDHCI_TRNS_MULTI | SDHCI_TRNS_ACMD12; - else - mode |= SDHCI_TRNS_MULTI; + if (mmc_op_multi(cmd->opcode) || data->blocks > 1) { + mode |= SDHCI_TRNS_MULTI; + /* + * If we are sending CMD23, CMD12 never gets sent + * on successful completion (so no Auto-CMD12). + */ + if (!host->mrq->sbc && (host->flags & SDHCI_AUTO_CMD12)) + mode |= SDHCI_TRNS_AUTO_CMD12; } if (data->flags & MMC_DATA_READ) mode |= SDHCI_TRNS_READ; @@ -893,7 +897,15 @@ static void sdhci_finish_data(struct sdhci_host *host) else data->bytes_xfered = data->blksz * data->blocks; - if (data->stop) { + /* + * Need to send CMD12 if - + * a) open-ended multiblock transfer (no CMD23) + * b) error in multiblock transfer + */ + if (data->stop && + (data->error || + !host->mrq->sbc)) { + /* * The controller needs a reset of internal state machines * upon error conditions. @@ -949,7 +961,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) sdhci_writel(host, cmd->arg, SDHCI_ARGUMENT); - sdhci_set_transfer_mode(host, cmd->data); + sdhci_set_transfer_mode(host, cmd); if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) { printk(KERN_ERR "%s: Unsupported response type!\n", @@ -1004,13 +1016,21 @@ static void sdhci_finish_command(struct sdhci_host *host) host->cmd->error = 0; - if (host->data && host->data_early) - sdhci_finish_data(host); + /* Finished CMD23, now send actual command. */ + if (host->cmd == host->mrq->sbc) { + host->cmd = NULL; + sdhci_send_command(host, host->mrq->cmd); + } else { - if (!host->cmd->data) - tasklet_schedule(&host->finish_tasklet); + /* Processed actual command. */ + if (host->data && host->data_early) + sdhci_finish_data(host); - host->cmd = NULL; + if (!host->cmd->data) + tasklet_schedule(&host->finish_tasklet); + + host->cmd = NULL; + } } static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) @@ -1189,7 +1209,12 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) #ifndef SDHCI_USE_LEDS_CLASS sdhci_activate_led(host); #endif - if (host->quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12) { + + /* + * Ensure we don't send the STOP for non-SET_BLOCK_COUNTED + * requests if Auto-CMD12 is enabled. + */ + if (!mrq->sbc && (host->flags & SDHCI_AUTO_CMD12)) { if (mrq->stop) { mrq->data->stop = NULL; mrq->stop = NULL; @@ -1227,7 +1252,10 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) host->mrq = mrq; } - sdhci_send_command(host, mrq->cmd); + if (mrq->sbc) + sdhci_send_command(host, mrq->sbc); + else + sdhci_send_command(host, mrq->cmd); } mmiowb(); @@ -2455,7 +2483,10 @@ int sdhci_add_host(struct sdhci_host *host) } else mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_200; - mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE; + mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE | MMC_CAP_CMD23; + + if (host->quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12) + host->flags |= SDHCI_AUTO_CMD12; /* * A controller may support 8-bit width, but the board itself diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 7e28eec97f04..2c3fbc5a4c07 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -36,7 +36,7 @@ #define SDHCI_TRANSFER_MODE 0x0C #define SDHCI_TRNS_DMA 0x01 #define SDHCI_TRNS_BLK_CNT_EN 0x02 -#define SDHCI_TRNS_ACMD12 0x04 +#define SDHCI_TRNS_AUTO_CMD12 0x04 #define SDHCI_TRNS_READ 0x10 #define SDHCI_TRNS_MULTI 0x20 diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h index e902618d68f4..73e27ba51e99 100644 --- a/include/linux/mmc/sdhci.h +++ b/include/linux/mmc/sdhci.h @@ -113,6 +113,7 @@ struct sdhci_host { #define SDHCI_DEVICE_DEAD (1<<3) /* Device unresponsive */ #define SDHCI_SDR50_NEEDS_TUNING (1<<4) /* SDR50 needs tuning */ #define SDHCI_NEEDS_RETUNING (1<<5) /* Host needs retuning */ +#define SDHCI_AUTO_CMD12 (1<<6) /* Auto CMD12 support */ unsigned int version; /* SDHCI spec. version */ -- cgit From f0d89972b01798cf9d245dfa1cacfa0ee78a3593 Mon Sep 17 00:00:00 2001 From: Andrei Warkentin Date: Mon, 23 May 2011 15:06:38 -0500 Subject: mmc: core: Block CMD23 support for UHS104/SDXC cards. SD cards operating at UHS104 or better support SET_BLOCK_COUNT. Signed-off-by: Andrei Warkentin Reviewed-by: Arindam Nath Signed-off-by: Chris Ball --- drivers/mmc/card/block.c | 9 ++++++--- drivers/mmc/core/sd.c | 2 ++ include/linux/mmc/card.h | 3 +++ include/linux/mmc/sd.h | 2 +- 4 files changed, 12 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index a380accaba9a..71da5641e258 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -1057,9 +1057,12 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, blk_queue_logical_block_size(md->queue.queue, 512); set_capacity(md->disk, size); - if (mmc_host_cmd23(card->host) && - mmc_card_mmc(card)) - md->flags |= MMC_BLK_CMD23; + if (mmc_host_cmd23(card->host)) { + if (mmc_card_mmc(card) || + (mmc_card_sd(card) && + card->scr.cmds & SD_SCR_CMD23_SUPPORT)) + md->flags |= MMC_BLK_CMD23; + } if (mmc_card_mmc(card) && md->flags & MMC_BLK_CMD23 && diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 596d0b9d30b8..ff2774128aa9 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -203,6 +203,8 @@ static int mmc_decode_scr(struct mmc_card *card) else card->erased_byte = 0x0; + if (scr->sda_spec3) + scr->cmds = UNSTUFF_BITS(resp, 32, 2); return 0; } diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 4a0e27baaea0..c6927a4d157f 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -72,6 +72,9 @@ struct sd_scr { unsigned char bus_widths; #define SD_SCR_BUS_WIDTH_1 (1<<0) #define SD_SCR_BUS_WIDTH_4 (1<<2) + unsigned char cmds; +#define SD_SCR_CMD20_SUPPORT (1<<0) +#define SD_SCR_CMD23_SUPPORT (1<<1) }; struct sd_ssr { diff --git a/include/linux/mmc/sd.h b/include/linux/mmc/sd.h index c648878f6734..7d35d52c3df3 100644 --- a/include/linux/mmc/sd.h +++ b/include/linux/mmc/sd.h @@ -66,7 +66,7 @@ #define SCR_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.01 */ #define SCR_SPEC_VER_1 1 /* Implements system specification 1.10 */ -#define SCR_SPEC_VER_2 2 /* Implements system specification 2.00 */ +#define SCR_SPEC_VER_2 2 /* Implements system specification 2.00-3.0X */ /* * SD bus widths -- cgit From 8edf63710bd43e62d59bfe017df542fa0713bbb3 Mon Sep 17 00:00:00 2001 From: Andrei Warkentin Date: Mon, 23 May 2011 15:06:39 -0500 Subject: mmc: sdhci: Auto-CMD23 support. Enables Auto-CMD23 support where available (SDHCI 3.0 controllers) Signed-off-by: Andrei Warkentin Tested-by: Arindam Nath Signed-off-by: Chris Ball --- drivers/mmc/host/sdhci.c | 17 ++++++++++++++++- drivers/mmc/host/sdhci.h | 2 ++ include/linux/mmc/sdhci.h | 1 + 3 files changed, 19 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index b9ed66307ac3..f845fd6a64ae 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -857,7 +857,12 @@ static void sdhci_set_transfer_mode(struct sdhci_host *host, */ if (!host->mrq->sbc && (host->flags & SDHCI_AUTO_CMD12)) mode |= SDHCI_TRNS_AUTO_CMD12; + else if (host->mrq->sbc && (host->flags & SDHCI_AUTO_CMD23)) { + mode |= SDHCI_TRNS_AUTO_CMD23; + sdhci_writel(host, host->mrq->sbc->arg, SDHCI_ARGUMENT2); + } } + if (data->flags & MMC_DATA_READ) mode |= SDHCI_TRNS_READ; if (host->flags & SDHCI_REQ_USE_DMA) @@ -1252,7 +1257,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) host->mrq = mrq; } - if (mrq->sbc) + if (mrq->sbc && !(host->flags & SDHCI_AUTO_CMD23)) sdhci_send_command(host, mrq->sbc); else sdhci_send_command(host, mrq->cmd); @@ -2488,6 +2493,16 @@ int sdhci_add_host(struct sdhci_host *host) if (host->quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12) host->flags |= SDHCI_AUTO_CMD12; + /* Auto-CMD23 stuff only works in ADMA or PIO. */ + if ((host->version == SDHCI_SPEC_300) && + ((host->flags & SDHCI_USE_ADMA) || + !(host->flags & SDHCI_REQ_USE_DMA))) { + host->flags |= SDHCI_AUTO_CMD23; + DBG("%s: Auto-CMD23 available\n", mmc_hostname(mmc)); + } else { + DBG("%s: Auto-CMD23 unavailable\n", mmc_hostname(mmc)); + } + /* * A controller may support 8-bit width, but the board itself * might not have the pins brought out. Boards that support diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 2c3fbc5a4c07..745c42fa41ed 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -25,6 +25,7 @@ */ #define SDHCI_DMA_ADDRESS 0x00 +#define SDHCI_ARGUMENT2 SDHCI_DMA_ADDRESS #define SDHCI_BLOCK_SIZE 0x04 #define SDHCI_MAKE_BLKSZ(dma, blksz) (((dma & 0x7) << 12) | (blksz & 0xFFF)) @@ -37,6 +38,7 @@ #define SDHCI_TRNS_DMA 0x01 #define SDHCI_TRNS_BLK_CNT_EN 0x02 #define SDHCI_TRNS_AUTO_CMD12 0x04 +#define SDHCI_TRNS_AUTO_CMD23 0x08 #define SDHCI_TRNS_READ 0x10 #define SDHCI_TRNS_MULTI 0x20 diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h index 73e27ba51e99..6a68c4eb4e44 100644 --- a/include/linux/mmc/sdhci.h +++ b/include/linux/mmc/sdhci.h @@ -114,6 +114,7 @@ struct sdhci_host { #define SDHCI_SDR50_NEEDS_TUNING (1<<4) /* SDR50 needs tuning */ #define SDHCI_NEEDS_RETUNING (1<<5) /* Host needs retuning */ #define SDHCI_AUTO_CMD12 (1<<6) /* Auto CMD12 support */ +#define SDHCI_AUTO_CMD23 (1<<7) /* Auto CMD23 support */ unsigned int version; /* SDHCI spec. version */ -- cgit From 6dcbbe25dcc9bd2bdeb4f685f8fb874ffc10e6be Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Tue, 24 May 2011 08:31:08 +0000 Subject: net: move is_vlan_dev into public header file (v2) Migrate is_vlan_dev() to if_vlan.h so that core networkig can use it Signed-off-by: Neil Horman CC: davem@davemloft.net CC: bhutchings@solarflare.com Signed-off-by: David S. Miller --- include/linux/if_vlan.h | 5 +++++ net/8021q/vlan.h | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index 290bd8ac94cf..dc01681fbb42 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -110,6 +110,11 @@ static inline void vlan_group_set_device(struct vlan_group *vg, array[vlan_id % VLAN_GROUP_ARRAY_PART_LEN] = dev; } +static inline int is_vlan_dev(struct net_device *dev) +{ + return dev->priv_flags & IFF_802_1Q_VLAN; +} + #define vlan_tx_tag_present(__skb) ((__skb)->vlan_tci & VLAN_TAG_PRESENT) #define vlan_tx_tag_get(__skb) ((__skb)->vlan_tci & ~VLAN_TAG_PRESENT) diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h index c3408def8a19..9da07e30d1a2 100644 --- a/net/8021q/vlan.h +++ b/net/8021q/vlan.h @@ -118,11 +118,6 @@ extern void vlan_netlink_fini(void); extern struct rtnl_link_ops vlan_link_ops; -static inline int is_vlan_dev(struct net_device *dev) -{ - return dev->priv_flags & IFF_802_1Q_VLAN; -} - extern int vlan_net_id; struct proc_dir_entry; -- cgit From f29c50419c8d1998edd759f1990c4243a248f469 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 19 May 2011 14:35:33 -0400 Subject: maccess,probe_kernel: Make write/read src const void * The functions probe_kernel_write() and probe_kernel_read() do not modify the src pointer. Allow const pointers to be passed in without the need of a typecast. Acked-by: Mike Frysinger Acked-by: Heiko Carstens Acked-by: Martin Schwidefsky Signed-off-by: Steven Rostedt Link: http://lkml.kernel.org/r/1305824936.1465.4.camel@gandalf.stny.rr.com --- arch/blackfin/mm/maccess.c | 4 ++-- arch/s390/mm/maccess.c | 4 ++-- include/linux/uaccess.h | 8 ++++---- mm/maccess.c | 8 ++++---- 4 files changed, 12 insertions(+), 12 deletions(-) (limited to 'include/linux') diff --git a/arch/blackfin/mm/maccess.c b/arch/blackfin/mm/maccess.c index b71cebc1f8a3..e2532114c5fd 100644 --- a/arch/blackfin/mm/maccess.c +++ b/arch/blackfin/mm/maccess.c @@ -16,7 +16,7 @@ static int validate_memory_access_address(unsigned long addr, int size) return bfin_mem_access_type(addr, size); } -long probe_kernel_read(void *dst, void *src, size_t size) +long probe_kernel_read(void *dst, const void *src, size_t size) { unsigned long lsrc = (unsigned long)src; int mem_type; @@ -55,7 +55,7 @@ long probe_kernel_read(void *dst, void *src, size_t size) return -EFAULT; } -long probe_kernel_write(void *dst, void *src, size_t size) +long probe_kernel_write(void *dst, const void *src, size_t size) { unsigned long ldst = (unsigned long)dst; int mem_type; diff --git a/arch/s390/mm/maccess.c b/arch/s390/mm/maccess.c index 71a4b0d34be0..51e5cd9b906a 100644 --- a/arch/s390/mm/maccess.c +++ b/arch/s390/mm/maccess.c @@ -19,7 +19,7 @@ * using the stura instruction. * Returns the number of bytes copied or -EFAULT. */ -static long probe_kernel_write_odd(void *dst, void *src, size_t size) +static long probe_kernel_write_odd(void *dst, const void *src, size_t size) { unsigned long count, aligned; int offset, mask; @@ -45,7 +45,7 @@ static long probe_kernel_write_odd(void *dst, void *src, size_t size) return rc ? rc : count; } -long probe_kernel_write(void *dst, void *src, size_t size) +long probe_kernel_write(void *dst, const void *src, size_t size) { long copied = 0; diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h index d512d98dfb7d..5ca0951e1855 100644 --- a/include/linux/uaccess.h +++ b/include/linux/uaccess.h @@ -93,8 +93,8 @@ static inline unsigned long __copy_from_user_nocache(void *to, * Safely read from address @src to the buffer at @dst. If a kernel fault * happens, handle that and return -EFAULT. */ -extern long probe_kernel_read(void *dst, void *src, size_t size); -extern long __probe_kernel_read(void *dst, void *src, size_t size); +extern long probe_kernel_read(void *dst, const void *src, size_t size); +extern long __probe_kernel_read(void *dst, const void *src, size_t size); /* * probe_kernel_write(): safely attempt to write to a location @@ -105,7 +105,7 @@ extern long __probe_kernel_read(void *dst, void *src, size_t size); * Safely write to address @dst from the buffer at @src. If a kernel fault * happens, handle that and return -EFAULT. */ -extern long notrace probe_kernel_write(void *dst, void *src, size_t size); -extern long notrace __probe_kernel_write(void *dst, void *src, size_t size); +extern long notrace probe_kernel_write(void *dst, const void *src, size_t size); +extern long notrace __probe_kernel_write(void *dst, const void *src, size_t size); #endif /* __LINUX_UACCESS_H__ */ diff --git a/mm/maccess.c b/mm/maccess.c index e2b6f5634e0d..4cee182ab5f3 100644 --- a/mm/maccess.c +++ b/mm/maccess.c @@ -15,10 +15,10 @@ * happens, handle that and return -EFAULT. */ -long __weak probe_kernel_read(void *dst, void *src, size_t size) +long __weak probe_kernel_read(void *dst, const void *src, size_t size) __attribute__((alias("__probe_kernel_read"))); -long __probe_kernel_read(void *dst, void *src, size_t size) +long __probe_kernel_read(void *dst, const void *src, size_t size) { long ret; mm_segment_t old_fs = get_fs(); @@ -43,10 +43,10 @@ EXPORT_SYMBOL_GPL(probe_kernel_read); * Safely write to address @dst from the buffer at @src. If a kernel fault * happens, handle that and return -EFAULT. */ -long __weak probe_kernel_write(void *dst, void *src, size_t size) +long __weak probe_kernel_write(void *dst, const void *src, size_t size) __attribute__((alias("__probe_kernel_write"))); -long __probe_kernel_write(void *dst, void *src, size_t size) +long __probe_kernel_write(void *dst, const void *src, size_t size) { long ret; mm_segment_t old_fs = get_fs(); -- cgit From 916f676f8dc016103f983c7ec54c18ecdbb6e349 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Wed, 25 May 2011 09:53:13 -0400 Subject: x86, efi: Retain boot service code until after switching to virtual mode UEFI stands for "Unified Extensible Firmware Interface", where "Firmware" is an ancient African word meaning "Why do something right when you can do it so wrong that children will weep and brave adults will cower before you", and "UEI" is Celtic for "We missed DOS so we burned it into your ROMs". The UEFI specification provides for runtime services (ie, another way for the operating system to be forced to depend on the firmware) and we rely on these for certain trivial tasks such as setting up the bootloader. But some hardware fails to work if we attempt to use these runtime services from physical mode, and so we have to switch into virtual mode. So far so dreadful. The specification makes it clear that the operating system is free to do whatever it wants with boot services code after ExitBootServices() has been called. SetVirtualAddressMap() can't be called until ExitBootServices() has been. So, obviously, a whole bunch of EFI implementations call into boot services code when we do that. Since we've been charmingly naive and trusted that the specification may be somehow relevant to the real world, we've already stuffed a picture of a penguin or something in that address space. And just to make things more entertaining, we've also marked it non-executable. This patch allocates the boot services regions during EFI init and makes sure that they're executable. Then, after SetVirtualAddressMap(), it discards them and everyone lives happily ever after. Except for the ones who have to work on EFI, who live sad lives haunted by the knowledge that someone's eventually going to write yet another firmware specification. [ hpa: adding this to urgent with a stable tag since it fixes currently-broken hardware. However, I do not know what the dependencies are and so I do not know which -stable versions this may be a candidate for. ] Signed-off-by: Matthew Garrett Link: http://lkml.kernel.org/r/1306331593-28715-1-git-send-email-mjg@redhat.com Signed-off-by: H. Peter Anvin Cc: Tony Luck Cc: --- arch/x86/kernel/setup.c | 7 +++++++ arch/x86/platform/efi/efi.c | 45 +++++++++++++++++++++++++++++++++++++++++- arch/x86/platform/efi/efi_64.c | 5 +++-- include/linux/efi.h | 1 + 4 files changed, 55 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 605e5ae19c7f..b9ca498f5602 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -910,6 +910,13 @@ void __init setup_arch(char **cmdline_p) memblock.current_limit = get_max_mapped(); memblock_x86_fill(); + /* + * The EFI specification says that boot service code won't be called + * after ExitBootServices(). This is, in fact, a lie. + */ + if (efi_enabled) + efi_reserve_boot_services(); + /* preallocate 4k for mptable mpc */ early_reserve_e820_mpc_new(); diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index b30aa26a8df2..0d3a4fa34560 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -304,6 +304,40 @@ static void __init print_efi_memmap(void) } #endif /* EFI_DEBUG */ +void __init efi_reserve_boot_services(void) +{ + void *p; + + for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { + efi_memory_desc_t *md = p; + unsigned long long start = md->phys_addr; + unsigned long long size = md->num_pages << EFI_PAGE_SHIFT; + + if (md->type != EFI_BOOT_SERVICES_CODE && + md->type != EFI_BOOT_SERVICES_DATA) + continue; + + memblock_x86_reserve_range(start, start + size, "EFI Boot"); + } +} + +static void __init efi_free_boot_services(void) +{ + void *p; + + for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { + efi_memory_desc_t *md = p; + unsigned long long start = md->phys_addr; + unsigned long long size = md->num_pages << EFI_PAGE_SHIFT; + + if (md->type != EFI_BOOT_SERVICES_CODE && + md->type != EFI_BOOT_SERVICES_DATA) + continue; + + free_bootmem_late(start, size); + } +} + void __init efi_init(void) { efi_config_table_t *config_tables; @@ -536,7 +570,9 @@ void __init efi_enter_virtual_mode(void) for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { md = p; - if (!(md->attribute & EFI_MEMORY_RUNTIME)) + if (!(md->attribute & EFI_MEMORY_RUNTIME) && + md->type != EFI_BOOT_SERVICES_CODE && + md->type != EFI_BOOT_SERVICES_DATA) continue; size = md->num_pages << EFI_PAGE_SHIFT; @@ -592,6 +628,13 @@ void __init efi_enter_virtual_mode(void) panic("EFI call to SetVirtualAddressMap() failed!"); } + /* + * Thankfully, it does seem that no runtime services other than + * SetVirtualAddressMap() will touch boot services code, so we can + * get rid of it all at this point + */ + efi_free_boot_services(); + /* * Now that EFI is in virtual mode, update the function * pointers in the runtime service table to the new virtual addresses. diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index 2649426a7905..ac3aa54e2654 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c @@ -49,10 +49,11 @@ static void __init early_code_mapping_set_exec(int executable) if (!(__supported_pte_mask & _PAGE_NX)) return; - /* Make EFI runtime service code area executable */ + /* Make EFI service code area executable */ for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { md = p; - if (md->type == EFI_RUNTIME_SERVICES_CODE) + if (md->type == EFI_RUNTIME_SERVICES_CODE || + md->type == EFI_BOOT_SERVICES_CODE) efi_set_executable(md, executable); } } diff --git a/include/linux/efi.h b/include/linux/efi.h index 33fa1203024e..e376270cd26e 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -299,6 +299,7 @@ extern void efi_initialize_iomem_resources(struct resource *code_resource, struct resource *data_resource, struct resource *bss_resource); extern unsigned long efi_get_time(void); extern int efi_set_rtc_mmss(unsigned long nowtime); +extern void efi_reserve_boot_services(void); extern struct efi_memory_map memmap; /** -- cgit From 2fc1b6f0d0a719e1e2a30bf076a3a799feaf6af2 Mon Sep 17 00:00:00 2001 From: liubo Date: Tue, 19 Apr 2011 09:35:28 +0800 Subject: tracing: Add __print_symbolic_u64 to avoid warnings on 32bit machine Filesystem, like Btrfs, has some "ULL" macros, and when these macros are passed to tracepoints'__print_symbolic(), there will be 64->32 truncate WARNINGS during compiling on 32bit box. Signed-off-by: Liu Bo Link: http://lkml.kernel.org/r/4DACE6E0.7000507@cn.fujitsu.com Signed-off-by: Steven Rostedt --- include/linux/ftrace_event.h | 12 ++++++++++++ include/trace/ftrace.h | 13 +++++++++++++ kernel/trace/trace_output.c | 27 +++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index b5a550a39a70..59d3ef100eb9 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h @@ -16,6 +16,11 @@ struct trace_print_flags { const char *name; }; +struct trace_print_flags_u64 { + unsigned long long mask; + const char *name; +}; + const char *ftrace_print_flags_seq(struct trace_seq *p, const char *delim, unsigned long flags, const struct trace_print_flags *flag_array); @@ -23,6 +28,13 @@ const char *ftrace_print_flags_seq(struct trace_seq *p, const char *delim, const char *ftrace_print_symbols_seq(struct trace_seq *p, unsigned long val, const struct trace_print_flags *symbol_array); +#if BITS_PER_LONG == 32 +const char *ftrace_print_symbols_seq_u64(struct trace_seq *p, + unsigned long long val, + const struct trace_print_flags_u64 + *symbol_array); +#endif + const char *ftrace_print_hex_seq(struct trace_seq *p, const unsigned char *buf, int len); diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index 3e68366d485a..533c49f48047 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h @@ -205,6 +205,19 @@ ftrace_print_symbols_seq(p, value, symbols); \ }) +#undef __print_symbolic_u64 +#if BITS_PER_LONG == 32 +#define __print_symbolic_u64(value, symbol_array...) \ + ({ \ + static const struct trace_print_flags_u64 symbols[] = \ + { symbol_array, { -1, NULL } }; \ + ftrace_print_symbols_seq_u64(p, value, symbols); \ + }) +#else +#define __print_symbolic_u64(value, symbol_array...) \ + __print_symbolic(value, symbol_array) +#endif + #undef __print_hex #define __print_hex(buf, buf_len) ftrace_print_hex_seq(p, buf, buf_len) diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c index cf535ccedc86..e37de492a9e1 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c @@ -353,6 +353,33 @@ ftrace_print_symbols_seq(struct trace_seq *p, unsigned long val, } EXPORT_SYMBOL(ftrace_print_symbols_seq); +#if BITS_PER_LONG == 32 +const char * +ftrace_print_symbols_seq_u64(struct trace_seq *p, unsigned long long val, + const struct trace_print_flags_u64 *symbol_array) +{ + int i; + const char *ret = p->buffer + p->len; + + for (i = 0; symbol_array[i].name; i++) { + + if (val != symbol_array[i].mask) + continue; + + trace_seq_puts(p, symbol_array[i].name); + break; + } + + if (!p->len) + trace_seq_printf(p, "0x%llx", val); + + trace_seq_putc(p, 0); + + return ret; +} +EXPORT_SYMBOL(ftrace_print_symbols_seq_u64); +#endif + const char * ftrace_print_hex_seq(struct trace_seq *p, const unsigned char *buf, int buf_len) { -- cgit From b1cff0ad1062621ae63cb6c5dc4165191fe2e9f1 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 25 May 2011 14:27:43 -0400 Subject: ftrace: Add internal recursive checks Witold reported a reboot caused by the selftests of the dynamic function tracer. He sent me a config and I used ktest to do a config_bisect on it (as my config did not cause the crash). It pointed out that the problem config was CONFIG_PROVE_RCU. What happened was that if multiple callbacks are attached to the function tracer, we iterate a list of callbacks. Because the list is managed by synchronize_sched() and preempt_disable, the access to the pointers uses rcu_dereference_raw(). When PROVE_RCU is enabled, the rcu_dereference_raw() calls some debugging functions, which happen to be traced. The tracing of the debug function would then call rcu_dereference_raw() which would then call the debug function and then... well you get the idea. I first wrote two different patches to solve this bug. 1) add a __rcu_dereference_raw() that would not do any checks. 2) add notrace to the offending debug functions. Both of these patches worked. Talking with Paul McKenney on IRC, he suggested to add recursion detection instead. This seemed to be a better solution, so I decided to implement it. As the task_struct already has a trace_recursion to detect recursion in the ring buffer, and that has a very small number it allows, I decided to use that same variable to add flags that can detect the recursion inside the infrastructure of the function tracer. I plan to change it so that the task struct bit can be checked in mcount, but as that requires changes to all archs, I will hold that off to the next merge window. Cc: Ingo Molnar Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: Frederic Weisbecker Cc: Paul E. McKenney Link: http://lkml.kernel.org/r/1306348063.1465.116.camel@gandalf.stny.rr.com Reported-by: Witold Baryluk Signed-off-by: Steven Rostedt --- include/linux/sched.h | 2 +- kernel/trace/ftrace.c | 13 ++++++++++++- kernel/trace/ring_buffer.c | 10 +++++----- kernel/trace/trace.h | 15 +++++++++++++++ 4 files changed, 33 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index d8b2d0bec0d8..7b78d9cad471 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1513,7 +1513,7 @@ struct task_struct { #ifdef CONFIG_TRACING /* state flags for use by tracers */ unsigned long trace; - /* bitmask of trace recursion */ + /* bitmask and counter of trace recursion */ unsigned long trace_recursion; #endif /* CONFIG_TRACING */ #ifdef CONFIG_CGROUP_MEM_RES_CTLR /* memcg uses this to do batch job */ diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 25949b33057c..1ee417fcbfa5 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -109,12 +109,18 @@ ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip); static void ftrace_global_list_func(unsigned long ip, unsigned long parent_ip) { - struct ftrace_ops *op = rcu_dereference_raw(ftrace_global_list); /*see above*/ + struct ftrace_ops *op; + + if (unlikely(trace_recursion_test(TRACE_GLOBAL_BIT))) + return; + trace_recursion_set(TRACE_GLOBAL_BIT); + op = rcu_dereference_raw(ftrace_global_list); /*see above*/ while (op != &ftrace_list_end) { op->func(ip, parent_ip); op = rcu_dereference_raw(op->next); /*see above*/ }; + trace_recursion_clear(TRACE_GLOBAL_BIT); } static void ftrace_pid_func(unsigned long ip, unsigned long parent_ip) @@ -3490,6 +3496,10 @@ ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip) { struct ftrace_ops *op; + if (unlikely(trace_recursion_test(TRACE_INTERNAL_BIT))) + return; + + trace_recursion_set(TRACE_INTERNAL_BIT); /* * Some of the ops may be dynamically allocated, * they must be freed after a synchronize_sched(). @@ -3502,6 +3512,7 @@ ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip) op = rcu_dereference_raw(op->next); }; preempt_enable_notrace(); + trace_recursion_clear(TRACE_INTERNAL_BIT); } static void clear_ftrace_swapper(void) diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 0ef7b4b2a1f7..b0c7aa407943 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -2216,7 +2216,7 @@ static noinline void trace_recursive_fail(void) printk_once(KERN_WARNING "Tracing recursion: depth[%ld]:" "HC[%lu]:SC[%lu]:NMI[%lu]\n", - current->trace_recursion, + trace_recursion_buffer(), hardirq_count() >> HARDIRQ_SHIFT, softirq_count() >> SOFTIRQ_SHIFT, in_nmi()); @@ -2226,9 +2226,9 @@ static noinline void trace_recursive_fail(void) static inline int trace_recursive_lock(void) { - current->trace_recursion++; + trace_recursion_inc(); - if (likely(current->trace_recursion < TRACE_RECURSIVE_DEPTH)) + if (likely(trace_recursion_buffer() < TRACE_RECURSIVE_DEPTH)) return 0; trace_recursive_fail(); @@ -2238,9 +2238,9 @@ static inline int trace_recursive_lock(void) static inline void trace_recursive_unlock(void) { - WARN_ON_ONCE(!current->trace_recursion); + WARN_ON_ONCE(!trace_recursion_buffer()); - current->trace_recursion--; + trace_recursion_dec(); } #else diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 6b69c4bd306f..229f8591f61d 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -784,4 +784,19 @@ extern const char *__stop___trace_bprintk_fmt[]; FTRACE_ENTRY(call, struct_name, id, PARAMS(tstruct), PARAMS(print)) #include "trace_entries.h" +/* Only current can touch trace_recursion */ +#define trace_recursion_inc() do { (current)->trace_recursion++; } while (0) +#define trace_recursion_dec() do { (current)->trace_recursion--; } while (0) + +/* Ring buffer has the 10 LSB bits to count */ +#define trace_recursion_buffer() ((current)->trace_recursion & 0x3ff) + +/* for function tracing recursion */ +#define TRACE_INTERNAL_BIT (1<<11) +#define TRACE_GLOBAL_BIT (1<<12) + +#define trace_recursion_set(bit) do { (current)->trace_recursion |= (bit); } while (0) +#define trace_recursion_clear(bit) do { (current)->trace_recursion &= ~(bit); } while (0) +#define trace_recursion_test(bit) ((current)->trace_recursion & (bit)) + #endif /* _LINUX_KERNEL_TRACE_H */ -- cgit From ce2a40458ebf9c2e47fa0806fec31f845bfcb9d5 Mon Sep 17 00:00:00 2001 From: Milton Miller Date: Tue, 10 May 2011 19:29:13 +0000 Subject: Remove unused MSG_ flags in linux/smp.h Now that powerpc has removed its use of MSG_ALL_BUT_SELF and MSG_ALL all these MSG_ flags are unused. Signed-off-by: Milton Miller Signed-off-by: Benjamin Herrenschmidt --- include/linux/smp.h | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'include/linux') diff --git a/include/linux/smp.h b/include/linux/smp.h index 74243c86ba39..7ad824d510a2 100644 --- a/include/linux/smp.h +++ b/include/linux/smp.h @@ -98,16 +98,6 @@ void ipi_call_unlock_irq(void); */ int on_each_cpu(smp_call_func_t func, void *info, int wait); -#define MSG_ALL_BUT_SELF 0x8000 /* Assume <32768 CPU's */ -#define MSG_ALL 0x8001 - -#define MSG_INVALIDATE_TLB 0x0001 /* Remote processor TLB invalidate */ -#define MSG_STOP_CPU 0x0002 /* Sent to shut down slave CPU's - * when rebooting - */ -#define MSG_RESCHEDULE 0x0003 /* Reschedule request from master CPU*/ -#define MSG_CALL_FUNCTION 0x0004 /* Call function on all other CPUs */ - /* * Mark the boot cpu "online" so that it can call console drivers in * printk() and can access its per-cpu storage. -- cgit From 7b7bf499f79de3f6c85a340c8453a78789523f85 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Thu, 19 May 2011 13:21:14 +0100 Subject: ARM: 6913/1: sparsemem: allow pfn_valid to be overridden when using SPARSEMEM In commit eb33575c ("[ARM] Double check memmap is actually valid with a memmap has unexpected holes V2"), a new function, memmap_valid_within, was introduced to mmzone.h so that holes in the memmap which pass pfn_valid in SPARSEMEM configurations can be detected and avoided. The fix to this problem checks that the pfn <-> page linkages are correct by calculating the page for the pfn and then checking that page_to_pfn on that page returns the original pfn. Unfortunately, in SPARSEMEM configurations, this results in reading from the page flags to determine the correct section. Since the memmap here has been freed, junk is read from memory and the check is no longer robust. In the best case, reading from /proc/pagetypeinfo will give you the wrong answer. In the worst case, you get SEGVs, Kernel OOPses and hung CPUs. Furthermore, ioremap implementations that use pfn_valid to disallow the remapping of normal memory will break. This patch allows architectures to provide their own pfn_valid function instead of using the default implementation used by sparsemem. The architecture-specific version is aware of the memmap state and will return false when passed a pfn for a freed page within a valid section. Acked-by: Mel Gorman Acked-by: Catalin Marinas Tested-by: H Hartley Sweeten Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/Kconfig | 3 +++ arch/arm/include/asm/page.h | 2 +- arch/arm/mm/init.c | 4 +++- include/linux/mmzone.h | 2 ++ 4 files changed, 9 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 7275009686e6..5be55d950ab5 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1516,6 +1516,9 @@ config ARCH_SPARSEMEM_DEFAULT config ARCH_SELECT_MEMORY_MODEL def_bool ARCH_SPARSEMEM_ENABLE +config HAVE_ARCH_PFN_VALID + def_bool ARCH_HAS_HOLES_MEMORYMODEL || !SPARSEMEM + config HIGHMEM bool "High Memory Support" depends on MMU diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h index f51a69595f6e..ac75d0848889 100644 --- a/arch/arm/include/asm/page.h +++ b/arch/arm/include/asm/page.h @@ -197,7 +197,7 @@ typedef unsigned long pgprot_t; typedef struct page *pgtable_t; -#ifndef CONFIG_SPARSEMEM +#ifdef CONFIG_HAVE_ARCH_PFN_VALID extern int pfn_valid(unsigned long); #endif diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 3f17ea146f0e..bbc3346e8bcd 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -273,13 +273,15 @@ static void __init arm_bootmem_free(unsigned long min, unsigned long max_low, free_area_init_node(0, zone_size, min, zhole_size); } -#ifndef CONFIG_SPARSEMEM +#ifdef CONFIG_HAVE_ARCH_PFN_VALID int pfn_valid(unsigned long pfn) { return memblock_is_memory(pfn << PAGE_SHIFT); } EXPORT_SYMBOL(pfn_valid); +#endif +#ifndef CONFIG_SPARSEMEM static void arm_memory_present(void) { } diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 217bcf6bca77..261f299c9441 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -1056,12 +1056,14 @@ static inline struct mem_section *__pfn_to_section(unsigned long pfn) return __nr_to_section(pfn_to_section_nr(pfn)); } +#ifndef CONFIG_HAVE_ARCH_PFN_VALID static inline int pfn_valid(unsigned long pfn) { if (pfn_to_section_nr(pfn) >= NR_MEM_SECTIONS) return 0; return valid_section(__nr_to_section(pfn_to_section_nr(pfn))); } +#endif static inline int pfn_present(unsigned long pfn) { -- cgit From 24da4fab5a617ecbf0f0c64e7ba7703383faa411 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 24 May 2011 00:23:34 +0200 Subject: vfs: Create __block_page_mkwrite() helper passing error values back Create __block_page_mkwrite() helper which does all what block_page_mkwrite() does except that it passes back errors from __block_write_begin / block_commit_write calls. Reviewed-by: Christoph Hellwig Signed-off-by: Jan Kara Signed-off-by: Al Viro --- fs/buffer.c | 37 ++++++++++++++++++++----------------- include/linux/buffer_head.h | 14 ++++++++++++++ 2 files changed, 34 insertions(+), 17 deletions(-) (limited to 'include/linux') diff --git a/fs/buffer.c b/fs/buffer.c index a08bb8e61c6f..f6ad8f9b8fa5 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -2332,23 +2332,22 @@ EXPORT_SYMBOL(block_commit_write); * beyond EOF, then the page is guaranteed safe against truncation until we * unlock the page. */ -int -block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, - get_block_t get_block) +int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, + get_block_t get_block) { struct page *page = vmf->page; struct inode *inode = vma->vm_file->f_path.dentry->d_inode; unsigned long end; loff_t size; - int ret = VM_FAULT_NOPAGE; /* make the VM retry the fault */ + int ret; lock_page(page); size = i_size_read(inode); if ((page->mapping != inode->i_mapping) || (page_offset(page) > size)) { - /* page got truncated out from underneath us */ - unlock_page(page); - goto out; + /* We overload EFAULT to mean page got truncated */ + ret = -EFAULT; + goto out_unlock; } /* page is wholly or partially inside EOF */ @@ -2361,18 +2360,22 @@ block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, if (!ret) ret = block_commit_write(page, 0, end); - if (unlikely(ret)) { - unlock_page(page); - if (ret == -ENOMEM) - ret = VM_FAULT_OOM; - else /* -ENOSPC, -EIO, etc */ - ret = VM_FAULT_SIGBUS; - } else - ret = VM_FAULT_LOCKED; - -out: + if (unlikely(ret < 0)) + goto out_unlock; + return 0; +out_unlock: + unlock_page(page); return ret; } +EXPORT_SYMBOL(__block_page_mkwrite); + +int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, + get_block_t get_block) +{ + int ret = __block_page_mkwrite(vma, vmf, get_block); + + return block_page_mkwrite_return(ret); +} EXPORT_SYMBOL(block_page_mkwrite); /* diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h index f5df23561b96..2bf6a9136a94 100644 --- a/include/linux/buffer_head.h +++ b/include/linux/buffer_head.h @@ -217,8 +217,22 @@ int cont_write_begin(struct file *, struct address_space *, loff_t, get_block_t *, loff_t *); int generic_cont_expand_simple(struct inode *inode, loff_t size); int block_commit_write(struct page *page, unsigned from, unsigned to); +int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, + get_block_t get_block); int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, get_block_t get_block); +/* Convert errno to return value from ->page_mkwrite() call */ +static inline int block_page_mkwrite_return(int err) +{ + if (err == 0) + return VM_FAULT_LOCKED; + if (err == -EFAULT) + return VM_FAULT_NOPAGE; + if (err == -ENOMEM) + return VM_FAULT_OOM; + /* -ENOSPC, -EDQUOT, -EIO ... */ + return VM_FAULT_SIGBUS; +} sector_t generic_block_bmap(struct address_space *, sector_t, get_block_t *); int block_truncate_page(struct address_space *, loff_t, get_block_t *); int nobh_write_begin(struct address_space *, loff_t, unsigned, unsigned, -- cgit From ea13a86463fd0c26c2c209c53dc46b8eff81bad4 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 24 May 2011 00:23:35 +0200 Subject: vfs: Block mmapped writes while the fs is frozen We should not allow file modification via mmap while the filesystem is frozen. So block in block_page_mkwrite() while the filesystem is frozen. We cannot do the blocking wait in __block_page_mkwrite() since e.g. ext4 will want to call that function with transaction started in some cases and that would deadlock. But we can at least do the non-blocking reliable check in __block_page_mkwrite() which is the hardest part anyway. We have to check for frozen filesystem with the page marked dirty and under page lock with which we then return from ->page_mkwrite(). Only that way we cannot race with writeback done by freezing code - either we mark the page dirty after the writeback has started, see freezing in progress and block, or writeback will wait for our page lock which is released only when the fault is done and then writeback will writeout and writeprotect the page again. Reviewed-by: Christoph Hellwig Signed-off-by: Jan Kara Signed-off-by: Al Viro --- fs/buffer.c | 24 +++++++++++++++++++++++- include/linux/buffer_head.h | 2 ++ 2 files changed, 25 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/fs/buffer.c b/fs/buffer.c index f6ad8f9b8fa5..b0675bfe8207 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -2331,6 +2331,9 @@ EXPORT_SYMBOL(block_commit_write); * page lock we can determine safely if the page is beyond EOF. If it is not * beyond EOF, then the page is guaranteed safe against truncation until we * unlock the page. + * + * Direct callers of this function should call vfs_check_frozen() so that page + * fault does not busyloop until the fs is thawed. */ int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, get_block_t get_block) @@ -2362,6 +2365,18 @@ int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, if (unlikely(ret < 0)) goto out_unlock; + /* + * Freezing in progress? We check after the page is marked dirty and + * with page lock held so if the test here fails, we are sure freezing + * code will wait during syncing until the page fault is done - at that + * point page will be dirty and unlocked so freezing code will write it + * and writeprotect it again. + */ + set_page_dirty(page); + if (inode->i_sb->s_frozen != SB_UNFROZEN) { + ret = -EAGAIN; + goto out_unlock; + } return 0; out_unlock: unlock_page(page); @@ -2372,8 +2387,15 @@ EXPORT_SYMBOL(__block_page_mkwrite); int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, get_block_t get_block) { - int ret = __block_page_mkwrite(vma, vmf, get_block); + int ret; + struct super_block *sb = vma->vm_file->f_path.dentry->d_inode->i_sb; + /* + * This check is racy but catches the common case. The check in + * __block_page_mkwrite() is reliable. + */ + vfs_check_frozen(sb, SB_FREEZE_WRITE); + ret = __block_page_mkwrite(vma, vmf, get_block); return block_page_mkwrite_return(ret); } EXPORT_SYMBOL(block_page_mkwrite); diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h index 2bf6a9136a94..503c8a6b3079 100644 --- a/include/linux/buffer_head.h +++ b/include/linux/buffer_head.h @@ -230,6 +230,8 @@ static inline int block_page_mkwrite_return(int err) return VM_FAULT_NOPAGE; if (err == -ENOMEM) return VM_FAULT_OOM; + if (err == -EAGAIN) + return VM_FAULT_RETRY; /* -ENOSPC, -EDQUOT, -EIO ... */ return VM_FAULT_SIGBUS; } -- cgit From 9fdfdcf17151e8326c4d18cc133abc6e58f47568 Mon Sep 17 00:00:00 2001 From: Dan Magenheimer Date: Thu, 26 May 2011 10:01:19 -0600 Subject: fs: add field to superblock to support cleancache This second patch of eight in this cleancache series adds a field to the generic superblock to squirrel away a pool identifier that is dynamically provided by cleancache-enabled filesystems at mount time to uniquely identify files and pages belonging to this mounted filesystem. Details and a FAQ can be found in Documentation/vm/cleancache.txt [v8: trivial merge conflict update] Signed-off-by: Dan Magenheimer Reviewed-by: Jeremy Fitzhardinge Reviewed-by: Konrad Rzeszutek Wilk Cc: Andrew Morton Cc: Al Viro Cc: Matthew Wilcox Cc: Nick Piggin Cc: Mel Gorman Cc: Rik Van Riel Cc: Jan Beulich Cc: Chris Mason Cc: Andreas Dilger Cc: Ted Ts'o Cc: Mark Fasheh Cc: Joel Becker Cc: Nitin Gupta --- include/linux/fs.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/fs.h b/include/linux/fs.h index cdf9495df204..0169ed3f106e 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1429,6 +1429,11 @@ struct super_block { */ char __rcu *s_options; const struct dentry_operations *s_d_op; /* default d_op for dentries */ + + /* + * Saved pool identifier for cleancache (-1 means none) + */ + int cleancache_poolid; }; extern struct timespec current_fs_time(struct super_block *sb); -- cgit From 077b1f83a69d94f2918630a882d74939baca0bce Mon Sep 17 00:00:00 2001 From: Dan Magenheimer Date: Thu, 26 May 2011 10:01:36 -0600 Subject: mm: cleancache core ops functions and config This third patch of eight in this cleancache series provides the core code for cleancache that interfaces between the hooks in VFS and individual filesystems and a cleancache backend. It also includes build and config patches. Two new files are added: mm/cleancache.c and include/linux/cleancache.h. Note that CONFIG_CLEANCACHE can default to on; in systems that do not provide a cleancache backend, all hooks devolve to a simple check of a global enable flag, so performance impact should be negligible but can be reduced to zero impact if config'ed off. However for this first commit, it defaults to off. Details and a FAQ can be found in Documentation/vm/cleancache.txt Credits: Cleancache_ops design derived from Jeremy Fitzhardinge design for tmem [v8: dan.magenheimer@oracle.com: fix exportfs call affecting btrfs] [v8: akpm@linux-foundation.org: use static inline function, not macro] [v7: dan.magenheimer@oracle.com: cleanup sysfs and remove cleancache prefix] [v6: JBeulich@novell.com: robustly handle buggy fs encode_fh actor definition] [v5: jeremy@goop.org: clean up global usage and static var names] [v5: jeremy@goop.org: simplify init hook and any future fs init changes] [v5: hch@infradead.org: cleaner non-global interface for ops registration] [v4: adilger@sun.com: interface must support exportfs FS's] [v4: hch@infradead.org: interface must support 64-bit FS on 32-bit kernel] [v3: akpm@linux-foundation.org: use one ops struct to avoid pointer hops] [v3: akpm@linux-foundation.org: document and ensure PageLocked reqts are met] [v3: ngupta@vflare.org: fix success/fail codes, change funcs to void] [v2: viro@ZenIV.linux.org.uk: use sane types] Signed-off-by: Dan Magenheimer Reviewed-by: Jeremy Fitzhardinge Reviewed-by: Konrad Rzeszutek Wilk Acked-by: Al Viro Acked-by: Andrew Morton Acked-by: Nitin Gupta Acked-by: Minchan Kim Acked-by: Andreas Dilger Acked-by: Jan Beulich Cc: Matthew Wilcox Cc: Nick Piggin Cc: Mel Gorman Cc: Rik Van Riel Cc: Chris Mason Cc: Ted Ts'o Cc: Mark Fasheh Cc: Joel Becker --- include/linux/cleancache.h | 122 +++++++++++++++++++++++ mm/Kconfig | 23 +++++ mm/Makefile | 1 + mm/cleancache.c | 244 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 390 insertions(+) create mode 100644 include/linux/cleancache.h create mode 100644 mm/cleancache.c (limited to 'include/linux') diff --git a/include/linux/cleancache.h b/include/linux/cleancache.h new file mode 100644 index 000000000000..04ffb2e6c9d0 --- /dev/null +++ b/include/linux/cleancache.h @@ -0,0 +1,122 @@ +#ifndef _LINUX_CLEANCACHE_H +#define _LINUX_CLEANCACHE_H + +#include +#include +#include + +#define CLEANCACHE_KEY_MAX 6 + +/* + * cleancache requires every file with a page in cleancache to have a + * unique key unless/until the file is removed/truncated. For some + * filesystems, the inode number is unique, but for "modern" filesystems + * an exportable filehandle is required (see exportfs.h) + */ +struct cleancache_filekey { + union { + ino_t ino; + __u32 fh[CLEANCACHE_KEY_MAX]; + u32 key[CLEANCACHE_KEY_MAX]; + } u; +}; + +struct cleancache_ops { + int (*init_fs)(size_t); + int (*init_shared_fs)(char *uuid, size_t); + int (*get_page)(int, struct cleancache_filekey, + pgoff_t, struct page *); + void (*put_page)(int, struct cleancache_filekey, + pgoff_t, struct page *); + void (*flush_page)(int, struct cleancache_filekey, pgoff_t); + void (*flush_inode)(int, struct cleancache_filekey); + void (*flush_fs)(int); +}; + +extern struct cleancache_ops + cleancache_register_ops(struct cleancache_ops *ops); +extern void __cleancache_init_fs(struct super_block *); +extern void __cleancache_init_shared_fs(char *, struct super_block *); +extern int __cleancache_get_page(struct page *); +extern void __cleancache_put_page(struct page *); +extern void __cleancache_flush_page(struct address_space *, struct page *); +extern void __cleancache_flush_inode(struct address_space *); +extern void __cleancache_flush_fs(struct super_block *); +extern int cleancache_enabled; + +#ifdef CONFIG_CLEANCACHE +static inline bool cleancache_fs_enabled(struct page *page) +{ + return page->mapping->host->i_sb->cleancache_poolid >= 0; +} +static inline bool cleancache_fs_enabled_mapping(struct address_space *mapping) +{ + return mapping->host->i_sb->cleancache_poolid >= 0; +} +#else +#define cleancache_enabled (0) +#define cleancache_fs_enabled(_page) (0) +#define cleancache_fs_enabled_mapping(_page) (0) +#endif + +/* + * The shim layer provided by these inline functions allows the compiler + * to reduce all cleancache hooks to nothingness if CONFIG_CLEANCACHE + * is disabled, to a single global variable check if CONFIG_CLEANCACHE + * is enabled but no cleancache "backend" has dynamically enabled it, + * and, for the most frequent cleancache ops, to a single global variable + * check plus a superblock element comparison if CONFIG_CLEANCACHE is enabled + * and a cleancache backend has dynamically enabled cleancache, but the + * filesystem referenced by that cleancache op has not enabled cleancache. + * As a result, CONFIG_CLEANCACHE can be enabled by default with essentially + * no measurable performance impact. + */ + +static inline void cleancache_init_fs(struct super_block *sb) +{ + if (cleancache_enabled) + __cleancache_init_fs(sb); +} + +static inline void cleancache_init_shared_fs(char *uuid, struct super_block *sb) +{ + if (cleancache_enabled) + __cleancache_init_shared_fs(uuid, sb); +} + +static inline int cleancache_get_page(struct page *page) +{ + int ret = -1; + + if (cleancache_enabled && cleancache_fs_enabled(page)) + ret = __cleancache_get_page(page); + return ret; +} + +static inline void cleancache_put_page(struct page *page) +{ + if (cleancache_enabled && cleancache_fs_enabled(page)) + __cleancache_put_page(page); +} + +static inline void cleancache_flush_page(struct address_space *mapping, + struct page *page) +{ + /* careful... page->mapping is NULL sometimes when this is called */ + if (cleancache_enabled && cleancache_fs_enabled_mapping(mapping)) + __cleancache_flush_page(mapping, page); +} + +static inline void cleancache_flush_inode(struct address_space *mapping) +{ + if (cleancache_enabled && cleancache_fs_enabled_mapping(mapping)) + __cleancache_flush_inode(mapping); +} + +static inline void cleancache_flush_fs(struct super_block *sb) +{ + if (cleancache_enabled) + __cleancache_flush_fs(sb); +} + +#endif /* _LINUX_CLEANCACHE_H */ diff --git a/mm/Kconfig b/mm/Kconfig index e9c0c61f2ddd..8ca47a5ee9c8 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -347,3 +347,26 @@ config NEED_PER_CPU_KM depends on !SMP bool default y + +config CLEANCACHE + bool "Enable cleancache driver to cache clean pages if tmem is present" + default n + help + Cleancache can be thought of as a page-granularity victim cache + for clean pages that the kernel's pageframe replacement algorithm + (PFRA) would like to keep around, but can't since there isn't enough + memory. So when the PFRA "evicts" a page, it first attempts to use + cleancacne code to put the data contained in that page into + "transcendent memory", memory that is not directly accessible or + addressable by the kernel and is of unknown and possibly + time-varying size. And when a cleancache-enabled + filesystem wishes to access a page in a file on disk, it first + checks cleancache to see if it already contains it; if it does, + the page is copied into the kernel and a disk access is avoided. + When a transcendent memory driver is available (such as zcache or + Xen transcendent memory), a significant I/O reduction + may be achieved. When none is available, all cleancache calls + are reduced to a single pointer-compare-against-NULL resulting + in a negligible performance hit. + + If unsure, say Y to enable cleancache diff --git a/mm/Makefile b/mm/Makefile index 42a8326c3e3d..836e4163c1bf 100644 --- a/mm/Makefile +++ b/mm/Makefile @@ -49,3 +49,4 @@ obj-$(CONFIG_MEMORY_FAILURE) += memory-failure.o obj-$(CONFIG_HWPOISON_INJECT) += hwpoison-inject.o obj-$(CONFIG_DEBUG_KMEMLEAK) += kmemleak.o obj-$(CONFIG_DEBUG_KMEMLEAK_TEST) += kmemleak-test.o +obj-$(CONFIG_CLEANCACHE) += cleancache.o diff --git a/mm/cleancache.c b/mm/cleancache.c new file mode 100644 index 000000000000..bcaae4c2a770 --- /dev/null +++ b/mm/cleancache.c @@ -0,0 +1,244 @@ +/* + * Cleancache frontend + * + * This code provides the generic "frontend" layer to call a matching + * "backend" driver implementation of cleancache. See + * Documentation/vm/cleancache.txt for more information. + * + * Copyright (C) 2009-2010 Oracle Corp. All rights reserved. + * Author: Dan Magenheimer + * + * This work is licensed under the terms of the GNU GPL, version 2. + */ + +#include +#include +#include +#include +#include + +/* + * This global enablement flag may be read thousands of times per second + * by cleancache_get/put/flush even on systems where cleancache_ops + * is not claimed (e.g. cleancache is config'ed on but remains + * disabled), so is preferred to the slower alternative: a function + * call that checks a non-global. + */ +int cleancache_enabled; +EXPORT_SYMBOL(cleancache_enabled); + +/* + * cleancache_ops is set by cleancache_ops_register to contain the pointers + * to the cleancache "backend" implementation functions. + */ +static struct cleancache_ops cleancache_ops; + +/* useful stats available in /sys/kernel/mm/cleancache */ +static unsigned long cleancache_succ_gets; +static unsigned long cleancache_failed_gets; +static unsigned long cleancache_puts; +static unsigned long cleancache_flushes; + +/* + * register operations for cleancache, returning previous thus allowing + * detection of multiple backends and possible nesting + */ +struct cleancache_ops cleancache_register_ops(struct cleancache_ops *ops) +{ + struct cleancache_ops old = cleancache_ops; + + cleancache_ops = *ops; + cleancache_enabled = 1; + return old; +} +EXPORT_SYMBOL(cleancache_register_ops); + +/* Called by a cleancache-enabled filesystem at time of mount */ +void __cleancache_init_fs(struct super_block *sb) +{ + sb->cleancache_poolid = (*cleancache_ops.init_fs)(PAGE_SIZE); +} +EXPORT_SYMBOL(__cleancache_init_fs); + +/* Called by a cleancache-enabled clustered filesystem at time of mount */ +void __cleancache_init_shared_fs(char *uuid, struct super_block *sb) +{ + sb->cleancache_poolid = + (*cleancache_ops.init_shared_fs)(uuid, PAGE_SIZE); +} +EXPORT_SYMBOL(__cleancache_init_shared_fs); + +/* + * If the filesystem uses exportable filehandles, use the filehandle as + * the key, else use the inode number. + */ +static int cleancache_get_key(struct inode *inode, + struct cleancache_filekey *key) +{ + int (*fhfn)(struct dentry *, __u32 *fh, int *, int); + int len = 0, maxlen = CLEANCACHE_KEY_MAX; + struct super_block *sb = inode->i_sb; + + key->u.ino = inode->i_ino; + if (sb->s_export_op != NULL) { + fhfn = sb->s_export_op->encode_fh; + if (fhfn) { + struct dentry d; + d.d_inode = inode; + len = (*fhfn)(&d, &key->u.fh[0], &maxlen, 0); + if (len <= 0 || len == 255) + return -1; + if (maxlen > CLEANCACHE_KEY_MAX) + return -1; + } + } + return 0; +} + +/* + * "Get" data from cleancache associated with the poolid/inode/index + * that were specified when the data was put to cleanache and, if + * successful, use it to fill the specified page with data and return 0. + * The pageframe is unchanged and returns -1 if the get fails. + * Page must be locked by caller. + */ +int __cleancache_get_page(struct page *page) +{ + int ret = -1; + int pool_id; + struct cleancache_filekey key = { .u.key = { 0 } }; + + VM_BUG_ON(!PageLocked(page)); + pool_id = page->mapping->host->i_sb->cleancache_poolid; + if (pool_id < 0) + goto out; + + if (cleancache_get_key(page->mapping->host, &key) < 0) + goto out; + + ret = (*cleancache_ops.get_page)(pool_id, key, page->index, page); + if (ret == 0) + cleancache_succ_gets++; + else + cleancache_failed_gets++; +out: + return ret; +} +EXPORT_SYMBOL(__cleancache_get_page); + +/* + * "Put" data from a page to cleancache and associate it with the + * (previously-obtained per-filesystem) poolid and the page's, + * inode and page index. Page must be locked. Note that a put_page + * always "succeeds", though a subsequent get_page may succeed or fail. + */ +void __cleancache_put_page(struct page *page) +{ + int pool_id; + struct cleancache_filekey key = { .u.key = { 0 } }; + + VM_BUG_ON(!PageLocked(page)); + pool_id = page->mapping->host->i_sb->cleancache_poolid; + if (pool_id >= 0 && + cleancache_get_key(page->mapping->host, &key) >= 0) { + (*cleancache_ops.put_page)(pool_id, key, page->index, page); + cleancache_puts++; + } +} +EXPORT_SYMBOL(__cleancache_put_page); + +/* + * Flush any data from cleancache associated with the poolid and the + * page's inode and page index so that a subsequent "get" will fail. + */ +void __cleancache_flush_page(struct address_space *mapping, struct page *page) +{ + /* careful... page->mapping is NULL sometimes when this is called */ + int pool_id = mapping->host->i_sb->cleancache_poolid; + struct cleancache_filekey key = { .u.key = { 0 } }; + + if (pool_id >= 0) { + VM_BUG_ON(!PageLocked(page)); + if (cleancache_get_key(mapping->host, &key) >= 0) { + (*cleancache_ops.flush_page)(pool_id, key, page->index); + cleancache_flushes++; + } + } +} +EXPORT_SYMBOL(__cleancache_flush_page); + +/* + * Flush all data from cleancache associated with the poolid and the + * mappings's inode so that all subsequent gets to this poolid/inode + * will fail. + */ +void __cleancache_flush_inode(struct address_space *mapping) +{ + int pool_id = mapping->host->i_sb->cleancache_poolid; + struct cleancache_filekey key = { .u.key = { 0 } }; + + if (pool_id >= 0 && cleancache_get_key(mapping->host, &key) >= 0) + (*cleancache_ops.flush_inode)(pool_id, key); +} +EXPORT_SYMBOL(__cleancache_flush_inode); + +/* + * Called by any cleancache-enabled filesystem at time of unmount; + * note that pool_id is surrendered and may be reutrned by a subsequent + * cleancache_init_fs or cleancache_init_shared_fs + */ +void __cleancache_flush_fs(struct super_block *sb) +{ + if (sb->cleancache_poolid >= 0) { + int old_poolid = sb->cleancache_poolid; + sb->cleancache_poolid = -1; + (*cleancache_ops.flush_fs)(old_poolid); + } +} +EXPORT_SYMBOL(__cleancache_flush_fs); + +#ifdef CONFIG_SYSFS + +/* see Documentation/ABI/xxx/sysfs-kernel-mm-cleancache */ + +#define CLEANCACHE_SYSFS_RO(_name) \ + static ssize_t cleancache_##_name##_show(struct kobject *kobj, \ + struct kobj_attribute *attr, char *buf) \ + { \ + return sprintf(buf, "%lu\n", cleancache_##_name); \ + } \ + static struct kobj_attribute cleancache_##_name##_attr = { \ + .attr = { .name = __stringify(_name), .mode = 0444 }, \ + .show = cleancache_##_name##_show, \ + } + +CLEANCACHE_SYSFS_RO(succ_gets); +CLEANCACHE_SYSFS_RO(failed_gets); +CLEANCACHE_SYSFS_RO(puts); +CLEANCACHE_SYSFS_RO(flushes); + +static struct attribute *cleancache_attrs[] = { + &cleancache_succ_gets_attr.attr, + &cleancache_failed_gets_attr.attr, + &cleancache_puts_attr.attr, + &cleancache_flushes_attr.attr, + NULL, +}; + +static struct attribute_group cleancache_attr_group = { + .attrs = cleancache_attrs, + .name = "cleancache", +}; + +#endif /* CONFIG_SYSFS */ + +static int __init init_cleancache(void) +{ +#ifdef CONFIG_SYSFS + int err; + + err = sysfs_create_group(mm_kobj, &cleancache_attr_group); +#endif /* CONFIG_SYSFS */ + return 0; +} +module_init(init_cleancache) -- cgit From ca16d140af91febe25daeb9e032bf8bd46b8c31f Mon Sep 17 00:00:00 2001 From: KOSAKI Motohiro Date: Thu, 26 May 2011 19:16:19 +0900 Subject: mm: don't access vm_flags as 'int' The type of vma->vm_flags is 'unsigned long'. Neither 'int' nor 'unsigned int'. This patch fixes such misuse. Signed-off-by: KOSAKI Motohiro [ Changed to use a typedef - we'll extend it to cover more cases later, since there has been discussion about making it a 64-bit type.. - Linus ] Signed-off-by: Linus Torvalds --- fs/hugetlbfs/inode.c | 3 ++- fs/proc/task_mmu.c | 2 +- include/linux/hugetlb.h | 6 +++--- include/linux/hugetlb_inline.h | 2 +- include/linux/mm.h | 6 +++--- include/linux/mm_types.h | 4 +++- ipc/shm.c | 2 +- mm/fremap.c | 2 +- mm/hugetlb.c | 4 ++-- mm/memory.c | 2 +- mm/mlock.c | 8 ++++---- mm/mmap.c | 8 ++++---- 12 files changed, 26 insertions(+), 23 deletions(-) (limited to 'include/linux') diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index e7a035781b7d..7aafeb8fa300 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -921,7 +921,8 @@ static int can_do_hugetlb_shm(void) return capable(CAP_IPC_LOCK) || in_group_p(sysctl_hugetlb_shm_group); } -struct file *hugetlb_file_setup(const char *name, size_t size, int acctflag, +struct file *hugetlb_file_setup(const char *name, size_t size, + vm_flags_t acctflag, struct user_struct **user, int creat_flags) { int error = -ENOMEM; diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 2c9db29ea358..db15935fa757 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -211,7 +211,7 @@ static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma) { struct mm_struct *mm = vma->vm_mm; struct file *file = vma->vm_file; - int flags = vma->vm_flags; + vm_flags_t flags = vma->vm_flags; unsigned long ino = 0; unsigned long long pgoff = 0; unsigned long start, end; diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 943c76b3d4bb..cf8931e1dd9d 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -41,7 +41,7 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long address, unsigned int flags); int hugetlb_reserve_pages(struct inode *inode, long from, long to, struct vm_area_struct *vma, - int acctflags); + vm_flags_t vm_flags); void hugetlb_unreserve_pages(struct inode *inode, long offset, long freed); int dequeue_hwpoisoned_huge_page(struct page *page); void copy_huge_page(struct page *dst, struct page *src); @@ -168,7 +168,7 @@ static inline struct hugetlbfs_sb_info *HUGETLBFS_SB(struct super_block *sb) extern const struct file_operations hugetlbfs_file_operations; extern const struct vm_operations_struct hugetlb_vm_ops; -struct file *hugetlb_file_setup(const char *name, size_t size, int acct, +struct file *hugetlb_file_setup(const char *name, size_t size, vm_flags_t acct, struct user_struct **user, int creat_flags); int hugetlb_get_quota(struct address_space *mapping, long delta); void hugetlb_put_quota(struct address_space *mapping, long delta); @@ -192,7 +192,7 @@ static inline void set_file_hugepages(struct file *file) #define is_file_hugepages(file) 0 #define set_file_hugepages(file) BUG() static inline struct file *hugetlb_file_setup(const char *name, size_t size, - int acctflag, struct user_struct **user, int creat_flags) + vm_flags_t acctflag, struct user_struct **user, int creat_flags) { return ERR_PTR(-ENOSYS); } diff --git a/include/linux/hugetlb_inline.h b/include/linux/hugetlb_inline.h index 6931489a5c14..2bb681fbeb35 100644 --- a/include/linux/hugetlb_inline.h +++ b/include/linux/hugetlb_inline.h @@ -7,7 +7,7 @@ static inline int is_vm_hugetlb_page(struct vm_area_struct *vma) { - return vma->vm_flags & VM_HUGETLB; + return !!(vma->vm_flags & VM_HUGETLB); } #else diff --git a/include/linux/mm.h b/include/linux/mm.h index 8eb969ebf904..fb8e814f78dc 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -165,12 +165,12 @@ extern pgprot_t protection_map[16]; */ static inline int is_linear_pfn_mapping(struct vm_area_struct *vma) { - return (vma->vm_flags & VM_PFN_AT_MMAP); + return !!(vma->vm_flags & VM_PFN_AT_MMAP); } static inline int is_pfn_mapping(struct vm_area_struct *vma) { - return (vma->vm_flags & VM_PFNMAP); + return !!(vma->vm_flags & VM_PFNMAP); } /* @@ -1432,7 +1432,7 @@ extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, unsigned long flag, unsigned long pgoff); extern unsigned long mmap_region(struct file *file, unsigned long addr, unsigned long len, unsigned long flags, - unsigned int vm_flags, unsigned long pgoff); + vm_flags_t vm_flags, unsigned long pgoff); static inline unsigned long do_mmap(struct file *file, unsigned long addr, unsigned long len, unsigned long prot, diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 071d459e866b..6fe96c19f85e 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -102,6 +102,8 @@ struct page { #endif }; +typedef unsigned long __nocast vm_flags_t; + /* * A region containing a mapping of a non-memory backed file under NOMMU * conditions. These are held in a global tree and are pinned by the VMAs that @@ -109,7 +111,7 @@ struct page { */ struct vm_region { struct rb_node vm_rb; /* link in global region tree */ - unsigned long vm_flags; /* VMA vm_flags */ + vm_flags_t vm_flags; /* VMA vm_flags */ unsigned long vm_start; /* start address of region */ unsigned long vm_end; /* region initialised to here */ unsigned long vm_top; /* region allocated to here */ diff --git a/ipc/shm.c b/ipc/shm.c index 729acb7e3148..ab3385a21b27 100644 --- a/ipc/shm.c +++ b/ipc/shm.c @@ -347,7 +347,7 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params) struct file * file; char name[13]; int id; - int acctflag = 0; + vm_flags_t acctflag = 0; if (size < SHMMIN || size > ns->shm_ctlmax) return -EINVAL; diff --git a/mm/fremap.c b/mm/fremap.c index 7f4123056e06..b8e0e2d468af 100644 --- a/mm/fremap.c +++ b/mm/fremap.c @@ -224,7 +224,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, /* * drop PG_Mlocked flag for over-mapped range */ - unsigned int saved_flags = vma->vm_flags; + vm_flags_t saved_flags = vma->vm_flags; munlock_vma_pages_range(vma, start, start + size); vma->vm_flags = saved_flags; } diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 5fd68b95c671..f33bb319b73f 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -2833,7 +2833,7 @@ void hugetlb_change_protection(struct vm_area_struct *vma, int hugetlb_reserve_pages(struct inode *inode, long from, long to, struct vm_area_struct *vma, - int acctflag) + vm_flags_t vm_flags) { long ret, chg; struct hstate *h = hstate_inode(inode); @@ -2843,7 +2843,7 @@ int hugetlb_reserve_pages(struct inode *inode, * attempt will be made for VM_NORESERVE to allocate a page * and filesystem quota without using reserves */ - if (acctflag & VM_NORESERVE) + if (vm_flags & VM_NORESERVE) return 0; /* diff --git a/mm/memory.c b/mm/memory.c index b73f677f0bb1..fc24f7d788bd 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -730,7 +730,7 @@ static void print_bad_pte(struct vm_area_struct *vma, unsigned long addr, add_taint(TAINT_BAD_PAGE); } -static inline int is_cow_mapping(unsigned int flags) +static inline int is_cow_mapping(vm_flags_t flags) { return (flags & (VM_SHARED | VM_MAYWRITE)) == VM_MAYWRITE; } diff --git a/mm/mlock.c b/mm/mlock.c index 516b2c2ddd5a..048260c4e02e 100644 --- a/mm/mlock.c +++ b/mm/mlock.c @@ -307,13 +307,13 @@ void munlock_vma_pages_range(struct vm_area_struct *vma, * For vmas that pass the filters, merge/split as appropriate. */ static int mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev, - unsigned long start, unsigned long end, unsigned int newflags) + unsigned long start, unsigned long end, vm_flags_t newflags) { struct mm_struct *mm = vma->vm_mm; pgoff_t pgoff; int nr_pages; int ret = 0; - int lock = newflags & VM_LOCKED; + int lock = !!(newflags & VM_LOCKED); if (newflags == vma->vm_flags || (vma->vm_flags & VM_SPECIAL) || is_vm_hugetlb_page(vma) || vma == get_gate_vma(current->mm)) @@ -385,7 +385,7 @@ static int do_mlock(unsigned long start, size_t len, int on) prev = vma; for (nstart = start ; ; ) { - unsigned int newflags; + vm_flags_t newflags; /* Here we know that vma->vm_start <= nstart < vma->vm_end. */ @@ -524,7 +524,7 @@ static int do_mlockall(int flags) goto out; for (vma = current->mm->mmap; vma ; vma = prev->vm_next) { - unsigned int newflags; + vm_flags_t newflags; newflags = vma->vm_flags | VM_LOCKED; if (!(flags & MCL_CURRENT)) diff --git a/mm/mmap.c b/mm/mmap.c index ac2631b7477f..bbdc9af5e117 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -960,7 +960,7 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, { struct mm_struct * mm = current->mm; struct inode *inode; - unsigned int vm_flags; + vm_flags_t vm_flags; int error; unsigned long reqprot = prot; @@ -1165,7 +1165,7 @@ SYSCALL_DEFINE1(old_mmap, struct mmap_arg_struct __user *, arg) */ int vma_wants_writenotify(struct vm_area_struct *vma) { - unsigned int vm_flags = vma->vm_flags; + vm_flags_t vm_flags = vma->vm_flags; /* If it was private or non-writable, the write bit is already clear */ if ((vm_flags & (VM_WRITE|VM_SHARED)) != ((VM_WRITE|VM_SHARED))) @@ -1193,7 +1193,7 @@ int vma_wants_writenotify(struct vm_area_struct *vma) * We account for memory if it's a private writeable mapping, * not hugepages and VM_NORESERVE wasn't set. */ -static inline int accountable_mapping(struct file *file, unsigned int vm_flags) +static inline int accountable_mapping(struct file *file, vm_flags_t vm_flags) { /* * hugetlb has its own accounting separate from the core VM @@ -1207,7 +1207,7 @@ static inline int accountable_mapping(struct file *file, unsigned int vm_flags) unsigned long mmap_region(struct file *file, unsigned long addr, unsigned long len, unsigned long flags, - unsigned int vm_flags, unsigned long pgoff) + vm_flags_t vm_flags, unsigned long pgoff) { struct mm_struct *mm = current->mm; struct vm_area_struct *vma, *prev; -- cgit From 249ddc79a38a8918ad53ac22606ca8af694344a5 Mon Sep 17 00:00:00 2001 From: Jozsef Kadlecsik Date: Tue, 24 May 2011 10:20:17 +0200 Subject: netfilter: ipset: Use proper timeout value to jiffies conversion Signed-off-by: Jozsef Kadlecsik Signed-off-by: Pablo Neira Ayuso --- include/linux/netfilter/ipset/ip_set_timeout.h | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netfilter/ipset/ip_set_timeout.h b/include/linux/netfilter/ipset/ip_set_timeout.h index 9f30c5f2ec1c..bcdd40ad39ed 100644 --- a/include/linux/netfilter/ipset/ip_set_timeout.h +++ b/include/linux/netfilter/ipset/ip_set_timeout.h @@ -45,7 +45,7 @@ ip_set_timeout_test(unsigned long timeout) { return timeout != IPSET_ELEM_UNSET && (timeout == IPSET_ELEM_PERMANENT || - time_after(timeout, jiffies)); + time_is_after_jiffies(timeout)); } static inline bool @@ -53,7 +53,7 @@ ip_set_timeout_expired(unsigned long timeout) { return timeout != IPSET_ELEM_UNSET && timeout != IPSET_ELEM_PERMANENT && - time_before(timeout, jiffies); + time_is_before_jiffies(timeout); } static inline unsigned long @@ -64,7 +64,7 @@ ip_set_timeout_set(u32 timeout) if (!timeout) return IPSET_ELEM_PERMANENT; - t = timeout * HZ + jiffies; + t = msecs_to_jiffies(timeout * 1000) + jiffies; if (t == IPSET_ELEM_UNSET || t == IPSET_ELEM_PERMANENT) /* Bingo! */ t++; @@ -75,7 +75,8 @@ ip_set_timeout_set(u32 timeout) static inline u32 ip_set_timeout_get(unsigned long timeout) { - return timeout == IPSET_ELEM_PERMANENT ? 0 : (timeout - jiffies)/HZ; + return timeout == IPSET_ELEM_PERMANENT ? 0 : + jiffies_to_msecs(timeout - jiffies)/1000; } #else @@ -89,14 +90,14 @@ static inline bool ip_set_timeout_test(unsigned long timeout) { return timeout == IPSET_ELEM_PERMANENT || - time_after(timeout, jiffies); + time_is_after_jiffies(timeout); } static inline bool ip_set_timeout_expired(unsigned long timeout) { return timeout != IPSET_ELEM_PERMANENT && - time_before(timeout, jiffies); + time_is_before_jiffies(timeout); } static inline unsigned long @@ -107,7 +108,7 @@ ip_set_timeout_set(u32 timeout) if (!timeout) return IPSET_ELEM_PERMANENT; - t = timeout * HZ + jiffies; + t = msecs_to_jiffies(timeout * 1000) + jiffies; if (t == IPSET_ELEM_PERMANENT) /* Bingo! :-) */ t++; @@ -118,7 +119,8 @@ ip_set_timeout_set(u32 timeout) static inline u32 ip_set_timeout_get(unsigned long timeout) { - return timeout == IPSET_ELEM_PERMANENT ? 0 : (timeout - jiffies)/HZ; + return timeout == IPSET_ELEM_PERMANENT ? 0 : + jiffies_to_msecs(timeout - jiffies)/1000; } #endif /* ! IP_SET_BITMAP_TIMEOUT */ -- cgit From b141c242ff978b63cdf0f3d1a767a5152750166b Mon Sep 17 00:00:00 2001 From: Jozsef Kadlecsik Date: Tue, 24 May 2011 10:20:18 +0200 Subject: netfilter: ipset: remove unused variable from type_pf_tdel() Variable 'ret' is set in type_pf_tdel() but not used, remove. Signed-off-by: Jozsef Kadlecsik Signed-off-by: Pablo Neira Ayuso --- include/linux/netfilter/ipset/ip_set_ahash.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netfilter/ipset/ip_set_ahash.h b/include/linux/netfilter/ipset/ip_set_ahash.h index a0196ac79051..ac3c822eb39a 100644 --- a/include/linux/netfilter/ipset/ip_set_ahash.h +++ b/include/linux/netfilter/ipset/ip_set_ahash.h @@ -839,7 +839,7 @@ type_pf_tdel(struct ip_set *set, void *value, u32 timeout) struct htable *t = h->table; const struct type_pf_elem *d = value; struct hbucket *n; - int i, ret = 0; + int i; struct type_pf_elem *data; u32 key; @@ -850,7 +850,7 @@ type_pf_tdel(struct ip_set *set, void *value, u32 timeout) if (!type_pf_data_equal(data, d)) continue; if (type_pf_data_expired(data)) - ret = -IPSET_ERR_EXIST; + return -IPSET_ERR_EXIST; if (i != n->pos - 1) /* Not last one */ type_pf_data_copy(data, ahash_tdata(n, n->pos - 1)); -- cgit From eb8956074e7652e802be5f078080c704c2c87104 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Wed, 6 Apr 2011 16:52:52 +0200 Subject: mfd: Add platform data pointer back Now that we have a way to pass MFD cells down to the sub drivers, we can gradually get rid of mfd_data by putting the platform pointer back in place. Signed-off-by: Samuel Ortiz --- drivers/mfd/mfd-core.c | 7 +++++++ include/linux/mfd/core.h | 4 ++++ 2 files changed, 11 insertions(+) (limited to 'include/linux') diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index f4c8c844b913..0902523af62d 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c @@ -88,6 +88,13 @@ static int mfd_add_device(struct device *parent, int id, pdev->dev.parent = parent; + if (cell->pdata_size) { + ret = platform_device_add_data(pdev, + cell->platform_data, cell->pdata_size); + if (ret) + goto fail_res; + } + ret = mfd_platform_add_cell(pdev, cell); if (ret) goto fail_res; diff --git a/include/linux/mfd/core.h b/include/linux/mfd/core.h index aef23309a742..68c13e52a50c 100644 --- a/include/linux/mfd/core.h +++ b/include/linux/mfd/core.h @@ -36,6 +36,10 @@ struct mfd_cell { /* mfd_data can be used to pass data to client drivers */ void *mfd_data; + /* platform data passed to the sub devices drivers */ + void *platform_data; + size_t pdata_size; + /* * These resources can be specified relative to the parent device. * For accessing hardware you should use resources from the platform dev -- cgit From 1f235a3785dbcfb324ff228048b859a3bd1e1a59 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Wed, 6 Apr 2011 00:20:24 +0200 Subject: mfd: Use mfd cell platform_data for ab3550 cells platform bits With the addition of a platform device mfd_cell pointer, MFD drivers can go back to passing platform data back to their sub drivers. This allows for an mfd_cell->mfd_data removal and thus keep the sub drivers MFD agnostic. This is mostly needed for non MFD aware sub drivers. Acked-by: Linus Walleij Signed-off-by: Samuel Ortiz --- drivers/mfd/ab3550-core.c | 6 ++++-- include/linux/mfd/abx500.h | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/drivers/mfd/ab3550-core.c b/drivers/mfd/ab3550-core.c index ff86acf3e6bd..3d7dce671b93 100644 --- a/drivers/mfd/ab3550-core.c +++ b/drivers/mfd/ab3550-core.c @@ -1320,8 +1320,10 @@ static int __init ab3550_probe(struct i2c_client *client, goto exit_no_ops; /* Set up and register the platform devices. */ - for (i = 0; i < AB3550_NUM_DEVICES; i++) - ab3550_devs[i].mfd_data = ab3550_plf_data->dev_data[i]; + for (i = 0; i < AB3550_NUM_DEVICES; i++) { + ab3550_devs[i].platform_data = ab3550_plf_data->dev_data[i]; + ab3550_devs[i].pdata_size = ab3550_plf_data->dev_data_sz[i]; + } err = mfd_add_devices(&client->dev, 0, ab3550_devs, ARRAY_SIZE(ab3550_devs), NULL, diff --git a/include/linux/mfd/abx500.h b/include/linux/mfd/abx500.h index 7d9b6ae1c203..67bd6f7ecf32 100644 --- a/include/linux/mfd/abx500.h +++ b/include/linux/mfd/abx500.h @@ -186,6 +186,7 @@ struct abx500_init_settings { struct ab3550_platform_data { struct {unsigned int base; unsigned int count; } irq; void *dev_data[AB3550_NUM_DEVICES]; + size_t dev_data_sz[AB3550_NUM_DEVICES]; struct abx500_init_settings *init_settings; unsigned int init_settings_sz; }; -- cgit From ba279f58c6148c1dc76265da98eb292e76c15a32 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Fri, 8 Apr 2011 02:04:50 +0200 Subject: mfd: Remove mfd_data Cell pointers are passed through device->mfd_cell and platform data is passed through the MFD cell platform_data pointer. Signed-off-by: Samuel Ortiz --- include/linux/mfd/core.h | 21 --------------------- 1 file changed, 21 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mfd/core.h b/include/linux/mfd/core.h index 68c13e52a50c..4e76163dd862 100644 --- a/include/linux/mfd/core.h +++ b/include/linux/mfd/core.h @@ -33,9 +33,6 @@ struct mfd_cell { int (*suspend)(struct platform_device *dev); int (*resume)(struct platform_device *dev); - /* mfd_data can be used to pass data to client drivers */ - void *mfd_data; - /* platform data passed to the sub devices drivers */ void *platform_data; size_t pdata_size; @@ -93,24 +90,6 @@ static inline const struct mfd_cell *mfd_get_cell(struct platform_device *pdev) return pdev->mfd_cell; } -/* - * Given a platform device that's been created by mfd_add_devices(), fetch - * the .mfd_data entry from the mfd_cell that created it. - * Otherwise just return the platform_data pointer. - * This maintains compatibility with platform drivers whose devices aren't - * created by the mfd layer, and expect platform_data to contain what would've - * otherwise been in mfd_data. - */ -static inline void *mfd_get_data(struct platform_device *pdev) -{ - const struct mfd_cell *cell = mfd_get_cell(pdev); - - if (cell) - return cell->mfd_data; - else - return pdev->dev.platform_data; -} - extern int mfd_add_devices(struct device *parent, int id, struct mfd_cell *cells, int n_devs, struct resource *mem_base, -- cgit From 8997619a045bef5d138f0f45141a398557f809e6 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 4 Apr 2011 11:04:12 +0900 Subject: mfd: Remove compatibility interface for WM831x specific IRQ API The last user was removed in the merge window. Signed-off-by: Mark Brown Signed-off-by: Samuel Ortiz --- include/linux/mfd/wm831x/core.h | 26 -------------------------- 1 file changed, 26 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mfd/wm831x/core.h b/include/linux/mfd/wm831x/core.h index 903280d21866..0d515ee1c247 100644 --- a/include/linux/mfd/wm831x/core.h +++ b/include/linux/mfd/wm831x/core.h @@ -301,30 +301,4 @@ int wm831x_device_suspend(struct wm831x *wm831x); int wm831x_irq_init(struct wm831x *wm831x, int irq); void wm831x_irq_exit(struct wm831x *wm831x); -static inline int __must_check wm831x_request_irq(struct wm831x *wm831x, - unsigned int irq, - irq_handler_t handler, - unsigned long flags, - const char *name, - void *dev) -{ - return request_threaded_irq(irq, NULL, handler, flags, name, dev); -} - -static inline void wm831x_free_irq(struct wm831x *wm831x, - unsigned int irq, void *dev) -{ - free_irq(irq, dev); -} - -static inline void wm831x_disable_irq(struct wm831x *wm831x, int irq) -{ - disable_irq(irq); -} - -static inline void wm831x_enable_irq(struct wm831x *wm831x, int irq) -{ - enable_irq(irq); -} - #endif -- cgit From 0b14c22ea1e0226d894df76176971d06e8886aa7 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 4 Apr 2011 11:04:42 +0900 Subject: mfd: Provide platform data for WM831x GPIO configuration Allow the GPIO mode of WM831x devices to be configured using platform data. Users may provide a table of GPIO register values in gpio_defaults[]. In order to allow 0 to be set explicitly out of range values are accepted and masked off, with a WM831X_GPIO_CONFIGURE define provided to set an out of range value. This can be used to configure higher numbered GPIOs or override values set in OTP for GPIOs configured using OTP. Signed-off-by: Mark Brown Signed-off-by: Samuel Ortiz --- drivers/mfd/wm831x-core.c | 13 ++++++++++++- include/linux/mfd/wm831x/pdata.h | 4 ++++ 2 files changed, 16 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c index 3fe9a58fe6c7..265f75fc6a25 100644 --- a/drivers/mfd/wm831x-core.c +++ b/drivers/mfd/wm831x-core.c @@ -1442,7 +1442,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) struct wm831x_pdata *pdata = wm831x->dev->platform_data; int rev; enum wm831x_parent parent; - int ret; + int ret, i; mutex_init(&wm831x->io_lock); mutex_init(&wm831x->key_lock); @@ -1581,6 +1581,17 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) } } + if (pdata) { + for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) { + if (!pdata->gpio_defaults[i]) + continue; + + wm831x_reg_write(wm831x, + WM831X_GPIO1_CONTROL + i, + pdata->gpio_defaults[i] & 0xffff); + } + } + ret = wm831x_irq_init(wm831x, irq); if (ret != 0) goto err; diff --git a/include/linux/mfd/wm831x/pdata.h b/include/linux/mfd/wm831x/pdata.h index 632d1567a1b6..ff42d700293f 100644 --- a/include/linux/mfd/wm831x/pdata.h +++ b/include/linux/mfd/wm831x/pdata.h @@ -105,6 +105,9 @@ struct wm831x_watchdog_pdata { #define WM831X_MAX_LDO 11 #define WM831X_MAX_ISINK 2 +#define WM831X_GPIO_CONFIGURE 0x10000 +#define WM831X_GPIO_NUM 16 + struct wm831x_pdata { /** Used to distinguish multiple WM831x chips */ int wm831x_num; @@ -119,6 +122,7 @@ struct wm831x_pdata { int irq_base; int gpio_base; + int gpio_defaults[WM831X_GPIO_NUM]; struct wm831x_backlight_pdata *backlight; struct wm831x_backup_pdata *backup; struct wm831x_battery_pdata *battery; -- cgit From d7ac829fa30d44d6553a0ead41f47bb92ee4d73e Mon Sep 17 00:00:00 2001 From: Lesly A M Date: Thu, 14 Apr 2011 17:57:51 +0530 Subject: mfd: Modifying the twl4030-power macro name Main_Ref to all caps Modifying the macro name Main_Ref to all caps(MAIN_REF). Suggested by Nishanth Menon Signed-off-by: Lesly A M Cc: Nishanth Menon Cc: David Derrick Signed-off-by: Samuel Ortiz --- arch/arm/mach-omap2/board-rx51-peripherals.c | 2 +- drivers/mfd/twl4030-power.c | 2 +- include/linux/i2c/twl.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index bbcb6775a6a3..01ee0a15ef88 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -730,7 +730,7 @@ static struct twl4030_resconfig twl4030_rconfig[] __initdata = { { .resource = RES_RESET, .devgroup = -1, .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1 }, - { .resource = RES_Main_Ref, .devgroup = -1, + { .resource = RES_MAIN_REF, .devgroup = -1, .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1 }, { 0, 0}, diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c index 8373d79323cc..8162e435c9ff 100644 --- a/drivers/mfd/twl4030-power.c +++ b/drivers/mfd/twl4030-power.c @@ -120,7 +120,7 @@ static u8 res_config_addrs[] = { [RES_HFCLKOUT] = 0x8b, [RES_32KCLKOUT] = 0x8e, [RES_RESET] = 0x91, - [RES_Main_Ref] = 0x94, + [RES_MAIN_REF] = 0x94, }; static int __init twl4030_write_script_byte(u8 address, u8 byte) diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h index 0c0d1ae79981..4ebd7c32bc59 100644 --- a/include/linux/i2c/twl.h +++ b/include/linux/i2c/twl.h @@ -501,7 +501,7 @@ static inline int twl6030_mmc_card_detect(struct device *dev, int slot) #define RES_32KCLKOUT 26 #define RES_RESET 27 /* Power Reference */ -#define RES_Main_Ref 28 +#define RES_MAIN_REF 28 #define TOTAL_RESOURCES 28 /* -- cgit From ca972d13382436530896e90591e2793e7a9e7eba Mon Sep 17 00:00:00 2001 From: Lesly A M Date: Thu, 14 Apr 2011 17:57:53 +0530 Subject: mfd: TWL5030 version checking in twl-core Added API to get the TWL5030 Si version from the IDCODE register. It is used for enabling the workaround for TWL erratum 27. Signed-off-by: Lesly A M Cc: Nishanth Menon Cc: David Derrick Signed-off-by: Samuel Ortiz --- drivers/mfd/twl-core.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/i2c/twl.h | 17 +++++++++++++- 2 files changed, 78 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index 960b5bed7f52..2bd9e0676bc2 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c @@ -229,6 +229,9 @@ /* is driver active, bound to a chip? */ static bool inuse; +/* TWL IDCODE Register value */ +static u32 twl_idcode; + static unsigned int twl_id; unsigned int twl_rev(void) { @@ -487,6 +490,58 @@ EXPORT_SYMBOL(twl_i2c_read_u8); /*----------------------------------------------------------------------*/ +/** + * twl_read_idcode_register - API to read the IDCODE register. + * + * Unlocks the IDCODE register and read the 32 bit value. + */ +static int twl_read_idcode_register(void) +{ + int err; + + err = twl_i2c_write_u8(TWL4030_MODULE_INTBR, TWL_EEPROM_R_UNLOCK, + REG_UNLOCK_TEST_REG); + if (err) { + pr_err("TWL4030 Unable to unlock IDCODE registers -%d\n", err); + goto fail; + } + + err = twl_i2c_read(TWL4030_MODULE_INTBR, (u8 *)(&twl_idcode), + REG_IDCODE_7_0, 4); + if (err) { + pr_err("TWL4030: unable to read IDCODE -%d\n", err); + goto fail; + } + + err = twl_i2c_write_u8(TWL4030_MODULE_INTBR, 0x0, REG_UNLOCK_TEST_REG); + if (err) + pr_err("TWL4030 Unable to relock IDCODE registers -%d\n", err); +fail: + return err; +} + +/** + * twl_get_type - API to get TWL Si type. + * + * Api to get the TWL Si type from IDCODE value. + */ +int twl_get_type(void) +{ + return TWL_SIL_TYPE(twl_idcode); +} +EXPORT_SYMBOL_GPL(twl_get_type); + +/** + * twl_get_version - API to get TWL Si version. + * + * Api to get the TWL Si version from IDCODE value. + */ +int twl_get_version(void) +{ + return TWL_SIL_REV(twl_idcode); +} +EXPORT_SYMBOL_GPL(twl_get_version); + static struct device * add_numbered_child(unsigned chip, const char *name, int num, void *pdata, unsigned pdata_len, @@ -1014,6 +1069,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) unsigned i; struct twl4030_platform_data *pdata = client->dev.platform_data; u8 temp; + int ret = 0; if (!pdata) { dev_dbg(&client->dev, "no platform data?\n"); @@ -1060,6 +1116,12 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) /* setup clock framework */ clocks_init(&client->dev, pdata->clock); + /* read TWL IDCODE Register */ + if (twl_id == TWL4030_CLASS_ID) { + ret = twl_read_idcode_register(); + WARN(ret < 0, "Error: reading twl_idcode register value\n"); + } + /* load power event scripts */ if (twl_has_power() && pdata->power) twl4030_power_init(pdata->power); diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h index 4ebd7c32bc59..314218e79c4a 100644 --- a/include/linux/i2c/twl.h +++ b/include/linux/i2c/twl.h @@ -150,7 +150,12 @@ #define MMC_PU (0x1 << 3) #define MMC_PD (0x1 << 2) - +#define TWL_SIL_TYPE(rev) ((rev) & 0x00FFFFFF) +#define TWL_SIL_REV(rev) ((rev) >> 24) +#define TWL_SIL_5030 0x09002F +#define TWL5030_REV_1_0 0x00 +#define TWL5030_REV_1_1 0x10 +#define TWL5030_REV_1_2 0x30 #define TWL4030_CLASS_ID 0x4030 #define TWL6030_CLASS_ID 0x6030 @@ -180,6 +185,9 @@ int twl_i2c_read_u8(u8 mod_no, u8 *val, u8 reg); int twl_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes); int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes); +int twl_get_type(void); +int twl_get_version(void); + int twl6030_interrupt_unmask(u8 bit_mask, u8 offset); int twl6030_interrupt_mask(u8 bit_mask, u8 offset); @@ -279,7 +287,12 @@ static inline int twl6030_mmc_card_detect(struct device *dev, int slot) *(Use TWL_4030_MODULE_INTBR) */ +#define REG_IDCODE_7_0 0x00 +#define REG_IDCODE_15_8 0x01 +#define REG_IDCODE_16_23 0x02 +#define REG_IDCODE_31_24 0x03 #define REG_GPPUPDCTR1 0x0F +#define REG_UNLOCK_TEST_REG 0x12 /*I2C1 and I2C4(SR) SDA/SCL pull-up control bits */ @@ -288,6 +301,8 @@ static inline int twl6030_mmc_card_detect(struct device *dev, int slot) #define SR_I2C_SCL_CTRL_PU BIT(4) #define SR_I2C_SDA_CTRL_PU BIT(6) +#define TWL_EEPROM_R_UNLOCK 0x49 + /*----------------------------------------------------------------------*/ /* -- cgit From cbdb53e1f33baf60ded045dc79cd0dd4e9705fa5 Mon Sep 17 00:00:00 2001 From: Abhijeet Dharmapurikar Date: Tue, 5 Apr 2011 14:40:52 -0700 Subject: mfd: Add Qualcomm PMIC 8921 core driver Add support for the Qualcomm PM8921 PMIC chip. The core driver will communicate with the PMIC chip via the MSM SSBI bus. Signed-off-by: Abhijeet Dharmapurikar Signed-off-by: Samuel Ortiz --- drivers/mfd/Kconfig | 18 +++++ drivers/mfd/Makefile | 1 + drivers/mfd/pm8921-core.c | 158 ++++++++++++++++++++++++++++++++++++++ include/linux/mfd/pm8xxx/core.h | 71 +++++++++++++++++ include/linux/mfd/pm8xxx/pm8921.h | 27 +++++++ 5 files changed, 275 insertions(+) create mode 100644 drivers/mfd/pm8921-core.c create mode 100644 include/linux/mfd/pm8xxx/core.h create mode 100644 include/linux/mfd/pm8xxx/pm8921.h (limited to 'include/linux') diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index ec2da8392466..d42328873dc9 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -691,6 +691,24 @@ config MFD_OMAP_USB_HOST This MFD driver does the required setup functionalities for OMAP USB Host drivers. +config MFD_PM8XXX + tristate + +config MFD_PM8921_CORE + tristate "Qualcomm PM8921 PMIC chip" + depends on MSM_SSBI + select MFD_CORE + select MFD_PM8XXX + help + If you say yes to this option, support will be included for the + built-in PM8921 PMIC chip. + + This is required if your board has a PM8921 and uses its features, + such as: MPPs, GPIOs, regulators, interrupts, and PWM. + + Say M here if you want to include support for PM8921 chip as a module. + This will build a module called "pm8921-core". + endif # MFD_SUPPORT menu "Multimedia Capabilities Port drivers" diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 24aa44448daf..d32a7b8f57f7 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -91,3 +91,4 @@ obj-$(CONFIG_MFD_VX855) += vx855.o obj-$(CONFIG_MFD_WL1273_CORE) += wl1273-core.o obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o +obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o diff --git a/drivers/mfd/pm8921-core.c b/drivers/mfd/pm8921-core.c new file mode 100644 index 000000000000..a2ecd3233b1b --- /dev/null +++ b/drivers/mfd/pm8921-core.c @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2011, Code Aurora Forum. 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. + */ + +#define pr_fmt(fmt) "%s: " fmt, __func__ + +#include +#include +#include +#include +#include +#include +#include + +#define REG_HWREV 0x002 /* PMIC4 revision */ +#define REG_HWREV_2 0x0E8 /* PMIC4 revision 2 */ + +struct pm8921 { + struct device *dev; +}; + +static int pm8921_readb(const struct device *dev, u16 addr, u8 *val) +{ + const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev); + const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data; + + return msm_ssbi_read(pmic->dev->parent, addr, val, 1); +} + +static int pm8921_writeb(const struct device *dev, u16 addr, u8 val) +{ + const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev); + const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data; + + return msm_ssbi_write(pmic->dev->parent, addr, &val, 1); +} + +static int pm8921_read_buf(const struct device *dev, u16 addr, u8 *buf, + int cnt) +{ + const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev); + const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data; + + return msm_ssbi_read(pmic->dev->parent, addr, buf, cnt); +} + +static int pm8921_write_buf(const struct device *dev, u16 addr, u8 *buf, + int cnt) +{ + const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev); + const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data; + + return msm_ssbi_write(pmic->dev->parent, addr, buf, cnt); +} + +static struct pm8xxx_drvdata pm8921_drvdata = { + .pmic_readb = pm8921_readb, + .pmic_writeb = pm8921_writeb, + .pmic_read_buf = pm8921_read_buf, + .pmic_write_buf = pm8921_write_buf, +}; + +static int __devinit pm8921_probe(struct platform_device *pdev) +{ + const struct pm8921_platform_data *pdata = pdev->dev.platform_data; + struct pm8921 *pmic; + int rc; + u8 val; + + if (!pdata) { + pr_err("missing platform data\n"); + return -EINVAL; + } + + pmic = kzalloc(sizeof(struct pm8921), GFP_KERNEL); + if (!pmic) { + pr_err("Cannot alloc pm8921 struct\n"); + return -ENOMEM; + } + + /* Read PMIC chip revision */ + rc = msm_ssbi_read(pdev->dev.parent, REG_HWREV, &val, sizeof(val)); + if (rc) { + pr_err("Failed to read hw rev reg %d:rc=%d\n", REG_HWREV, rc); + goto err_read_rev; + } + pr_info("PMIC revision 1: %02X\n", val); + + /* Read PMIC chip revision 2 */ + rc = msm_ssbi_read(pdev->dev.parent, REG_HWREV_2, &val, sizeof(val)); + if (rc) { + pr_err("Failed to read hw rev 2 reg %d:rc=%d\n", + REG_HWREV_2, rc); + goto err_read_rev; + } + pr_info("PMIC revision 2: %02X\n", val); + + pmic->dev = &pdev->dev; + pm8921_drvdata.pm_chip_data = pmic; + platform_set_drvdata(pdev, &pm8921_drvdata); + + return 0; + +err_read_rev: + kfree(pmic); + return rc; +} + +static int __devexit pm8921_remove(struct platform_device *pdev) +{ + struct pm8xxx_drvdata *drvdata; + struct pm8921 *pmic = NULL; + + drvdata = platform_get_drvdata(pdev); + if (drvdata) + pmic = drvdata->pm_chip_data; + if (pmic) + mfd_remove_devices(pmic->dev); + platform_set_drvdata(pdev, NULL); + kfree(pmic); + + return 0; +} + +static struct platform_driver pm8921_driver = { + .probe = pm8921_probe, + .remove = __devexit_p(pm8921_remove), + .driver = { + .name = "pm8921-core", + .owner = THIS_MODULE, + }, +}; + +static int __init pm8921_init(void) +{ + return platform_driver_register(&pm8921_driver); +} +subsys_initcall(pm8921_init); + +static void __exit pm8921_exit(void) +{ + platform_driver_unregister(&pm8921_driver); +} +module_exit(pm8921_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("PMIC 8921 core driver"); +MODULE_VERSION("1.0"); +MODULE_ALIAS("platform:pm8921-core"); diff --git a/include/linux/mfd/pm8xxx/core.h b/include/linux/mfd/pm8xxx/core.h new file mode 100644 index 000000000000..36ccb33332ed --- /dev/null +++ b/include/linux/mfd/pm8xxx/core.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2011, Code Aurora Forum. 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. + */ +/* + * Qualcomm PMIC 8xxx driver header file + * + */ + +#ifndef __MFD_PM8XXX_CORE_H +#define __MFD_PM8XXX_CORE_H + +#include + +struct pm8xxx_drvdata { + int (*pmic_readb) (const struct device *dev, u16 addr, u8 *val); + int (*pmic_writeb) (const struct device *dev, u16 addr, u8 val); + int (*pmic_read_buf) (const struct device *dev, u16 addr, u8 *buf, + int n); + int (*pmic_write_buf) (const struct device *dev, u16 addr, u8 *buf, + int n); + void *pm_chip_data; +}; + +static inline int pm8xxx_readb(const struct device *dev, u16 addr, u8 *val) +{ + struct pm8xxx_drvdata *dd = dev_get_drvdata(dev); + + if (!dd) + return -EINVAL; + return dd->pmic_readb(dev, addr, val); +} + +static inline int pm8xxx_writeb(const struct device *dev, u16 addr, u8 val) +{ + struct pm8xxx_drvdata *dd = dev_get_drvdata(dev); + + if (!dd) + return -EINVAL; + return dd->pmic_writeb(dev, addr, val); +} + +static inline int pm8xxx_read_buf(const struct device *dev, u16 addr, u8 *buf, + int n) +{ + struct pm8xxx_drvdata *dd = dev_get_drvdata(dev); + + if (!dd) + return -EINVAL; + return dd->pmic_read_buf(dev, addr, buf, n); +} + +static inline int pm8xxx_write_buf(const struct device *dev, u16 addr, u8 *buf, + int n) +{ + struct pm8xxx_drvdata *dd = dev_get_drvdata(dev); + + if (!dd) + return -EINVAL; + return dd->pmic_write_buf(dev, addr, buf, n); +} + +#endif diff --git a/include/linux/mfd/pm8xxx/pm8921.h b/include/linux/mfd/pm8xxx/pm8921.h new file mode 100644 index 000000000000..33fbe9c960a3 --- /dev/null +++ b/include/linux/mfd/pm8xxx/pm8921.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2011, Code Aurora Forum. 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. + */ +/* + * Qualcomm PMIC 8921 driver header file + * + */ + +#ifndef __MFD_PM8921_H +#define __MFD_PM8921_H + +#include + +struct pm8921_platform_data { + int irq_base; +}; + +#endif -- cgit From c013f0a56c56b88ac63c4037f2dfaaf2422fa863 Mon Sep 17 00:00:00 2001 From: Abhijeet Dharmapurikar Date: Tue, 5 Apr 2011 14:40:53 -0700 Subject: mfd: Add pm8xxx irq support Add support for the irq controller in Qualcomm 8xxx pmic. The 8xxx interrupt controller provides control for gpio and mpp configured as interrupts in addition to other subdevice interrupts. The interrupt controller also provides a way to read the real time status of an interrupt. This real time status is the only way one can get the input values of gpio and mpp lines. Signed-off-by: Abhijeet Dharmapurikar Signed-off-by: Samuel Ortiz --- drivers/mfd/Kconfig | 10 + drivers/mfd/Makefile | 1 + drivers/mfd/pm8921-core.c | 54 ++++++ drivers/mfd/pm8xxx-irq.c | 371 ++++++++++++++++++++++++++++++++++++++ include/linux/mfd/pm8xxx/core.h | 10 + include/linux/mfd/pm8xxx/irq.h | 59 ++++++ include/linux/mfd/pm8xxx/pm8921.h | 4 + 7 files changed, 509 insertions(+) create mode 100644 drivers/mfd/pm8xxx-irq.c create mode 100644 include/linux/mfd/pm8xxx/irq.h (limited to 'include/linux') diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index d42328873dc9..8344fc0ab858 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -709,6 +709,16 @@ config MFD_PM8921_CORE Say M here if you want to include support for PM8921 chip as a module. This will build a module called "pm8921-core". +config MFD_PM8XXX_IRQ + bool "Support for Qualcomm PM8xxx IRQ features" + depends on MFD_PM8XXX + default y if MFD_PM8XXX + help + This is the IRQ driver for Qualcomm PM 8xxx PMIC chips. + + This is required to use certain other PM 8xxx features, such as GPIO + and MPP. + endif # MFD_SUPPORT menu "Multimedia Capabilities Port drivers" diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index d32a7b8f57f7..1acb8f29a96c 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -92,3 +92,4 @@ obj-$(CONFIG_MFD_WL1273_CORE) += wl1273-core.o obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o +obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.o diff --git a/drivers/mfd/pm8921-core.c b/drivers/mfd/pm8921-core.c index a2ecd3233b1b..e873b15753d8 100644 --- a/drivers/mfd/pm8921-core.c +++ b/drivers/mfd/pm8921-core.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -26,6 +27,7 @@ struct pm8921 { struct device *dev; + struct pm_irq_chip *irq_chip; }; static int pm8921_readb(const struct device *dev, u16 addr, u8 *val) @@ -62,19 +64,53 @@ static int pm8921_write_buf(const struct device *dev, u16 addr, u8 *buf, return msm_ssbi_write(pmic->dev->parent, addr, buf, cnt); } +static int pm8921_read_irq_stat(const struct device *dev, int irq) +{ + const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev); + const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data; + + return pm8xxx_get_irq_stat(pmic->irq_chip, irq); +} + static struct pm8xxx_drvdata pm8921_drvdata = { .pmic_readb = pm8921_readb, .pmic_writeb = pm8921_writeb, .pmic_read_buf = pm8921_read_buf, .pmic_write_buf = pm8921_write_buf, + .pmic_read_irq_stat = pm8921_read_irq_stat, }; +static int __devinit pm8921_add_subdevices(const struct pm8921_platform_data + *pdata, + struct pm8921 *pmic, + u32 rev) +{ + int ret = 0, irq_base = 0; + struct pm_irq_chip *irq_chip; + + if (pdata->irq_pdata) { + pdata->irq_pdata->irq_cdata.nirqs = PM8921_NR_IRQS; + pdata->irq_pdata->irq_cdata.rev = rev; + irq_base = pdata->irq_pdata->irq_base; + irq_chip = pm8xxx_irq_init(pmic->dev, pdata->irq_pdata); + + if (IS_ERR(irq_chip)) { + pr_err("Failed to init interrupts ret=%ld\n", + PTR_ERR(irq_chip)); + return PTR_ERR(irq_chip); + } + pmic->irq_chip = irq_chip; + } + return ret; +} + static int __devinit pm8921_probe(struct platform_device *pdev) { const struct pm8921_platform_data *pdata = pdev->dev.platform_data; struct pm8921 *pmic; int rc; u8 val; + u32 rev; if (!pdata) { pr_err("missing platform data\n"); @@ -94,6 +130,7 @@ static int __devinit pm8921_probe(struct platform_device *pdev) goto err_read_rev; } pr_info("PMIC revision 1: %02X\n", val); + rev = val; /* Read PMIC chip revision 2 */ rc = msm_ssbi_read(pdev->dev.parent, REG_HWREV_2, &val, sizeof(val)); @@ -103,13 +140,26 @@ static int __devinit pm8921_probe(struct platform_device *pdev) goto err_read_rev; } pr_info("PMIC revision 2: %02X\n", val); + rev |= val << BITS_PER_BYTE; pmic->dev = &pdev->dev; pm8921_drvdata.pm_chip_data = pmic; platform_set_drvdata(pdev, &pm8921_drvdata); + rc = pm8921_add_subdevices(pdata, pmic, rev); + if (rc) { + pr_err("Cannot add subdevices rc=%d\n", rc); + goto err; + } + + /* gpio might not work if no irq device is found */ + WARN_ON(pmic->irq_chip == NULL); + return 0; +err: + mfd_remove_devices(pmic->dev); + platform_set_drvdata(pdev, NULL); err_read_rev: kfree(pmic); return rc; @@ -125,6 +175,10 @@ static int __devexit pm8921_remove(struct platform_device *pdev) pmic = drvdata->pm_chip_data; if (pmic) mfd_remove_devices(pmic->dev); + if (pmic->irq_chip) { + pm8xxx_irq_exit(pmic->irq_chip); + pmic->irq_chip = NULL; + } platform_set_drvdata(pdev, NULL); kfree(pmic); diff --git a/drivers/mfd/pm8xxx-irq.c b/drivers/mfd/pm8xxx-irq.c new file mode 100644 index 000000000000..d452dd013081 --- /dev/null +++ b/drivers/mfd/pm8xxx-irq.c @@ -0,0 +1,371 @@ +/* + * Copyright (c) 2011, Code Aurora Forum. 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. + */ + +#define pr_fmt(fmt) "%s: " fmt, __func__ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* PMIC8xxx IRQ */ + +#define SSBI_REG_ADDR_IRQ_BASE 0x1BB + +#define SSBI_REG_ADDR_IRQ_ROOT (SSBI_REG_ADDR_IRQ_BASE + 0) +#define SSBI_REG_ADDR_IRQ_M_STATUS1 (SSBI_REG_ADDR_IRQ_BASE + 1) +#define SSBI_REG_ADDR_IRQ_M_STATUS2 (SSBI_REG_ADDR_IRQ_BASE + 2) +#define SSBI_REG_ADDR_IRQ_M_STATUS3 (SSBI_REG_ADDR_IRQ_BASE + 3) +#define SSBI_REG_ADDR_IRQ_M_STATUS4 (SSBI_REG_ADDR_IRQ_BASE + 4) +#define SSBI_REG_ADDR_IRQ_BLK_SEL (SSBI_REG_ADDR_IRQ_BASE + 5) +#define SSBI_REG_ADDR_IRQ_IT_STATUS (SSBI_REG_ADDR_IRQ_BASE + 6) +#define SSBI_REG_ADDR_IRQ_CONFIG (SSBI_REG_ADDR_IRQ_BASE + 7) +#define SSBI_REG_ADDR_IRQ_RT_STATUS (SSBI_REG_ADDR_IRQ_BASE + 8) + +#define PM_IRQF_LVL_SEL 0x01 /* level select */ +#define PM_IRQF_MASK_FE 0x02 /* mask falling edge */ +#define PM_IRQF_MASK_RE 0x04 /* mask rising edge */ +#define PM_IRQF_CLR 0x08 /* clear interrupt */ +#define PM_IRQF_BITS_MASK 0x70 +#define PM_IRQF_BITS_SHIFT 4 +#define PM_IRQF_WRITE 0x80 + +#define PM_IRQF_MASK_ALL (PM_IRQF_MASK_FE | \ + PM_IRQF_MASK_RE) + +struct pm_irq_chip { + struct device *dev; + spinlock_t pm_irq_lock; + unsigned int devirq; + unsigned int irq_base; + unsigned int num_irqs; + unsigned int num_blocks; + unsigned int num_masters; + u8 config[0]; +}; + +static int pm8xxx_read_root_irq(const struct pm_irq_chip *chip, u8 *rp) +{ + return pm8xxx_readb(chip->dev, SSBI_REG_ADDR_IRQ_ROOT, rp); +} + +static int pm8xxx_read_master_irq(const struct pm_irq_chip *chip, u8 m, u8 *bp) +{ + return pm8xxx_readb(chip->dev, + SSBI_REG_ADDR_IRQ_M_STATUS1 + m, bp); +} + +static int pm8xxx_read_block_irq(struct pm_irq_chip *chip, u8 bp, u8 *ip) +{ + int rc; + + spin_lock(&chip->pm_irq_lock); + rc = pm8xxx_writeb(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, bp); + if (rc) { + pr_err("Failed Selecting Block %d rc=%d\n", bp, rc); + goto bail; + } + + rc = pm8xxx_readb(chip->dev, SSBI_REG_ADDR_IRQ_IT_STATUS, ip); + if (rc) + pr_err("Failed Reading Status rc=%d\n", rc); +bail: + spin_unlock(&chip->pm_irq_lock); + return rc; +} + +static int pm8xxx_config_irq(struct pm_irq_chip *chip, u8 bp, u8 cp) +{ + int rc; + + spin_lock(&chip->pm_irq_lock); + rc = pm8xxx_writeb(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, bp); + if (rc) { + pr_err("Failed Selecting Block %d rc=%d\n", bp, rc); + goto bail; + } + + cp |= PM_IRQF_WRITE; + rc = pm8xxx_writeb(chip->dev, SSBI_REG_ADDR_IRQ_CONFIG, cp); + if (rc) + pr_err("Failed Configuring IRQ rc=%d\n", rc); +bail: + spin_unlock(&chip->pm_irq_lock); + return rc; +} + +static int pm8xxx_irq_block_handler(struct pm_irq_chip *chip, int block) +{ + int pmirq, irq, i, ret = 0; + u8 bits; + + ret = pm8xxx_read_block_irq(chip, block, &bits); + if (ret) { + pr_err("Failed reading %d block ret=%d", block, ret); + return ret; + } + if (!bits) { + pr_err("block bit set in master but no irqs: %d", block); + return 0; + } + + /* Check IRQ bits */ + for (i = 0; i < 8; i++) { + if (bits & (1 << i)) { + pmirq = block * 8 + i; + irq = pmirq + chip->irq_base; + generic_handle_irq(irq); + } + } + return 0; +} + +static int pm8xxx_irq_master_handler(struct pm_irq_chip *chip, int master) +{ + u8 blockbits; + int block_number, i, ret = 0; + + ret = pm8xxx_read_master_irq(chip, master, &blockbits); + if (ret) { + pr_err("Failed to read master %d ret=%d\n", master, ret); + return ret; + } + if (!blockbits) { + pr_err("master bit set in root but no blocks: %d", master); + return 0; + } + + for (i = 0; i < 8; i++) + if (blockbits & (1 << i)) { + block_number = master * 8 + i; /* block # */ + ret |= pm8xxx_irq_block_handler(chip, block_number); + } + return ret; +} + +static void pm8xxx_irq_handler(unsigned int irq, struct irq_desc *desc) +{ + struct pm_irq_chip *chip = irq_desc_get_handler_data(desc); + struct irq_chip *irq_chip = irq_desc_get_chip(desc); + u8 root; + int i, ret, masters = 0; + + ret = pm8xxx_read_root_irq(chip, &root); + if (ret) { + pr_err("Can't read root status ret=%d\n", ret); + return; + } + + /* on pm8xxx series masters start from bit 1 of the root */ + masters = root >> 1; + + /* Read allowed masters for blocks. */ + for (i = 0; i < chip->num_masters; i++) + if (masters & (1 << i)) + pm8xxx_irq_master_handler(chip, i); + + irq_chip->irq_ack(&desc->irq_data); +} + +static void pm8xxx_irq_mask_ack(struct irq_data *d) +{ + struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d); + unsigned int pmirq = d->irq - chip->irq_base; + int master, irq_bit; + u8 block, config; + + block = pmirq / 8; + master = block / 8; + irq_bit = pmirq % 8; + + config = chip->config[pmirq] | PM_IRQF_MASK_ALL | PM_IRQF_CLR; + pm8xxx_config_irq(chip, block, config); +} + +static void pm8xxx_irq_unmask(struct irq_data *d) +{ + struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d); + unsigned int pmirq = d->irq - chip->irq_base; + int master, irq_bit; + u8 block, config; + + block = pmirq / 8; + master = block / 8; + irq_bit = pmirq % 8; + + config = chip->config[pmirq]; + pm8xxx_config_irq(chip, block, config); +} + +static int pm8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type) +{ + struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d); + unsigned int pmirq = d->irq - chip->irq_base; + int master, irq_bit; + u8 block, config; + + block = pmirq / 8; + master = block / 8; + irq_bit = pmirq % 8; + + chip->config[pmirq] = (irq_bit << PM_IRQF_BITS_SHIFT) + | PM_IRQF_MASK_ALL; + if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) { + if (flow_type & IRQF_TRIGGER_RISING) + chip->config[pmirq] &= ~PM_IRQF_MASK_RE; + if (flow_type & IRQF_TRIGGER_FALLING) + chip->config[pmirq] &= ~PM_IRQF_MASK_FE; + } else { + chip->config[pmirq] |= PM_IRQF_LVL_SEL; + + if (flow_type & IRQF_TRIGGER_HIGH) + chip->config[pmirq] &= ~PM_IRQF_MASK_RE; + else + chip->config[pmirq] &= ~PM_IRQF_MASK_FE; + } + + config = chip->config[pmirq] | PM_IRQF_CLR; + return pm8xxx_config_irq(chip, block, config); +} + +static int pm8xxx_irq_set_wake(struct irq_data *d, unsigned int on) +{ + return 0; +} + +static struct irq_chip pm8xxx_irq_chip = { + .name = "pm8xxx", + .irq_mask_ack = pm8xxx_irq_mask_ack, + .irq_unmask = pm8xxx_irq_unmask, + .irq_set_type = pm8xxx_irq_set_type, + .irq_set_wake = pm8xxx_irq_set_wake, + .flags = IRQCHIP_MASK_ON_SUSPEND, +}; + +/** + * pm8xxx_get_irq_stat - get the status of the irq line + * @chip: pointer to identify a pmic irq controller + * @irq: the irq number + * + * The pm8xxx gpio and mpp rely on the interrupt block to read + * the values on their pins. This function is to facilitate reading + * the status of a gpio or an mpp line. The caller has to convert the + * gpio number to irq number. + * + * RETURNS: + * an int indicating the value read on that line + */ +int pm8xxx_get_irq_stat(struct pm_irq_chip *chip, int irq) +{ + int pmirq, rc; + u8 block, bits, bit; + unsigned long flags; + + if (chip == NULL || irq < chip->irq_base || + irq >= chip->irq_base + chip->num_irqs) + return -EINVAL; + + pmirq = irq - chip->irq_base; + + block = pmirq / 8; + bit = pmirq % 8; + + spin_lock_irqsave(&chip->pm_irq_lock, flags); + + rc = pm8xxx_writeb(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, block); + if (rc) { + pr_err("Failed Selecting block irq=%d pmirq=%d blk=%d rc=%d\n", + irq, pmirq, block, rc); + goto bail_out; + } + + rc = pm8xxx_readb(chip->dev, SSBI_REG_ADDR_IRQ_RT_STATUS, &bits); + if (rc) { + pr_err("Failed Configuring irq=%d pmirq=%d blk=%d rc=%d\n", + irq, pmirq, block, rc); + goto bail_out; + } + + rc = (bits & (1 << bit)) ? 1 : 0; + +bail_out: + spin_unlock_irqrestore(&chip->pm_irq_lock, flags); + + return rc; +} +EXPORT_SYMBOL_GPL(pm8xxx_get_irq_stat); + +struct pm_irq_chip * __devinit pm8xxx_irq_init(struct device *dev, + const struct pm8xxx_irq_platform_data *pdata) +{ + struct pm_irq_chip *chip; + int devirq, rc; + unsigned int pmirq; + + if (!pdata) { + pr_err("No platform data\n"); + return ERR_PTR(-EINVAL); + } + + devirq = pdata->devirq; + if (devirq < 0) { + pr_err("missing devirq\n"); + rc = devirq; + return ERR_PTR(-EINVAL); + } + + chip = kzalloc(sizeof(struct pm_irq_chip) + + sizeof(u8) * pdata->irq_cdata.nirqs, GFP_KERNEL); + if (!chip) { + pr_err("Cannot alloc pm_irq_chip struct\n"); + return ERR_PTR(-EINVAL); + } + + chip->dev = dev; + chip->devirq = devirq; + chip->irq_base = pdata->irq_base; + chip->num_irqs = pdata->irq_cdata.nirqs; + chip->num_blocks = DIV_ROUND_UP(chip->num_irqs, 8); + chip->num_masters = DIV_ROUND_UP(chip->num_blocks, 8); + spin_lock_init(&chip->pm_irq_lock); + + for (pmirq = 0; pmirq < chip->num_irqs; pmirq++) { + irq_set_chip_and_handler(chip->irq_base + pmirq, + &pm8xxx_irq_chip, + handle_level_irq); + irq_set_chip_data(chip->irq_base + pmirq, chip); +#ifdef CONFIG_ARM + set_irq_flags(chip->irq_base + pmirq, IRQF_VALID); +#else + irq_set_noprobe(chip->irq_base + pmirq); +#endif + } + + irq_set_irq_type(devirq, pdata->irq_trigger_flag); + irq_set_handler_data(devirq, chip); + irq_set_chained_handler(devirq, pm8xxx_irq_handler); + set_irq_wake(devirq, 1); + + return chip; +} + +int __devexit pm8xxx_irq_exit(struct pm_irq_chip *chip) +{ + irq_set_chained_handler(chip->devirq, NULL); + kfree(chip); + return 0; +} diff --git a/include/linux/mfd/pm8xxx/core.h b/include/linux/mfd/pm8xxx/core.h index 36ccb33332ed..bd2f4f64e931 100644 --- a/include/linux/mfd/pm8xxx/core.h +++ b/include/linux/mfd/pm8xxx/core.h @@ -27,6 +27,7 @@ struct pm8xxx_drvdata { int n); int (*pmic_write_buf) (const struct device *dev, u16 addr, u8 *buf, int n); + int (*pmic_read_irq_stat) (const struct device *dev, int irq); void *pm_chip_data; }; @@ -68,4 +69,13 @@ static inline int pm8xxx_write_buf(const struct device *dev, u16 addr, u8 *buf, return dd->pmic_write_buf(dev, addr, buf, n); } +static inline int pm8xxx_read_irq_stat(const struct device *dev, int irq) +{ + struct pm8xxx_drvdata *dd = dev_get_drvdata(dev); + + if (!dd) + return -EINVAL; + return dd->pmic_read_irq_stat(dev, irq); +} + #endif diff --git a/include/linux/mfd/pm8xxx/irq.h b/include/linux/mfd/pm8xxx/irq.h new file mode 100644 index 000000000000..4b21769f4483 --- /dev/null +++ b/include/linux/mfd/pm8xxx/irq.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2011, Code Aurora Forum. 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. + */ +/* + * Qualcomm PMIC irq 8xxx driver header file + * + */ + +#ifndef __MFD_PM8XXX_IRQ_H +#define __MFD_PM8XXX_IRQ_H + +#include +#include + +struct pm8xxx_irq_core_data { + u32 rev; + int nirqs; +}; + +struct pm8xxx_irq_platform_data { + int irq_base; + struct pm8xxx_irq_core_data irq_cdata; + int devirq; + int irq_trigger_flag; +}; + +struct pm_irq_chip; + +#ifdef CONFIG_MFD_PM8XXX_IRQ +int pm8xxx_get_irq_stat(struct pm_irq_chip *chip, int irq); +struct pm_irq_chip * __devinit pm8xxx_irq_init(struct device *dev, + const struct pm8xxx_irq_platform_data *pdata); +int __devexit pm8xxx_irq_exit(struct pm_irq_chip *chip); +#else +static inline int pm8xxx_get_irq_stat(struct pm_irq_chip *chip, int irq) +{ + return -ENXIO; +} +static inline struct pm_irq_chip * __devinit pm8xxx_irq_init( + const struct device *dev, + const struct pm8xxx_irq_platform_data *pdata) +{ + return ERR_PTR(-ENXIO); +} +static inline int __devexit pm8xxx_irq_exit(struct pm_irq_chip *chip) +{ + return -ENXIO; +} +#endif /* CONFIG_MFD_PM8XXX_IRQ */ +#endif /* __MFD_PM8XXX_IRQ_H */ diff --git a/include/linux/mfd/pm8xxx/pm8921.h b/include/linux/mfd/pm8xxx/pm8921.h index 33fbe9c960a3..d5517fd32d1b 100644 --- a/include/linux/mfd/pm8xxx/pm8921.h +++ b/include/linux/mfd/pm8xxx/pm8921.h @@ -19,9 +19,13 @@ #define __MFD_PM8921_H #include +#include + +#define PM8921_NR_IRQS 256 struct pm8921_platform_data { int irq_base; + struct pm8xxx_irq_platform_data *irq_pdata; }; #endif -- cgit From 008b30408c40ede5985397e7daac45d30b375a01 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Fri, 6 May 2011 17:21:20 +0800 Subject: mfd: Add rtc support to 88pm860x Enable rtc function in 88pm860x PMIC. Signed-off-by: Haojian Zhuang Cc: Alessandro Zummo Signed-off-by: Samuel Ortiz --- drivers/mfd/88pm860x-core.c | 29 +++ drivers/rtc/Kconfig | 10 + drivers/rtc/Makefile | 1 + drivers/rtc/rtc-88pm860x.c | 427 +++++++++++++++++++++++++++++++++++++++++++ include/linux/mfd/88pm860x.h | 6 + 5 files changed, 473 insertions(+) create mode 100644 drivers/rtc/rtc-88pm860x.c (limited to 'include/linux') diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c index 7ba4aafb051d..f2cac9287756 100644 --- a/drivers/mfd/88pm860x-core.c +++ b/drivers/mfd/88pm860x-core.c @@ -90,6 +90,10 @@ static struct resource charger_resources[] __devinitdata = { {PM8607_IRQ_VCHG, PM8607_IRQ_VCHG, "vchg voltage", IORESOURCE_IRQ,}, }; +static struct resource rtc_resources[] __devinitdata = { + {PM8607_IRQ_RTC, PM8607_IRQ_RTC, "rtc", IORESOURCE_IRQ,}, +}; + static struct mfd_cell bk_devs[] = { {"88pm860x-backlight", 0,}, {"88pm860x-backlight", 1,}, @@ -143,6 +147,10 @@ static struct mfd_cell power_devs[] = { {"88pm860x-charger", -1,}, }; +static struct mfd_cell rtc_devs[] = { + {"88pm860x-rtc", -1,}, +}; + static struct pm860x_backlight_pdata bk_pdata[ARRAY_SIZE(bk_devs)]; static struct pm860x_led_pdata led_pdata[ARRAY_SIZE(led_devs)]; static struct regulator_init_data regulator_pdata[ARRAY_SIZE(regulator_devs)]; @@ -635,6 +643,26 @@ out: return; } +static void __devinit device_rtc_init(struct pm860x_chip *chip, + struct i2c_client *i2c, + struct pm860x_platform_data *pdata) +{ + int ret; + + if ((pdata == NULL)) + return; + + rtc_devs[0].platform_data = pdata->rtc; + rtc_devs[0].pdata_size = sizeof(struct pm860x_rtc_pdata); + rtc_devs[0].num_resources = ARRAY_SIZE(rtc_resources); + rtc_devs[0].resources = &rtc_resources[0]; + ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0], + ARRAY_SIZE(rtc_devs), &rtc_resources[0], + chip->irq_base); + if (ret < 0) + dev_err(chip->dev, "Failed to add rtc subdev\n"); +} + static void __devinit device_touch_init(struct pm860x_chip *chip, struct i2c_client *i2c, struct pm860x_platform_data *pdata) @@ -770,6 +798,7 @@ static void __devinit device_8607_init(struct pm860x_chip *chip, goto out; device_regulator_init(chip, i2c, pdata); + device_rtc_init(chip, i2c, pdata); device_onkey_init(chip, i2c, pdata); device_touch_init(chip, i2c, pdata); device_power_init(chip, i2c, pdata); diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index b8f4e9e66cd5..8e437e2f6281 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -125,6 +125,16 @@ comment "I2C RTC drivers" if I2C +config RTC_DRV_88PM860X + tristate "Marvell 88PM860x" + depends on RTC_CLASS && I2C && MFD_88PM860X + help + If you say yes here you get support for RTC function in Marvell + 88PM860x chips. + + This driver can also be built as a module. If so, the module + will be called rtc-88pm860x. + config RTC_DRV_DS1307 tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSON RX-8025" help diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 9574748d1c73..612f5a88a8ee 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -15,6 +15,7 @@ rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o # Keep the list ordered. +obj-$(CONFIG_RTC_DRV_88PM860X) += rtc-88pm860x.o obj-$(CONFIG_RTC_DRV_AB3100) += rtc-ab3100.o obj-$(CONFIG_RTC_DRV_AB8500) += rtc-ab8500.o obj-$(CONFIG_RTC_DRV_AT32AP700X)+= rtc-at32ap700x.o diff --git a/drivers/rtc/rtc-88pm860x.c b/drivers/rtc/rtc-88pm860x.c new file mode 100644 index 000000000000..64b847b7f970 --- /dev/null +++ b/drivers/rtc/rtc-88pm860x.c @@ -0,0 +1,427 @@ +/* + * Real Time Clock driver for Marvell 88PM860x PMIC + * + * Copyright (c) 2010 Marvell International Ltd. + * Author: Haojian Zhuang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define VRTC_CALIBRATION + +struct pm860x_rtc_info { + struct pm860x_chip *chip; + struct i2c_client *i2c; + struct rtc_device *rtc_dev; + struct device *dev; + struct delayed_work calib_work; + + int irq; + int vrtc; + int (*sync)(unsigned int ticks); +}; + +#define REG_VRTC_MEAS1 0x7D + +#define REG0_ADDR 0xB0 +#define REG1_ADDR 0xB2 +#define REG2_ADDR 0xB4 +#define REG3_ADDR 0xB6 + +#define REG0_DATA 0xB1 +#define REG1_DATA 0xB3 +#define REG2_DATA 0xB5 +#define REG3_DATA 0xB7 + +/* bit definitions of Measurement Enable Register 2 (0x51) */ +#define MEAS2_VRTC (1 << 0) + +/* bit definitions of RTC Register 1 (0xA0) */ +#define ALARM_EN (1 << 3) +#define ALARM_WAKEUP (1 << 4) +#define ALARM (1 << 5) +#define RTC1_USE_XO (1 << 7) + +#define VRTC_CALIB_INTERVAL (HZ * 60 * 10) /* 10 minutes */ + +static irqreturn_t rtc_update_handler(int irq, void *data) +{ + struct pm860x_rtc_info *info = (struct pm860x_rtc_info *)data; + int mask; + + mask = ALARM | ALARM_WAKEUP; + pm860x_set_bits(info->i2c, PM8607_RTC1, mask | ALARM_EN, mask); + rtc_update_irq(info->rtc_dev, 1, RTC_AF); + return IRQ_HANDLED; +} + +static int pm860x_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) +{ + struct pm860x_rtc_info *info = dev_get_drvdata(dev); + + if (enabled) + pm860x_set_bits(info->i2c, PM8607_RTC1, ALARM, ALARM); + else + pm860x_set_bits(info->i2c, PM8607_RTC1, ALARM, 0); + return 0; +} + +/* + * Calculate the next alarm time given the requested alarm time mask + * and the current time. + */ +static void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, + struct rtc_time *alrm) +{ + unsigned long next_time; + unsigned long now_time; + + next->tm_year = now->tm_year; + next->tm_mon = now->tm_mon; + next->tm_mday = now->tm_mday; + next->tm_hour = alrm->tm_hour; + next->tm_min = alrm->tm_min; + next->tm_sec = alrm->tm_sec; + + rtc_tm_to_time(now, &now_time); + rtc_tm_to_time(next, &next_time); + + if (next_time < now_time) { + /* Advance one day */ + next_time += 60 * 60 * 24; + rtc_time_to_tm(next_time, next); + } +} + +static int pm860x_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + struct pm860x_rtc_info *info = dev_get_drvdata(dev); + unsigned char buf[8]; + unsigned long ticks, base, data; + + pm860x_page_bulk_read(info->i2c, REG0_ADDR, 8, buf); + dev_dbg(info->dev, "%x-%x-%x-%x-%x-%x-%x-%x\n", buf[0], buf[1], + buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); + base = (buf[1] << 24) | (buf[3] << 16) | (buf[5] << 8) | buf[7]; + + /* load 32-bit read-only counter */ + pm860x_bulk_read(info->i2c, PM8607_RTC_COUNTER1, 4, buf); + data = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; + ticks = base + data; + dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n", + base, data, ticks); + + rtc_time_to_tm(ticks, tm); + + return 0; +} + +static int pm860x_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + struct pm860x_rtc_info *info = dev_get_drvdata(dev); + unsigned char buf[4]; + unsigned long ticks, base, data; + + if ((tm->tm_year < 70) || (tm->tm_year > 138)) { + dev_dbg(info->dev, "Set time %d out of range. " + "Please set time between 1970 to 2038.\n", + 1900 + tm->tm_year); + return -EINVAL; + } + rtc_tm_to_time(tm, &ticks); + + /* load 32-bit read-only counter */ + pm860x_bulk_read(info->i2c, PM8607_RTC_COUNTER1, 4, buf); + data = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; + base = ticks - data; + dev_dbg(info->dev, "set base:0x%lx, RO count:0x%lx, ticks:0x%lx\n", + base, data, ticks); + + pm860x_page_reg_write(info->i2c, REG0_DATA, (base >> 24) & 0xFF); + pm860x_page_reg_write(info->i2c, REG1_DATA, (base >> 16) & 0xFF); + pm860x_page_reg_write(info->i2c, REG2_DATA, (base >> 8) & 0xFF); + pm860x_page_reg_write(info->i2c, REG3_DATA, base & 0xFF); + + if (info->sync) + info->sync(ticks); + return 0; +} + +static int pm860x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ + struct pm860x_rtc_info *info = dev_get_drvdata(dev); + unsigned char buf[8]; + unsigned long ticks, base, data; + int ret; + + pm860x_page_bulk_read(info->i2c, REG0_ADDR, 8, buf); + dev_dbg(info->dev, "%x-%x-%x-%x-%x-%x-%x-%x\n", buf[0], buf[1], + buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); + base = (buf[1] << 24) | (buf[3] << 16) | (buf[5] << 8) | buf[7]; + + pm860x_bulk_read(info->i2c, PM8607_RTC_EXPIRE1, 4, buf); + data = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; + ticks = base + data; + dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n", + base, data, ticks); + + rtc_time_to_tm(ticks, &alrm->time); + ret = pm860x_reg_read(info->i2c, PM8607_RTC1); + alrm->enabled = (ret & ALARM_EN) ? 1 : 0; + alrm->pending = (ret & (ALARM | ALARM_WAKEUP)) ? 1 : 0; + return 0; +} + +static int pm860x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ + struct pm860x_rtc_info *info = dev_get_drvdata(dev); + struct rtc_time now_tm, alarm_tm; + unsigned long ticks, base, data; + unsigned char buf[8]; + int mask; + + pm860x_set_bits(info->i2c, PM8607_RTC1, ALARM_EN, 0); + + pm860x_page_bulk_read(info->i2c, REG0_ADDR, 8, buf); + dev_dbg(info->dev, "%x-%x-%x-%x-%x-%x-%x-%x\n", buf[0], buf[1], + buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); + base = (buf[1] << 24) | (buf[3] << 16) | (buf[5] << 8) | buf[7]; + + /* load 32-bit read-only counter */ + pm860x_bulk_read(info->i2c, PM8607_RTC_COUNTER1, 4, buf); + data = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; + ticks = base + data; + dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n", + base, data, ticks); + + rtc_time_to_tm(ticks, &now_tm); + rtc_next_alarm_time(&alarm_tm, &now_tm, &alrm->time); + /* get new ticks for alarm in 24 hours */ + rtc_tm_to_time(&alarm_tm, &ticks); + data = ticks - base; + + buf[0] = data & 0xff; + buf[1] = (data >> 8) & 0xff; + buf[2] = (data >> 16) & 0xff; + buf[3] = (data >> 24) & 0xff; + pm860x_bulk_write(info->i2c, PM8607_RTC_EXPIRE1, 4, buf); + if (alrm->enabled) { + mask = ALARM | ALARM_WAKEUP | ALARM_EN; + pm860x_set_bits(info->i2c, PM8607_RTC1, mask, mask); + } else { + mask = ALARM | ALARM_WAKEUP | ALARM_EN; + pm860x_set_bits(info->i2c, PM8607_RTC1, mask, + ALARM | ALARM_WAKEUP); + } + return 0; +} + +static const struct rtc_class_ops pm860x_rtc_ops = { + .read_time = pm860x_rtc_read_time, + .set_time = pm860x_rtc_set_time, + .read_alarm = pm860x_rtc_read_alarm, + .set_alarm = pm860x_rtc_set_alarm, + .alarm_irq_enable = pm860x_rtc_alarm_irq_enable, +}; + +#ifdef VRTC_CALIBRATION +static void calibrate_vrtc_work(struct work_struct *work) +{ + struct pm860x_rtc_info *info = container_of(work, + struct pm860x_rtc_info, calib_work.work); + unsigned char buf[2]; + unsigned int sum, data, mean, vrtc_set; + int i; + + for (i = 0, sum = 0; i < 16; i++) { + msleep(100); + pm860x_bulk_read(info->i2c, REG_VRTC_MEAS1, 2, buf); + data = (buf[0] << 4) | buf[1]; + data = (data * 5400) >> 12; /* convert to mv */ + sum += data; + } + mean = sum >> 4; + vrtc_set = 2700 + (info->vrtc & 0x3) * 200; + dev_dbg(info->dev, "mean:%d, vrtc_set:%d\n", mean, vrtc_set); + + sum = pm860x_reg_read(info->i2c, PM8607_RTC_MISC1); + data = sum & 0x3; + if ((mean + 200) < vrtc_set) { + /* try higher voltage */ + if (++data == 4) + goto out; + data = (sum & 0xf8) | (data & 0x3); + pm860x_reg_write(info->i2c, PM8607_RTC_MISC1, data); + } else if ((mean - 200) > vrtc_set) { + /* try lower voltage */ + if (data-- == 0) + goto out; + data = (sum & 0xf8) | (data & 0x3); + pm860x_reg_write(info->i2c, PM8607_RTC_MISC1, data); + } else + goto out; + dev_dbg(info->dev, "set 0x%x to RTC_MISC1\n", data); + /* trigger next calibration since VRTC is updated */ + schedule_delayed_work(&info->calib_work, VRTC_CALIB_INTERVAL); + return; +out: + /* disable measurement */ + pm860x_set_bits(info->i2c, PM8607_MEAS_EN2, MEAS2_VRTC, 0); + dev_dbg(info->dev, "finish VRTC calibration\n"); + return; +} +#endif + +static int __devinit pm860x_rtc_probe(struct platform_device *pdev) +{ + struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); + struct pm860x_rtc_pdata *pdata = NULL; + struct pm860x_rtc_info *info; + struct rtc_time tm; + unsigned long ticks = 0; + int ret; + + pdata = pdev->dev.platform_data; + if (pdata == NULL) + dev_warn(&pdev->dev, "No platform data!\n"); + + info = kzalloc(sizeof(struct pm860x_rtc_info), GFP_KERNEL); + if (!info) + return -ENOMEM; + info->irq = platform_get_irq(pdev, 0); + if (info->irq < 0) { + dev_err(&pdev->dev, "No IRQ resource!\n"); + ret = -EINVAL; + goto out; + } + + info->chip = chip; + info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; + info->dev = &pdev->dev; + dev_set_drvdata(&pdev->dev, info); + + ret = request_threaded_irq(info->irq, NULL, rtc_update_handler, + IRQF_ONESHOT, "rtc", info); + if (ret < 0) { + dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", + info->irq, ret); + goto out; + } + + /* set addresses of 32-bit base value for RTC time */ + pm860x_page_reg_write(info->i2c, REG0_ADDR, REG0_DATA); + pm860x_page_reg_write(info->i2c, REG1_ADDR, REG1_DATA); + pm860x_page_reg_write(info->i2c, REG2_ADDR, REG2_DATA); + pm860x_page_reg_write(info->i2c, REG3_ADDR, REG3_DATA); + + ret = pm860x_rtc_read_time(&pdev->dev, &tm); + if (ret < 0) { + dev_err(&pdev->dev, "Failed to read initial time.\n"); + goto out_rtc; + } + if ((tm.tm_year < 70) || (tm.tm_year > 138)) { + tm.tm_year = 70; + tm.tm_mon = 0; + tm.tm_mday = 1; + tm.tm_hour = 0; + tm.tm_min = 0; + tm.tm_sec = 0; + ret = pm860x_rtc_set_time(&pdev->dev, &tm); + if (ret < 0) { + dev_err(&pdev->dev, "Failed to set initial time.\n"); + goto out_rtc; + } + } + rtc_tm_to_time(&tm, &ticks); + if (pdata && pdata->sync) { + pdata->sync(ticks); + info->sync = pdata->sync; + } + + info->rtc_dev = rtc_device_register("88pm860x-rtc", &pdev->dev, + &pm860x_rtc_ops, THIS_MODULE); + ret = PTR_ERR(info->rtc_dev); + if (IS_ERR(info->rtc_dev)) { + dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret); + goto out_rtc; + } + + /* + * enable internal XO instead of internal 3.25MHz clock since it can + * free running in PMIC power-down state. + */ + pm860x_set_bits(info->i2c, PM8607_RTC1, RTC1_USE_XO, RTC1_USE_XO); + +#ifdef VRTC_CALIBRATION + /* <00> -- 2.7V, <01> -- 2.9V, <10> -- 3.1V, <11> -- 3.3V */ + if (pdata && pdata->vrtc) + info->vrtc = pdata->vrtc & 0x3; + else + info->vrtc = 1; + pm860x_set_bits(info->i2c, PM8607_MEAS_EN2, MEAS2_VRTC, MEAS2_VRTC); + + /* calibrate VRTC */ + INIT_DELAYED_WORK(&info->calib_work, calibrate_vrtc_work); + schedule_delayed_work(&info->calib_work, VRTC_CALIB_INTERVAL); +#endif /* VRTC_CALIBRATION */ + return 0; +out_rtc: + free_irq(info->irq, info); +out: + kfree(info); + return ret; +} + +static int __devexit pm860x_rtc_remove(struct platform_device *pdev) +{ + struct pm860x_rtc_info *info = platform_get_drvdata(pdev); + +#ifdef VRTC_CALIBRATION + flush_scheduled_work(); + /* disable measurement */ + pm860x_set_bits(info->i2c, PM8607_MEAS_EN2, MEAS2_VRTC, 0); +#endif /* VRTC_CALIBRATION */ + + platform_set_drvdata(pdev, NULL); + rtc_device_unregister(info->rtc_dev); + free_irq(info->irq, info); + kfree(info); + return 0; +} + +static struct platform_driver pm860x_rtc_driver = { + .driver = { + .name = "88pm860x-rtc", + .owner = THIS_MODULE, + }, + .probe = pm860x_rtc_probe, + .remove = __devexit_p(pm860x_rtc_remove), +}; + +static int __init pm860x_rtc_init(void) +{ + return platform_driver_register(&pm860x_rtc_driver); +} +module_init(pm860x_rtc_init); + +static void __exit pm860x_rtc_exit(void) +{ + platform_driver_unregister(&pm860x_rtc_driver); +} +module_exit(pm860x_rtc_exit); + +MODULE_DESCRIPTION("Marvell 88PM860x RTC driver"); +MODULE_AUTHOR("Haojian Zhuang "); +MODULE_LICENSE("GPL"); diff --git a/include/linux/mfd/88pm860x.h b/include/linux/mfd/88pm860x.h index 8fba7972ff5f..63b4fb8e3b6f 100644 --- a/include/linux/mfd/88pm860x.h +++ b/include/linux/mfd/88pm860x.h @@ -330,6 +330,11 @@ struct pm860x_led_pdata { unsigned long flags; }; +struct pm860x_rtc_pdata { + int (*sync)(unsigned int ticks); + int vrtc; +}; + struct pm860x_touch_pdata { int gpadc_prebias; int slot_cycle; @@ -349,6 +354,7 @@ struct pm860x_power_pdata { struct pm860x_platform_data { struct pm860x_backlight_pdata *backlight; struct pm860x_led_pdata *led; + struct pm860x_rtc_pdata *rtc; struct pm860x_touch_pdata *touch; struct pm860x_power_pdata *power; struct regulator_init_data *regulator; -- cgit From 521d8ec3f0d8069bea3b3afa70f487cdb5118018 Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Thu, 12 May 2011 14:27:55 +0100 Subject: mfd: Add phoenix lite (twl6025) support to twl6030 Phoenix Lite is based on the twl6030 family of PMICs. It has mostly the same feature set of twl6030 but with small changes. The codec block has also been removed. It also has a new charger block and new features in its ADC block. VUSB handling also differs. Signed-off-by: Graeme Gregory Reviewed-by: Mark Brown Signed-off-by: Samuel Ortiz --- drivers/mfd/twl-core.c | 190 ++++++++++++++++++++++++++++++++++++++---------- include/linux/i2c/twl.h | 34 +++++++++ 2 files changed, 187 insertions(+), 37 deletions(-) (limited to 'include/linux') diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index 2bd9e0676bc2..b8f2a4e7f6e7 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c @@ -198,6 +198,7 @@ #define TWL6030_BASEADD_GASGAUGE 0x00C0 #define TWL6030_BASEADD_PIH 0x00D0 #define TWL6030_BASEADD_CHARGER 0x00E0 +#define TWL6025_BASEADD_CHARGER 0x00DA /* subchip/slave 2 0x4A - DFT */ #define TWL6030_BASEADD_DIEID 0x00C0 @@ -331,6 +332,7 @@ static struct twl_mapping twl6030_map[] = { { SUB_CHIP_ID0, TWL6030_BASEADD_RTC }, { SUB_CHIP_ID0, TWL6030_BASEADD_MEM }, + { SUB_CHIP_ID1, TWL6025_BASEADD_CHARGER }, }; /*----------------------------------------------------------------------*/ @@ -604,7 +606,7 @@ static inline struct device *add_child(unsigned chip, const char *name, static struct device * add_regulator_linked(int num, struct regulator_init_data *pdata, struct regulator_consumer_supply *consumers, - unsigned num_consumers) + unsigned num_consumers, unsigned long features) { unsigned sub_chip_id; /* regulator framework demands init_data ... */ @@ -616,6 +618,8 @@ add_regulator_linked(int num, struct regulator_init_data *pdata, pdata->num_consumer_supplies = num_consumers; } + pdata->driver_data = (void *)features; + /* NOTE: we currently ignore regulator IRQs, e.g. for short circuits */ sub_chip_id = twl_map[TWL_MODULE_PM_MASTER].sid; return add_numbered_child(sub_chip_id, "twl_reg", num, @@ -623,9 +627,10 @@ add_regulator_linked(int num, struct regulator_init_data *pdata, } static struct device * -add_regulator(int num, struct regulator_init_data *pdata) +add_regulator(int num, struct regulator_init_data *pdata, + unsigned long features) { - return add_regulator_linked(num, pdata, NULL, 0); + return add_regulator_linked(num, pdata, NULL, 0, features); } /* @@ -705,17 +710,20 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) }; child = add_regulator_linked(TWL4030_REG_VUSB1V5, - &usb_fixed, &usb1v5, 1); + &usb_fixed, &usb1v5, 1, + features); if (IS_ERR(child)) return PTR_ERR(child); child = add_regulator_linked(TWL4030_REG_VUSB1V8, - &usb_fixed, &usb1v8, 1); + &usb_fixed, &usb1v8, 1, + features); if (IS_ERR(child)) return PTR_ERR(child); child = add_regulator_linked(TWL4030_REG_VUSB3V1, - &usb_fixed, &usb3v1, 1); + &usb_fixed, &usb3v1, 1, + features); if (IS_ERR(child)) return PTR_ERR(child); @@ -740,9 +748,8 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) } if (twl_has_usb() && pdata->usb && twl_class_is_6030()) { - static struct regulator_consumer_supply usb3v3 = { - .supply = "vusb", - }; + static struct regulator_consumer_supply usb3v3; + int regulator; if (twl_has_regulator()) { /* this is a template that gets copied */ @@ -755,12 +762,22 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) | REGULATOR_CHANGE_STATUS, }; - child = add_regulator_linked(TWL6030_REG_VUSB, - &usb_fixed, &usb3v3, 1); + if (features & TWL6025_SUBCLASS) { + usb3v3.supply = "ldousb"; + regulator = TWL6025_REG_LDOUSB; + } else { + usb3v3.supply = "vusb"; + regulator = TWL6030_REG_VUSB; + } + child = add_regulator_linked(regulator, &usb_fixed, + &usb3v3, 1, + features); if (IS_ERR(child)) return PTR_ERR(child); } + pdata->usb->features = features; + child = add_child(0, "twl6030_usb", pdata->usb, sizeof(*pdata->usb), true, @@ -773,7 +790,16 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) /* we need to connect regulators to this transceiver */ if (twl_has_regulator() && child) usb3v3.dev = child; + } else if (twl_has_regulator() && twl_class_is_6030()) { + if (features & TWL6025_SUBCLASS) + child = add_regulator(TWL6025_REG_LDOUSB, + pdata->ldousb, features); + else + child = add_regulator(TWL6030_REG_VUSB, + pdata->vusb, features); + if (IS_ERR(child)) + return PTR_ERR(child); } if (twl_has_watchdog() && twl_class_is_4030()) { @@ -810,46 +836,55 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) /* twl4030 regulators */ if (twl_has_regulator() && twl_class_is_4030()) { - child = add_regulator(TWL4030_REG_VPLL1, pdata->vpll1); + child = add_regulator(TWL4030_REG_VPLL1, pdata->vpll1, + features); if (IS_ERR(child)) return PTR_ERR(child); - child = add_regulator(TWL4030_REG_VIO, pdata->vio); + child = add_regulator(TWL4030_REG_VIO, pdata->vio, + features); if (IS_ERR(child)) return PTR_ERR(child); - child = add_regulator(TWL4030_REG_VDD1, pdata->vdd1); + child = add_regulator(TWL4030_REG_VDD1, pdata->vdd1, + features); if (IS_ERR(child)) return PTR_ERR(child); - child = add_regulator(TWL4030_REG_VDD2, pdata->vdd2); + child = add_regulator(TWL4030_REG_VDD2, pdata->vdd2, + features); if (IS_ERR(child)) return PTR_ERR(child); - child = add_regulator(TWL4030_REG_VMMC1, pdata->vmmc1); + child = add_regulator(TWL4030_REG_VMMC1, pdata->vmmc1, + features); if (IS_ERR(child)) return PTR_ERR(child); - child = add_regulator(TWL4030_REG_VDAC, pdata->vdac); + child = add_regulator(TWL4030_REG_VDAC, pdata->vdac, + features); if (IS_ERR(child)) return PTR_ERR(child); child = add_regulator((features & TWL4030_VAUX2) ? TWL4030_REG_VAUX2_4030 : TWL4030_REG_VAUX2, - pdata->vaux2); + pdata->vaux2, features); if (IS_ERR(child)) return PTR_ERR(child); - child = add_regulator(TWL4030_REG_VINTANA1, pdata->vintana1); + child = add_regulator(TWL4030_REG_VINTANA1, pdata->vintana1, + features); if (IS_ERR(child)) return PTR_ERR(child); - child = add_regulator(TWL4030_REG_VINTANA2, pdata->vintana2); + child = add_regulator(TWL4030_REG_VINTANA2, pdata->vintana2, + features); if (IS_ERR(child)) return PTR_ERR(child); - child = add_regulator(TWL4030_REG_VINTDIG, pdata->vintdig); + child = add_regulator(TWL4030_REG_VINTDIG, pdata->vintdig, + features); if (IS_ERR(child)) return PTR_ERR(child); } @@ -857,72 +892,152 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) /* maybe add LDOs that are omitted on cost-reduced parts */ if (twl_has_regulator() && !(features & TPS_SUBSET) && twl_class_is_4030()) { - child = add_regulator(TWL4030_REG_VPLL2, pdata->vpll2); + child = add_regulator(TWL4030_REG_VPLL2, pdata->vpll2, + features); if (IS_ERR(child)) return PTR_ERR(child); - child = add_regulator(TWL4030_REG_VMMC2, pdata->vmmc2); + child = add_regulator(TWL4030_REG_VMMC2, pdata->vmmc2, + features); if (IS_ERR(child)) return PTR_ERR(child); - child = add_regulator(TWL4030_REG_VSIM, pdata->vsim); + child = add_regulator(TWL4030_REG_VSIM, pdata->vsim, + features); if (IS_ERR(child)) return PTR_ERR(child); - child = add_regulator(TWL4030_REG_VAUX1, pdata->vaux1); + child = add_regulator(TWL4030_REG_VAUX1, pdata->vaux1, + features); if (IS_ERR(child)) return PTR_ERR(child); - child = add_regulator(TWL4030_REG_VAUX3, pdata->vaux3); + child = add_regulator(TWL4030_REG_VAUX3, pdata->vaux3, + features); if (IS_ERR(child)) return PTR_ERR(child); - child = add_regulator(TWL4030_REG_VAUX4, pdata->vaux4); + child = add_regulator(TWL4030_REG_VAUX4, pdata->vaux4, + features); if (IS_ERR(child)) return PTR_ERR(child); } /* twl6030 regulators */ + if (twl_has_regulator() && twl_class_is_6030() && + !(features & TWL6025_SUBCLASS)) { + child = add_regulator(TWL6030_REG_VMMC, pdata->vmmc, + features); + if (IS_ERR(child)) + return PTR_ERR(child); + + child = add_regulator(TWL6030_REG_VPP, pdata->vpp, + features); + if (IS_ERR(child)) + return PTR_ERR(child); + + child = add_regulator(TWL6030_REG_VUSIM, pdata->vusim, + features); + if (IS_ERR(child)) + return PTR_ERR(child); + + child = add_regulator(TWL6030_REG_VCXIO, pdata->vcxio, + features); + if (IS_ERR(child)) + return PTR_ERR(child); + + child = add_regulator(TWL6030_REG_VDAC, pdata->vdac, + features); + if (IS_ERR(child)) + return PTR_ERR(child); + + child = add_regulator(TWL6030_REG_VAUX1_6030, pdata->vaux1, + features); + if (IS_ERR(child)) + return PTR_ERR(child); + + child = add_regulator(TWL6030_REG_VAUX2_6030, pdata->vaux2, + features); + if (IS_ERR(child)) + return PTR_ERR(child); + + child = add_regulator(TWL6030_REG_VAUX3_6030, pdata->vaux3, + features); + if (IS_ERR(child)) + return PTR_ERR(child); + + child = add_regulator(TWL6030_REG_CLK32KG, pdata->clk32kg, + features); + if (IS_ERR(child)) + return PTR_ERR(child); + } + + /* 6030 and 6025 share this regulator */ if (twl_has_regulator() && twl_class_is_6030()) { - child = add_regulator(TWL6030_REG_VMMC, pdata->vmmc); + child = add_regulator(TWL6030_REG_VANA, pdata->vana, + features); + if (IS_ERR(child)) + return PTR_ERR(child); + } + + /* twl6025 regulators */ + if (twl_has_regulator() && twl_class_is_6030() && + (features & TWL6025_SUBCLASS)) { + child = add_regulator(TWL6025_REG_LDO5, pdata->ldo5, + features); if (IS_ERR(child)) return PTR_ERR(child); - child = add_regulator(TWL6030_REG_VPP, pdata->vpp); + child = add_regulator(TWL6025_REG_LDO1, pdata->ldo1, + features); if (IS_ERR(child)) return PTR_ERR(child); - child = add_regulator(TWL6030_REG_VUSIM, pdata->vusim); + child = add_regulator(TWL6025_REG_LDO7, pdata->ldo7, + features); if (IS_ERR(child)) return PTR_ERR(child); - child = add_regulator(TWL6030_REG_VANA, pdata->vana); + child = add_regulator(TWL6025_REG_LDO6, pdata->ldo6, + features); if (IS_ERR(child)) return PTR_ERR(child); - child = add_regulator(TWL6030_REG_VCXIO, pdata->vcxio); + child = add_regulator(TWL6025_REG_LDOLN, pdata->ldoln, + features); if (IS_ERR(child)) return PTR_ERR(child); - child = add_regulator(TWL6030_REG_VDAC, pdata->vdac); + child = add_regulator(TWL6025_REG_LDO2, pdata->ldo2, + features); if (IS_ERR(child)) return PTR_ERR(child); - child = add_regulator(TWL6030_REG_VAUX1_6030, pdata->vaux1); + child = add_regulator(TWL6025_REG_LDO4, pdata->ldo4, + features); if (IS_ERR(child)) return PTR_ERR(child); - child = add_regulator(TWL6030_REG_VAUX2_6030, pdata->vaux2); + child = add_regulator(TWL6025_REG_LDO3, pdata->ldo3, + features); if (IS_ERR(child)) return PTR_ERR(child); - child = add_regulator(TWL6030_REG_VAUX3_6030, pdata->vaux3); + child = add_regulator(TWL6025_REG_SMPS3, pdata->smps3, + features); if (IS_ERR(child)) return PTR_ERR(child); - child = add_regulator(TWL6030_REG_CLK32KG, pdata->clk32kg); + child = add_regulator(TWL6025_REG_SMPS4, pdata->smps4, + features); if (IS_ERR(child)) return PTR_ERR(child); + + child = add_regulator(TWL6025_REG_VIO, pdata->vio6025, + features); + if (IS_ERR(child)) + return PTR_ERR(child); + } if (twl_has_bci() && pdata->bci && @@ -1170,6 +1285,7 @@ static const struct i2c_device_id twl_ids[] = { { "tps65930", TPS_SUBSET }, /* fewer LDOs and DACs; no charger */ { "tps65920", TPS_SUBSET }, /* fewer LDOs; no codec or charger */ { "twl6030", TWL6030_CLASS }, /* "Phoenix power chip" */ + { "twl6025", TWL6030_CLASS | TWL6025_SUBCLASS }, /* "Phoenix lite" */ { /* end of list */ }, }; MODULE_DEVICE_TABLE(i2c, twl_ids); diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h index 314218e79c4a..d70e704cbbb6 100644 --- a/include/linux/i2c/twl.h +++ b/include/linux/i2c/twl.h @@ -170,6 +170,8 @@ static inline int twl_class_is_ ##class(void) \ TWL_CLASS_IS(4030, TWL4030_CLASS_ID) TWL_CLASS_IS(6030, TWL6030_CLASS_ID) +#define TWL6025_SUBCLASS BIT(4) /* TWL6025 has changed registers */ + /* * Read and write single 8-bit registers */ @@ -608,6 +610,7 @@ enum twl4030_usb_mode { struct twl4030_usb_data { enum twl4030_usb_mode usb_mode; + unsigned long features; int (*phy_init)(struct device *dev); int (*phy_exit)(struct device *dev); @@ -714,6 +717,20 @@ struct twl4030_platform_data { struct regulator_init_data *vcxio; struct regulator_init_data *vusb; struct regulator_init_data *clk32kg; + /* TWL6025 LDO regulators */ + struct regulator_init_data *ldo1; + struct regulator_init_data *ldo2; + struct regulator_init_data *ldo3; + struct regulator_init_data *ldo4; + struct regulator_init_data *ldo5; + struct regulator_init_data *ldo6; + struct regulator_init_data *ldo7; + struct regulator_init_data *ldoln; + struct regulator_init_data *ldousb; + /* TWL6025 DCDC regulators */ + struct regulator_init_data *smps3; + struct regulator_init_data *smps4; + struct regulator_init_data *vio6025; }; /*----------------------------------------------------------------------*/ @@ -795,4 +812,21 @@ static inline int twl4030charger_usb_en(int enable) { return 0; } #define TWL6030_REG_VRTC 47 #define TWL6030_REG_CLK32KG 48 +/* LDOs on 6025 have different names */ +#define TWL6025_REG_LDO2 49 +#define TWL6025_REG_LDO4 50 +#define TWL6025_REG_LDO3 51 +#define TWL6025_REG_LDO5 52 +#define TWL6025_REG_LDO1 53 +#define TWL6025_REG_LDO7 54 +#define TWL6025_REG_LDO6 55 +#define TWL6025_REG_LDOLN 56 +#define TWL6025_REG_LDOUSB 57 + +/* 6025 DCDC supplies */ +#define TWL6025_REG_SMPS3 58 +#define TWL6025_REG_SMPS4 59 +#define TWL6025_REG_VIO 60 + + #endif /* End of __TWL4030_H */ -- cgit From 6523b148b44be38d89c2ee9865d34da30d9f5f1c Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Thu, 12 May 2011 14:27:56 +0100 Subject: mfd: Fix twl6030 irq definitions The charger fault IRQs from the twl will in future patches be handled by a seperate IRQ handler in the charger driver than the general charger IRQ. Give them different IRQ numbers now to allow the charger driver to be merged in the future. Signed-off-by: Graeme Gregory Signed-off-by: Samuel Ortiz --- drivers/mfd/twl6030-irq.c | 4 ++-- include/linux/i2c/twl.h | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c index dfbae34e1804..eb3b5f88e566 100644 --- a/drivers/mfd/twl6030-irq.c +++ b/drivers/mfd/twl6030-irq.c @@ -76,8 +76,8 @@ static int twl6030_interrupt_mapping[24] = { USBOTG_INTR_OFFSET, /* Bit 18 ID */ USB_PRES_INTR_OFFSET, /* Bit 19 VBUS */ CHARGER_INTR_OFFSET, /* Bit 20 CHRG_CTRL */ - CHARGER_INTR_OFFSET, /* Bit 21 EXT_CHRG */ - CHARGER_INTR_OFFSET, /* Bit 22 INT_CHRG */ + CHARGERFAULT_INTR_OFFSET, /* Bit 21 EXT_CHRG */ + CHARGERFAULT_INTR_OFFSET, /* Bit 22 INT_CHRG */ RSV_INTR_OFFSET, /* Bit 23 Reserved */ }; /*----------------------------------------------------------------------*/ diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h index d70e704cbbb6..ba4f88624fcd 100644 --- a/include/linux/i2c/twl.h +++ b/include/linux/i2c/twl.h @@ -91,6 +91,7 @@ #define BCI_INTR_OFFSET 2 #define MADC_INTR_OFFSET 3 #define USB_INTR_OFFSET 4 +#define CHARGERFAULT_INTR_OFFSET 5 #define BCI_PRES_INTR_OFFSET 9 #define USB_PRES_INTR_OFFSET 10 #define RTC_INTR_OFFSET 11 -- cgit From 863dde5bfa3c48f459c6302daf64f94a11c7c1e5 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sun, 8 May 2011 00:54:45 +0200 Subject: mfd: Provide ab8500-core enumerators for chip cuts Since functionality in MFD cells may need to be adjusted according to chip revision, let's enumerate them and keep track of them. Signed-off-by: Linus Walleij Signed-off-by: Samuel Ortiz --- drivers/mfd/ab8500-core.c | 32 ++++++++++++++++---------------- include/linux/mfd/abx500.h | 7 +++++++ 2 files changed, 23 insertions(+), 16 deletions(-) (limited to 'include/linux') diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index 67d01c938284..fc0c1af1566e 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c @@ -254,8 +254,9 @@ static void ab8500_irq_sync_unlock(struct irq_data *data) if (new == old) continue; - /* Interrupt register 12 does'nt exist prior to version 0x20 */ - if (ab8500_irq_regoffset[i] == 11 && ab8500->chip_id < 0x20) + /* Interrupt register 12 doesn't exist prior to version 2.0 */ + if (ab8500_irq_regoffset[i] == 11 && + ab8500->chip_id < AB8500_CUT2P0) continue; ab8500->oldmask[i] = new; @@ -307,8 +308,8 @@ static irqreturn_t ab8500_irq(int irq, void *dev) int status; u8 value; - /* Interrupt register 12 does'nt exist prior to version 0x20 */ - if (regoffset == 11 && ab8500->chip_id < 0x20) + /* Interrupt register 12 doesn't exist prior to version 2.0 */ + if (regoffset == 11 && ab8500->chip_id < AB8500_CUT2P0) continue; status = get_register_interruptible(ab8500, AB8500_INTERRUPT, @@ -724,17 +725,15 @@ int __devinit ab8500_init(struct ab8500 *ab8500) if (ret < 0) return ret; - /* - * 0x0 - Early Drop - * 0x10 - Cut 1.0 - * 0x11 - Cut 1.1 - * 0x20 - Cut 2.0 - * 0x30 - Cut 3.0 - */ - if (value == 0x0 || value == 0x10 || value == 0x11 || value == 0x20 || - value == 0x30) { + switch (value) { + case AB8500_CUTEARLY: + case AB8500_CUT1P0: + case AB8500_CUT1P1: + case AB8500_CUT2P0: + case AB8500_CUT3P0: dev_info(ab8500->dev, "detected chip, revision: %#x\n", value); - } else { + break; + default: dev_err(ab8500->dev, "unknown chip, revision: %#x\n", value); return -EINVAL; } @@ -763,8 +762,9 @@ int __devinit ab8500_init(struct ab8500 *ab8500) /* Clear and mask all interrupts */ for (i = 0; i < AB8500_NUM_IRQ_REGS; i++) { - /* Interrupt register 12 does'nt exist prior to version 0x20 */ - if (ab8500_irq_regoffset[i] == 11 && ab8500->chip_id < 0x20) + /* Interrupt register 12 doesn't exist prior to version 2.0 */ + if (ab8500_irq_regoffset[i] == 11 && + ab8500->chip_id < AB8500_CUT2P0) continue; get_register_interruptible(ab8500, AB8500_INTERRUPT, diff --git a/include/linux/mfd/abx500.h b/include/linux/mfd/abx500.h index 67bd6f7ecf32..896b5e47f16e 100644 --- a/include/linux/mfd/abx500.h +++ b/include/linux/mfd/abx500.h @@ -34,6 +34,13 @@ #define AB5500_2_0 0x21 #define AB5500_2_1 0x22 +/* AB8500 CIDs*/ +#define AB8500_CUTEARLY 0x00 +#define AB8500_CUT1P0 0x10 +#define AB8500_CUT1P1 0x11 +#define AB8500_CUT2P0 0x20 +#define AB8500_CUT3P0 0x30 + /* * AB3100, EVENTA1, A2 and A3 event register flags * these are catenated into a single 32-bit flag in the code -- cgit From 4a7c00cd94d4ca7061c481fe823a256e37436044 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 10 May 2011 08:59:23 +0300 Subject: mfd: Update twl4030-code maintainer e-mail address Signed-off-by: Peter Ujfalusi Signed-off-by: Samuel Ortiz --- drivers/mfd/twl4030-codec.c | 4 ++-- include/linux/mfd/twl4030-codec.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/drivers/mfd/twl4030-codec.c b/drivers/mfd/twl4030-codec.c index 315b5ead8437..2bf4136464c1 100644 --- a/drivers/mfd/twl4030-codec.c +++ b/drivers/mfd/twl4030-codec.c @@ -1,7 +1,7 @@ /* * MFD driver for twl4030 codec submodule * - * Author: Peter Ujfalusi + * Author: Peter Ujfalusi * * Copyright: (C) 2009 Nokia Corporation * @@ -272,6 +272,6 @@ static void __devexit twl4030_codec_exit(void) } module_exit(twl4030_codec_exit); -MODULE_AUTHOR("Peter Ujfalusi "); +MODULE_AUTHOR("Peter Ujfalusi "); MODULE_LICENSE("GPL"); diff --git a/include/linux/mfd/twl4030-codec.h b/include/linux/mfd/twl4030-codec.h index 2ec317c68e59..5cc16bbd1da1 100644 --- a/include/linux/mfd/twl4030-codec.h +++ b/include/linux/mfd/twl4030-codec.h @@ -1,7 +1,7 @@ /* * MFD driver for twl4030 codec submodule * - * Author: Peter Ujfalusi + * Author: Peter Ujfalusi * * Copyright: (C) 2009 Nokia Corporation * -- cgit From 7d9e7e9fbd3041a0596394579d800788bbf94939 Mon Sep 17 00:00:00 2001 From: Paul Parsons Date: Fri, 13 May 2011 18:52:56 +0000 Subject: leds: Add ASIC3 LED support Add LED support for the HTC ASIC3. Underlying support is provided by the mfd/asic3 and leds/leds-asic3 drivers. An example configuration is provided by the pxa/hx4700 platform. Signed-off-by: Paul Parsons Signed-off-by: Samuel Ortiz --- drivers/leds/Kconfig | 10 +++ drivers/leds/Makefile | 1 + drivers/leds/leds-asic3.c | 165 ++++++++++++++++++++++++++++++++++++++++++++++ include/linux/mfd/asic3.h | 22 ++++++- 4 files changed, 195 insertions(+), 3 deletions(-) create mode 100644 drivers/leds/leds-asic3.c (limited to 'include/linux') diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 1d027b475b22..23f0d5e99f35 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -389,6 +389,16 @@ config LEDS_NETXBIG and 5Big Network v2 boards. The LEDs are wired to a CPLD and are controlled through a GPIO extension bus. +config LEDS_ASIC3 + bool "LED support for the HTC ASIC3" + depends on MFD_ASIC3 + default y + help + This option enables support for the LEDs on the HTC ASIC3. The HTC + ASIC3 LED GPIOs are inputs, not outputs, thus the leds-gpio driver + cannot be used. This driver supports hardware blinking with an on+off + period from 62ms to 125s. Say Y to enable LEDs on the HP iPAQ hx4700. + config LEDS_TRIGGERS bool "LED Trigger support" depends on LEDS_CLASS diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index bccb96c9bb45..bbfd2e367dc0 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -42,6 +42,7 @@ obj-$(CONFIG_LEDS_DELL_NETBOOKS) += dell-led.o obj-$(CONFIG_LEDS_MC13783) += leds-mc13783.o obj-$(CONFIG_LEDS_NS2) += leds-ns2.o obj-$(CONFIG_LEDS_NETXBIG) += leds-netxbig.o +obj-$(CONFIG_LEDS_ASIC3) += leds-asic3.o # LED SPI Drivers obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o diff --git a/drivers/leds/leds-asic3.c b/drivers/leds/leds-asic3.c new file mode 100644 index 000000000000..22f847c890c9 --- /dev/null +++ b/drivers/leds/leds-asic3.c @@ -0,0 +1,165 @@ +/* + * Copyright (C) 2011 Paul Parsons + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include + +#include +#include + +/* + * The HTC ASIC3 LED GPIOs are inputs, not outputs. + * Hence we turn the LEDs on/off via the TimeBase register. + */ + +/* + * When TimeBase is 4 the clock resolution is about 32Hz. + * This driver supports hardware blinking with an on+off + * period from 62ms (2 clocks) to 125s (4000 clocks). + */ +#define MS_TO_CLK(ms) DIV_ROUND_CLOSEST(((ms)*1024), 32000) +#define CLK_TO_MS(clk) (((clk)*32000)/1024) +#define MAX_CLK 4000 /* Fits into 12-bit Time registers */ +#define MAX_MS CLK_TO_MS(MAX_CLK) + +static const unsigned int led_n_base[ASIC3_NUM_LEDS] = { + [0] = ASIC3_LED_0_Base, + [1] = ASIC3_LED_1_Base, + [2] = ASIC3_LED_2_Base, +}; + +static void brightness_set(struct led_classdev *cdev, + enum led_brightness value) +{ + struct platform_device *pdev = to_platform_device(cdev->dev->parent); + const struct mfd_cell *cell = mfd_get_cell(pdev); + struct asic3 *asic = dev_get_drvdata(pdev->dev.parent); + u32 timebase; + unsigned int base; + + timebase = (value == LED_OFF) ? 0 : (LED_EN|0x4); + + base = led_n_base[cell->id]; + asic3_write_register(asic, (base + ASIC3_LED_PeriodTime), 32); + asic3_write_register(asic, (base + ASIC3_LED_DutyTime), 32); + asic3_write_register(asic, (base + ASIC3_LED_AutoStopCount), 0); + asic3_write_register(asic, (base + ASIC3_LED_TimeBase), timebase); +} + +static int blink_set(struct led_classdev *cdev, + unsigned long *delay_on, + unsigned long *delay_off) +{ + struct platform_device *pdev = to_platform_device(cdev->dev->parent); + const struct mfd_cell *cell = mfd_get_cell(pdev); + struct asic3 *asic = dev_get_drvdata(pdev->dev.parent); + u32 on; + u32 off; + unsigned int base; + + if (*delay_on > MAX_MS || *delay_off > MAX_MS) + return -EINVAL; + + if (*delay_on == 0 && *delay_off == 0) { + /* If both are zero then a sensible default should be chosen */ + on = MS_TO_CLK(500); + off = MS_TO_CLK(500); + } else { + on = MS_TO_CLK(*delay_on); + off = MS_TO_CLK(*delay_off); + if ((on + off) > MAX_CLK) + return -EINVAL; + } + + base = led_n_base[cell->id]; + asic3_write_register(asic, (base + ASIC3_LED_PeriodTime), (on + off)); + asic3_write_register(asic, (base + ASIC3_LED_DutyTime), on); + asic3_write_register(asic, (base + ASIC3_LED_AutoStopCount), 0); + asic3_write_register(asic, (base + ASIC3_LED_TimeBase), (LED_EN|0x4)); + + *delay_on = CLK_TO_MS(on); + *delay_off = CLK_TO_MS(off); + + return 0; +} + +static int __devinit asic3_led_probe(struct platform_device *pdev) +{ + struct asic3_led *led = pdev->dev.platform_data; + int ret; + + ret = mfd_cell_enable(pdev); + if (ret < 0) + goto ret0; + + led->cdev = kzalloc(sizeof(struct led_classdev), GFP_KERNEL); + if (!led->cdev) { + ret = -ENOMEM; + goto ret1; + } + + led->cdev->name = led->name; + led->cdev->default_trigger = led->default_trigger; + led->cdev->brightness_set = brightness_set; + led->cdev->blink_set = blink_set; + + ret = led_classdev_register(&pdev->dev, led->cdev); + if (ret < 0) + goto ret2; + + return 0; + +ret2: + kfree(led->cdev); +ret1: + (void) mfd_cell_disable(pdev); +ret0: + return ret; +} + +static int __devexit asic3_led_remove(struct platform_device *pdev) +{ + struct asic3_led *led = pdev->dev.platform_data; + + led_classdev_unregister(led->cdev); + + kfree(led->cdev); + + return mfd_cell_disable(pdev); +} + +static struct platform_driver asic3_led_driver = { + .probe = asic3_led_probe, + .remove = __devexit_p(asic3_led_remove), + .driver = { + .name = "leds-asic3", + .owner = THIS_MODULE, + }, +}; + +MODULE_ALIAS("platform:leds-asic3"); + +static int __init asic3_led_init(void) +{ + return platform_driver_register(&asic3_led_driver); +} + +static void __exit asic3_led_exit(void) +{ + platform_driver_unregister(&asic3_led_driver); +} + +module_init(asic3_led_init); +module_exit(asic3_led_exit); + +MODULE_AUTHOR("Paul Parsons "); +MODULE_DESCRIPTION("HTC ASIC3 LED driver"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/mfd/asic3.h b/include/linux/mfd/asic3.h index de3c4ad19afb..d0dd3ebd8488 100644 --- a/include/linux/mfd/asic3.h +++ b/include/linux/mfd/asic3.h @@ -16,6 +16,13 @@ #include +struct led_classdev; +struct asic3_led { + const char *name; + const char *default_trigger; + struct led_classdev *cdev; +}; + struct asic3_platform_data { u16 *gpio_config; unsigned int gpio_config_num; @@ -23,6 +30,8 @@ struct asic3_platform_data { unsigned int irq_base; unsigned int gpio_base; + + struct asic3_led *leds; }; #define ASIC3_NUM_GPIO_BANKS 4 @@ -111,9 +120,9 @@ struct asic3_platform_data { #define ASIC3_GPIOA11_PWM0 ASIC3_CONFIG_GPIO(11, 1, 1, 0) #define ASIC3_GPIOA12_PWM1 ASIC3_CONFIG_GPIO(12, 1, 1, 0) #define ASIC3_GPIOA15_CONTROL_CX ASIC3_CONFIG_GPIO(15, 1, 1, 0) -#define ASIC3_GPIOC0_LED0 ASIC3_CONFIG_GPIO(32, 1, 1, 0) -#define ASIC3_GPIOC1_LED1 ASIC3_CONFIG_GPIO(33, 1, 1, 0) -#define ASIC3_GPIOC2_LED2 ASIC3_CONFIG_GPIO(34, 1, 1, 0) +#define ASIC3_GPIOC0_LED0 ASIC3_CONFIG_GPIO(32, 1, 0, 0) +#define ASIC3_GPIOC1_LED1 ASIC3_CONFIG_GPIO(33, 1, 0, 0) +#define ASIC3_GPIOC2_LED2 ASIC3_CONFIG_GPIO(34, 1, 0, 0) #define ASIC3_GPIOC3_SPI_RXD ASIC3_CONFIG_GPIO(35, 1, 0, 0) #define ASIC3_GPIOC4_CF_nCD ASIC3_CONFIG_GPIO(36, 1, 0, 0) #define ASIC3_GPIOC4_SPI_TXD ASIC3_CONFIG_GPIO(36, 1, 1, 0) @@ -152,6 +161,7 @@ struct asic3_platform_data { #define PWM_TIMEBASE_VALUE(x) ((x)&0xf) /* Low 4 bits sets time base */ #define PWM_TIMEBASE_ENABLE (1 << 4) /* Enable clock */ +#define ASIC3_NUM_LEDS 3 #define ASIC3_LED_0_Base 0x0700 #define ASIC3_LED_1_Base 0x0800 #define ASIC3_LED_2_Base 0x0900 @@ -293,4 +303,10 @@ struct asic3_platform_data { #define ASIC3_MAP_SIZE_32BIT 0x2000 #define ASIC3_MAP_SIZE_16BIT 0x1000 +/* Functions needed by leds-asic3 */ + +struct asic3; +extern void asic3_write_register(struct asic3 *asic, unsigned int reg, u32 val); +extern u32 asic3_read_register(struct asic3 *asic, unsigned int reg); + #endif /* __ASIC3_H__ */ -- cgit From 74e32d1b68f177f9c998041d789253df9c7f3575 Mon Sep 17 00:00:00 2001 From: Paul Parsons Date: Sun, 15 May 2011 14:13:11 +0000 Subject: mfd: Fix ASIC3 SD Host Controller Configuration size The size of the TC6380AF SD Host Controller Configuration area is 0x200 bytes (assuming registers are aligned on 32-bit boundaries), not 0x400 bytes. Source: Toshiba TC6380AF Specification sections 4.2 and 4.3.1 Signed-off-by: Paul Parsons Signed-off-by: Samuel Ortiz --- drivers/mfd/asic3.c | 3 ++- include/linux/mfd/asic3.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index 52e56ea43a85..c27fd1fc3b86 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c @@ -856,7 +856,8 @@ static int __init asic3_mfd_probe(struct platform_device *pdev, /* MMC */ asic->tmio_cnf = ioremap((ASIC3_SD_CONFIG_BASE >> asic->bus_shift) + - mem_sdio->start, 0x400 >> asic->bus_shift); + mem_sdio->start, + ASIC3_SD_CONFIG_SIZE >> asic->bus_shift); if (!asic->tmio_cnf) { ret = -ENOMEM; dev_dbg(asic->dev, "Couldn't ioremap SD_CONFIG\n"); diff --git a/include/linux/mfd/asic3.h b/include/linux/mfd/asic3.h index d0dd3ebd8488..ed793b77a1c5 100644 --- a/include/linux/mfd/asic3.h +++ b/include/linux/mfd/asic3.h @@ -297,6 +297,7 @@ struct asic3_platform_data { * *****************************************************************************/ #define ASIC3_SD_CONFIG_BASE 0x0400 /* Assumes 32 bit addressing */ +#define ASIC3_SD_CONFIG_SIZE 0x0200 /* Assumes 32 bit addressing */ #define ASIC3_SD_CTRL_BASE 0x1000 #define ASIC3_SDIO_CTRL_BASE 0x1200 -- cgit From 39325b59d88b42ba2ccf2e62c234059e9941a47c Mon Sep 17 00:00:00 2001 From: Trilok Soni Date: Thu, 19 May 2011 10:54:04 +0530 Subject: input: Add Qualcomm pm8xxx keypad controller driver Add Qualcomm PMIC8XXX based keypad controller driver supporting upto 18x8 matrix configuration. Acked-by: Dmitry Torokhov Signed-off-by: Trilok Soni Signed-off-by: Anirudh Ghayal Signed-off-by: Samuel Ortiz --- drivers/input/keyboard/Kconfig | 11 + drivers/input/keyboard/Makefile | 1 + drivers/input/keyboard/pmic8xxx-keypad.c | 799 +++++++++++++++++++++++++++++++ include/linux/input/pmic8xxx-keypad.h | 52 ++ 4 files changed, 863 insertions(+) create mode 100644 drivers/input/keyboard/pmic8xxx-keypad.c create mode 100644 include/linux/input/pmic8xxx-keypad.h (limited to 'include/linux') diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 69badb4e06aa..b4dee9d5a055 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -412,6 +412,17 @@ config KEYBOARD_PXA930_ROTARY To compile this driver as a module, choose M here: the module will be called pxa930_rotary. +config KEYBOARD_PMIC8XXX + tristate "Qualcomm PMIC8XXX keypad support" + depends on MFD_PM8XXX + help + Say Y here if you want to enable the driver for the PMIC8XXX + keypad provided as a reference design from Qualcomm. This is intended + to support upto 18x8 matrix based keypad design. + + To compile this driver as a module, choose M here: the module will + be called pmic8xxx-keypad. + config KEYBOARD_SAMSUNG tristate "Samsung keypad support" depends on SAMSUNG_DEV_KEYPAD diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index c49cf8e04cd7..ddde0fd476f7 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile @@ -34,6 +34,7 @@ obj-$(CONFIG_KEYBOARD_NOMADIK) += nomadik-ske-keypad.o obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o obj-$(CONFIG_KEYBOARD_OMAP4) += omap4-keypad.o obj-$(CONFIG_KEYBOARD_OPENCORES) += opencores-kbd.o +obj-$(CONFIG_KEYBOARD_PMIC8XXX) += pmic8xxx-keypad.o obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keypad.o obj-$(CONFIG_KEYBOARD_PXA930_ROTARY) += pxa930_rotary.o obj-$(CONFIG_KEYBOARD_QT1070) += qt1070.o diff --git a/drivers/input/keyboard/pmic8xxx-keypad.c b/drivers/input/keyboard/pmic8xxx-keypad.c new file mode 100644 index 000000000000..40b02ae96f86 --- /dev/null +++ b/drivers/input/keyboard/pmic8xxx-keypad.c @@ -0,0 +1,799 @@ +/* Copyright (c) 2009-2011, Code Aurora Forum. 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define PM8XXX_MAX_ROWS 18 +#define PM8XXX_MAX_COLS 8 +#define PM8XXX_ROW_SHIFT 3 +#define PM8XXX_MATRIX_MAX_SIZE (PM8XXX_MAX_ROWS * PM8XXX_MAX_COLS) + +#define PM8XXX_MIN_ROWS 5 +#define PM8XXX_MIN_COLS 5 + +#define MAX_SCAN_DELAY 128 +#define MIN_SCAN_DELAY 1 + +/* in nanoseconds */ +#define MAX_ROW_HOLD_DELAY 122000 +#define MIN_ROW_HOLD_DELAY 30500 + +#define MAX_DEBOUNCE_TIME 20 +#define MIN_DEBOUNCE_TIME 5 + +#define KEYP_CTRL 0x148 + +#define KEYP_CTRL_EVNTS BIT(0) +#define KEYP_CTRL_EVNTS_MASK 0x3 + +#define KEYP_CTRL_SCAN_COLS_SHIFT 5 +#define KEYP_CTRL_SCAN_COLS_MIN 5 +#define KEYP_CTRL_SCAN_COLS_BITS 0x3 + +#define KEYP_CTRL_SCAN_ROWS_SHIFT 2 +#define KEYP_CTRL_SCAN_ROWS_MIN 5 +#define KEYP_CTRL_SCAN_ROWS_BITS 0x7 + +#define KEYP_CTRL_KEYP_EN BIT(7) + +#define KEYP_SCAN 0x149 + +#define KEYP_SCAN_READ_STATE BIT(0) +#define KEYP_SCAN_DBOUNCE_SHIFT 1 +#define KEYP_SCAN_PAUSE_SHIFT 3 +#define KEYP_SCAN_ROW_HOLD_SHIFT 6 + +#define KEYP_TEST 0x14A + +#define KEYP_TEST_CLEAR_RECENT_SCAN BIT(6) +#define KEYP_TEST_CLEAR_OLD_SCAN BIT(5) +#define KEYP_TEST_READ_RESET BIT(4) +#define KEYP_TEST_DTEST_EN BIT(3) +#define KEYP_TEST_ABORT_READ BIT(0) + +#define KEYP_TEST_DBG_SELECT_SHIFT 1 + +/* bits of these registers represent + * '0' for key press + * '1' for key release + */ +#define KEYP_RECENT_DATA 0x14B +#define KEYP_OLD_DATA 0x14C + +#define KEYP_CLOCK_FREQ 32768 + +/** + * struct pmic8xxx_kp - internal keypad data structure + * @pdata - keypad platform data pointer + * @input - input device pointer for keypad + * @key_sense_irq - key press/release irq number + * @key_stuck_irq - key stuck notification irq number + * @keycodes - array to hold the key codes + * @dev - parent device pointer + * @keystate - present key press/release state + * @stuckstate - present state when key stuck irq + * @ctrl_reg - control register value + */ +struct pmic8xxx_kp { + const struct pm8xxx_keypad_platform_data *pdata; + struct input_dev *input; + int key_sense_irq; + int key_stuck_irq; + + unsigned short keycodes[PM8XXX_MATRIX_MAX_SIZE]; + + struct device *dev; + u16 keystate[PM8XXX_MAX_ROWS]; + u16 stuckstate[PM8XXX_MAX_ROWS]; + + u8 ctrl_reg; +}; + +static int pmic8xxx_kp_write_u8(struct pmic8xxx_kp *kp, + u8 data, u16 reg) +{ + int rc; + + rc = pm8xxx_writeb(kp->dev->parent, reg, data); + return rc; +} + +static int pmic8xxx_kp_read(struct pmic8xxx_kp *kp, + u8 *data, u16 reg, unsigned num_bytes) +{ + int rc; + + rc = pm8xxx_read_buf(kp->dev->parent, reg, data, num_bytes); + return rc; +} + +static int pmic8xxx_kp_read_u8(struct pmic8xxx_kp *kp, + u8 *data, u16 reg) +{ + int rc; + + rc = pmic8xxx_kp_read(kp, data, reg, 1); + return rc; +} + +static u8 pmic8xxx_col_state(struct pmic8xxx_kp *kp, u8 col) +{ + /* all keys pressed on that particular row? */ + if (col == 0x00) + return 1 << kp->pdata->num_cols; + else + return col & ((1 << kp->pdata->num_cols) - 1); +} + +/* + * Synchronous read protocol for RevB0 onwards: + * + * 1. Write '1' to ReadState bit in KEYP_SCAN register + * 2. Wait 2*32KHz clocks, so that HW can successfully enter read mode + * synchronously + * 3. Read rows in old array first if events are more than one + * 4. Read rows in recent array + * 5. Wait 4*32KHz clocks + * 6. Write '0' to ReadState bit of KEYP_SCAN register so that hw can + * synchronously exit read mode. + */ +static int pmic8xxx_chk_sync_read(struct pmic8xxx_kp *kp) +{ + int rc; + u8 scan_val; + + rc = pmic8xxx_kp_read_u8(kp, &scan_val, KEYP_SCAN); + if (rc < 0) { + dev_err(kp->dev, "Error reading KEYP_SCAN reg, rc=%d\n", rc); + return rc; + } + + scan_val |= 0x1; + + rc = pmic8xxx_kp_write_u8(kp, scan_val, KEYP_SCAN); + if (rc < 0) { + dev_err(kp->dev, "Error writing KEYP_SCAN reg, rc=%d\n", rc); + return rc; + } + + /* 2 * 32KHz clocks */ + udelay((2 * DIV_ROUND_UP(USEC_PER_SEC, KEYP_CLOCK_FREQ)) + 1); + + return rc; +} + +static int pmic8xxx_kp_read_data(struct pmic8xxx_kp *kp, u16 *state, + u16 data_reg, int read_rows) +{ + int rc, row; + u8 new_data[PM8XXX_MAX_ROWS]; + + rc = pmic8xxx_kp_read(kp, new_data, data_reg, read_rows); + if (rc) + return rc; + + for (row = 0; row < kp->pdata->num_rows; row++) { + dev_dbg(kp->dev, "new_data[%d] = %d\n", row, + new_data[row]); + state[row] = pmic8xxx_col_state(kp, new_data[row]); + } + + return rc; +} + +static int pmic8xxx_kp_read_matrix(struct pmic8xxx_kp *kp, u16 *new_state, + u16 *old_state) +{ + int rc, read_rows; + u8 scan_val; + + if (kp->pdata->num_rows < PM8XXX_MIN_ROWS) + read_rows = PM8XXX_MIN_ROWS; + else + read_rows = kp->pdata->num_rows; + + pmic8xxx_chk_sync_read(kp); + + if (old_state) { + rc = pmic8xxx_kp_read_data(kp, old_state, KEYP_OLD_DATA, + read_rows); + if (rc < 0) { + dev_err(kp->dev, + "Error reading KEYP_OLD_DATA, rc=%d\n", rc); + return rc; + } + } + + rc = pmic8xxx_kp_read_data(kp, new_state, KEYP_RECENT_DATA, + read_rows); + if (rc < 0) { + dev_err(kp->dev, + "Error reading KEYP_RECENT_DATA, rc=%d\n", rc); + return rc; + } + + /* 4 * 32KHz clocks */ + udelay((4 * DIV_ROUND_UP(USEC_PER_SEC, KEYP_CLOCK_FREQ)) + 1); + + rc = pmic8xxx_kp_read_u8(kp, &scan_val, KEYP_SCAN); + if (rc < 0) { + dev_err(kp->dev, "Error reading KEYP_SCAN reg, rc=%d\n", rc); + return rc; + } + + scan_val &= 0xFE; + rc = pmic8xxx_kp_write_u8(kp, scan_val, KEYP_SCAN); + if (rc < 0) + dev_err(kp->dev, "Error writing KEYP_SCAN reg, rc=%d\n", rc); + + return rc; +} + +static void __pmic8xxx_kp_scan_matrix(struct pmic8xxx_kp *kp, u16 *new_state, + u16 *old_state) +{ + int row, col, code; + + for (row = 0; row < kp->pdata->num_rows; row++) { + int bits_changed = new_state[row] ^ old_state[row]; + + if (!bits_changed) + continue; + + for (col = 0; col < kp->pdata->num_cols; col++) { + if (!(bits_changed & (1 << col))) + continue; + + dev_dbg(kp->dev, "key [%d:%d] %s\n", row, col, + !(new_state[row] & (1 << col)) ? + "pressed" : "released"); + + code = MATRIX_SCAN_CODE(row, col, PM8XXX_ROW_SHIFT); + + input_event(kp->input, EV_MSC, MSC_SCAN, code); + input_report_key(kp->input, + kp->keycodes[code], + !(new_state[row] & (1 << col))); + + input_sync(kp->input); + } + } +} + +static bool pmic8xxx_detect_ghost_keys(struct pmic8xxx_kp *kp, u16 *new_state) +{ + int row, found_first = -1; + u16 check, row_state; + + check = 0; + for (row = 0; row < kp->pdata->num_rows; row++) { + row_state = (~new_state[row]) & + ((1 << kp->pdata->num_cols) - 1); + + if (hweight16(row_state) > 1) { + if (found_first == -1) + found_first = row; + if (check & row_state) { + dev_dbg(kp->dev, "detected ghost key on row[%d]" + " and row[%d]\n", found_first, row); + return true; + } + } + check |= row_state; + } + return false; +} + +static int pmic8xxx_kp_scan_matrix(struct pmic8xxx_kp *kp, unsigned int events) +{ + u16 new_state[PM8XXX_MAX_ROWS]; + u16 old_state[PM8XXX_MAX_ROWS]; + int rc; + + switch (events) { + case 0x1: + rc = pmic8xxx_kp_read_matrix(kp, new_state, NULL); + if (rc < 0) + return rc; + + /* detecting ghost key is not an error */ + if (pmic8xxx_detect_ghost_keys(kp, new_state)) + return 0; + __pmic8xxx_kp_scan_matrix(kp, new_state, kp->keystate); + memcpy(kp->keystate, new_state, sizeof(new_state)); + break; + case 0x3: /* two events - eventcounter is gray-coded */ + rc = pmic8xxx_kp_read_matrix(kp, new_state, old_state); + if (rc < 0) + return rc; + + __pmic8xxx_kp_scan_matrix(kp, old_state, kp->keystate); + __pmic8xxx_kp_scan_matrix(kp, new_state, old_state); + memcpy(kp->keystate, new_state, sizeof(new_state)); + break; + case 0x2: + dev_dbg(kp->dev, "Some key events were lost\n"); + rc = pmic8xxx_kp_read_matrix(kp, new_state, old_state); + if (rc < 0) + return rc; + __pmic8xxx_kp_scan_matrix(kp, old_state, kp->keystate); + __pmic8xxx_kp_scan_matrix(kp, new_state, old_state); + memcpy(kp->keystate, new_state, sizeof(new_state)); + break; + default: + rc = -EINVAL; + } + return rc; +} + +/* + * NOTE: We are reading recent and old data registers blindly + * whenever key-stuck interrupt happens, because events counter doesn't + * get updated when this interrupt happens due to key stuck doesn't get + * considered as key state change. + * + * We are not using old data register contents after they are being read + * because it might report the key which was pressed before the key being stuck + * as stuck key because it's pressed status is stored in the old data + * register. + */ +static irqreturn_t pmic8xxx_kp_stuck_irq(int irq, void *data) +{ + u16 new_state[PM8XXX_MAX_ROWS]; + u16 old_state[PM8XXX_MAX_ROWS]; + int rc; + struct pmic8xxx_kp *kp = data; + + rc = pmic8xxx_kp_read_matrix(kp, new_state, old_state); + if (rc < 0) { + dev_err(kp->dev, "failed to read keypad matrix\n"); + return IRQ_HANDLED; + } + + __pmic8xxx_kp_scan_matrix(kp, new_state, kp->stuckstate); + + return IRQ_HANDLED; +} + +static irqreturn_t pmic8xxx_kp_irq(int irq, void *data) +{ + struct pmic8xxx_kp *kp = data; + u8 ctrl_val, events; + int rc; + + rc = pmic8xxx_kp_read(kp, &ctrl_val, KEYP_CTRL, 1); + if (rc < 0) { + dev_err(kp->dev, "failed to read keyp_ctrl register\n"); + return IRQ_HANDLED; + } + + events = ctrl_val & KEYP_CTRL_EVNTS_MASK; + + rc = pmic8xxx_kp_scan_matrix(kp, events); + if (rc < 0) + dev_err(kp->dev, "failed to scan matrix\n"); + + return IRQ_HANDLED; +} + +static int __devinit pmic8xxx_kpd_init(struct pmic8xxx_kp *kp) +{ + int bits, rc, cycles; + u8 scan_val = 0, ctrl_val = 0; + static const u8 row_bits[] = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, + }; + + /* Find column bits */ + if (kp->pdata->num_cols < KEYP_CTRL_SCAN_COLS_MIN) + bits = 0; + else + bits = kp->pdata->num_cols - KEYP_CTRL_SCAN_COLS_MIN; + ctrl_val = (bits & KEYP_CTRL_SCAN_COLS_BITS) << + KEYP_CTRL_SCAN_COLS_SHIFT; + + /* Find row bits */ + if (kp->pdata->num_rows < KEYP_CTRL_SCAN_ROWS_MIN) + bits = 0; + else + bits = row_bits[kp->pdata->num_rows - KEYP_CTRL_SCAN_ROWS_MIN]; + + ctrl_val |= (bits << KEYP_CTRL_SCAN_ROWS_SHIFT); + + rc = pmic8xxx_kp_write_u8(kp, ctrl_val, KEYP_CTRL); + if (rc < 0) { + dev_err(kp->dev, "Error writing KEYP_CTRL reg, rc=%d\n", rc); + return rc; + } + + bits = (kp->pdata->debounce_ms / 5) - 1; + + scan_val |= (bits << KEYP_SCAN_DBOUNCE_SHIFT); + + bits = fls(kp->pdata->scan_delay_ms) - 1; + scan_val |= (bits << KEYP_SCAN_PAUSE_SHIFT); + + /* Row hold time is a multiple of 32KHz cycles. */ + cycles = (kp->pdata->row_hold_ns * KEYP_CLOCK_FREQ) / NSEC_PER_SEC; + + scan_val |= (cycles << KEYP_SCAN_ROW_HOLD_SHIFT); + + rc = pmic8xxx_kp_write_u8(kp, scan_val, KEYP_SCAN); + if (rc) + dev_err(kp->dev, "Error writing KEYP_SCAN reg, rc=%d\n", rc); + + return rc; + +} + +static int __devinit pmic8xxx_kp_config_gpio(int gpio_start, int num_gpios, + struct pmic8xxx_kp *kp, struct pm_gpio *gpio_config) +{ + int rc, i; + + if (gpio_start < 0 || num_gpios < 0) + return -EINVAL; + + for (i = 0; i < num_gpios; i++) { + rc = pm8xxx_gpio_config(gpio_start + i, gpio_config); + if (rc) { + dev_err(kp->dev, "%s: FAIL pm8xxx_gpio_config():" + "for PM GPIO [%d] rc=%d.\n", + __func__, gpio_start + i, rc); + return rc; + } + } + + return 0; +} + +static int pmic8xxx_kp_enable(struct pmic8xxx_kp *kp) +{ + int rc; + + kp->ctrl_reg |= KEYP_CTRL_KEYP_EN; + + rc = pmic8xxx_kp_write_u8(kp, kp->ctrl_reg, KEYP_CTRL); + if (rc < 0) + dev_err(kp->dev, "Error writing KEYP_CTRL reg, rc=%d\n", rc); + + return rc; +} + +static int pmic8xxx_kp_disable(struct pmic8xxx_kp *kp) +{ + int rc; + + kp->ctrl_reg &= ~KEYP_CTRL_KEYP_EN; + + rc = pmic8xxx_kp_write_u8(kp, kp->ctrl_reg, KEYP_CTRL); + if (rc < 0) + return rc; + + return rc; +} + +static int pmic8xxx_kp_open(struct input_dev *dev) +{ + struct pmic8xxx_kp *kp = input_get_drvdata(dev); + + return pmic8xxx_kp_enable(kp); +} + +static void pmic8xxx_kp_close(struct input_dev *dev) +{ + struct pmic8xxx_kp *kp = input_get_drvdata(dev); + + pmic8xxx_kp_disable(kp); +} + +/* + * keypad controller should be initialized in the following sequence + * only, otherwise it might get into FSM stuck state. + * + * - Initialize keypad control parameters, like no. of rows, columns, + * timing values etc., + * - configure rows and column gpios pull up/down. + * - set irq edge type. + * - enable the keypad controller. + */ +static int __devinit pmic8xxx_kp_probe(struct platform_device *pdev) +{ + const struct pm8xxx_keypad_platform_data *pdata = mfd_get_data(pdev); + const struct matrix_keymap_data *keymap_data; + struct pmic8xxx_kp *kp; + int rc; + u8 ctrl_val; + + struct pm_gpio kypd_drv = { + .direction = PM_GPIO_DIR_OUT, + .output_buffer = PM_GPIO_OUT_BUF_OPEN_DRAIN, + .output_value = 0, + .pull = PM_GPIO_PULL_NO, + .vin_sel = PM_GPIO_VIN_S3, + .out_strength = PM_GPIO_STRENGTH_LOW, + .function = PM_GPIO_FUNC_1, + .inv_int_pol = 1, + }; + + struct pm_gpio kypd_sns = { + .direction = PM_GPIO_DIR_IN, + .pull = PM_GPIO_PULL_UP_31P5, + .vin_sel = PM_GPIO_VIN_S3, + .out_strength = PM_GPIO_STRENGTH_NO, + .function = PM_GPIO_FUNC_NORMAL, + .inv_int_pol = 1, + }; + + + if (!pdata || !pdata->num_cols || !pdata->num_rows || + pdata->num_cols > PM8XXX_MAX_COLS || + pdata->num_rows > PM8XXX_MAX_ROWS || + pdata->num_cols < PM8XXX_MIN_COLS) { + dev_err(&pdev->dev, "invalid platform data\n"); + return -EINVAL; + } + + if (!pdata->scan_delay_ms || + pdata->scan_delay_ms > MAX_SCAN_DELAY || + pdata->scan_delay_ms < MIN_SCAN_DELAY || + !is_power_of_2(pdata->scan_delay_ms)) { + dev_err(&pdev->dev, "invalid keypad scan time supplied\n"); + return -EINVAL; + } + + if (!pdata->row_hold_ns || + pdata->row_hold_ns > MAX_ROW_HOLD_DELAY || + pdata->row_hold_ns < MIN_ROW_HOLD_DELAY || + ((pdata->row_hold_ns % MIN_ROW_HOLD_DELAY) != 0)) { + dev_err(&pdev->dev, "invalid keypad row hold time supplied\n"); + return -EINVAL; + } + + if (!pdata->debounce_ms || + ((pdata->debounce_ms % 5) != 0) || + pdata->debounce_ms > MAX_DEBOUNCE_TIME || + pdata->debounce_ms < MIN_DEBOUNCE_TIME) { + dev_err(&pdev->dev, "invalid debounce time supplied\n"); + return -EINVAL; + } + + keymap_data = pdata->keymap_data; + if (!keymap_data) { + dev_err(&pdev->dev, "no keymap data supplied\n"); + return -EINVAL; + } + + kp = kzalloc(sizeof(*kp), GFP_KERNEL); + if (!kp) + return -ENOMEM; + + platform_set_drvdata(pdev, kp); + + kp->pdata = pdata; + kp->dev = &pdev->dev; + + kp->input = input_allocate_device(); + if (!kp->input) { + dev_err(&pdev->dev, "unable to allocate input device\n"); + rc = -ENOMEM; + goto err_alloc_device; + } + + kp->key_sense_irq = platform_get_irq(pdev, 0); + if (kp->key_sense_irq < 0) { + dev_err(&pdev->dev, "unable to get keypad sense irq\n"); + rc = -ENXIO; + goto err_get_irq; + } + + kp->key_stuck_irq = platform_get_irq(pdev, 1); + if (kp->key_stuck_irq < 0) { + dev_err(&pdev->dev, "unable to get keypad stuck irq\n"); + rc = -ENXIO; + goto err_get_irq; + } + + kp->input->name = pdata->input_name ? : "PMIC8XXX keypad"; + kp->input->phys = pdata->input_phys_device ? : "pmic8xxx_keypad/input0"; + + kp->input->dev.parent = &pdev->dev; + + kp->input->id.bustype = BUS_I2C; + kp->input->id.version = 0x0001; + kp->input->id.product = 0x0001; + kp->input->id.vendor = 0x0001; + + kp->input->evbit[0] = BIT_MASK(EV_KEY); + + if (pdata->rep) + __set_bit(EV_REP, kp->input->evbit); + + kp->input->keycode = kp->keycodes; + kp->input->keycodemax = PM8XXX_MATRIX_MAX_SIZE; + kp->input->keycodesize = sizeof(kp->keycodes); + kp->input->open = pmic8xxx_kp_open; + kp->input->close = pmic8xxx_kp_close; + + matrix_keypad_build_keymap(keymap_data, PM8XXX_ROW_SHIFT, + kp->input->keycode, kp->input->keybit); + + input_set_capability(kp->input, EV_MSC, MSC_SCAN); + input_set_drvdata(kp->input, kp); + + /* initialize keypad state */ + memset(kp->keystate, 0xff, sizeof(kp->keystate)); + memset(kp->stuckstate, 0xff, sizeof(kp->stuckstate)); + + rc = pmic8xxx_kpd_init(kp); + if (rc < 0) { + dev_err(&pdev->dev, "unable to initialize keypad controller\n"); + goto err_get_irq; + } + + rc = pmic8xxx_kp_config_gpio(pdata->cols_gpio_start, + pdata->num_cols, kp, &kypd_sns); + if (rc < 0) { + dev_err(&pdev->dev, "unable to configure keypad sense lines\n"); + goto err_gpio_config; + } + + rc = pmic8xxx_kp_config_gpio(pdata->rows_gpio_start, + pdata->num_rows, kp, &kypd_drv); + if (rc < 0) { + dev_err(&pdev->dev, "unable to configure keypad drive lines\n"); + goto err_gpio_config; + } + + rc = request_any_context_irq(kp->key_sense_irq, pmic8xxx_kp_irq, + IRQF_TRIGGER_RISING, "pmic-keypad", kp); + if (rc < 0) { + dev_err(&pdev->dev, "failed to request keypad sense irq\n"); + goto err_get_irq; + } + + rc = request_any_context_irq(kp->key_stuck_irq, pmic8xxx_kp_stuck_irq, + IRQF_TRIGGER_RISING, "pmic-keypad-stuck", kp); + if (rc < 0) { + dev_err(&pdev->dev, "failed to request keypad stuck irq\n"); + goto err_req_stuck_irq; + } + + rc = pmic8xxx_kp_read_u8(kp, &ctrl_val, KEYP_CTRL); + if (rc < 0) { + dev_err(&pdev->dev, "failed to read KEYP_CTRL register\n"); + goto err_pmic_reg_read; + } + + kp->ctrl_reg = ctrl_val; + + rc = input_register_device(kp->input); + if (rc < 0) { + dev_err(&pdev->dev, "unable to register keypad input device\n"); + goto err_pmic_reg_read; + } + + device_init_wakeup(&pdev->dev, pdata->wakeup); + + return 0; + +err_pmic_reg_read: + free_irq(kp->key_stuck_irq, NULL); +err_req_stuck_irq: + free_irq(kp->key_sense_irq, NULL); +err_gpio_config: +err_get_irq: + input_free_device(kp->input); +err_alloc_device: + platform_set_drvdata(pdev, NULL); + kfree(kp); + return rc; +} + +static int __devexit pmic8xxx_kp_remove(struct platform_device *pdev) +{ + struct pmic8xxx_kp *kp = platform_get_drvdata(pdev); + + device_init_wakeup(&pdev->dev, 0); + free_irq(kp->key_stuck_irq, NULL); + free_irq(kp->key_sense_irq, NULL); + input_unregister_device(kp->input); + kfree(kp); + + platform_set_drvdata(pdev, NULL); + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int pmic8xxx_kp_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct pmic8xxx_kp *kp = platform_get_drvdata(pdev); + struct input_dev *input_dev = kp->input; + + if (device_may_wakeup(dev)) { + enable_irq_wake(kp->key_sense_irq); + } else { + mutex_lock(&input_dev->mutex); + + if (input_dev->users) + pmic8xxx_kp_disable(kp); + + mutex_unlock(&input_dev->mutex); + } + + return 0; +} + +static int pmic8xxx_kp_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct pmic8xxx_kp *kp = platform_get_drvdata(pdev); + struct input_dev *input_dev = kp->input; + + if (device_may_wakeup(dev)) { + disable_irq_wake(kp->key_sense_irq); + } else { + mutex_lock(&input_dev->mutex); + + if (input_dev->users) + pmic8xxx_kp_enable(kp); + + mutex_unlock(&input_dev->mutex); + } + + return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(pm8xxx_kp_pm_ops, + pmic8xxx_kp_suspend, pmic8xxx_kp_resume); + +static struct platform_driver pmic8xxx_kp_driver = { + .probe = pmic8xxx_kp_probe, + .remove = __devexit_p(pmic8xxx_kp_remove), + .driver = { + .name = PM8XXX_KEYPAD_DEV_NAME, + .owner = THIS_MODULE, + .pm = &pm8xxx_kp_pm_ops, + }, +}; + +static int __init pmic8xxx_kp_init(void) +{ + return platform_driver_register(&pmic8xxx_kp_driver); +} +module_init(pmic8xxx_kp_init); + +static void __exit pmic8xxx_kp_exit(void) +{ + platform_driver_unregister(&pmic8xxx_kp_driver); +} +module_exit(pmic8xxx_kp_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("PMIC8XXX keypad driver"); +MODULE_VERSION("1.0"); +MODULE_ALIAS("platform:pmic8xxx_keypad"); +MODULE_AUTHOR("Trilok Soni "); diff --git a/include/linux/input/pmic8xxx-keypad.h b/include/linux/input/pmic8xxx-keypad.h new file mode 100644 index 000000000000..5f1e2f9ad959 --- /dev/null +++ b/include/linux/input/pmic8xxx-keypad.h @@ -0,0 +1,52 @@ +/* Copyright (c) 2011, Code Aurora Forum. 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 __PMIC8XXX_KEYPAD_H__ +#define __PMIC8XXX_KEYPAD_H__ + +#include + +#define PM8XXX_KEYPAD_DEV_NAME "pm8xxx-keypad" + +/** + * struct pm8xxx_keypad_platform_data - platform data for keypad + * @keymap_data - matrix keymap data + * @input_name - input device name + * @input_phys_device - input device name + * @num_cols - number of columns of keypad + * @num_rows - number of row of keypad + * @debounce_ms - debounce period in milliseconds + * @scan_delay_ms - scan delay in milliseconds + * @row_hold_ns - row hold period in nanoseconds + * @wakeup - configure keypad as wakeup + * @rep - enable or disable key repeat bit + */ +struct pm8xxx_keypad_platform_data { + const struct matrix_keymap_data *keymap_data; + + const char *input_name; + const char *input_phys_device; + + unsigned int num_cols; + unsigned int num_rows; + unsigned int rows_gpio_start; + unsigned int cols_gpio_start; + + unsigned int debounce_ms; + unsigned int scan_delay_ms; + unsigned int row_hold_ns; + + bool wakeup; + bool rep; +}; + +#endif /*__PMIC8XXX_KEYPAD_H__ */ -- cgit From 92d57a73e41047bff7d0812e06f893567876d455 Mon Sep 17 00:00:00 2001 From: Trilok Soni Date: Fri, 13 May 2011 15:17:51 +0530 Subject: input: Add support for Qualcomm PMIC8XXX power key Add support for PMIC8XXX power key driven over dedicated KYPD_PWR_N pin. Acked-by: Dmitry Torokhov Signed-off-by: Trilok Soni Signed-off-by: Anirudh Ghayal Signed-off-by: Samuel Ortiz --- drivers/input/misc/Kconfig | 11 ++ drivers/input/misc/Makefile | 1 + drivers/input/misc/pmic8xxx-pwrkey.c | 231 ++++++++++++++++++++++++++++++++++ include/linux/input/pmic8xxx-pwrkey.h | 31 +++++ 4 files changed, 274 insertions(+) create mode 100644 drivers/input/misc/pmic8xxx-pwrkey.c create mode 100644 include/linux/input/pmic8xxx-pwrkey.h (limited to 'include/linux') diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index f9cf0881b0e3..45dc6aa62ba4 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -330,6 +330,17 @@ config INPUT_PWM_BEEPER To compile this driver as a module, choose M here: the module will be called pwm-beeper. +config INPUT_PMIC8XXX_PWRKEY + tristate "PMIC8XXX power key support" + depends on MFD_PM8XXX + help + Say Y here if you want support for the PMIC8XXX power key. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called pmic8xxx-pwrkey. + config INPUT_GPIO_ROTARY_ENCODER tristate "Rotary encoders connected to GPIO pins" depends on GPIOLIB && GENERIC_GPIO diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index e3f7984e6274..38efb2cb182b 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_INPUT_PCF8574) += pcf8574_keypad.o obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o obj-$(CONFIG_INPUT_POWERMATE) += powermate.o obj-$(CONFIG_INPUT_PWM_BEEPER) += pwm-beeper.o +obj-$(CONFIG_INPUT_PMIC8XXX_PWRKEY) += pmic8xxx-pwrkey.o obj-$(CONFIG_INPUT_RB532_BUTTON) += rb532_button.o obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER) += rotary_encoder.o obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o diff --git a/drivers/input/misc/pmic8xxx-pwrkey.c b/drivers/input/misc/pmic8xxx-pwrkey.c new file mode 100644 index 000000000000..97e07e786e41 --- /dev/null +++ b/drivers/input/misc/pmic8xxx-pwrkey.c @@ -0,0 +1,231 @@ +/* Copyright (c) 2010-2011, Code Aurora Forum. 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define PON_CNTL_1 0x1C +#define PON_CNTL_PULL_UP BIT(7) +#define PON_CNTL_TRIG_DELAY_MASK (0x7) + +/** + * struct pmic8xxx_pwrkey - pmic8xxx pwrkey information + * @key_press_irq: key press irq number + */ +struct pmic8xxx_pwrkey { + struct input_dev *pwr; + int key_press_irq; +}; + +static irqreturn_t pwrkey_press_irq(int irq, void *_pwrkey) +{ + struct pmic8xxx_pwrkey *pwrkey = _pwrkey; + + input_report_key(pwrkey->pwr, KEY_POWER, 1); + input_sync(pwrkey->pwr); + + return IRQ_HANDLED; +} + +static irqreturn_t pwrkey_release_irq(int irq, void *_pwrkey) +{ + struct pmic8xxx_pwrkey *pwrkey = _pwrkey; + + input_report_key(pwrkey->pwr, KEY_POWER, 0); + input_sync(pwrkey->pwr); + + return IRQ_HANDLED; +} + +#ifdef CONFIG_PM_SLEEP +static int pmic8xxx_pwrkey_suspend(struct device *dev) +{ + struct pmic8xxx_pwrkey *pwrkey = dev_get_drvdata(dev); + + if (device_may_wakeup(dev)) + enable_irq_wake(pwrkey->key_press_irq); + + return 0; +} + +static int pmic8xxx_pwrkey_resume(struct device *dev) +{ + struct pmic8xxx_pwrkey *pwrkey = dev_get_drvdata(dev); + + if (device_may_wakeup(dev)) + disable_irq_wake(pwrkey->key_press_irq); + + return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(pm8xxx_pwr_key_pm_ops, + pmic8xxx_pwrkey_suspend, pmic8xxx_pwrkey_resume); + +static int __devinit pmic8xxx_pwrkey_probe(struct platform_device *pdev) +{ + struct input_dev *pwr; + int key_release_irq = platform_get_irq(pdev, 0); + int key_press_irq = platform_get_irq(pdev, 1); + int err; + unsigned int delay; + u8 pon_cntl; + struct pmic8xxx_pwrkey *pwrkey; + const struct pm8xxx_pwrkey_platform_data *pdata = mfd_get_data(pdev); + + if (!pdata) { + dev_err(&pdev->dev, "power key platform data not supplied\n"); + return -EINVAL; + } + + if (pdata->kpd_trigger_delay_us > 62500) { + dev_err(&pdev->dev, "invalid power key trigger delay\n"); + return -EINVAL; + } + + pwrkey = kzalloc(sizeof(*pwrkey), GFP_KERNEL); + if (!pwrkey) + return -ENOMEM; + + pwr = input_allocate_device(); + if (!pwr) { + dev_dbg(&pdev->dev, "Can't allocate power button\n"); + err = -ENOMEM; + goto free_pwrkey; + } + + input_set_capability(pwr, EV_KEY, KEY_POWER); + + pwr->name = "pmic8xxx_pwrkey"; + pwr->phys = "pmic8xxx_pwrkey/input0"; + pwr->dev.parent = &pdev->dev; + + delay = (pdata->kpd_trigger_delay_us << 10) / USEC_PER_SEC; + delay = 1 + ilog2(delay); + + err = pm8xxx_readb(pdev->dev.parent, PON_CNTL_1, &pon_cntl); + if (err < 0) { + dev_err(&pdev->dev, "failed reading PON_CNTL_1 err=%d\n", err); + goto free_input_dev; + } + + pon_cntl &= ~PON_CNTL_TRIG_DELAY_MASK; + pon_cntl |= (delay & PON_CNTL_TRIG_DELAY_MASK); + if (pdata->pull_up) + pon_cntl |= PON_CNTL_PULL_UP; + else + pon_cntl &= ~PON_CNTL_PULL_UP; + + err = pm8xxx_writeb(pdev->dev.parent, PON_CNTL_1, pon_cntl); + if (err < 0) { + dev_err(&pdev->dev, "failed writing PON_CNTL_1 err=%d\n", err); + goto free_input_dev; + } + + err = input_register_device(pwr); + if (err) { + dev_dbg(&pdev->dev, "Can't register power key: %d\n", err); + goto free_input_dev; + } + + pwrkey->key_press_irq = key_press_irq; + pwrkey->pwr = pwr; + + platform_set_drvdata(pdev, pwrkey); + + err = request_irq(key_press_irq, pwrkey_press_irq, + IRQF_TRIGGER_RISING, "pmic8xxx_pwrkey_press", pwrkey); + if (err < 0) { + dev_dbg(&pdev->dev, "Can't get %d IRQ for pwrkey: %d\n", + key_press_irq, err); + goto unreg_input_dev; + } + + err = request_irq(key_release_irq, pwrkey_release_irq, + IRQF_TRIGGER_RISING, "pmic8xxx_pwrkey_release", pwrkey); + if (err < 0) { + dev_dbg(&pdev->dev, "Can't get %d IRQ for pwrkey: %d\n", + key_release_irq, err); + + goto free_press_irq; + } + + device_init_wakeup(&pdev->dev, pdata->wakeup); + + return 0; + +free_press_irq: + free_irq(key_press_irq, NULL); +unreg_input_dev: + platform_set_drvdata(pdev, NULL); + input_unregister_device(pwr); + pwr = NULL; +free_input_dev: + input_free_device(pwr); +free_pwrkey: + kfree(pwrkey); + return err; +} + +static int __devexit pmic8xxx_pwrkey_remove(struct platform_device *pdev) +{ + struct pmic8xxx_pwrkey *pwrkey = platform_get_drvdata(pdev); + int key_release_irq = platform_get_irq(pdev, 0); + int key_press_irq = platform_get_irq(pdev, 1); + + device_init_wakeup(&pdev->dev, 0); + + free_irq(key_press_irq, pwrkey); + free_irq(key_release_irq, pwrkey); + input_unregister_device(pwrkey->pwr); + platform_set_drvdata(pdev, NULL); + kfree(pwrkey); + + return 0; +} + +static struct platform_driver pmic8xxx_pwrkey_driver = { + .probe = pmic8xxx_pwrkey_probe, + .remove = __devexit_p(pmic8xxx_pwrkey_remove), + .driver = { + .name = PM8XXX_PWRKEY_DEV_NAME, + .owner = THIS_MODULE, + .pm = &pm8xxx_pwr_key_pm_ops, + }, +}; + +static int __init pmic8xxx_pwrkey_init(void) +{ + return platform_driver_register(&pmic8xxx_pwrkey_driver); +} +module_init(pmic8xxx_pwrkey_init); + +static void __exit pmic8xxx_pwrkey_exit(void) +{ + platform_driver_unregister(&pmic8xxx_pwrkey_driver); +} +module_exit(pmic8xxx_pwrkey_exit); + +MODULE_ALIAS("platform:pmic8xxx_pwrkey"); +MODULE_DESCRIPTION("PMIC8XXX Power Key driver"); +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Trilok Soni "); diff --git a/include/linux/input/pmic8xxx-pwrkey.h b/include/linux/input/pmic8xxx-pwrkey.h new file mode 100644 index 000000000000..6d2974e57109 --- /dev/null +++ b/include/linux/input/pmic8xxx-pwrkey.h @@ -0,0 +1,31 @@ +/* Copyright (c) 2010-2011, Code Aurora Forum. 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 __PMIC8XXX_PWRKEY_H__ +#define __PMIC8XXX_PWRKEY_H__ + +#define PM8XXX_PWRKEY_DEV_NAME "pm8xxx-pwrkey" + +/** + * struct pm8xxx_pwrkey_platform_data - platform data for pwrkey driver + * @pull up: power on register control for pull up/down configuration + * @kpd_trigger_delay_us: time delay for power key state change interrupt + * trigger. + * @wakeup: configure power key as wakeup source + */ +struct pm8xxx_pwrkey_platform_data { + bool pull_up; + u32 kpd_trigger_delay_us; + u32 wakeup; +}; + +#endif /* __PMIC8XXX_PWRKEY_H__ */ -- cgit From 86e4ca66e81bba0f8640f1fa19b8b8f72cbd0561 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 26 May 2011 15:00:31 -0400 Subject: bug.h: Move ratelimit warn interfaces to ratelimit.h As reported by Ingo Molnar, we still have configuration combinations where use of the WARN_RATELIMIT interfaces break the build because dependencies don't get met. Instead of going down the long road of trying to make it so that ratelimit.h can get included by kernel.h or asm-generic/bug.h, just move the interface into ratelimit.h and make users have to include that. Reported-by: Ingo Molnar Signed-off-by: David S. Miller Acked-by: Randy Dunlap --- include/asm-generic/bug.h | 40 ---------------------------------------- include/linux/ratelimit.h | 40 ++++++++++++++++++++++++++++++++++++++++ net/core/filter.c | 1 + 3 files changed, 41 insertions(+), 40 deletions(-) (limited to 'include/linux') diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h index 91784841e407..dfb0ec666c94 100644 --- a/include/asm-generic/bug.h +++ b/include/asm-generic/bug.h @@ -162,46 +162,6 @@ extern void warn_slowpath_null(const char *file, const int line); unlikely(__ret_warn_once); \ }) -#ifdef CONFIG_PRINTK - -#define WARN_ON_RATELIMIT(condition, state) \ - WARN_ON((condition) && __ratelimit(state)) - -#define __WARN_RATELIMIT(condition, state, format...) \ -({ \ - int rtn = 0; \ - if (unlikely(__ratelimit(state))) \ - rtn = WARN(condition, format); \ - rtn; \ -}) - -#define WARN_RATELIMIT(condition, format...) \ -({ \ - static DEFINE_RATELIMIT_STATE(_rs, \ - DEFAULT_RATELIMIT_INTERVAL, \ - DEFAULT_RATELIMIT_BURST); \ - __WARN_RATELIMIT(condition, &_rs, format); \ -}) - -#else - -#define WARN_ON_RATELIMIT(condition, state) \ - WARN_ON(condition) - -#define __WARN_RATELIMIT(condition, state, format...) \ -({ \ - int rtn = WARN(condition, format); \ - rtn; \ -}) - -#define WARN_RATELIMIT(condition, format...) \ -({ \ - int rtn = WARN(condition, format); \ - rtn; \ -}) - -#endif - /* * WARN_ON_SMP() is for cases that the warning is either * meaningless for !SMP or may even cause failures. diff --git a/include/linux/ratelimit.h b/include/linux/ratelimit.h index 03ff67b0cdf5..2f007157fab9 100644 --- a/include/linux/ratelimit.h +++ b/include/linux/ratelimit.h @@ -41,4 +41,44 @@ extern struct ratelimit_state printk_ratelimit_state; extern int ___ratelimit(struct ratelimit_state *rs, const char *func); #define __ratelimit(state) ___ratelimit(state, __func__) +#ifdef CONFIG_PRINTK + +#define WARN_ON_RATELIMIT(condition, state) \ + WARN_ON((condition) && __ratelimit(state)) + +#define __WARN_RATELIMIT(condition, state, format...) \ +({ \ + int rtn = 0; \ + if (unlikely(__ratelimit(state))) \ + rtn = WARN(condition, format); \ + rtn; \ +}) + +#define WARN_RATELIMIT(condition, format...) \ +({ \ + static DEFINE_RATELIMIT_STATE(_rs, \ + DEFAULT_RATELIMIT_INTERVAL, \ + DEFAULT_RATELIMIT_BURST); \ + __WARN_RATELIMIT(condition, &_rs, format); \ +}) + +#else + +#define WARN_ON_RATELIMIT(condition, state) \ + WARN_ON(condition) + +#define __WARN_RATELIMIT(condition, state, format...) \ +({ \ + int rtn = WARN(condition, format); \ + rtn; \ +}) + +#define WARN_RATELIMIT(condition, format...) \ +({ \ + int rtn = WARN(condition, format); \ + rtn; \ +}) + +#endif + #endif /* _LINUX_RATELIMIT_H */ diff --git a/net/core/filter.c b/net/core/filter.c index 0e3622f1dcb1..36f975fa87cb 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -38,6 +38,7 @@ #include #include #include +#include /* No hurry in this branch */ static void *__load_pointer(const struct sk_buff *skb, int k, unsigned int size) -- cgit From be93d8cfbae1996052e91b2883d306a5d9d0fe18 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 26 May 2011 12:03:50 -0700 Subject: Fix build with !HUGETLBFS I stupidly broke the case of CONFIG_HUGETLBFS=n when doing the conversion to vm_flags_t in commit ca16d140af91 ("mm: don't access vm_flags as 'int'"). And my 'allyesconfig' build didn't find it, for obvious reasons.. Include in . The problem could have been avoided by just turning the hugetlb_file_setup() error wrapper into a macro, but mm_types.h is a reasonable include in this file. Reported-by: Richard -rw- Weinberger Signed-off-by: Linus Torvalds --- include/linux/hugetlb.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index cf8931e1dd9d..59225ef27d15 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -1,6 +1,7 @@ #ifndef _LINUX_HUGETLB_H #define _LINUX_HUGETLB_H +#include #include #include -- cgit From 7fe4fc881d1340f17396f52c836e597dadadea42 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Wed, 25 May 2011 10:33:17 -0700 Subject: Intel xhci: Add PCI id for Panther Point xHCI host. This adds the PCI ID for the xHCI (USB 3.0) host controller in the Intel Panther Point chipset. It will be used by both the EHCI and xHCI driver in the following patches. Signed-off-by: Sarah Sharp --- include/linux/pci_ids.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 24787b751286..a311008af5e1 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2483,6 +2483,7 @@ #define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX 0x1c5f #define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_0 0x1d40 #define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_1 0x1d41 +#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_XHCI 0x1e31 #define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MIN 0x1e40 #define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MAX 0x1e5f #define PCI_DEVICE_ID_INTEL_DH89XXCC_LPC_MIN 0x2310 -- cgit From 704f15ddb5fc2a7f25a12eb0913302d8ad9ffab3 Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Thu, 26 May 2011 16:25:02 -0700 Subject: flex_array: avoid divisions when accessing elements On most architectures division is an expensive operation and accessing an element currently requires four of them. This performance penalty effectively precludes flex arrays from being used on any kind of fast path. However, two of these divisions can be handled at creation time and the others can be replaced by a reciprocal divide, completely avoiding real divisions on access. [eparis@redhat.com: rebase on top of changes to support 0 len elements] [eparis@redhat.com: initialize part_nr when array fits entirely in base] Signed-off-by: Jesse Gross Signed-off-by: Eric Paris Cc: Dave Hansen Cc: David Rientjes Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/flex_array.h | 2 ++ lib/flex_array.c | 51 ++++++++++++++++++++++++++-------------------- 2 files changed, 31 insertions(+), 22 deletions(-) (limited to 'include/linux') diff --git a/include/linux/flex_array.h b/include/linux/flex_array.h index ebeb2f3ad068..6843cf193a44 100644 --- a/include/linux/flex_array.h +++ b/include/linux/flex_array.h @@ -21,6 +21,8 @@ struct flex_array { struct { int element_size; int total_nr_elements; + int elems_per_part; + u32 reciprocal_elems; struct flex_array_part *parts[]; }; /* diff --git a/lib/flex_array.c b/lib/flex_array.c index cab7621f98aa..9b8b89458c4c 100644 --- a/lib/flex_array.c +++ b/lib/flex_array.c @@ -24,6 +24,7 @@ #include #include #include +#include struct flex_array_part { char elements[FLEX_ARRAY_PART_SIZE]; @@ -70,15 +71,15 @@ static inline int elements_fit_in_base(struct flex_array *fa) * Element size | Objects | Objects | * PAGE_SIZE=4k | 32-bit | 64-bit | * ---------------------------------| - * 1 bytes | 4186112 | 2093056 | - * 2 bytes | 2093056 | 1046528 | - * 3 bytes | 1395030 | 697515 | - * 4 bytes | 1046528 | 523264 | - * 32 bytes | 130816 | 65408 | - * 33 bytes | 126728 | 63364 | - * 2048 bytes | 2044 | 1022 | - * 2049 bytes | 1022 | 511 | - * void * | 1046528 | 261632 | + * 1 bytes | 4177920 | 2088960 | + * 2 bytes | 2088960 | 1044480 | + * 3 bytes | 1392300 | 696150 | + * 4 bytes | 1044480 | 522240 | + * 32 bytes | 130560 | 65408 | + * 33 bytes | 126480 | 63240 | + * 2048 bytes | 2040 | 1020 | + * 2049 bytes | 1020 | 510 | + * void * | 1044480 | 261120 | * * Since 64-bit pointers are twice the size, we lose half the * capacity in the base structure. Also note that no effort is made @@ -88,11 +89,15 @@ struct flex_array *flex_array_alloc(int element_size, unsigned int total, gfp_t flags) { struct flex_array *ret; + int elems_per_part = 0; + int reciprocal_elems = 0; int max_size = 0; - if (element_size) - max_size = FLEX_ARRAY_NR_BASE_PTRS * - FLEX_ARRAY_ELEMENTS_PER_PART(element_size); + if (element_size) { + elems_per_part = FLEX_ARRAY_ELEMENTS_PER_PART(element_size); + reciprocal_elems = reciprocal_value(elems_per_part); + max_size = FLEX_ARRAY_NR_BASE_PTRS * elems_per_part; + } /* max_size will end up 0 if element_size > PAGE_SIZE */ if (total > max_size) @@ -102,6 +107,8 @@ struct flex_array *flex_array_alloc(int element_size, unsigned int total, return NULL; ret->element_size = element_size; ret->total_nr_elements = total; + ret->elems_per_part = elems_per_part; + ret->reciprocal_elems = reciprocal_elems; if (elements_fit_in_base(ret) && !(flags & __GFP_ZERO)) memset(&ret->parts[0], FLEX_ARRAY_FREE, FLEX_ARRAY_BASE_BYTES_LEFT); @@ -112,7 +119,7 @@ EXPORT_SYMBOL(flex_array_alloc); static int fa_element_to_part_nr(struct flex_array *fa, unsigned int element_nr) { - return element_nr / FLEX_ARRAY_ELEMENTS_PER_PART(fa->element_size); + return reciprocal_divide(element_nr, fa->reciprocal_elems); } /** @@ -141,12 +148,12 @@ void flex_array_free(struct flex_array *fa) EXPORT_SYMBOL(flex_array_free); static unsigned int index_inside_part(struct flex_array *fa, - unsigned int element_nr) + unsigned int element_nr, + unsigned int part_nr) { unsigned int part_offset; - part_offset = element_nr % - FLEX_ARRAY_ELEMENTS_PER_PART(fa->element_size); + part_offset = element_nr - part_nr * fa->elems_per_part; return part_offset * fa->element_size; } @@ -186,7 +193,7 @@ __fa_get_part(struct flex_array *fa, int part_nr, gfp_t flags) int flex_array_put(struct flex_array *fa, unsigned int element_nr, void *src, gfp_t flags) { - int part_nr; + int part_nr = 0; struct flex_array_part *part; void *dst; @@ -202,7 +209,7 @@ int flex_array_put(struct flex_array *fa, unsigned int element_nr, void *src, if (!part) return -ENOMEM; } - dst = &part->elements[index_inside_part(fa, element_nr)]; + dst = &part->elements[index_inside_part(fa, element_nr, part_nr)]; memcpy(dst, src, fa->element_size); return 0; } @@ -217,7 +224,7 @@ EXPORT_SYMBOL(flex_array_put); */ int flex_array_clear(struct flex_array *fa, unsigned int element_nr) { - int part_nr; + int part_nr = 0; struct flex_array_part *part; void *dst; @@ -233,7 +240,7 @@ int flex_array_clear(struct flex_array *fa, unsigned int element_nr) if (!part) return -EINVAL; } - dst = &part->elements[index_inside_part(fa, element_nr)]; + dst = &part->elements[index_inside_part(fa, element_nr, part_nr)]; memset(dst, FLEX_ARRAY_FREE, fa->element_size); return 0; } @@ -302,7 +309,7 @@ EXPORT_SYMBOL(flex_array_prealloc); */ void *flex_array_get(struct flex_array *fa, unsigned int element_nr) { - int part_nr; + int part_nr = 0; struct flex_array_part *part; if (!fa->element_size) @@ -317,7 +324,7 @@ void *flex_array_get(struct flex_array *fa, unsigned int element_nr) if (!part) return NULL; } - return &part->elements[index_inside_part(fa, element_nr)]; + return &part->elements[index_inside_part(fa, element_nr, part_nr)]; } EXPORT_SYMBOL(flex_array_get); -- cgit From 9796cc964daf7f18b4cd84c86975b3bc3804ca5a Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 26 May 2011 16:25:12 -0700 Subject: drivers/rtc/rtc-mxc.c: remove defines already included in rtc.h [akpm@linux-foundation.org: retain the code comments] Signed-off-by: Wolfram Sang Cc: Vladimir Zapolskiy Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-mxc.c | 6 ------ include/linux/rtc.h | 8 ++++---- 2 files changed, 4 insertions(+), 10 deletions(-) (limited to 'include/linux') diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c index d814417bee8c..39e41fbdf08b 100644 --- a/drivers/rtc/rtc-mxc.c +++ b/drivers/rtc/rtc-mxc.c @@ -55,12 +55,6 @@ static const u32 PIE_BIT_DEF[MAX_PIE_NUM][2] = { { MAX_PIE_FREQ, RTC_SAM7_BIT }, }; -/* Those are the bits from a classic RTC we want to mimic */ -#define RTC_IRQF 0x80 /* any of the following 3 is active */ -#define RTC_PF 0x40 /* Periodic interrupt */ -#define RTC_AF 0x20 /* Alarm interrupt */ -#define RTC_UF 0x10 /* Update interrupt for 1Hz RTC */ - #define MXC_RTC_TIME 0 #define MXC_RTC_ALARM 1 diff --git a/include/linux/rtc.h b/include/linux/rtc.h index 877ece45426f..b27ebea25660 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -92,10 +92,10 @@ struct rtc_pll_info { #define RTC_PLL_SET _IOW('p', 0x12, struct rtc_pll_info) /* Set PLL correction */ /* interrupt flags */ -#define RTC_IRQF 0x80 /* any of the following is active */ -#define RTC_PF 0x40 -#define RTC_AF 0x20 -#define RTC_UF 0x10 +#define RTC_IRQF 0x80 /* Any of the following is active */ +#define RTC_PF 0x40 /* Periodic interrupt */ +#define RTC_AF 0x20 /* Alarm interrupt */ +#define RTC_UF 0x10 /* Update interrupt for 1Hz RTC */ #ifdef __KERNEL__ -- cgit From 4714d1d32d97239fb5ae3e10521d3f133a899b66 Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Thu, 26 May 2011 16:25:18 -0700 Subject: cgroups: read-write lock CLONE_THREAD forking per threadgroup Adds functionality to read/write lock CLONE_THREAD fork()ing per-threadgroup Add an rwsem that lives in a threadgroup's signal_struct that's taken for reading in the fork path, under CONFIG_CGROUPS. If another part of the kernel later wants to use such a locking mechanism, the CONFIG_CGROUPS ifdefs should be changed to a higher-up flag that CGROUPS and the other system would both depend on. This is a pre-patch for cgroup-procs-write.patch. Signed-off-by: Ben Blum Cc: "Eric W. Biederman" Cc: Li Zefan Cc: Matt Helsley Reviewed-by: Paul Menage Cc: Oleg Nesterov Cc: David Rientjes Cc: Miao Xie Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/init_task.h | 9 +++++++++ include/linux/sched.h | 36 ++++++++++++++++++++++++++++++++++++ kernel/fork.c | 10 ++++++++++ 3 files changed, 55 insertions(+) (limited to 'include/linux') diff --git a/include/linux/init_task.h b/include/linux/init_task.h index bafc58c00fc3..580f70c02391 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h @@ -22,6 +22,14 @@ extern struct files_struct init_files; extern struct fs_struct init_fs; +#ifdef CONFIG_CGROUPS +#define INIT_THREADGROUP_FORK_LOCK(sig) \ + .threadgroup_fork_lock = \ + __RWSEM_INITIALIZER(sig.threadgroup_fork_lock), +#else +#define INIT_THREADGROUP_FORK_LOCK(sig) +#endif + #define INIT_SIGNALS(sig) { \ .nr_threads = 1, \ .wait_chldexit = __WAIT_QUEUE_HEAD_INITIALIZER(sig.wait_chldexit),\ @@ -38,6 +46,7 @@ extern struct fs_struct init_fs; }, \ .cred_guard_mutex = \ __MUTEX_INITIALIZER(sig.cred_guard_mutex), \ + INIT_THREADGROUP_FORK_LOCK(sig) \ } extern struct nsproxy init_nsproxy; diff --git a/include/linux/sched.h b/include/linux/sched.h index f18300eddfcb..dc8871295a5a 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -513,6 +513,7 @@ struct thread_group_cputimer { spinlock_t lock; }; +#include struct autogroup; /* @@ -632,6 +633,16 @@ struct signal_struct { unsigned audit_tty; struct tty_audit_buf *tty_audit_buf; #endif +#ifdef CONFIG_CGROUPS + /* + * The threadgroup_fork_lock prevents threads from forking with + * CLONE_THREAD while held for writing. Use this for fork-sensitive + * threadgroup-wide operations. It's taken for reading in fork.c in + * copy_process(). + * Currently only needed write-side by cgroups. + */ + struct rw_semaphore threadgroup_fork_lock; +#endif int oom_adj; /* OOM kill score adjustment (bit shift) */ int oom_score_adj; /* OOM kill score adjustment */ @@ -2323,6 +2334,31 @@ static inline void unlock_task_sighand(struct task_struct *tsk, spin_unlock_irqrestore(&tsk->sighand->siglock, *flags); } +/* See the declaration of threadgroup_fork_lock in signal_struct. */ +#ifdef CONFIG_CGROUPS +static inline void threadgroup_fork_read_lock(struct task_struct *tsk) +{ + down_read(&tsk->signal->threadgroup_fork_lock); +} +static inline void threadgroup_fork_read_unlock(struct task_struct *tsk) +{ + up_read(&tsk->signal->threadgroup_fork_lock); +} +static inline void threadgroup_fork_write_lock(struct task_struct *tsk) +{ + down_write(&tsk->signal->threadgroup_fork_lock); +} +static inline void threadgroup_fork_write_unlock(struct task_struct *tsk) +{ + up_write(&tsk->signal->threadgroup_fork_lock); +} +#else +static inline void threadgroup_fork_read_lock(struct task_struct *tsk) {} +static inline void threadgroup_fork_read_unlock(struct task_struct *tsk) {} +static inline void threadgroup_fork_write_lock(struct task_struct *tsk) {} +static inline void threadgroup_fork_write_unlock(struct task_struct *tsk) {} +#endif + #ifndef __HAVE_THREAD_FUNCTIONS #define task_thread_info(task) ((struct thread_info *)(task)->stack) diff --git a/kernel/fork.c b/kernel/fork.c index 8e7e135d0817..1fa9d940e301 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -957,6 +957,10 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) tty_audit_fork(sig); sched_autogroup_fork(sig); +#ifdef CONFIG_CGROUPS + init_rwsem(&sig->threadgroup_fork_lock); +#endif + sig->oom_adj = current->signal->oom_adj; sig->oom_score_adj = current->signal->oom_score_adj; sig->oom_score_adj_min = current->signal->oom_score_adj_min; @@ -1138,6 +1142,8 @@ static struct task_struct *copy_process(unsigned long clone_flags, monotonic_to_bootbased(&p->real_start_time); p->io_context = NULL; p->audit_context = NULL; + if (clone_flags & CLONE_THREAD) + threadgroup_fork_read_lock(current); cgroup_fork(p); #ifdef CONFIG_NUMA p->mempolicy = mpol_dup(p->mempolicy); @@ -1342,6 +1348,8 @@ static struct task_struct *copy_process(unsigned long clone_flags, write_unlock_irq(&tasklist_lock); proc_fork_connector(p); cgroup_post_fork(p); + if (clone_flags & CLONE_THREAD) + threadgroup_fork_read_unlock(current); perf_event_fork(p); return p; @@ -1380,6 +1388,8 @@ bad_fork_cleanup_policy: mpol_put(p->mempolicy); bad_fork_cleanup_cgroup: #endif + if (clone_flags & CLONE_THREAD) + threadgroup_fork_read_unlock(current); cgroup_exit(p, cgroup_callbacks_done); delayacct_tsk_free(p); module_put(task_thread_info(p)->exec_domain->module); -- cgit From f780bdb7c1c73009cb57adcf99ef50027d80bf3c Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Thu, 26 May 2011 16:25:19 -0700 Subject: cgroups: add per-thread subsystem callbacks Add cgroup subsystem callbacks for per-thread attachment in atomic contexts Add can_attach_task(), pre_attach(), and attach_task() as new callbacks for cgroups's subsystem interface. Unlike can_attach and attach, these are for per-thread operations, to be called potentially many times when attaching an entire threadgroup. Also, the old "bool threadgroup" interface is removed, as replaced by this. All subsystems are modified for the new interface - of note is cpuset, which requires from/to nodemasks for attach to be globally scoped (though per-cpuset would work too) to persist from its pre_attach to attach_task and attach. This is a pre-patch for cgroup-procs-writable.patch. Signed-off-by: Ben Blum Cc: "Eric W. Biederman" Cc: Li Zefan Cc: Matt Helsley Reviewed-by: Paul Menage Cc: Oleg Nesterov Cc: David Rientjes Cc: Miao Xie Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/cgroups/cgroups.txt | 30 ++++++++---- block/blk-cgroup.c | 18 +++----- include/linux/cgroup.h | 10 ++-- kernel/cgroup.c | 17 +++++-- kernel/cgroup_freezer.c | 26 ++++------- kernel/cpuset.c | 96 +++++++++++++++++++-------------------- kernel/sched.c | 38 ++-------------- mm/memcontrol.c | 18 +++----- security/device_cgroup.c | 3 +- 9 files changed, 114 insertions(+), 142 deletions(-) (limited to 'include/linux') diff --git a/Documentation/cgroups/cgroups.txt b/Documentation/cgroups/cgroups.txt index aedf1bd02fdd..b3bd3bdbe202 100644 --- a/Documentation/cgroups/cgroups.txt +++ b/Documentation/cgroups/cgroups.txt @@ -575,7 +575,7 @@ rmdir() will fail with it. From this behavior, pre_destroy() can be called multiple times against a cgroup. int can_attach(struct cgroup_subsys *ss, struct cgroup *cgrp, - struct task_struct *task, bool threadgroup) + struct task_struct *task) (cgroup_mutex held by caller) Called prior to moving a task into a cgroup; if the subsystem @@ -584,9 +584,14 @@ task is passed, then a successful result indicates that *any* unspecified task can be moved into the cgroup. Note that this isn't called on a fork. If this method returns 0 (success) then this should remain valid while the caller holds cgroup_mutex and it is ensured that either -attach() or cancel_attach() will be called in future. If threadgroup is -true, then a successful result indicates that all threads in the given -thread's threadgroup can be moved together. +attach() or cancel_attach() will be called in future. + +int can_attach_task(struct cgroup *cgrp, struct task_struct *tsk); +(cgroup_mutex held by caller) + +As can_attach, but for operations that must be run once per task to be +attached (possibly many when using cgroup_attach_proc). Called after +can_attach. void cancel_attach(struct cgroup_subsys *ss, struct cgroup *cgrp, struct task_struct *task, bool threadgroup) @@ -598,15 +603,24 @@ function, so that the subsystem can implement a rollback. If not, not necessary. This will be called only about subsystems whose can_attach() operation have succeeded. +void pre_attach(struct cgroup *cgrp); +(cgroup_mutex held by caller) + +For any non-per-thread attachment work that needs to happen before +attach_task. Needed by cpuset. + void attach(struct cgroup_subsys *ss, struct cgroup *cgrp, - struct cgroup *old_cgrp, struct task_struct *task, - bool threadgroup) + struct cgroup *old_cgrp, struct task_struct *task) (cgroup_mutex held by caller) Called after the task has been attached to the cgroup, to allow any post-attachment activity that requires memory allocations or blocking. -If threadgroup is true, the subsystem should take care of all threads -in the specified thread's threadgroup. Currently does not support any + +void attach_task(struct cgroup *cgrp, struct task_struct *tsk); +(cgroup_mutex held by caller) + +As attach, but for operations that must be run once per task to be attached, +like can_attach_task. Called before attach. Currently does not support any subsystem that might need the old_cgrp for every thread in the group. void fork(struct cgroup_subsy *ss, struct task_struct *task) diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index 07371cfdfae6..bcaf16ee6ad1 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c @@ -30,10 +30,8 @@ EXPORT_SYMBOL_GPL(blkio_root_cgroup); static struct cgroup_subsys_state *blkiocg_create(struct cgroup_subsys *, struct cgroup *); -static int blkiocg_can_attach(struct cgroup_subsys *, struct cgroup *, - struct task_struct *, bool); -static void blkiocg_attach(struct cgroup_subsys *, struct cgroup *, - struct cgroup *, struct task_struct *, bool); +static int blkiocg_can_attach_task(struct cgroup *, struct task_struct *); +static void blkiocg_attach_task(struct cgroup *, struct task_struct *); static void blkiocg_destroy(struct cgroup_subsys *, struct cgroup *); static int blkiocg_populate(struct cgroup_subsys *, struct cgroup *); @@ -46,8 +44,8 @@ static int blkiocg_populate(struct cgroup_subsys *, struct cgroup *); struct cgroup_subsys blkio_subsys = { .name = "blkio", .create = blkiocg_create, - .can_attach = blkiocg_can_attach, - .attach = blkiocg_attach, + .can_attach_task = blkiocg_can_attach_task, + .attach_task = blkiocg_attach_task, .destroy = blkiocg_destroy, .populate = blkiocg_populate, #ifdef CONFIG_BLK_CGROUP @@ -1616,9 +1614,7 @@ done: * of the main cic data structures. For now we allow a task to change * its cgroup only if it's the only owner of its ioc. */ -static int blkiocg_can_attach(struct cgroup_subsys *subsys, - struct cgroup *cgroup, struct task_struct *tsk, - bool threadgroup) +static int blkiocg_can_attach_task(struct cgroup *cgrp, struct task_struct *tsk) { struct io_context *ioc; int ret = 0; @@ -1633,9 +1629,7 @@ static int blkiocg_can_attach(struct cgroup_subsys *subsys, return ret; } -static void blkiocg_attach(struct cgroup_subsys *subsys, struct cgroup *cgroup, - struct cgroup *prev, struct task_struct *tsk, - bool threadgroup) +static void blkiocg_attach_task(struct cgroup *cgrp, struct task_struct *tsk) { struct io_context *ioc; diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 5ac7ebc36dbb..1e6cde21fa3f 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -467,12 +467,14 @@ struct cgroup_subsys { int (*pre_destroy)(struct cgroup_subsys *ss, struct cgroup *cgrp); void (*destroy)(struct cgroup_subsys *ss, struct cgroup *cgrp); int (*can_attach)(struct cgroup_subsys *ss, struct cgroup *cgrp, - struct task_struct *tsk, bool threadgroup); + struct task_struct *tsk); + int (*can_attach_task)(struct cgroup *cgrp, struct task_struct *tsk); void (*cancel_attach)(struct cgroup_subsys *ss, struct cgroup *cgrp, - struct task_struct *tsk, bool threadgroup); + struct task_struct *tsk); + void (*pre_attach)(struct cgroup *cgrp); + void (*attach_task)(struct cgroup *cgrp, struct task_struct *tsk); void (*attach)(struct cgroup_subsys *ss, struct cgroup *cgrp, - struct cgroup *old_cgrp, struct task_struct *tsk, - bool threadgroup); + struct cgroup *old_cgrp, struct task_struct *tsk); void (*fork)(struct cgroup_subsys *ss, struct task_struct *task); void (*exit)(struct cgroup_subsys *ss, struct cgroup *cgrp, struct cgroup *old_cgrp, struct task_struct *task); diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 909a35510af5..38fb0ad1cb46 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -1759,7 +1759,7 @@ int cgroup_attach_task(struct cgroup *cgrp, struct task_struct *tsk) for_each_subsys(root, ss) { if (ss->can_attach) { - retval = ss->can_attach(ss, cgrp, tsk, false); + retval = ss->can_attach(ss, cgrp, tsk); if (retval) { /* * Remember on which subsystem the can_attach() @@ -1771,6 +1771,13 @@ int cgroup_attach_task(struct cgroup *cgrp, struct task_struct *tsk) goto out; } } + if (ss->can_attach_task) { + retval = ss->can_attach_task(cgrp, tsk); + if (retval) { + failed_ss = ss; + goto out; + } + } } task_lock(tsk); @@ -1805,8 +1812,12 @@ int cgroup_attach_task(struct cgroup *cgrp, struct task_struct *tsk) write_unlock(&css_set_lock); for_each_subsys(root, ss) { + if (ss->pre_attach) + ss->pre_attach(cgrp); + if (ss->attach_task) + ss->attach_task(cgrp, tsk); if (ss->attach) - ss->attach(ss, cgrp, oldcgrp, tsk, false); + ss->attach(ss, cgrp, oldcgrp, tsk); } set_bit(CGRP_RELEASABLE, &oldcgrp->flags); synchronize_rcu(); @@ -1829,7 +1840,7 @@ out: */ break; if (ss->cancel_attach) - ss->cancel_attach(ss, cgrp, tsk, false); + ss->cancel_attach(ss, cgrp, tsk); } } return retval; diff --git a/kernel/cgroup_freezer.c b/kernel/cgroup_freezer.c index e7bebb7c6c38..e691818d7e45 100644 --- a/kernel/cgroup_freezer.c +++ b/kernel/cgroup_freezer.c @@ -160,7 +160,7 @@ static void freezer_destroy(struct cgroup_subsys *ss, */ static int freezer_can_attach(struct cgroup_subsys *ss, struct cgroup *new_cgroup, - struct task_struct *task, bool threadgroup) + struct task_struct *task) { struct freezer *freezer; @@ -172,26 +172,17 @@ static int freezer_can_attach(struct cgroup_subsys *ss, if (freezer->state != CGROUP_THAWED) return -EBUSY; + return 0; +} + +static int freezer_can_attach_task(struct cgroup *cgrp, struct task_struct *tsk) +{ rcu_read_lock(); - if (__cgroup_freezing_or_frozen(task)) { + if (__cgroup_freezing_or_frozen(tsk)) { rcu_read_unlock(); return -EBUSY; } rcu_read_unlock(); - - if (threadgroup) { - struct task_struct *c; - - rcu_read_lock(); - list_for_each_entry_rcu(c, &task->thread_group, thread_group) { - if (__cgroup_freezing_or_frozen(c)) { - rcu_read_unlock(); - return -EBUSY; - } - } - rcu_read_unlock(); - } - return 0; } @@ -390,6 +381,9 @@ struct cgroup_subsys freezer_subsys = { .populate = freezer_populate, .subsys_id = freezer_subsys_id, .can_attach = freezer_can_attach, + .can_attach_task = freezer_can_attach_task, + .pre_attach = NULL, + .attach_task = NULL, .attach = NULL, .fork = freezer_fork, .exit = NULL, diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 2bb8c2e98fff..55b297d78adc 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c @@ -1367,14 +1367,10 @@ static int fmeter_getrate(struct fmeter *fmp) return val; } -/* Protected by cgroup_lock */ -static cpumask_var_t cpus_attach; - /* Called by cgroups to determine if a cpuset is usable; cgroup_mutex held */ static int cpuset_can_attach(struct cgroup_subsys *ss, struct cgroup *cont, - struct task_struct *tsk, bool threadgroup) + struct task_struct *tsk) { - int ret; struct cpuset *cs = cgroup_cs(cont); if (cpumask_empty(cs->cpus_allowed) || nodes_empty(cs->mems_allowed)) @@ -1391,29 +1387,42 @@ static int cpuset_can_attach(struct cgroup_subsys *ss, struct cgroup *cont, if (tsk->flags & PF_THREAD_BOUND) return -EINVAL; - ret = security_task_setscheduler(tsk); - if (ret) - return ret; - if (threadgroup) { - struct task_struct *c; - - rcu_read_lock(); - list_for_each_entry_rcu(c, &tsk->thread_group, thread_group) { - ret = security_task_setscheduler(c); - if (ret) { - rcu_read_unlock(); - return ret; - } - } - rcu_read_unlock(); - } return 0; } -static void cpuset_attach_task(struct task_struct *tsk, nodemask_t *to, - struct cpuset *cs) +static int cpuset_can_attach_task(struct cgroup *cgrp, struct task_struct *task) +{ + return security_task_setscheduler(task); +} + +/* + * Protected by cgroup_lock. The nodemasks must be stored globally because + * dynamically allocating them is not allowed in pre_attach, and they must + * persist among pre_attach, attach_task, and attach. + */ +static cpumask_var_t cpus_attach; +static nodemask_t cpuset_attach_nodemask_from; +static nodemask_t cpuset_attach_nodemask_to; + +/* Set-up work for before attaching each task. */ +static void cpuset_pre_attach(struct cgroup *cont) +{ + struct cpuset *cs = cgroup_cs(cont); + + if (cs == &top_cpuset) + cpumask_copy(cpus_attach, cpu_possible_mask); + else + guarantee_online_cpus(cs, cpus_attach); + + guarantee_online_mems(cs, &cpuset_attach_nodemask_to); +} + +/* Per-thread attachment work. */ +static void cpuset_attach_task(struct cgroup *cont, struct task_struct *tsk) { int err; + struct cpuset *cs = cgroup_cs(cont); + /* * can_attach beforehand should guarantee that this doesn't fail. * TODO: have a better way to handle failure here @@ -1421,45 +1430,29 @@ static void cpuset_attach_task(struct task_struct *tsk, nodemask_t *to, err = set_cpus_allowed_ptr(tsk, cpus_attach); WARN_ON_ONCE(err); - cpuset_change_task_nodemask(tsk, to); + cpuset_change_task_nodemask(tsk, &cpuset_attach_nodemask_to); cpuset_update_task_spread_flag(cs, tsk); - } static void cpuset_attach(struct cgroup_subsys *ss, struct cgroup *cont, - struct cgroup *oldcont, struct task_struct *tsk, - bool threadgroup) + struct cgroup *oldcont, struct task_struct *tsk) { struct mm_struct *mm; struct cpuset *cs = cgroup_cs(cont); struct cpuset *oldcs = cgroup_cs(oldcont); - static nodemask_t to; /* protected by cgroup_mutex */ - if (cs == &top_cpuset) { - cpumask_copy(cpus_attach, cpu_possible_mask); - } else { - guarantee_online_cpus(cs, cpus_attach); - } - guarantee_online_mems(cs, &to); - - /* do per-task migration stuff possibly for each in the threadgroup */ - cpuset_attach_task(tsk, &to, cs); - if (threadgroup) { - struct task_struct *c; - rcu_read_lock(); - list_for_each_entry_rcu(c, &tsk->thread_group, thread_group) { - cpuset_attach_task(c, &to, cs); - } - rcu_read_unlock(); - } - - /* change mm; only needs to be done once even if threadgroup */ - to = cs->mems_allowed; + /* + * Change mm, possibly for multiple threads in a threadgroup. This is + * expensive and may sleep. + */ + cpuset_attach_nodemask_from = oldcs->mems_allowed; + cpuset_attach_nodemask_to = cs->mems_allowed; mm = get_task_mm(tsk); if (mm) { - mpol_rebind_mm(mm, &to); + mpol_rebind_mm(mm, &cpuset_attach_nodemask_to); if (is_memory_migrate(cs)) - cpuset_migrate_mm(mm, &oldcs->mems_allowed, &to); + cpuset_migrate_mm(mm, &cpuset_attach_nodemask_from, + &cpuset_attach_nodemask_to); mmput(mm); } } @@ -1911,6 +1904,9 @@ struct cgroup_subsys cpuset_subsys = { .create = cpuset_create, .destroy = cpuset_destroy, .can_attach = cpuset_can_attach, + .can_attach_task = cpuset_can_attach_task, + .pre_attach = cpuset_pre_attach, + .attach_task = cpuset_attach_task, .attach = cpuset_attach, .populate = cpuset_populate, .post_clone = cpuset_post_clone, diff --git a/kernel/sched.c b/kernel/sched.c index 2d12893b8b0f..5e43e9dc65d1 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -8764,42 +8764,10 @@ cpu_cgroup_can_attach_task(struct cgroup *cgrp, struct task_struct *tsk) return 0; } -static int -cpu_cgroup_can_attach(struct cgroup_subsys *ss, struct cgroup *cgrp, - struct task_struct *tsk, bool threadgroup) -{ - int retval = cpu_cgroup_can_attach_task(cgrp, tsk); - if (retval) - return retval; - if (threadgroup) { - struct task_struct *c; - rcu_read_lock(); - list_for_each_entry_rcu(c, &tsk->thread_group, thread_group) { - retval = cpu_cgroup_can_attach_task(cgrp, c); - if (retval) { - rcu_read_unlock(); - return retval; - } - } - rcu_read_unlock(); - } - return 0; -} - static void -cpu_cgroup_attach(struct cgroup_subsys *ss, struct cgroup *cgrp, - struct cgroup *old_cont, struct task_struct *tsk, - bool threadgroup) +cpu_cgroup_attach_task(struct cgroup *cgrp, struct task_struct *tsk) { sched_move_task(tsk); - if (threadgroup) { - struct task_struct *c; - rcu_read_lock(); - list_for_each_entry_rcu(c, &tsk->thread_group, thread_group) { - sched_move_task(c); - } - rcu_read_unlock(); - } } static void @@ -8887,8 +8855,8 @@ struct cgroup_subsys cpu_cgroup_subsys = { .name = "cpu", .create = cpu_cgroup_create, .destroy = cpu_cgroup_destroy, - .can_attach = cpu_cgroup_can_attach, - .attach = cpu_cgroup_attach, + .can_attach_task = cpu_cgroup_can_attach_task, + .attach_task = cpu_cgroup_attach_task, .exit = cpu_cgroup_exit, .populate = cpu_cgroup_populate, .subsys_id = cpu_cgroup_subsys_id, diff --git a/mm/memcontrol.c b/mm/memcontrol.c index d5fd3dcd3f2e..fc259926c170 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -4953,8 +4953,7 @@ static void mem_cgroup_clear_mc(void) static int mem_cgroup_can_attach(struct cgroup_subsys *ss, struct cgroup *cgroup, - struct task_struct *p, - bool threadgroup) + struct task_struct *p) { int ret = 0; struct mem_cgroup *mem = mem_cgroup_from_cont(cgroup); @@ -4993,8 +4992,7 @@ static int mem_cgroup_can_attach(struct cgroup_subsys *ss, static void mem_cgroup_cancel_attach(struct cgroup_subsys *ss, struct cgroup *cgroup, - struct task_struct *p, - bool threadgroup) + struct task_struct *p) { mem_cgroup_clear_mc(); } @@ -5112,8 +5110,7 @@ retry: static void mem_cgroup_move_task(struct cgroup_subsys *ss, struct cgroup *cont, struct cgroup *old_cont, - struct task_struct *p, - bool threadgroup) + struct task_struct *p) { struct mm_struct *mm; @@ -5131,22 +5128,19 @@ static void mem_cgroup_move_task(struct cgroup_subsys *ss, #else /* !CONFIG_MMU */ static int mem_cgroup_can_attach(struct cgroup_subsys *ss, struct cgroup *cgroup, - struct task_struct *p, - bool threadgroup) + struct task_struct *p) { return 0; } static void mem_cgroup_cancel_attach(struct cgroup_subsys *ss, struct cgroup *cgroup, - struct task_struct *p, - bool threadgroup) + struct task_struct *p) { } static void mem_cgroup_move_task(struct cgroup_subsys *ss, struct cgroup *cont, struct cgroup *old_cont, - struct task_struct *p, - bool threadgroup) + struct task_struct *p) { } #endif diff --git a/security/device_cgroup.c b/security/device_cgroup.c index 8d9c48f13774..cd1f779fa51d 100644 --- a/security/device_cgroup.c +++ b/security/device_cgroup.c @@ -62,8 +62,7 @@ static inline struct dev_cgroup *task_devcgroup(struct task_struct *task) struct cgroup_subsys devices_subsys; static int devcgroup_can_attach(struct cgroup_subsys *ss, - struct cgroup *new_cgroup, struct task_struct *task, - bool threadgroup) + struct cgroup *new_cgroup, struct task_struct *task) { if (current != task && !capable(CAP_SYS_ADMIN)) return -EPERM; -- cgit From a77aea92010acf54ad785047234418d5d68772e2 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Thu, 26 May 2011 16:25:23 -0700 Subject: cgroup: remove the ns_cgroup The ns_cgroup is an annoying cgroup at the namespace / cgroup frontier and leads to some problems: * cgroup creation is out-of-control * cgroup name can conflict when pids are looping * it is not possible to have a single process handling a lot of namespaces without falling in a exponential creation time * we may want to create a namespace without creating a cgroup The ns_cgroup was replaced by a compatibility flag 'clone_children', where a newly created cgroup will copy the parent cgroup values. The userspace has to manually create a cgroup and add a task to the 'tasks' file. This patch removes the ns_cgroup as suggested in the following thread: https://lists.linux-foundation.org/pipermail/containers/2009-June/018616.html The 'cgroup_clone' function is removed because it is no longer used. This is a userspace-visible change. Commit 45531757b45c ("cgroup: notify ns_cgroup deprecated") (merged into 2.6.27) caused the kernel to emit a printk warning users that the feature is planned for removal. Since that time we have heard from XXX users who were affected by this. Signed-off-by: Daniel Lezcano Signed-off-by: Serge E. Hallyn Cc: Eric W. Biederman Cc: Jamal Hadi Salim Reviewed-by: Li Zefan Acked-by: Paul Menage Acked-by: Matt Helsley Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/cgroups/cgroups.txt | 2 +- arch/mips/configs/bcm47xx_defconfig | 1 - arch/mn10300/configs/asb2364_defconfig | 1 - arch/powerpc/configs/ppc6xx_defconfig | 1 - arch/powerpc/configs/pseries_defconfig | 1 - arch/sh/configs/apsh4ad0a_defconfig | 1 - arch/sh/configs/sdk7786_defconfig | 1 - arch/sh/configs/se7206_defconfig | 1 - arch/sh/configs/shx3_defconfig | 1 - arch/sh/configs/urquell_defconfig | 1 - arch/x86/configs/i386_defconfig | 1 - arch/x86/configs/x86_64_defconfig | 1 - include/linux/cgroup.h | 3 - include/linux/cgroup_subsys.h | 6 -- include/linux/nsproxy.h | 9 --- init/Kconfig | 8 --- kernel/Makefile | 1 - kernel/cgroup.c | 116 -------------------------------- kernel/cpuset.c | 7 +- kernel/fork.c | 6 -- kernel/ns_cgroup.c | 118 --------------------------------- kernel/nsproxy.c | 4 -- 22 files changed, 4 insertions(+), 287 deletions(-) delete mode 100644 kernel/ns_cgroup.c (limited to 'include/linux') diff --git a/Documentation/cgroups/cgroups.txt b/Documentation/cgroups/cgroups.txt index 8c4f3466c894..0ed99f08f1f3 100644 --- a/Documentation/cgroups/cgroups.txt +++ b/Documentation/cgroups/cgroups.txt @@ -651,7 +651,7 @@ always handled well. void post_clone(struct cgroup_subsys *ss, struct cgroup *cgrp) (cgroup_mutex held by caller) -Called at the end of cgroup_clone() to do any parameter +Called during cgroup_create() to do any parameter initialization which might be required before a task could attach. For example in cpusets, no task may attach before 'cpus' and 'mems' are set up. diff --git a/arch/mips/configs/bcm47xx_defconfig b/arch/mips/configs/bcm47xx_defconfig index 22fdf2f0cc23..ad15fb10322b 100644 --- a/arch/mips/configs/bcm47xx_defconfig +++ b/arch/mips/configs/bcm47xx_defconfig @@ -16,7 +16,6 @@ CONFIG_TASK_IO_ACCOUNTING=y CONFIG_AUDIT=y CONFIG_TINY_RCU=y CONFIG_CGROUPS=y -CONFIG_CGROUP_NS=y CONFIG_CGROUP_CPUACCT=y CONFIG_RELAY=y CONFIG_BLK_DEV_INITRD=y diff --git a/arch/mn10300/configs/asb2364_defconfig b/arch/mn10300/configs/asb2364_defconfig index 31d76261a3d5..fbb96ae3122a 100644 --- a/arch/mn10300/configs/asb2364_defconfig +++ b/arch/mn10300/configs/asb2364_defconfig @@ -8,7 +8,6 @@ CONFIG_TASK_XACCT=y CONFIG_TASK_IO_ACCOUNTING=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_CGROUPS=y -CONFIG_CGROUP_NS=y CONFIG_CGROUP_FREEZER=y CONFIG_CGROUP_DEVICE=y CONFIG_CGROUP_CPUACCT=y diff --git a/arch/powerpc/configs/ppc6xx_defconfig b/arch/powerpc/configs/ppc6xx_defconfig index 214208924a9c..04360f9b0109 100644 --- a/arch/powerpc/configs/ppc6xx_defconfig +++ b/arch/powerpc/configs/ppc6xx_defconfig @@ -10,7 +10,6 @@ CONFIG_TASK_XACCT=y CONFIG_TASK_IO_ACCOUNTING=y CONFIG_AUDIT=y CONFIG_CGROUPS=y -CONFIG_CGROUP_NS=y CONFIG_CGROUP_DEVICE=y CONFIG_CGROUP_CPUACCT=y CONFIG_RESOURCE_COUNTERS=y diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig index 7de13865508c..c9f212b5f3de 100644 --- a/arch/powerpc/configs/pseries_defconfig +++ b/arch/powerpc/configs/pseries_defconfig @@ -15,7 +15,6 @@ CONFIG_AUDITSYSCALL=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_CGROUPS=y -CONFIG_CGROUP_NS=y CONFIG_CGROUP_FREEZER=y CONFIG_CGROUP_DEVICE=y CONFIG_CPUSETS=y diff --git a/arch/sh/configs/apsh4ad0a_defconfig b/arch/sh/configs/apsh4ad0a_defconfig index 77ec0e7b8ddf..e7583484cc07 100644 --- a/arch/sh/configs/apsh4ad0a_defconfig +++ b/arch/sh/configs/apsh4ad0a_defconfig @@ -7,7 +7,6 @@ CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_CGROUPS=y -CONFIG_CGROUP_NS=y CONFIG_CGROUP_FREEZER=y CONFIG_CGROUP_DEVICE=y CONFIG_CGROUP_CPUACCT=y diff --git a/arch/sh/configs/sdk7786_defconfig b/arch/sh/configs/sdk7786_defconfig index c41650572d79..8a7dd7b59c5c 100644 --- a/arch/sh/configs/sdk7786_defconfig +++ b/arch/sh/configs/sdk7786_defconfig @@ -12,7 +12,6 @@ CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_CGROUPS=y CONFIG_CGROUP_DEBUG=y -CONFIG_CGROUP_NS=y CONFIG_CGROUP_FREEZER=y CONFIG_CGROUP_DEVICE=y CONFIG_CPUSETS=y diff --git a/arch/sh/configs/se7206_defconfig b/arch/sh/configs/se7206_defconfig index a468ff227fc6..72c3fad7383f 100644 --- a/arch/sh/configs/se7206_defconfig +++ b/arch/sh/configs/se7206_defconfig @@ -8,7 +8,6 @@ CONFIG_RCU_TRACE=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_CGROUPS=y CONFIG_CGROUP_DEBUG=y -CONFIG_CGROUP_NS=y CONFIG_CGROUP_DEVICE=y CONFIG_CGROUP_CPUACCT=y CONFIG_RESOURCE_COUNTERS=y diff --git a/arch/sh/configs/shx3_defconfig b/arch/sh/configs/shx3_defconfig index 3f92d37c6374..6bb413036892 100644 --- a/arch/sh/configs/shx3_defconfig +++ b/arch/sh/configs/shx3_defconfig @@ -9,7 +9,6 @@ CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_CGROUPS=y -CONFIG_CGROUP_NS=y CONFIG_CGROUP_FREEZER=y CONFIG_CGROUP_DEVICE=y CONFIG_CGROUP_CPUACCT=y diff --git a/arch/sh/configs/urquell_defconfig b/arch/sh/configs/urquell_defconfig index 7b3daec6fefe..8bfa4d056d7a 100644 --- a/arch/sh/configs/urquell_defconfig +++ b/arch/sh/configs/urquell_defconfig @@ -9,7 +9,6 @@ CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_CGROUPS=y CONFIG_CGROUP_DEBUG=y -CONFIG_CGROUP_NS=y CONFIG_CGROUP_FREEZER=y CONFIG_CGROUP_DEVICE=y CONFIG_CPUSETS=y diff --git a/arch/x86/configs/i386_defconfig b/arch/x86/configs/i386_defconfig index 6f9872658dd2..2bf18059fbea 100644 --- a/arch/x86/configs/i386_defconfig +++ b/arch/x86/configs/i386_defconfig @@ -10,7 +10,6 @@ CONFIG_TASK_IO_ACCOUNTING=y CONFIG_AUDIT=y CONFIG_LOG_BUF_SHIFT=18 CONFIG_CGROUPS=y -CONFIG_CGROUP_NS=y CONFIG_CGROUP_FREEZER=y CONFIG_CPUSETS=y CONFIG_CGROUP_CPUACCT=y diff --git a/arch/x86/configs/x86_64_defconfig b/arch/x86/configs/x86_64_defconfig index ee01a9d5d4f0..22a0dc8e51dd 100644 --- a/arch/x86/configs/x86_64_defconfig +++ b/arch/x86/configs/x86_64_defconfig @@ -11,7 +11,6 @@ CONFIG_TASK_IO_ACCOUNTING=y CONFIG_AUDIT=y CONFIG_LOG_BUF_SHIFT=18 CONFIG_CGROUPS=y -CONFIG_CGROUP_NS=y CONFIG_CGROUP_FREEZER=y CONFIG_CPUSETS=y CONFIG_CGROUP_CPUACCT=y diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 1e6cde21fa3f..ab4ac0ccb857 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -555,9 +555,6 @@ static inline struct cgroup* task_cgroup(struct task_struct *task, return task_subsys_state(task, subsys_id)->cgroup; } -int cgroup_clone(struct task_struct *tsk, struct cgroup_subsys *ss, - char *nodename); - /* A cgroup_iter should be treated as an opaque object */ struct cgroup_iter { struct list_head *cg_link; diff --git a/include/linux/cgroup_subsys.h b/include/linux/cgroup_subsys.h index cdbfcb8780ec..ac663c18776c 100644 --- a/include/linux/cgroup_subsys.h +++ b/include/linux/cgroup_subsys.h @@ -19,12 +19,6 @@ SUBSYS(debug) /* */ -#ifdef CONFIG_CGROUP_NS -SUBSYS(ns) -#endif - -/* */ - #ifdef CONFIG_CGROUP_SCHED SUBSYS(cpu_cgroup) #endif diff --git a/include/linux/nsproxy.h b/include/linux/nsproxy.h index 7b370c7cfeff..50d20aba57d3 100644 --- a/include/linux/nsproxy.h +++ b/include/linux/nsproxy.h @@ -81,13 +81,4 @@ static inline void get_nsproxy(struct nsproxy *ns) atomic_inc(&ns->count); } -#ifdef CONFIG_CGROUP_NS -int ns_cgroup_clone(struct task_struct *tsk, struct pid *pid); -#else -static inline int ns_cgroup_clone(struct task_struct *tsk, struct pid *pid) -{ - return 0; -} -#endif - #endif diff --git a/init/Kconfig b/init/Kconfig index 332aac649966..ebafac4231ee 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -589,14 +589,6 @@ config CGROUP_DEBUG Say N if unsure. -config CGROUP_NS - bool "Namespace cgroup subsystem" - help - Provides a simple namespace cgroup subsystem to - provide hierarchical naming of sets of namespaces, - for instance virtual servers and checkpoint/restart - jobs. - config CGROUP_FREEZER bool "Freezer cgroup subsystem" help diff --git a/kernel/Makefile b/kernel/Makefile index e9cf19155b46..2d64cfcc8b42 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -61,7 +61,6 @@ obj-$(CONFIG_COMPAT) += compat.o obj-$(CONFIG_CGROUPS) += cgroup.o obj-$(CONFIG_CGROUP_FREEZER) += cgroup_freezer.o obj-$(CONFIG_CPUSETS) += cpuset.o -obj-$(CONFIG_CGROUP_NS) += ns_cgroup.o obj-$(CONFIG_UTS_NS) += utsname.o obj-$(CONFIG_USER_NS) += user_namespace.o obj-$(CONFIG_PID_NS) += pid_namespace.o diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 00a884342d3d..2731d115d725 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -4629,122 +4629,6 @@ void cgroup_exit(struct task_struct *tsk, int run_callbacks) put_css_set_taskexit(cg); } -/** - * cgroup_clone - clone the cgroup the given subsystem is attached to - * @tsk: the task to be moved - * @subsys: the given subsystem - * @nodename: the name for the new cgroup - * - * Duplicate the current cgroup in the hierarchy that the given - * subsystem is attached to, and move this task into the new - * child. - */ -int cgroup_clone(struct task_struct *tsk, struct cgroup_subsys *subsys, - char *nodename) -{ - struct dentry *dentry; - int ret = 0; - struct cgroup *parent, *child; - struct inode *inode; - struct css_set *cg; - struct cgroupfs_root *root; - struct cgroup_subsys *ss; - - /* We shouldn't be called by an unregistered subsystem */ - BUG_ON(!subsys->active); - - /* First figure out what hierarchy and cgroup we're dealing - * with, and pin them so we can drop cgroup_mutex */ - mutex_lock(&cgroup_mutex); - again: - root = subsys->root; - if (root == &rootnode) { - mutex_unlock(&cgroup_mutex); - return 0; - } - - /* Pin the hierarchy */ - if (!atomic_inc_not_zero(&root->sb->s_active)) { - /* We race with the final deactivate_super() */ - mutex_unlock(&cgroup_mutex); - return 0; - } - - /* Keep the cgroup alive */ - task_lock(tsk); - parent = task_cgroup(tsk, subsys->subsys_id); - cg = tsk->cgroups; - get_css_set(cg); - task_unlock(tsk); - - mutex_unlock(&cgroup_mutex); - - /* Now do the VFS work to create a cgroup */ - inode = parent->dentry->d_inode; - - /* Hold the parent directory mutex across this operation to - * stop anyone else deleting the new cgroup */ - mutex_lock(&inode->i_mutex); - dentry = lookup_one_len(nodename, parent->dentry, strlen(nodename)); - if (IS_ERR(dentry)) { - printk(KERN_INFO - "cgroup: Couldn't allocate dentry for %s: %ld\n", nodename, - PTR_ERR(dentry)); - ret = PTR_ERR(dentry); - goto out_release; - } - - /* Create the cgroup directory, which also creates the cgroup */ - ret = vfs_mkdir(inode, dentry, 0755); - child = __d_cgrp(dentry); - dput(dentry); - if (ret) { - printk(KERN_INFO - "Failed to create cgroup %s: %d\n", nodename, - ret); - goto out_release; - } - - /* The cgroup now exists. Retake cgroup_mutex and check - * that we're still in the same state that we thought we - * were. */ - mutex_lock(&cgroup_mutex); - if ((root != subsys->root) || - (parent != task_cgroup(tsk, subsys->subsys_id))) { - /* Aargh, we raced ... */ - mutex_unlock(&inode->i_mutex); - put_css_set(cg); - - deactivate_super(root->sb); - /* The cgroup is still accessible in the VFS, but - * we're not going to try to rmdir() it at this - * point. */ - printk(KERN_INFO - "Race in cgroup_clone() - leaking cgroup %s\n", - nodename); - goto again; - } - - /* do any required auto-setup */ - for_each_subsys(root, ss) { - if (ss->post_clone) - ss->post_clone(ss, child); - } - - /* All seems fine. Finish by moving the task into the new cgroup */ - ret = cgroup_attach_task(child, tsk); - mutex_unlock(&cgroup_mutex); - - out_release: - mutex_unlock(&inode->i_mutex); - - mutex_lock(&cgroup_mutex); - put_css_set(cg); - mutex_unlock(&cgroup_mutex); - deactivate_super(root->sb); - return ret; -} - /** * cgroup_is_descendant - see if @cgrp is a descendant of @task's cgrp * @cgrp: the cgroup in question diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 55b297d78adc..1ceeb049c827 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c @@ -1802,10 +1802,9 @@ static int cpuset_populate(struct cgroup_subsys *ss, struct cgroup *cont) } /* - * post_clone() is called at the end of cgroup_clone(). - * 'cgroup' was just created automatically as a result of - * a cgroup_clone(), and the current task is about to - * be moved into 'cgroup'. + * post_clone() is called during cgroup_create() when the + * clone_children mount argument was specified. The cgroup + * can not yet have any tasks. * * Currently we refuse to set up the cgroup - thereby * refusing the task to be entered, and as a result refusing diff --git a/kernel/fork.c b/kernel/fork.c index 1fa9d940e301..1f84099ecce6 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1229,12 +1229,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, if (clone_flags & CLONE_THREAD) p->tgid = current->tgid; - if (current->nsproxy != p->nsproxy) { - retval = ns_cgroup_clone(p, pid); - if (retval) - goto bad_fork_free_pid; - } - p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL; /* * Clear TID on mm_release()? diff --git a/kernel/ns_cgroup.c b/kernel/ns_cgroup.c deleted file mode 100644 index 2c98ad94ba0e..000000000000 --- a/kernel/ns_cgroup.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * ns_cgroup.c - namespace cgroup subsystem - * - * Copyright 2006, 2007 IBM Corp - */ - -#include -#include -#include -#include -#include -#include - -struct ns_cgroup { - struct cgroup_subsys_state css; -}; - -struct cgroup_subsys ns_subsys; - -static inline struct ns_cgroup *cgroup_to_ns( - struct cgroup *cgroup) -{ - return container_of(cgroup_subsys_state(cgroup, ns_subsys_id), - struct ns_cgroup, css); -} - -int ns_cgroup_clone(struct task_struct *task, struct pid *pid) -{ - char name[PROC_NUMBUF]; - - snprintf(name, PROC_NUMBUF, "%d", pid_vnr(pid)); - return cgroup_clone(task, &ns_subsys, name); -} - -/* - * Rules: - * 1. you can only enter a cgroup which is a descendant of your current - * cgroup - * 2. you can only place another process into a cgroup if - * a. you have CAP_SYS_ADMIN - * b. your cgroup is an ancestor of task's destination cgroup - * (hence either you are in the same cgroup as task, or in an - * ancestor cgroup thereof) - */ -static int ns_can_attach(struct cgroup_subsys *ss, struct cgroup *new_cgroup, - struct task_struct *task, bool threadgroup) -{ - if (current != task) { - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - if (!cgroup_is_descendant(new_cgroup, current)) - return -EPERM; - } - - if (!cgroup_is_descendant(new_cgroup, task)) - return -EPERM; - - if (threadgroup) { - struct task_struct *c; - rcu_read_lock(); - list_for_each_entry_rcu(c, &task->thread_group, thread_group) { - if (!cgroup_is_descendant(new_cgroup, c)) { - rcu_read_unlock(); - return -EPERM; - } - } - rcu_read_unlock(); - } - - return 0; -} - -/* - * Rules: you can only create a cgroup if - * 1. you are capable(CAP_SYS_ADMIN) - * 2. the target cgroup is a descendant of your own cgroup - */ -static struct cgroup_subsys_state *ns_create(struct cgroup_subsys *ss, - struct cgroup *cgroup) -{ - struct ns_cgroup *ns_cgroup; - - if (!capable(CAP_SYS_ADMIN)) - return ERR_PTR(-EPERM); - if (!cgroup_is_descendant(cgroup, current)) - return ERR_PTR(-EPERM); - if (test_bit(CGRP_CLONE_CHILDREN, &cgroup->flags)) { - printk("ns_cgroup can't be created with parent " - "'clone_children' set.\n"); - return ERR_PTR(-EINVAL); - } - - printk_once("ns_cgroup deprecated: consider using the " - "'clone_children' flag without the ns_cgroup.\n"); - - ns_cgroup = kzalloc(sizeof(*ns_cgroup), GFP_KERNEL); - if (!ns_cgroup) - return ERR_PTR(-ENOMEM); - return &ns_cgroup->css; -} - -static void ns_destroy(struct cgroup_subsys *ss, - struct cgroup *cgroup) -{ - struct ns_cgroup *ns_cgroup; - - ns_cgroup = cgroup_to_ns(cgroup); - kfree(ns_cgroup); -} - -struct cgroup_subsys ns_subsys = { - .name = "ns", - .can_attach = ns_can_attach, - .create = ns_create, - .destroy = ns_destroy, - .subsys_id = ns_subsys_id, -}; diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c index 5424e37673ed..d6a00f3de15d 100644 --- a/kernel/nsproxy.c +++ b/kernel/nsproxy.c @@ -201,10 +201,6 @@ int unshare_nsproxy_namespaces(unsigned long unshare_flags, goto out; } - err = ns_cgroup_clone(current, task_pid(current)); - if (err) - put_nsproxy(*new_nsp); - out: return err; } -- cgit From f042e707ee671e4beb5389abeb9a1819a2cf5532 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 26 May 2011 16:25:24 -0700 Subject: mm: move enum vm_event_item into a standalone header file enums are problematic because they cannot be forward-declared: akpm2:/home/akpm> cat t.c enum foo; static inline void bar(enum foo f) { } akpm2:/home/akpm> gcc -c t.c t.c:4: error: parameter 1 ('f') has incomplete type So move the enum's definition into a standalone header file which can be used wherever its definition is needed. Cc: Ying Han Cc: KAMEZAWA Hiroyuki Cc: KOSAKI Motohiro Cc: Minchan Kim Cc: Daisuke Nishimura Cc: Balbir Singh Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/vm_event_item.h | 64 +++++++++++++++++++++++++++++++++++++++++++ include/linux/vmstat.h | 62 +---------------------------------------- 2 files changed, 65 insertions(+), 61 deletions(-) create mode 100644 include/linux/vm_event_item.h (limited to 'include/linux') diff --git a/include/linux/vm_event_item.h b/include/linux/vm_event_item.h new file mode 100644 index 000000000000..03b90cdc1921 --- /dev/null +++ b/include/linux/vm_event_item.h @@ -0,0 +1,64 @@ +#ifndef VM_EVENT_ITEM_H_INCLUDED +#define VM_EVENT_ITEM_H_INCLUDED + +#ifdef CONFIG_ZONE_DMA +#define DMA_ZONE(xx) xx##_DMA, +#else +#define DMA_ZONE(xx) +#endif + +#ifdef CONFIG_ZONE_DMA32 +#define DMA32_ZONE(xx) xx##_DMA32, +#else +#define DMA32_ZONE(xx) +#endif + +#ifdef CONFIG_HIGHMEM +#define HIGHMEM_ZONE(xx) , xx##_HIGH +#else +#define HIGHMEM_ZONE(xx) +#endif + +#define FOR_ALL_ZONES(xx) DMA_ZONE(xx) DMA32_ZONE(xx) xx##_NORMAL HIGHMEM_ZONE(xx) , xx##_MOVABLE + +enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT, + FOR_ALL_ZONES(PGALLOC), + PGFREE, PGACTIVATE, PGDEACTIVATE, + PGFAULT, PGMAJFAULT, + FOR_ALL_ZONES(PGREFILL), + FOR_ALL_ZONES(PGSTEAL), + FOR_ALL_ZONES(PGSCAN_KSWAPD), + FOR_ALL_ZONES(PGSCAN_DIRECT), +#ifdef CONFIG_NUMA + PGSCAN_ZONE_RECLAIM_FAILED, +#endif + PGINODESTEAL, SLABS_SCANNED, KSWAPD_STEAL, KSWAPD_INODESTEAL, + KSWAPD_LOW_WMARK_HIT_QUICKLY, KSWAPD_HIGH_WMARK_HIT_QUICKLY, + KSWAPD_SKIP_CONGESTION_WAIT, + PAGEOUTRUN, ALLOCSTALL, PGROTATED, +#ifdef CONFIG_COMPACTION + COMPACTBLOCKS, COMPACTPAGES, COMPACTPAGEFAILED, + COMPACTSTALL, COMPACTFAIL, COMPACTSUCCESS, +#endif +#ifdef CONFIG_HUGETLB_PAGE + HTLB_BUDDY_PGALLOC, HTLB_BUDDY_PGALLOC_FAIL, +#endif + UNEVICTABLE_PGCULLED, /* culled to noreclaim list */ + UNEVICTABLE_PGSCANNED, /* scanned for reclaimability */ + UNEVICTABLE_PGRESCUED, /* rescued from noreclaim list */ + UNEVICTABLE_PGMLOCKED, + UNEVICTABLE_PGMUNLOCKED, + UNEVICTABLE_PGCLEARED, /* on COW, page truncate */ + UNEVICTABLE_PGSTRANDED, /* unable to isolate on unlock */ + UNEVICTABLE_MLOCKFREED, +#ifdef CONFIG_TRANSPARENT_HUGEPAGE + THP_FAULT_ALLOC, + THP_FAULT_FALLBACK, + THP_COLLAPSE_ALLOC, + THP_COLLAPSE_ALLOC_FAILED, + THP_SPLIT, +#endif + NR_VM_EVENT_ITEMS +}; + +#endif /* VM_EVENT_ITEM_H_INCLUDED */ diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h index 51359837511a..bcd942fa611c 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h @@ -5,69 +5,9 @@ #include #include #include +#include #include -#ifdef CONFIG_ZONE_DMA -#define DMA_ZONE(xx) xx##_DMA, -#else -#define DMA_ZONE(xx) -#endif - -#ifdef CONFIG_ZONE_DMA32 -#define DMA32_ZONE(xx) xx##_DMA32, -#else -#define DMA32_ZONE(xx) -#endif - -#ifdef CONFIG_HIGHMEM -#define HIGHMEM_ZONE(xx) , xx##_HIGH -#else -#define HIGHMEM_ZONE(xx) -#endif - - -#define FOR_ALL_ZONES(xx) DMA_ZONE(xx) DMA32_ZONE(xx) xx##_NORMAL HIGHMEM_ZONE(xx) , xx##_MOVABLE - -enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT, - FOR_ALL_ZONES(PGALLOC), - PGFREE, PGACTIVATE, PGDEACTIVATE, - PGFAULT, PGMAJFAULT, - FOR_ALL_ZONES(PGREFILL), - FOR_ALL_ZONES(PGSTEAL), - FOR_ALL_ZONES(PGSCAN_KSWAPD), - FOR_ALL_ZONES(PGSCAN_DIRECT), -#ifdef CONFIG_NUMA - PGSCAN_ZONE_RECLAIM_FAILED, -#endif - PGINODESTEAL, SLABS_SCANNED, KSWAPD_STEAL, KSWAPD_INODESTEAL, - KSWAPD_LOW_WMARK_HIT_QUICKLY, KSWAPD_HIGH_WMARK_HIT_QUICKLY, - KSWAPD_SKIP_CONGESTION_WAIT, - PAGEOUTRUN, ALLOCSTALL, PGROTATED, -#ifdef CONFIG_COMPACTION - COMPACTBLOCKS, COMPACTPAGES, COMPACTPAGEFAILED, - COMPACTSTALL, COMPACTFAIL, COMPACTSUCCESS, -#endif -#ifdef CONFIG_HUGETLB_PAGE - HTLB_BUDDY_PGALLOC, HTLB_BUDDY_PGALLOC_FAIL, -#endif - UNEVICTABLE_PGCULLED, /* culled to noreclaim list */ - UNEVICTABLE_PGSCANNED, /* scanned for reclaimability */ - UNEVICTABLE_PGRESCUED, /* rescued from noreclaim list */ - UNEVICTABLE_PGMLOCKED, - UNEVICTABLE_PGMUNLOCKED, - UNEVICTABLE_PGCLEARED, /* on COW, page truncate */ - UNEVICTABLE_PGSTRANDED, /* unable to isolate on unlock */ - UNEVICTABLE_MLOCKFREED, -#ifdef CONFIG_TRANSPARENT_HUGEPAGE - THP_FAULT_ALLOC, - THP_FAULT_FALLBACK, - THP_COLLAPSE_ALLOC, - THP_COLLAPSE_ALLOC_FAILED, - THP_SPLIT, -#endif - NR_VM_EVENT_ITEMS -}; - extern int sysctl_stat_interval; #ifdef CONFIG_VM_EVENT_COUNTERS -- cgit From 0ae5e89c60c9eb87da36a2614836bc434b0ec2ad Mon Sep 17 00:00:00 2001 From: Ying Han Date: Thu, 26 May 2011 16:25:25 -0700 Subject: memcg: count the soft_limit reclaim in global background reclaim The global kswapd scans per-zone LRU and reclaims pages regardless of the cgroup. It breaks memory isolation since one cgroup can end up reclaiming pages from another cgroup. Instead we should rely on memcg-aware target reclaim including per-memcg kswapd and soft_limit hierarchical reclaim under memory pressure. In the global background reclaim, we do soft reclaim before scanning the per-zone LRU. However, the return value is ignored. This patch is the first step to skip shrink_zone() if soft_limit reclaim does enough work. This is part of the effort which tries to reduce reclaiming pages in global LRU in memcg. The per-memcg background reclaim patchset further enhances the per-cgroup targetting reclaim, which I should have V4 posted shortly. Try running multiple memory intensive workloads within seperate memcgs. Watch the counters of soft_steal in memory.stat. $ cat /dev/cgroup/A/memory.stat | grep 'soft' soft_steal 240000 soft_scan 240000 total_soft_steal 240000 total_soft_scan 240000 This patch: In the global background reclaim, we do soft reclaim before scanning the per-zone LRU. However, the return value is ignored. We would like to skip shrink_zone() if soft_limit reclaim does enough work. Also, we need to make the memory pressure balanced across per-memcg zones, like the logic vm-core. This patch is the first step where we start with counting the nr_scanned and nr_reclaimed from soft_limit reclaim into the global scan_control. Signed-off-by: Ying Han Cc: KOSAKI Motohiro Cc: Minchan Kim Cc: Rik van Riel Cc: Mel Gorman Cc: KAMEZAWA Hiroyuki Cc: Balbir Singh Acked-by: Daisuke Nishimura Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memcontrol.h | 6 ++++-- include/linux/swap.h | 3 ++- mm/memcontrol.c | 29 ++++++++++++++++++++--------- mm/vmscan.c | 16 +++++++++++++--- 4 files changed, 39 insertions(+), 15 deletions(-) (limited to 'include/linux') diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 5e9840f50980..0629121f2c0b 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -144,7 +144,8 @@ static inline void mem_cgroup_dec_page_stat(struct page *page, } unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order, - gfp_t gfp_mask); + gfp_t gfp_mask, + unsigned long *total_scanned); u64 mem_cgroup_get_limit(struct mem_cgroup *mem); #ifdef CONFIG_TRANSPARENT_HUGEPAGE @@ -338,7 +339,8 @@ static inline void mem_cgroup_dec_page_stat(struct page *page, static inline unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order, - gfp_t gfp_mask) + gfp_t gfp_mask, + unsigned long *total_scanned) { return 0; } diff --git a/include/linux/swap.h b/include/linux/swap.h index a5c6da5d8df8..384eb5fe530b 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -257,7 +257,8 @@ extern unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem, extern unsigned long mem_cgroup_shrink_node_zone(struct mem_cgroup *mem, gfp_t gfp_mask, bool noswap, unsigned int swappiness, - struct zone *zone); + struct zone *zone, + unsigned long *nr_scanned); extern int __isolate_lru_page(struct page *page, int mode, int file); extern unsigned long shrink_all_memory(unsigned long nr_pages); extern int vm_swappiness; diff --git a/mm/memcontrol.c b/mm/memcontrol.c index fc259926c170..e41a6c26f1e7 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -1433,7 +1433,8 @@ mem_cgroup_select_victim(struct mem_cgroup *root_mem) static int mem_cgroup_hierarchical_reclaim(struct mem_cgroup *root_mem, struct zone *zone, gfp_t gfp_mask, - unsigned long reclaim_options) + unsigned long reclaim_options, + unsigned long *total_scanned) { struct mem_cgroup *victim; int ret, total = 0; @@ -1442,6 +1443,7 @@ static int mem_cgroup_hierarchical_reclaim(struct mem_cgroup *root_mem, bool shrink = reclaim_options & MEM_CGROUP_RECLAIM_SHRINK; bool check_soft = reclaim_options & MEM_CGROUP_RECLAIM_SOFT; unsigned long excess; + unsigned long nr_scanned; excess = res_counter_soft_limit_excess(&root_mem->res) >> PAGE_SHIFT; @@ -1484,10 +1486,12 @@ static int mem_cgroup_hierarchical_reclaim(struct mem_cgroup *root_mem, continue; } /* we use swappiness of local cgroup */ - if (check_soft) + if (check_soft) { ret = mem_cgroup_shrink_node_zone(victim, gfp_mask, - noswap, get_swappiness(victim), zone); - else + noswap, get_swappiness(victim), zone, + &nr_scanned); + *total_scanned += nr_scanned; + } else ret = try_to_free_mem_cgroup_pages(victim, gfp_mask, noswap, get_swappiness(victim)); css_put(&victim->css); @@ -1928,7 +1932,7 @@ static int mem_cgroup_do_charge(struct mem_cgroup *mem, gfp_t gfp_mask, return CHARGE_WOULDBLOCK; ret = mem_cgroup_hierarchical_reclaim(mem_over_limit, NULL, - gfp_mask, flags); + gfp_mask, flags, NULL); if (mem_cgroup_margin(mem_over_limit) >= nr_pages) return CHARGE_RETRY; /* @@ -3211,7 +3215,8 @@ static int mem_cgroup_resize_limit(struct mem_cgroup *memcg, break; mem_cgroup_hierarchical_reclaim(memcg, NULL, GFP_KERNEL, - MEM_CGROUP_RECLAIM_SHRINK); + MEM_CGROUP_RECLAIM_SHRINK, + NULL); curusage = res_counter_read_u64(&memcg->res, RES_USAGE); /* Usage is reduced ? */ if (curusage >= oldusage) @@ -3271,7 +3276,8 @@ static int mem_cgroup_resize_memsw_limit(struct mem_cgroup *memcg, mem_cgroup_hierarchical_reclaim(memcg, NULL, GFP_KERNEL, MEM_CGROUP_RECLAIM_NOSWAP | - MEM_CGROUP_RECLAIM_SHRINK); + MEM_CGROUP_RECLAIM_SHRINK, + NULL); curusage = res_counter_read_u64(&memcg->memsw, RES_USAGE); /* Usage is reduced ? */ if (curusage >= oldusage) @@ -3285,7 +3291,8 @@ static int mem_cgroup_resize_memsw_limit(struct mem_cgroup *memcg, } unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order, - gfp_t gfp_mask) + gfp_t gfp_mask, + unsigned long *total_scanned) { unsigned long nr_reclaimed = 0; struct mem_cgroup_per_zone *mz, *next_mz = NULL; @@ -3293,6 +3300,7 @@ unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order, int loop = 0; struct mem_cgroup_tree_per_zone *mctz; unsigned long long excess; + unsigned long nr_scanned; if (order > 0) return 0; @@ -3311,10 +3319,13 @@ unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order, if (!mz) break; + nr_scanned = 0; reclaimed = mem_cgroup_hierarchical_reclaim(mz->mem, zone, gfp_mask, - MEM_CGROUP_RECLAIM_SOFT); + MEM_CGROUP_RECLAIM_SOFT, + &nr_scanned); nr_reclaimed += reclaimed; + *total_scanned += nr_scanned; spin_lock(&mctz->lock); /* diff --git a/mm/vmscan.c b/mm/vmscan.c index 7e0116150dc7..9ce6ec84328e 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -2171,9 +2171,11 @@ unsigned long try_to_free_pages(struct zonelist *zonelist, int order, unsigned long mem_cgroup_shrink_node_zone(struct mem_cgroup *mem, gfp_t gfp_mask, bool noswap, unsigned int swappiness, - struct zone *zone) + struct zone *zone, + unsigned long *nr_scanned) { struct scan_control sc = { + .nr_scanned = 0, .nr_to_reclaim = SWAP_CLUSTER_MAX, .may_writepage = !laptop_mode, .may_unmap = 1, @@ -2182,6 +2184,7 @@ unsigned long mem_cgroup_shrink_node_zone(struct mem_cgroup *mem, .order = 0, .mem_cgroup = mem, }; + sc.gfp_mask = (gfp_mask & GFP_RECLAIM_MASK) | (GFP_HIGHUSER_MOVABLE & ~GFP_RECLAIM_MASK); @@ -2200,6 +2203,7 @@ unsigned long mem_cgroup_shrink_node_zone(struct mem_cgroup *mem, trace_mm_vmscan_memcg_softlimit_reclaim_end(sc.nr_reclaimed); + *nr_scanned = sc.nr_scanned; return sc.nr_reclaimed; } @@ -2347,6 +2351,8 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order, int end_zone = 0; /* Inclusive. 0 = ZONE_DMA */ unsigned long total_scanned; struct reclaim_state *reclaim_state = current->reclaim_state; + unsigned long nr_soft_reclaimed; + unsigned long nr_soft_scanned; struct scan_control sc = { .gfp_mask = GFP_KERNEL, .may_unmap = 1, @@ -2439,11 +2445,15 @@ loop_again: sc.nr_scanned = 0; + nr_soft_scanned = 0; /* * Call soft limit reclaim before calling shrink_zone. - * For now we ignore the return value */ - mem_cgroup_soft_limit_reclaim(zone, order, sc.gfp_mask); + nr_soft_reclaimed = mem_cgroup_soft_limit_reclaim(zone, + order, sc.gfp_mask, + &nr_soft_scanned); + sc.nr_reclaimed += nr_soft_reclaimed; + total_scanned += nr_soft_scanned; /* * We put equal pressure on every zone, unless -- cgit From 889976dbcb1218119fdd950fb7819084e37d7d37 Mon Sep 17 00:00:00 2001 From: Ying Han Date: Thu, 26 May 2011 16:25:33 -0700 Subject: memcg: reclaim memory from nodes in round-robin order Presently, memory cgroup's direct reclaim frees memory from the current node. But this has some troubles. Usually when a set of threads works in a cooperative way, they tend to operate on the same node. So if they hit limits under memcg they will reclaim memory from themselves, damaging the active working set. For example, assume 2 node system which has Node 0 and Node 1 and a memcg which has 1G limit. After some work, file cache remains and the usages are Node 0: 1M Node 1: 998M. and run an application on Node 0, it will eat its foot before freeing unnecessary file caches. This patch adds round-robin for NUMA and adds equal pressure to each node. When using cpuset's spread memory feature, this will work very well. But yes, a better algorithm is needed. [akpm@linux-foundation.org: comment editing] [kamezawa.hiroyu@jp.fujitsu.com: fix time comparisons] Signed-off-by: Ying Han Signed-off-by: KAMEZAWA Hiroyuki Cc: Balbir Singh Cc: KOSAKI Motohiro Cc: Daisuke Nishimura Cc: Mel Gorman Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memcontrol.h | 1 + mm/memcontrol.c | 102 ++++++++++++++++++++++++++++++++++++++++++--- mm/vmscan.c | 10 ++++- 3 files changed, 106 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 0629121f2c0b..16052117131e 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -106,6 +106,7 @@ extern void mem_cgroup_end_migration(struct mem_cgroup *mem, */ int mem_cgroup_inactive_anon_is_low(struct mem_cgroup *memcg); int mem_cgroup_inactive_file_is_low(struct mem_cgroup *memcg); +int mem_cgroup_select_victim_node(struct mem_cgroup *memcg); unsigned long mem_cgroup_zone_nr_pages(struct mem_cgroup *memcg, struct zone *zone, enum lru_list lru); diff --git a/mm/memcontrol.c b/mm/memcontrol.c index fc62c714f3b6..1520efd1c7c4 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -231,6 +231,11 @@ struct mem_cgroup { * reclaimed from. */ int last_scanned_child; + int last_scanned_node; +#if MAX_NUMNODES > 1 + nodemask_t scan_nodes; + unsigned long next_scan_node_update; +#endif /* * Should the accounting and control be hierarchical, per subtree? */ @@ -624,18 +629,27 @@ static void mem_cgroup_charge_statistics(struct mem_cgroup *mem, preempt_enable(); } +static unsigned long +mem_cgroup_get_zonestat_node(struct mem_cgroup *mem, int nid, enum lru_list idx) +{ + struct mem_cgroup_per_zone *mz; + u64 total = 0; + int zid; + + for (zid = 0; zid < MAX_NR_ZONES; zid++) { + mz = mem_cgroup_zoneinfo(mem, nid, zid); + total += MEM_CGROUP_ZSTAT(mz, idx); + } + return total; +} static unsigned long mem_cgroup_get_local_zonestat(struct mem_cgroup *mem, enum lru_list idx) { - int nid, zid; - struct mem_cgroup_per_zone *mz; + int nid; u64 total = 0; for_each_online_node(nid) - for (zid = 0; zid < MAX_NR_ZONES; zid++) { - mz = mem_cgroup_zoneinfo(mem, nid, zid); - total += MEM_CGROUP_ZSTAT(mz, idx); - } + total += mem_cgroup_get_zonestat_node(mem, nid, idx); return total; } @@ -1418,6 +1432,81 @@ mem_cgroup_select_victim(struct mem_cgroup *root_mem) return ret; } +#if MAX_NUMNODES > 1 + +/* + * Always updating the nodemask is not very good - even if we have an empty + * list or the wrong list here, we can start from some node and traverse all + * nodes based on the zonelist. So update the list loosely once per 10 secs. + * + */ +static void mem_cgroup_may_update_nodemask(struct mem_cgroup *mem) +{ + int nid; + + if (time_after(mem->next_scan_node_update, jiffies)) + return; + + mem->next_scan_node_update = jiffies + 10*HZ; + /* make a nodemask where this memcg uses memory from */ + mem->scan_nodes = node_states[N_HIGH_MEMORY]; + + for_each_node_mask(nid, node_states[N_HIGH_MEMORY]) { + + if (mem_cgroup_get_zonestat_node(mem, nid, LRU_INACTIVE_FILE) || + mem_cgroup_get_zonestat_node(mem, nid, LRU_ACTIVE_FILE)) + continue; + + if (total_swap_pages && + (mem_cgroup_get_zonestat_node(mem, nid, LRU_INACTIVE_ANON) || + mem_cgroup_get_zonestat_node(mem, nid, LRU_ACTIVE_ANON))) + continue; + node_clear(nid, mem->scan_nodes); + } +} + +/* + * Selecting a node where we start reclaim from. Because what we need is just + * reducing usage counter, start from anywhere is O,K. Considering + * memory reclaim from current node, there are pros. and cons. + * + * Freeing memory from current node means freeing memory from a node which + * we'll use or we've used. So, it may make LRU bad. And if several threads + * hit limits, it will see a contention on a node. But freeing from remote + * node means more costs for memory reclaim because of memory latency. + * + * Now, we use round-robin. Better algorithm is welcomed. + */ +int mem_cgroup_select_victim_node(struct mem_cgroup *mem) +{ + int node; + + mem_cgroup_may_update_nodemask(mem); + node = mem->last_scanned_node; + + node = next_node(node, mem->scan_nodes); + if (node == MAX_NUMNODES) + node = first_node(mem->scan_nodes); + /* + * We call this when we hit limit, not when pages are added to LRU. + * No LRU may hold pages because all pages are UNEVICTABLE or + * memcg is too small and all pages are not on LRU. In that case, + * we use curret node. + */ + if (unlikely(node == MAX_NUMNODES)) + node = numa_node_id(); + + mem->last_scanned_node = node; + return node; +} + +#else +int mem_cgroup_select_victim_node(struct mem_cgroup *mem) +{ + return 0; +} +#endif + /* * Scan the hierarchy if needed to reclaim memory. We remember the last child * we reclaimed from, so that we don't end up penalizing one child extensively @@ -4606,6 +4695,7 @@ mem_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont) res_counter_init(&mem->memsw, NULL); } mem->last_scanned_child = 0; + mem->last_scanned_node = MAX_NUMNODES; INIT_LIST_HEAD(&mem->oom_notify); if (parent) diff --git a/mm/vmscan.c b/mm/vmscan.c index 884ae08c16cc..b0875871820d 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -2226,6 +2226,7 @@ unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem_cont, { struct zonelist *zonelist; unsigned long nr_reclaimed; + int nid; struct scan_control sc = { .may_writepage = !laptop_mode, .may_unmap = 1, @@ -2242,7 +2243,14 @@ unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem_cont, .gfp_mask = sc.gfp_mask, }; - zonelist = NODE_DATA(numa_node_id())->node_zonelists; + /* + * Unlike direct reclaim via alloc_pages(), memcg's reclaim doesn't + * take care of from where we get pages. So the node where we start the + * scan does not need to be the current node. + */ + nid = mem_cgroup_select_victim_node(mem_cont); + + zonelist = NODE_DATA(nid)->node_zonelists; trace_mm_vmscan_memcg_reclaim_begin(0, sc.may_writepage, -- cgit From 246e87a9393448c20873bc5dee64be68ed559e24 Mon Sep 17 00:00:00 2001 From: KAMEZAWA Hiroyuki Date: Thu, 26 May 2011 16:25:34 -0700 Subject: memcg: fix get_scan_count() for small targets During memory reclaim we determine the number of pages to be scanned per zone as (anon + file) >> priority. Assume scan = (anon + file) >> priority. If scan < SWAP_CLUSTER_MAX, the scan will be skipped for this time and priority gets higher. This has some problems. 1. This increases priority as 1 without any scan. To do scan in this priority, amount of pages should be larger than 512M. If pages>>priority < SWAP_CLUSTER_MAX, it's recorded and scan will be batched, later. (But we lose 1 priority.) If memory size is below 16M, pages >> priority is 0 and no scan in DEF_PRIORITY forever. 2. If zone->all_unreclaimabe==true, it's scanned only when priority==0. So, x86's ZONE_DMA will never be recoverred until the user of pages frees memory by itself. 3. With memcg, the limit of memory can be small. When using small memcg, it gets priority < DEF_PRIORITY-2 very easily and need to call wait_iff_congested(). For doing scan before priorty=9, 64MB of memory should be used. Then, this patch tries to scan SWAP_CLUSTER_MAX of pages in force...when 1. the target is enough small. 2. it's kswapd or memcg reclaim. Then we can avoid rapid priority drop and may be able to recover all_unreclaimable in a small zones. And this patch removes nr_saved_scan. This will allow scanning in this priority even when pages >> priority is very small. Signed-off-by: KAMEZAWA Hiroyuki Acked-by: Ying Han Cc: Balbir Singh Cc: KOSAKI Motohiro Cc: Daisuke Nishimura Cc: Mel Gorman Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mmzone.h | 5 ----- mm/page_alloc.c | 4 +--- mm/vmscan.c | 60 +++++++++++++++++++++++++++----------------------- 3 files changed, 34 insertions(+), 35 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 217bcf6bca77..29312bdf119f 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -273,11 +273,6 @@ struct zone_reclaim_stat { */ unsigned long recent_rotated[2]; unsigned long recent_scanned[2]; - - /* - * accumulated for batching - */ - unsigned long nr_saved_scan[NR_LRU_LISTS]; }; struct zone { diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 2a00f17c3bf4..a4e1db3f1981 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -4323,10 +4323,8 @@ static void __paginginit free_area_init_core(struct pglist_data *pgdat, zone->zone_pgdat = pgdat; zone_pcp_init(zone); - for_each_lru(l) { + for_each_lru(l) INIT_LIST_HEAD(&zone->lru[l].list); - zone->reclaim_stat.nr_saved_scan[l] = 0; - } zone->reclaim_stat.recent_rotated[0] = 0; zone->reclaim_stat.recent_rotated[1] = 0; zone->reclaim_stat.recent_scanned[0] = 0; diff --git a/mm/vmscan.c b/mm/vmscan.c index b0875871820d..2e8fbacd8744 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1717,26 +1717,6 @@ static unsigned long shrink_list(enum lru_list lru, unsigned long nr_to_scan, return shrink_inactive_list(nr_to_scan, zone, sc, priority, file); } -/* - * Smallish @nr_to_scan's are deposited in @nr_saved_scan, - * until we collected @swap_cluster_max pages to scan. - */ -static unsigned long nr_scan_try_batch(unsigned long nr_to_scan, - unsigned long *nr_saved_scan) -{ - unsigned long nr; - - *nr_saved_scan += nr_to_scan; - nr = *nr_saved_scan; - - if (nr >= SWAP_CLUSTER_MAX) - *nr_saved_scan = 0; - else - nr = 0; - - return nr; -} - /* * Determine how aggressively the anon and file LRU lists should be * scanned. The relative value of each set of LRU lists is determined @@ -1755,6 +1735,22 @@ static void get_scan_count(struct zone *zone, struct scan_control *sc, u64 fraction[2], denominator; enum lru_list l; int noswap = 0; + int force_scan = 0; + + + anon = zone_nr_lru_pages(zone, sc, LRU_ACTIVE_ANON) + + zone_nr_lru_pages(zone, sc, LRU_INACTIVE_ANON); + file = zone_nr_lru_pages(zone, sc, LRU_ACTIVE_FILE) + + zone_nr_lru_pages(zone, sc, LRU_INACTIVE_FILE); + + if (((anon + file) >> priority) < SWAP_CLUSTER_MAX) { + /* kswapd does zone balancing and need to scan this zone */ + if (scanning_global_lru(sc) && current_is_kswapd()) + force_scan = 1; + /* memcg may have small limit and need to avoid priority drop */ + if (!scanning_global_lru(sc)) + force_scan = 1; + } /* If we have no swap space, do not bother scanning anon pages. */ if (!sc->may_swap || (nr_swap_pages <= 0)) { @@ -1765,11 +1761,6 @@ static void get_scan_count(struct zone *zone, struct scan_control *sc, goto out; } - anon = zone_nr_lru_pages(zone, sc, LRU_ACTIVE_ANON) + - zone_nr_lru_pages(zone, sc, LRU_INACTIVE_ANON); - file = zone_nr_lru_pages(zone, sc, LRU_ACTIVE_FILE) + - zone_nr_lru_pages(zone, sc, LRU_INACTIVE_FILE); - if (scanning_global_lru(sc)) { free = zone_page_state(zone, NR_FREE_PAGES); /* If we have very few page cache pages, @@ -1836,8 +1827,23 @@ out: scan >>= priority; scan = div64_u64(scan * fraction[file], denominator); } - nr[l] = nr_scan_try_batch(scan, - &reclaim_stat->nr_saved_scan[l]); + + /* + * If zone is small or memcg is small, nr[l] can be 0. + * This results no-scan on this priority and priority drop down. + * For global direct reclaim, it can visit next zone and tend + * not to have problems. For global kswapd, it's for zone + * balancing and it need to scan a small amounts. When using + * memcg, priority drop can cause big latency. So, it's better + * to scan small amount. See may_noscan above. + */ + if (!scan && force_scan) { + if (file) + scan = SWAP_CLUSTER_MAX; + else if (!noswap) + scan = SWAP_CLUSTER_MAX; + } + nr[l] = scan; } } -- cgit From 1bac180bd29e03989f50054af97b53b8d37a364a Mon Sep 17 00:00:00 2001 From: Ying Han Date: Thu, 26 May 2011 16:25:36 -0700 Subject: memcg: rename mem_cgroup_zone_nr_pages() to mem_cgroup_zone_nr_lru_pages() The caller of the function has been renamed to zone_nr_lru_pages(), and this is just fixing up in the memcg code. The current name is easily to be mis-read as zone's total number of pages. Signed-off-by: Ying Han Acked-by: Johannes Weiner Acked-by: KAMEZAWA Hiroyuki Reviewed-by: Minchan Kim Cc: Balbir Singh Cc: Daisuke Nishimura Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memcontrol.h | 10 +++++----- mm/memcontrol.c | 6 +++--- mm/vmscan.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'include/linux') diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 16052117131e..ac1e5d20916a 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -107,9 +107,9 @@ extern void mem_cgroup_end_migration(struct mem_cgroup *mem, int mem_cgroup_inactive_anon_is_low(struct mem_cgroup *memcg); int mem_cgroup_inactive_file_is_low(struct mem_cgroup *memcg); int mem_cgroup_select_victim_node(struct mem_cgroup *memcg); -unsigned long mem_cgroup_zone_nr_pages(struct mem_cgroup *memcg, - struct zone *zone, - enum lru_list lru); +unsigned long mem_cgroup_zone_nr_lru_pages(struct mem_cgroup *memcg, + struct zone *zone, + enum lru_list lru); struct zone_reclaim_stat *mem_cgroup_get_reclaim_stat(struct mem_cgroup *memcg, struct zone *zone); struct zone_reclaim_stat* @@ -304,8 +304,8 @@ mem_cgroup_inactive_file_is_low(struct mem_cgroup *memcg) } static inline unsigned long -mem_cgroup_zone_nr_pages(struct mem_cgroup *memcg, struct zone *zone, - enum lru_list lru) +mem_cgroup_zone_nr_lru_pages(struct mem_cgroup *memcg, struct zone *zone, + enum lru_list lru) { return 0; } diff --git a/mm/memcontrol.c b/mm/memcontrol.c index bcb0a0bee1fc..cc48a6854f7e 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -1078,9 +1078,9 @@ int mem_cgroup_inactive_file_is_low(struct mem_cgroup *memcg) return (active > inactive); } -unsigned long mem_cgroup_zone_nr_pages(struct mem_cgroup *memcg, - struct zone *zone, - enum lru_list lru) +unsigned long mem_cgroup_zone_nr_lru_pages(struct mem_cgroup *memcg, + struct zone *zone, + enum lru_list lru) { int nid = zone_to_nid(zone); int zid = zone_idx(zone); diff --git a/mm/vmscan.c b/mm/vmscan.c index 2e8fbacd8744..faa0a088f9cc 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -173,7 +173,7 @@ static unsigned long zone_nr_lru_pages(struct zone *zone, struct scan_control *sc, enum lru_list lru) { if (!scanning_global_lru(sc)) - return mem_cgroup_zone_nr_pages(sc->mem_cgroup, zone, lru); + return mem_cgroup_zone_nr_lru_pages(sc->mem_cgroup, zone, lru); return zone_page_state(zone, NR_LRU_BASE + lru); } -- cgit From 456f998ec817ebfa254464be4f089542fa390645 Mon Sep 17 00:00:00 2001 From: Ying Han Date: Thu, 26 May 2011 16:25:38 -0700 Subject: memcg: add the pagefault count into memcg stats Two new stats in per-memcg memory.stat which tracks the number of page faults and number of major page faults. "pgfault" "pgmajfault" They are different from "pgpgin"/"pgpgout" stat which count number of pages charged/discharged to the cgroup and have no meaning of reading/ writing page to disk. It is valuable to track the two stats for both measuring application's performance as well as the efficiency of the kernel page reclaim path. Counting pagefaults per process is useful, but we also need the aggregated value since processes are monitored and controlled in cgroup basis in memcg. Functional test: check the total number of pgfault/pgmajfault of all memcgs and compare with global vmstat value: $ cat /proc/vmstat | grep fault pgfault 1070751 pgmajfault 553 $ cat /dev/cgroup/memory.stat | grep fault pgfault 1071138 pgmajfault 553 total_pgfault 1071142 total_pgmajfault 553 $ cat /dev/cgroup/A/memory.stat | grep fault pgfault 199 pgmajfault 0 total_pgfault 199 total_pgmajfault 0 Performance test: run page fault test(pft) wit 16 thread on faulting in 15G anon pages in 16G container. There is no regression noticed on the "flt/cpu/s" Sample output from pft: TAG pft:anon-sys-default: Gb Thr CLine User System Wall flt/cpu/s fault/wsec 15 16 1 0.67s 233.41s 14.76s 16798.546 266356.260 +-------------------------------------------------------------------------+ N Min Max Median Avg Stddev x 10 16682.962 17344.027 16913.524 16928.812 166.5362 + 10 16695.568 16923.896 16820.604 16824.652 84.816568 No difference proven at 95.0% confidence [akpm@linux-foundation.org: fix build] [hughd@google.com: shmem fix] Signed-off-by: Ying Han Acked-by: KAMEZAWA Hiroyuki Cc: KOSAKI Motohiro Reviewed-by: Minchan Kim Cc: Daisuke Nishimura Acked-by: Balbir Singh Signed-off-by: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/ncpfs/mmap.c | 2 ++ include/linux/memcontrol.h | 7 +++++++ mm/filemap.c | 1 + mm/memcontrol.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++ mm/memory.c | 2 ++ mm/shmem.c | 11 ++++++----- 6 files changed, 65 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/fs/ncpfs/mmap.c b/fs/ncpfs/mmap.c index a7c07b44b100..e5d71b27a5b0 100644 --- a/fs/ncpfs/mmap.c +++ b/fs/ncpfs/mmap.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -92,6 +93,7 @@ static int ncp_file_mmap_fault(struct vm_area_struct *area, * -- wli */ count_vm_event(PGMAJFAULT); + mem_cgroup_count_vm_event(area->vm_mm, PGMAJFAULT); return VM_FAULT_MAJOR; } diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index ac1e5d20916a..9724a38ee69d 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -20,6 +20,8 @@ #ifndef _LINUX_MEMCONTROL_H #define _LINUX_MEMCONTROL_H #include +#include + struct mem_cgroup; struct page_cgroup; struct page; @@ -149,6 +151,7 @@ unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order, unsigned long *total_scanned); u64 mem_cgroup_get_limit(struct mem_cgroup *mem); +void mem_cgroup_count_vm_event(struct mm_struct *mm, enum vm_event_item idx); #ifdef CONFIG_TRANSPARENT_HUGEPAGE void mem_cgroup_split_huge_fixup(struct page *head, struct page *tail); #endif @@ -357,6 +360,10 @@ static inline void mem_cgroup_split_huge_fixup(struct page *head, { } +static inline +void mem_cgroup_count_vm_event(struct mm_struct *mm, enum vm_event_item idx) +{ +} #endif /* CONFIG_CGROUP_MEM_CONT */ #if !defined(CONFIG_CGROUP_MEM_RES_CTLR) || !defined(CONFIG_DEBUG_VM) diff --git a/mm/filemap.c b/mm/filemap.c index 7455ccd8bda8..bcdc393b6580 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1661,6 +1661,7 @@ int filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) /* No page in the page cache at all */ do_sync_mmap_readahead(vma, ra, file, offset); count_vm_event(PGMAJFAULT); + mem_cgroup_count_vm_event(vma->vm_mm, PGMAJFAULT); ret = VM_FAULT_MAJOR; retry_find: page = find_get_page(mapping, offset); diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 4021fcd71b60..bd9052a5d3ad 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -94,6 +94,8 @@ enum mem_cgroup_events_index { MEM_CGROUP_EVENTS_PGPGIN, /* # of pages paged in */ MEM_CGROUP_EVENTS_PGPGOUT, /* # of pages paged out */ MEM_CGROUP_EVENTS_COUNT, /* # of pages paged in/out */ + MEM_CGROUP_EVENTS_PGFAULT, /* # of page-faults */ + MEM_CGROUP_EVENTS_PGMAJFAULT, /* # of major page-faults */ MEM_CGROUP_EVENTS_NSTATS, }; /* @@ -590,6 +592,16 @@ static void mem_cgroup_swap_statistics(struct mem_cgroup *mem, this_cpu_add(mem->stat->count[MEM_CGROUP_STAT_SWAPOUT], val); } +void mem_cgroup_pgfault(struct mem_cgroup *mem, int val) +{ + this_cpu_add(mem->stat->events[MEM_CGROUP_EVENTS_PGFAULT], val); +} + +void mem_cgroup_pgmajfault(struct mem_cgroup *mem, int val) +{ + this_cpu_add(mem->stat->events[MEM_CGROUP_EVENTS_PGMAJFAULT], val); +} + static unsigned long mem_cgroup_read_events(struct mem_cgroup *mem, enum mem_cgroup_events_index idx) { @@ -827,6 +839,33 @@ static inline bool mem_cgroup_is_root(struct mem_cgroup *mem) return (mem == root_mem_cgroup); } +void mem_cgroup_count_vm_event(struct mm_struct *mm, enum vm_event_item idx) +{ + struct mem_cgroup *mem; + + if (!mm) + return; + + rcu_read_lock(); + mem = mem_cgroup_from_task(rcu_dereference(mm->owner)); + if (unlikely(!mem)) + goto out; + + switch (idx) { + case PGMAJFAULT: + mem_cgroup_pgmajfault(mem, 1); + break; + case PGFAULT: + mem_cgroup_pgfault(mem, 1); + break; + default: + BUG(); + } +out: + rcu_read_unlock(); +} +EXPORT_SYMBOL(mem_cgroup_count_vm_event); + /* * Following LRU functions are allowed to be used without PCG_LOCK. * Operations are called by routine of global LRU independently from memcg. @@ -3958,6 +3997,8 @@ enum { MCS_PGPGIN, MCS_PGPGOUT, MCS_SWAP, + MCS_PGFAULT, + MCS_PGMAJFAULT, MCS_INACTIVE_ANON, MCS_ACTIVE_ANON, MCS_INACTIVE_FILE, @@ -3980,6 +4021,8 @@ struct { {"pgpgin", "total_pgpgin"}, {"pgpgout", "total_pgpgout"}, {"swap", "total_swap"}, + {"pgfault", "total_pgfault"}, + {"pgmajfault", "total_pgmajfault"}, {"inactive_anon", "total_inactive_anon"}, {"active_anon", "total_active_anon"}, {"inactive_file", "total_inactive_file"}, @@ -4008,6 +4051,10 @@ mem_cgroup_get_local_stat(struct mem_cgroup *mem, struct mcs_total_stat *s) val = mem_cgroup_read_stat(mem, MEM_CGROUP_STAT_SWAPOUT); s->stat[MCS_SWAP] += val * PAGE_SIZE; } + val = mem_cgroup_read_events(mem, MEM_CGROUP_EVENTS_PGFAULT); + s->stat[MCS_PGFAULT] += val; + val = mem_cgroup_read_events(mem, MEM_CGROUP_EVENTS_PGMAJFAULT); + s->stat[MCS_PGMAJFAULT] += val; /* per zone stat */ val = mem_cgroup_get_local_zonestat(mem, LRU_INACTIVE_ANON); diff --git a/mm/memory.c b/mm/memory.c index fc24f7d788bd..6953d3926e01 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -2874,6 +2874,7 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma, /* Had to read the page from swap area: Major fault */ ret = VM_FAULT_MAJOR; count_vm_event(PGMAJFAULT); + mem_cgroup_count_vm_event(mm, PGMAJFAULT); } else if (PageHWPoison(page)) { /* * hwpoisoned dirty swapcache pages are kept for killing @@ -3413,6 +3414,7 @@ int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma, __set_current_state(TASK_RUNNING); count_vm_event(PGFAULT); + mem_cgroup_count_vm_event(mm, PGFAULT); /* do counter updates before entering really critical section. */ check_sync_rss_stat(current); diff --git a/mm/shmem.c b/mm/shmem.c index 69edb45a9f28..1acfb2687bfa 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -1305,12 +1305,10 @@ repeat: swappage = lookup_swap_cache(swap); if (!swappage) { shmem_swp_unmap(entry); + spin_unlock(&info->lock); /* here we actually do the io */ - if (type && !(*type & VM_FAULT_MAJOR)) { - __count_vm_event(PGMAJFAULT); + if (type) *type |= VM_FAULT_MAJOR; - } - spin_unlock(&info->lock); swappage = shmem_swapin(swap, gfp, info, idx); if (!swappage) { spin_lock(&info->lock); @@ -1549,7 +1547,10 @@ static int shmem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) error = shmem_getpage(inode, vmf->pgoff, &vmf->page, SGP_CACHE, &ret); if (error) return ((error == -ENOMEM) ? VM_FAULT_OOM : VM_FAULT_SIGBUS); - + if (ret & VM_FAULT_MAJOR) { + count_vm_event(PGMAJFAULT); + mem_cgroup_count_vm_event(vma->vm_mm, PGMAJFAULT); + } return ret | VM_FAULT_LOCKED; } -- cgit From 3864601387cf4196371e3c1897fdffa5228296f9 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 26 May 2011 16:25:46 -0700 Subject: mm: extract exe_file handling from procfs Setup and cleanup of mm_struct->exe_file is currently done in fs/proc/. This was because exe_file was needed only for /proc//exe. Since we will need the exe_file functionality also for core dumps (so core name can contain full binary path), built this functionality always into the kernel. To achieve that move that out of proc FS to the kernel/ where in fact it should belong. By doing that we can make dup_mm_exe_file static. Also we can drop linux/proc_fs.h inclusion in fs/exec.c and kernel/fork.c. Signed-off-by: Jiri Slaby Cc: Alexander Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/exec.c | 1 - fs/proc/base.c | 51 ----------------------------------------------- include/linux/mm.h | 10 ++-------- include/linux/mm_types.h | 2 -- include/linux/proc_fs.h | 19 ------------------ kernel/fork.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++- 6 files changed, 53 insertions(+), 82 deletions(-) (limited to 'include/linux') diff --git a/fs/exec.c b/fs/exec.c index 936f5776655c..88a16c572282 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include #include diff --git a/fs/proc/base.c b/fs/proc/base.c index dc8bca72b002..c2ac2fb123c8 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -1576,57 +1576,6 @@ static const struct file_operations proc_pid_set_comm_operations = { .release = single_release, }; -/* - * We added or removed a vma mapping the executable. The vmas are only mapped - * during exec and are not mapped with the mmap system call. - * Callers must hold down_write() on the mm's mmap_sem for these - */ -void added_exe_file_vma(struct mm_struct *mm) -{ - mm->num_exe_file_vmas++; -} - -void removed_exe_file_vma(struct mm_struct *mm) -{ - mm->num_exe_file_vmas--; - if ((mm->num_exe_file_vmas == 0) && mm->exe_file){ - fput(mm->exe_file); - mm->exe_file = NULL; - } - -} - -void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file) -{ - if (new_exe_file) - get_file(new_exe_file); - if (mm->exe_file) - fput(mm->exe_file); - mm->exe_file = new_exe_file; - mm->num_exe_file_vmas = 0; -} - -struct file *get_mm_exe_file(struct mm_struct *mm) -{ - struct file *exe_file; - - /* We need mmap_sem to protect against races with removal of - * VM_EXECUTABLE vmas */ - down_read(&mm->mmap_sem); - exe_file = mm->exe_file; - if (exe_file) - get_file(exe_file); - up_read(&mm->mmap_sem); - return exe_file; -} - -void dup_mm_exe_file(struct mm_struct *oldmm, struct mm_struct *newmm) -{ - /* It's safe to write the exe_file pointer without exe_file_lock because - * this is called during fork when the task is not yet in /proc */ - newmm->exe_file = get_mm_exe_file(oldmm); -} - static int proc_exe_link(struct inode *inode, struct path *exe_path) { struct task_struct *task; diff --git a/include/linux/mm.h b/include/linux/mm.h index fb8e814f78dc..9670f71d7be9 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1408,17 +1408,11 @@ extern void exit_mmap(struct mm_struct *); extern int mm_take_all_locks(struct mm_struct *mm); extern void mm_drop_all_locks(struct mm_struct *mm); -#ifdef CONFIG_PROC_FS /* From fs/proc/base.c. callers must _not_ hold the mm's exe_file_lock */ extern void added_exe_file_vma(struct mm_struct *mm); extern void removed_exe_file_vma(struct mm_struct *mm); -#else -static inline void added_exe_file_vma(struct mm_struct *mm) -{} - -static inline void removed_exe_file_vma(struct mm_struct *mm) -{} -#endif /* CONFIG_PROC_FS */ +extern void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file); +extern struct file *get_mm_exe_file(struct mm_struct *mm); extern int may_expand_vm(struct mm_struct *mm, unsigned long npages); extern int install_special_mapping(struct mm_struct *mm, diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 6fe96c19f85e..2a78aae78c69 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -302,11 +302,9 @@ struct mm_struct { struct task_struct __rcu *owner; #endif -#ifdef CONFIG_PROC_FS /* store ref to file /proc//exe symlink points to */ struct file *exe_file; unsigned long num_exe_file_vmas; -#endif #ifdef CONFIG_MMU_NOTIFIER struct mmu_notifier_mm *mmu_notifier_mm; #endif diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index 648c9c58add7..e7576cf9e32d 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -173,12 +173,6 @@ extern void proc_net_remove(struct net *net, const char *name); extern struct proc_dir_entry *proc_net_mkdir(struct net *net, const char *name, struct proc_dir_entry *parent); -/* While the {get|set|dup}_mm_exe_file functions are for mm_structs, they are - * only needed to implement /proc/|self/exe so we define them here. */ -extern void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file); -extern struct file *get_mm_exe_file(struct mm_struct *mm); -extern void dup_mm_exe_file(struct mm_struct *oldmm, struct mm_struct *newmm); - extern struct file *proc_ns_fget(int fd); #else @@ -230,19 +224,6 @@ static inline void pid_ns_release_proc(struct pid_namespace *ns) { } -static inline void set_mm_exe_file(struct mm_struct *mm, - struct file *new_exe_file) -{} - -static inline struct file *get_mm_exe_file(struct mm_struct *mm) -{ - return NULL; -} - -static inline void dup_mm_exe_file(struct mm_struct *oldmm, - struct mm_struct *newmm) -{} - static inline struct file *proc_ns_fget(int fd) { return ERR_PTR(-EINVAL); diff --git a/kernel/fork.c b/kernel/fork.c index 1f84099ecce6..ca406d916713 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -59,7 +59,6 @@ #include #include #include -#include #include #include #include @@ -597,6 +596,57 @@ void mmput(struct mm_struct *mm) } EXPORT_SYMBOL_GPL(mmput); +/* + * We added or removed a vma mapping the executable. The vmas are only mapped + * during exec and are not mapped with the mmap system call. + * Callers must hold down_write() on the mm's mmap_sem for these + */ +void added_exe_file_vma(struct mm_struct *mm) +{ + mm->num_exe_file_vmas++; +} + +void removed_exe_file_vma(struct mm_struct *mm) +{ + mm->num_exe_file_vmas--; + if ((mm->num_exe_file_vmas == 0) && mm->exe_file){ + fput(mm->exe_file); + mm->exe_file = NULL; + } + +} + +void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file) +{ + if (new_exe_file) + get_file(new_exe_file); + if (mm->exe_file) + fput(mm->exe_file); + mm->exe_file = new_exe_file; + mm->num_exe_file_vmas = 0; +} + +struct file *get_mm_exe_file(struct mm_struct *mm) +{ + struct file *exe_file; + + /* We need mmap_sem to protect against races with removal of + * VM_EXECUTABLE vmas */ + down_read(&mm->mmap_sem); + exe_file = mm->exe_file; + if (exe_file) + get_file(exe_file); + up_read(&mm->mmap_sem); + return exe_file; +} + +static void dup_mm_exe_file(struct mm_struct *oldmm, struct mm_struct *newmm) +{ + /* It's safe to write the exe_file pointer without exe_file_lock because + * this is called during fork when the task is not yet in /proc */ + newmm->exe_file = get_mm_exe_file(oldmm); +} + /** * get_task_mm - acquire a reference to the task's mm * -- cgit From 997c136f518c5debd63847e78e2a8694f56dcf90 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Thu, 26 May 2011 16:25:54 -0700 Subject: fs/proc/vmcore.c: add hook to read_from_oldmem() to check for non-ram pages The balloon driver in a Xen guest frees guest pages and marks them as mmio. When the kernel crashes and the crash kernel attempts to read the oldmem via /proc/vmcore a read from ballooned pages will generate 100% load in dom0 because Xen asks qemu-dm for the page content. Since the reads come in as 8byte requests each ballooned page is tried 512 times. With this change a hook can be registered which checks wether the given pfn is really ram. The hook has to return a value > 0 for ram pages, a value < 0 on error (because the hypercall is not known) and 0 for non-ram pages. This will reduce the time to read /proc/vmcore. Without this change a 512M guest with 128M crashkernel region needs 200 seconds to read it, with this change it takes just 2 seconds. Signed-off-by: Olaf Hering Cc: Alexey Dobriyan Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/proc/vmcore.c | 52 +++++++++++++++++++++++++++++++++++++++++++--- include/linux/crash_dump.h | 5 +++++ 2 files changed, 54 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c index 74802bc5ded9..cd99bf557650 100644 --- a/fs/proc/vmcore.c +++ b/fs/proc/vmcore.c @@ -35,6 +35,46 @@ static u64 vmcore_size; static struct proc_dir_entry *proc_vmcore = NULL; +/* + * Returns > 0 for RAM pages, 0 for non-RAM pages, < 0 on error + * The called function has to take care of module refcounting. + */ +static int (*oldmem_pfn_is_ram)(unsigned long pfn); + +int register_oldmem_pfn_is_ram(int (*fn)(unsigned long pfn)) +{ + if (oldmem_pfn_is_ram) + return -EBUSY; + oldmem_pfn_is_ram = fn; + return 0; +} +EXPORT_SYMBOL_GPL(register_oldmem_pfn_is_ram); + +void unregister_oldmem_pfn_is_ram(void) +{ + oldmem_pfn_is_ram = NULL; + wmb(); +} +EXPORT_SYMBOL_GPL(unregister_oldmem_pfn_is_ram); + +static int pfn_is_ram(unsigned long pfn) +{ + int (*fn)(unsigned long pfn); + /* pfn is ram unless fn() checks pagetype */ + int ret = 1; + + /* + * Ask hypervisor if the pfn is really ram. + * A ballooned page contains no data and reading from such a page + * will cause high load in the hypervisor. + */ + fn = oldmem_pfn_is_ram; + if (fn) + ret = fn(pfn); + + return ret; +} + /* Reads a page from the oldmem device from given offset. */ static ssize_t read_from_oldmem(char *buf, size_t count, u64 *ppos, int userbuf) @@ -55,9 +95,15 @@ static ssize_t read_from_oldmem(char *buf, size_t count, else nr_bytes = count; - tmp = copy_oldmem_page(pfn, buf, nr_bytes, offset, userbuf); - if (tmp < 0) - return tmp; + /* If pfn is not ram, return zeros for sparse dump files */ + if (pfn_is_ram(pfn) == 0) + memset(buf, 0, nr_bytes); + else { + tmp = copy_oldmem_page(pfn, buf, nr_bytes, + offset, userbuf); + if (tmp < 0) + return tmp; + } *ppos += nr_bytes; count -= nr_bytes; buf += nr_bytes; diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h index 088cd4ace4ef..74054074e876 100644 --- a/include/linux/crash_dump.h +++ b/include/linux/crash_dump.h @@ -66,6 +66,11 @@ static inline void vmcore_unusable(void) if (is_kdump_kernel()) elfcorehdr_addr = ELFCORE_ADDR_ERR; } + +#define HAVE_OLDMEM_PFN_IS_RAM 1 +extern int register_oldmem_pfn_is_ram(int (*fn)(unsigned long pfn)); +extern void unregister_oldmem_pfn_is_ram(void); + #else /* !CONFIG_CRASH_DUMP */ static inline int is_kdump_kernel(void) { return 0; } #endif /* CONFIG_CRASH_DUMP */ -- cgit From 074127367a503de0168e2ca5d0b36a6f761f026a Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Thu, 26 May 2011 16:25:55 -0700 Subject: ipmi: convert to seq_file interface The ->read_proc interface is going away, convert to seq_file. Signed-off-by: Alexey Dobriyan Cc:Corey Minyard Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_msghandler.c | 138 +++++++++++++++++++++--------------- drivers/char/ipmi/ipmi_si_intf.c | 88 +++++++++++++++-------- include/linux/ipmi_smi.h | 2 +- 3 files changed, 142 insertions(+), 86 deletions(-) (limited to 'include/linux') diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 38223e93aa98..58c0e6387cf7 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -1896,102 +1897,128 @@ int ipmi_request_supply_msgs(ipmi_user_t user, EXPORT_SYMBOL(ipmi_request_supply_msgs); #ifdef CONFIG_PROC_FS -static int ipmb_file_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int smi_ipmb_proc_show(struct seq_file *m, void *v) { - char *out = (char *) page; - ipmi_smi_t intf = data; + ipmi_smi_t intf = m->private; int i; - int rv = 0; - for (i = 0; i < IPMI_MAX_CHANNELS; i++) - rv += sprintf(out+rv, "%x ", intf->channels[i].address); - out[rv-1] = '\n'; /* Replace the final space with a newline */ - out[rv] = '\0'; - rv++; - return rv; + seq_printf(m, "%x", intf->channels[0].address); + for (i = 1; i < IPMI_MAX_CHANNELS; i++) + seq_printf(m, " %x", intf->channels[i].address); + return seq_putc(m, '\n'); } -static int version_file_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int smi_ipmb_proc_open(struct inode *inode, struct file *file) { - char *out = (char *) page; - ipmi_smi_t intf = data; + return single_open(file, smi_ipmb_proc_show, PDE(inode)->data); +} - return sprintf(out, "%u.%u\n", +static const struct file_operations smi_ipmb_proc_ops = { + .open = smi_ipmb_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int smi_version_proc_show(struct seq_file *m, void *v) +{ + ipmi_smi_t intf = m->private; + + return seq_printf(m, "%u.%u\n", ipmi_version_major(&intf->bmc->id), ipmi_version_minor(&intf->bmc->id)); } -static int stat_file_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int smi_version_proc_open(struct inode *inode, struct file *file) { - char *out = (char *) page; - ipmi_smi_t intf = data; + return single_open(file, smi_version_proc_show, PDE(inode)->data); +} + +static const struct file_operations smi_version_proc_ops = { + .open = smi_version_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; - out += sprintf(out, "sent_invalid_commands: %u\n", +static int smi_stats_proc_show(struct seq_file *m, void *v) +{ + ipmi_smi_t intf = m->private; + + seq_printf(m, "sent_invalid_commands: %u\n", ipmi_get_stat(intf, sent_invalid_commands)); - out += sprintf(out, "sent_local_commands: %u\n", + seq_printf(m, "sent_local_commands: %u\n", ipmi_get_stat(intf, sent_local_commands)); - out += sprintf(out, "handled_local_responses: %u\n", + seq_printf(m, "handled_local_responses: %u\n", ipmi_get_stat(intf, handled_local_responses)); - out += sprintf(out, "unhandled_local_responses: %u\n", + seq_printf(m, "unhandled_local_responses: %u\n", ipmi_get_stat(intf, unhandled_local_responses)); - out += sprintf(out, "sent_ipmb_commands: %u\n", + seq_printf(m, "sent_ipmb_commands: %u\n", ipmi_get_stat(intf, sent_ipmb_commands)); - out += sprintf(out, "sent_ipmb_command_errs: %u\n", + seq_printf(m, "sent_ipmb_command_errs: %u\n", ipmi_get_stat(intf, sent_ipmb_command_errs)); - out += sprintf(out, "retransmitted_ipmb_commands: %u\n", + seq_printf(m, "retransmitted_ipmb_commands: %u\n", ipmi_get_stat(intf, retransmitted_ipmb_commands)); - out += sprintf(out, "timed_out_ipmb_commands: %u\n", + seq_printf(m, "timed_out_ipmb_commands: %u\n", ipmi_get_stat(intf, timed_out_ipmb_commands)); - out += sprintf(out, "timed_out_ipmb_broadcasts: %u\n", + seq_printf(m, "timed_out_ipmb_broadcasts: %u\n", ipmi_get_stat(intf, timed_out_ipmb_broadcasts)); - out += sprintf(out, "sent_ipmb_responses: %u\n", + seq_printf(m, "sent_ipmb_responses: %u\n", ipmi_get_stat(intf, sent_ipmb_responses)); - out += sprintf(out, "handled_ipmb_responses: %u\n", + seq_printf(m, "handled_ipmb_responses: %u\n", ipmi_get_stat(intf, handled_ipmb_responses)); - out += sprintf(out, "invalid_ipmb_responses: %u\n", + seq_printf(m, "invalid_ipmb_responses: %u\n", ipmi_get_stat(intf, invalid_ipmb_responses)); - out += sprintf(out, "unhandled_ipmb_responses: %u\n", + seq_printf(m, "unhandled_ipmb_responses: %u\n", ipmi_get_stat(intf, unhandled_ipmb_responses)); - out += sprintf(out, "sent_lan_commands: %u\n", + seq_printf(m, "sent_lan_commands: %u\n", ipmi_get_stat(intf, sent_lan_commands)); - out += sprintf(out, "sent_lan_command_errs: %u\n", + seq_printf(m, "sent_lan_command_errs: %u\n", ipmi_get_stat(intf, sent_lan_command_errs)); - out += sprintf(out, "retransmitted_lan_commands: %u\n", + seq_printf(m, "retransmitted_lan_commands: %u\n", ipmi_get_stat(intf, retransmitted_lan_commands)); - out += sprintf(out, "timed_out_lan_commands: %u\n", + seq_printf(m, "timed_out_lan_commands: %u\n", ipmi_get_stat(intf, timed_out_lan_commands)); - out += sprintf(out, "sent_lan_responses: %u\n", + seq_printf(m, "sent_lan_responses: %u\n", ipmi_get_stat(intf, sent_lan_responses)); - out += sprintf(out, "handled_lan_responses: %u\n", + seq_printf(m, "handled_lan_responses: %u\n", ipmi_get_stat(intf, handled_lan_responses)); - out += sprintf(out, "invalid_lan_responses: %u\n", + seq_printf(m, "invalid_lan_responses: %u\n", ipmi_get_stat(intf, invalid_lan_responses)); - out += sprintf(out, "unhandled_lan_responses: %u\n", + seq_printf(m, "unhandled_lan_responses: %u\n", ipmi_get_stat(intf, unhandled_lan_responses)); - out += sprintf(out, "handled_commands: %u\n", + seq_printf(m, "handled_commands: %u\n", ipmi_get_stat(intf, handled_commands)); - out += sprintf(out, "invalid_commands: %u\n", + seq_printf(m, "invalid_commands: %u\n", ipmi_get_stat(intf, invalid_commands)); - out += sprintf(out, "unhandled_commands: %u\n", + seq_printf(m, "unhandled_commands: %u\n", ipmi_get_stat(intf, unhandled_commands)); - out += sprintf(out, "invalid_events: %u\n", + seq_printf(m, "invalid_events: %u\n", ipmi_get_stat(intf, invalid_events)); - out += sprintf(out, "events: %u\n", + seq_printf(m, "events: %u\n", ipmi_get_stat(intf, events)); - out += sprintf(out, "failed rexmit LAN msgs: %u\n", + seq_printf(m, "failed rexmit LAN msgs: %u\n", ipmi_get_stat(intf, dropped_rexmit_lan_commands)); - out += sprintf(out, "failed rexmit IPMB msgs: %u\n", + seq_printf(m, "failed rexmit IPMB msgs: %u\n", ipmi_get_stat(intf, dropped_rexmit_ipmb_commands)); + return 0; +} - return (out - ((char *) page)); +static int smi_stats_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, smi_stats_proc_show, PDE(inode)->data); } + +static const struct file_operations smi_stats_proc_ops = { + .open = smi_stats_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; #endif /* CONFIG_PROC_FS */ int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name, - read_proc_t *read_proc, + const struct file_operations *proc_ops, void *data) { int rv = 0; @@ -2010,15 +2037,12 @@ int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name, } strcpy(entry->name, name); - file = create_proc_entry(name, 0, smi->proc_dir); + file = proc_create_data(name, 0, smi->proc_dir, proc_ops, data); if (!file) { kfree(entry->name); kfree(entry); rv = -ENOMEM; } else { - file->data = data; - file->read_proc = read_proc; - mutex_lock(&smi->proc_entry_lock); /* Stick it on the list. */ entry->next = smi->proc_entries; @@ -2043,17 +2067,17 @@ static int add_proc_entries(ipmi_smi_t smi, int num) if (rv == 0) rv = ipmi_smi_add_proc_entry(smi, "stats", - stat_file_read_proc, + &smi_stats_proc_ops, smi); if (rv == 0) rv = ipmi_smi_add_proc_entry(smi, "ipmb", - ipmb_file_read_proc, + &smi_ipmb_proc_ops, smi); if (rv == 0) rv = ipmi_smi_add_proc_entry(smi, "version", - version_file_read_proc, + &smi_version_proc_ops, smi); #endif /* CONFIG_PROC_FS */ diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 64c6b8530615..9397ab49b72e 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -2805,54 +2806,73 @@ static int try_enable_event_buffer(struct smi_info *smi_info) return rv; } -static int type_file_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int smi_type_proc_show(struct seq_file *m, void *v) { - struct smi_info *smi = data; + struct smi_info *smi = m->private; - return sprintf(page, "%s\n", si_to_str[smi->si_type]); + return seq_printf(m, "%s\n", si_to_str[smi->si_type]); } -static int stat_file_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int smi_type_proc_open(struct inode *inode, struct file *file) { - char *out = (char *) page; - struct smi_info *smi = data; + return single_open(file, smi_type_proc_show, PDE(inode)->data); +} + +static const struct file_operations smi_type_proc_ops = { + .open = smi_type_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int smi_si_stats_proc_show(struct seq_file *m, void *v) +{ + struct smi_info *smi = m->private; - out += sprintf(out, "interrupts_enabled: %d\n", + seq_printf(m, "interrupts_enabled: %d\n", smi->irq && !smi->interrupt_disabled); - out += sprintf(out, "short_timeouts: %u\n", + seq_printf(m, "short_timeouts: %u\n", smi_get_stat(smi, short_timeouts)); - out += sprintf(out, "long_timeouts: %u\n", + seq_printf(m, "long_timeouts: %u\n", smi_get_stat(smi, long_timeouts)); - out += sprintf(out, "idles: %u\n", + seq_printf(m, "idles: %u\n", smi_get_stat(smi, idles)); - out += sprintf(out, "interrupts: %u\n", + seq_printf(m, "interrupts: %u\n", smi_get_stat(smi, interrupts)); - out += sprintf(out, "attentions: %u\n", + seq_printf(m, "attentions: %u\n", smi_get_stat(smi, attentions)); - out += sprintf(out, "flag_fetches: %u\n", + seq_printf(m, "flag_fetches: %u\n", smi_get_stat(smi, flag_fetches)); - out += sprintf(out, "hosed_count: %u\n", + seq_printf(m, "hosed_count: %u\n", smi_get_stat(smi, hosed_count)); - out += sprintf(out, "complete_transactions: %u\n", + seq_printf(m, "complete_transactions: %u\n", smi_get_stat(smi, complete_transactions)); - out += sprintf(out, "events: %u\n", + seq_printf(m, "events: %u\n", smi_get_stat(smi, events)); - out += sprintf(out, "watchdog_pretimeouts: %u\n", + seq_printf(m, "watchdog_pretimeouts: %u\n", smi_get_stat(smi, watchdog_pretimeouts)); - out += sprintf(out, "incoming_messages: %u\n", + seq_printf(m, "incoming_messages: %u\n", smi_get_stat(smi, incoming_messages)); + return 0; +} - return out - page; +static int smi_si_stats_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, smi_si_stats_proc_show, PDE(inode)->data); } -static int param_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) +static const struct file_operations smi_si_stats_proc_ops = { + .open = smi_si_stats_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int smi_params_proc_show(struct seq_file *m, void *v) { - struct smi_info *smi = data; + struct smi_info *smi = m->private; - return sprintf(page, + return seq_printf(m, "%s,%s,0x%lx,rsp=%d,rsi=%d,rsh=%d,irq=%d,ipmb=%d\n", si_to_str[smi->si_type], addr_space_to_str[smi->io.addr_type], @@ -2864,6 +2884,18 @@ static int param_read_proc(char *page, char **start, off_t off, smi->slave_addr); } +static int smi_params_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, smi_params_proc_show, PDE(inode)->data); +} + +static const struct file_operations smi_params_proc_ops = { + .open = smi_params_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + /* * oem_data_avail_to_receive_msg_avail * @info - smi_info structure with msg_flags set @@ -3257,7 +3289,7 @@ static int try_smi_init(struct smi_info *new_smi) } rv = ipmi_smi_add_proc_entry(new_smi->intf, "type", - type_file_read_proc, + &smi_type_proc_ops, new_smi); if (rv) { dev_err(new_smi->dev, "Unable to create proc entry: %d\n", rv); @@ -3265,7 +3297,7 @@ static int try_smi_init(struct smi_info *new_smi) } rv = ipmi_smi_add_proc_entry(new_smi->intf, "si_stats", - stat_file_read_proc, + &smi_si_stats_proc_ops, new_smi); if (rv) { dev_err(new_smi->dev, "Unable to create proc entry: %d\n", rv); @@ -3273,7 +3305,7 @@ static int try_smi_init(struct smi_info *new_smi) } rv = ipmi_smi_add_proc_entry(new_smi->intf, "params", - param_read_proc, + &smi_params_proc_ops, new_smi); if (rv) { dev_err(new_smi->dev, "Unable to create proc entry: %d\n", rv); diff --git a/include/linux/ipmi_smi.h b/include/linux/ipmi_smi.h index 906590aa6907..204f9cd26c16 100644 --- a/include/linux/ipmi_smi.h +++ b/include/linux/ipmi_smi.h @@ -236,7 +236,7 @@ static inline void ipmi_free_smi_msg(struct ipmi_smi_msg *msg) directory for this interface. Note that the entry will automatically be dstroyed when the interface is destroyed. */ int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name, - read_proc_t *read_proc, + const struct file_operations *proc_ops, void *data); #endif /* __LINUX_IPMI_SMI_H */ -- cgit From 26498e89e83c62cffcb8836a2ac2c5b795d84258 Mon Sep 17 00:00:00 2001 From: Sisir Koppaka Date: Thu, 26 May 2011 16:25:57 -0700 Subject: pid: fix typo in function description finds is misspelt as finr. No functional change. Signed-off-by: Sisir Koppaka Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/pid.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/pid.h b/include/linux/pid.h index cdced84261d7..b152d44fb181 100644 --- a/include/linux/pid.h +++ b/include/linux/pid.h @@ -105,7 +105,7 @@ extern struct pid_namespace init_pid_ns; * or rcu_read_lock() held. * * find_pid_ns() finds the pid in the namespace specified - * find_vpid() finr the pid by its virtual id, i.e. in the current namespace + * find_vpid() finds the pid by its virtual id, i.e. in the current namespace * * see also find_task_by_vpid() set in include/linux/sched.h */ -- cgit From 19de85ef574c3a2182e3ccad9581805052f14946 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Thu, 26 May 2011 16:26:09 -0700 Subject: bitops: add #ifndef for each of find bitops The style that we normally use in asm-generic is to test the macro itself for existence, so in asm-generic, do: #ifndef find_next_zero_bit_le extern unsigned long find_next_zero_bit_le(const void *addr, unsigned long size, unsigned long offset); #endif and in the architectures, write static inline unsigned long find_next_zero_bit_le(const void *addr, unsigned long size, unsigned long offset) #define find_next_zero_bit_le find_next_zero_bit_le This adds the #ifndef for each of the find bitops in the generic header and source files. Suggested-by: Arnd Bergmann Signed-off-by: Akinobu Mita Acked-by: Russell King Cc: Martin Schwidefsky Cc: Heiko Carstens Cc: Greg Ungerer Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-generic/bitops/find.h | 4 ++++ include/asm-generic/bitops/le.h | 7 +++++++ include/linux/bitops.h | 2 ++ lib/find_last_bit.c | 4 ++++ lib/find_next_bit.c | 12 ++++++++++++ 5 files changed, 29 insertions(+) (limited to 'include/linux') diff --git a/include/asm-generic/bitops/find.h b/include/asm-generic/bitops/find.h index 110fa700f853..71c778033f57 100644 --- a/include/asm-generic/bitops/find.h +++ b/include/asm-generic/bitops/find.h @@ -1,6 +1,7 @@ #ifndef _ASM_GENERIC_BITOPS_FIND_H_ #define _ASM_GENERIC_BITOPS_FIND_H_ +#ifndef find_next_bit /** * find_next_bit - find the next set bit in a memory region * @addr: The address to base the search on @@ -9,7 +10,9 @@ */ extern unsigned long find_next_bit(const unsigned long *addr, unsigned long size, unsigned long offset); +#endif +#ifndef find_next_zero_bit /** * find_next_zero_bit - find the next cleared bit in a memory region * @addr: The address to base the search on @@ -18,6 +21,7 @@ extern unsigned long find_next_bit(const unsigned long *addr, unsigned long */ extern unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size, unsigned long offset); +#endif #ifdef CONFIG_GENERIC_FIND_FIRST_BIT diff --git a/include/asm-generic/bitops/le.h b/include/asm-generic/bitops/le.h index 946a21b1b5dc..f95c663a6a41 100644 --- a/include/asm-generic/bitops/le.h +++ b/include/asm-generic/bitops/le.h @@ -30,13 +30,20 @@ static inline unsigned long find_first_zero_bit_le(const void *addr, #define BITOP_LE_SWIZZLE ((BITS_PER_LONG-1) & ~0x7) +#ifndef find_next_zero_bit_le extern unsigned long find_next_zero_bit_le(const void *addr, unsigned long size, unsigned long offset); +#endif + +#ifndef find_next_bit_le extern unsigned long find_next_bit_le(const void *addr, unsigned long size, unsigned long offset); +#endif +#ifndef find_first_zero_bit_le #define find_first_zero_bit_le(addr, size) \ find_next_zero_bit_le((addr), (size), 0) +#endif #else #error "Please fix " diff --git a/include/linux/bitops.h b/include/linux/bitops.h index 2184c6b97aeb..4829252d7cfa 100644 --- a/include/linux/bitops.h +++ b/include/linux/bitops.h @@ -149,6 +149,7 @@ static inline unsigned long __ffs64(u64 word) #ifdef __KERNEL__ #ifdef CONFIG_GENERIC_FIND_LAST_BIT +#ifndef find_last_bit /** * find_last_bit - find the last set bit in a memory region * @addr: The address to start the search at @@ -158,6 +159,7 @@ static inline unsigned long __ffs64(u64 word) */ extern unsigned long find_last_bit(const unsigned long *addr, unsigned long size); +#endif #endif /* CONFIG_GENERIC_FIND_LAST_BIT */ #endif /* __KERNEL__ */ diff --git a/lib/find_last_bit.c b/lib/find_last_bit.c index 5d202e36bdd8..d903959ad695 100644 --- a/lib/find_last_bit.c +++ b/lib/find_last_bit.c @@ -15,6 +15,8 @@ #include #include +#ifndef find_last_bit + unsigned long find_last_bit(const unsigned long *addr, unsigned long size) { unsigned long words; @@ -43,3 +45,5 @@ found: return size; } EXPORT_SYMBOL(find_last_bit); + +#endif diff --git a/lib/find_next_bit.c b/lib/find_next_bit.c index b0a8767282bf..c02d09f37d58 100644 --- a/lib/find_next_bit.c +++ b/lib/find_next_bit.c @@ -17,6 +17,7 @@ #define BITOP_WORD(nr) ((nr) / BITS_PER_LONG) #ifdef CONFIG_GENERIC_FIND_NEXT_BIT +#ifndef find_next_bit /* * Find the next set bit in a memory region. */ @@ -59,7 +60,9 @@ found_middle: return result + __ffs(tmp); } EXPORT_SYMBOL(find_next_bit); +#endif +#ifndef find_next_zero_bit /* * This implementation of find_{first,next}_zero_bit was stolen from * Linus' asm-alpha/bitops.h. @@ -103,9 +106,11 @@ found_middle: return result + ffz(tmp); } EXPORT_SYMBOL(find_next_zero_bit); +#endif #endif /* CONFIG_GENERIC_FIND_NEXT_BIT */ #ifdef CONFIG_GENERIC_FIND_FIRST_BIT +#ifndef find_first_bit /* * Find the first set bit in a memory region. */ @@ -131,7 +136,9 @@ found: return result + __ffs(tmp); } EXPORT_SYMBOL(find_first_bit); +#endif +#ifndef find_first_zero_bit /* * Find the first cleared bit in a memory region. */ @@ -157,6 +164,7 @@ found: return result + ffz(tmp); } EXPORT_SYMBOL(find_first_zero_bit); +#endif #endif /* CONFIG_GENERIC_FIND_FIRST_BIT */ #ifdef __BIG_ENDIAN @@ -186,6 +194,7 @@ static inline unsigned long ext2_swab(const unsigned long y) #endif } +#ifndef find_next_zero_bit_le unsigned long find_next_zero_bit_le(const void *addr, unsigned long size, unsigned long offset) { @@ -229,7 +238,9 @@ found_middle_swap: return result + ffz(ext2_swab(tmp)); } EXPORT_SYMBOL(find_next_zero_bit_le); +#endif +#ifndef find_next_bit_le unsigned long find_next_bit_le(const void *addr, unsigned long size, unsigned long offset) { @@ -274,6 +285,7 @@ found_middle_swap: return result + __ffs(ext2_swab(tmp)); } EXPORT_SYMBOL(find_next_bit_le); +#endif #endif /* CONFIG_GENERIC_FIND_BIT_LE */ #endif /* __BIG_ENDIAN */ -- cgit From 63e424c84429903c92a0f1e9654c31ccaf6694d0 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Thu, 26 May 2011 16:26:10 -0700 Subject: arch: remove CONFIG_GENERIC_FIND_{NEXT_BIT,BIT_LE,LAST_BIT} By the previous style change, CONFIG_GENERIC_FIND_NEXT_BIT, CONFIG_GENERIC_FIND_BIT_LE, and CONFIG_GENERIC_FIND_LAST_BIT are not used to test for existence of find bitops anymore. Signed-off-by: Akinobu Mita Acked-by: Greg Ungerer Cc: Arnd Bergmann Cc: Russell King Cc: Martin Schwidefsky Cc: Heiko Carstens Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/alpha/Kconfig | 4 ---- arch/blackfin/Kconfig | 3 --- arch/cris/Kconfig | 4 ---- arch/frv/Kconfig | 8 -------- arch/h8300/Kconfig | 8 -------- arch/ia64/Kconfig | 4 ---- arch/m32r/Kconfig | 8 -------- arch/m68k/Kconfig.nommu | 4 ---- arch/microblaze/Kconfig | 6 ------ arch/mips/Kconfig | 8 -------- arch/mn10300/Kconfig | 3 --- arch/parisc/Kconfig | 8 -------- arch/powerpc/Kconfig | 8 -------- arch/score/Kconfig | 3 --- arch/sh/Kconfig | 6 ------ arch/sparc/Kconfig | 8 -------- arch/tile/Kconfig | 1 - arch/um/Kconfig.x86 | 1 - arch/x86/Kconfig | 1 - arch/xtensa/Kconfig | 6 ------ include/linux/bitops.h | 2 -- lib/Kconfig | 10 ---------- lib/Makefile | 8 ++------ lib/find_next_bit.c | 6 ------ 24 files changed, 2 insertions(+), 126 deletions(-) (limited to 'include/linux') diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index e3a82775f9da..60219bf94198 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig @@ -41,10 +41,6 @@ config ARCH_HAS_ILOG2_U64 bool default n -config GENERIC_FIND_NEXT_BIT - bool - default y - config GENERIC_CALIBRATE_DELAY bool default y diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index a18180f2d007..d619b17c4413 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -47,9 +47,6 @@ config GENERIC_BUG config ZONE_DMA def_bool y -config GENERIC_FIND_NEXT_BIT - def_bool y - config GENERIC_GPIO def_bool y diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig index a6d03069d0ff..b6b94a27d276 100644 --- a/arch/cris/Kconfig +++ b/arch/cris/Kconfig @@ -31,10 +31,6 @@ config ARCH_HAS_ILOG2_U64 bool default n -config GENERIC_FIND_NEXT_BIT - bool - default y - config GENERIC_HWEIGHT bool default y diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig index 064f62196745..cb884e489425 100644 --- a/arch/frv/Kconfig +++ b/arch/frv/Kconfig @@ -19,14 +19,6 @@ config RWSEM_GENERIC_SPINLOCK config RWSEM_XCHGADD_ALGORITHM bool -config GENERIC_FIND_NEXT_BIT - bool - default y - -config GENERIC_FIND_BIT_LE - bool - default y - config GENERIC_HWEIGHT bool default y diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig index e20322ffcaf8..091ed6192ae8 100644 --- a/arch/h8300/Kconfig +++ b/arch/h8300/Kconfig @@ -41,14 +41,6 @@ config ARCH_HAS_ILOG2_U64 bool default n -config GENERIC_FIND_NEXT_BIT - bool - default y - -config GENERIC_FIND_BIT_LE - bool - default y - config GENERIC_HWEIGHT bool default y diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index e5cc56ae6ce3..38280ef4a2af 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -78,10 +78,6 @@ config HUGETLB_PAGE_SIZE_VARIABLE depends on HUGETLB_PAGE default y -config GENERIC_FIND_NEXT_BIT - bool - default y - config GENERIC_CALIBRATE_DELAY bool default y diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig index 736b808d2291..85b44e858225 100644 --- a/arch/m32r/Kconfig +++ b/arch/m32r/Kconfig @@ -256,14 +256,6 @@ config ARCH_HAS_ILOG2_U64 bool default n -config GENERIC_FIND_NEXT_BIT - bool - default y - -config GENERIC_FIND_BIT_LE - bool - default y - config GENERIC_HWEIGHT bool default y diff --git a/arch/m68k/Kconfig.nommu b/arch/m68k/Kconfig.nommu index 273bccab9517..fc98f9b9d4d2 100644 --- a/arch/m68k/Kconfig.nommu +++ b/arch/m68k/Kconfig.nommu @@ -2,10 +2,6 @@ config FPU bool default n -config GENERIC_FIND_NEXT_BIT - bool - default y - config GENERIC_GPIO bool default n diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index eccdefe70d4e..e446bab2427b 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -33,12 +33,6 @@ config ARCH_HAS_ILOG2_U32 config ARCH_HAS_ILOG2_U64 def_bool n -config GENERIC_FIND_NEXT_BIT - def_bool y - -config GENERIC_FIND_BIT_LE - def_bool y - config GENERIC_HWEIGHT def_bool y diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index cef1a854487d..653da62d0682 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -821,14 +821,6 @@ config ARCH_SUPPORTS_OPROFILE bool default y if !MIPS_MT_SMTC -config GENERIC_FIND_NEXT_BIT - bool - default y - -config GENERIC_FIND_BIT_LE - bool - default y - config GENERIC_HWEIGHT bool default y diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig index feaf09cc8632..1f870340ebdd 100644 --- a/arch/mn10300/Kconfig +++ b/arch/mn10300/Kconfig @@ -44,9 +44,6 @@ config GENERIC_CALIBRATE_DELAY config GENERIC_CMOS_UPDATE def_bool n -config GENERIC_FIND_NEXT_BIT - def_bool y - config GENERIC_HWEIGHT def_bool y diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 69ff049c8571..65adc86a230e 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -47,14 +47,6 @@ config ARCH_HAS_ILOG2_U64 bool default n -config GENERIC_FIND_NEXT_BIT - bool - default y - -config GENERIC_FIND_BIT_LE - bool - default y - config GENERIC_BUG bool default y diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 2f6a22e8e935..2729c6663d8a 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -91,14 +91,6 @@ config GENERIC_HWEIGHT bool default y -config GENERIC_FIND_NEXT_BIT - bool - default y - -config GENERIC_FIND_BIT_LE - bool - default y - config GENERIC_GPIO bool help diff --git a/arch/score/Kconfig b/arch/score/Kconfig index e73bc781cc14..288add8d168f 100644 --- a/arch/score/Kconfig +++ b/arch/score/Kconfig @@ -43,9 +43,6 @@ config NO_DMA config RWSEM_GENERIC_SPINLOCK def_bool y -config GENERIC_FIND_NEXT_BIT - def_bool y - config GENERIC_HWEIGHT def_bool y diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index b44e37753b9a..74495a5ea027 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -71,12 +71,6 @@ config GENERIC_CSUM def_bool y depends on SUPERH64 -config GENERIC_FIND_NEXT_BIT - def_bool y - -config GENERIC_FIND_BIT_LE - def_bool y - config GENERIC_HWEIGHT def_bool y diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 63a027c9ada5..af32e17fa170 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -190,14 +190,6 @@ config RWSEM_XCHGADD_ALGORITHM bool default y if SPARC64 -config GENERIC_FIND_NEXT_BIT - bool - default y - -config GENERIC_FIND_BIT_LE - bool - default y - config GENERIC_HWEIGHT bool default y if !ULTRA_HAS_POPULATION_COUNT diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig index 635e1bfb1c5d..e1e50101b3bb 100644 --- a/arch/tile/Kconfig +++ b/arch/tile/Kconfig @@ -5,7 +5,6 @@ config TILE def_bool y select HAVE_KVM if !TILEGX select GENERIC_FIND_FIRST_BIT - select GENERIC_FIND_NEXT_BIT select USE_GENERIC_SMP_HELPERS select CC_OPTIMIZE_FOR_SIZE select HAVE_GENERIC_HARDIRQS diff --git a/arch/um/Kconfig.x86 b/arch/um/Kconfig.x86 index 795ea8e869f4..8aae429a56e2 100644 --- a/arch/um/Kconfig.x86 +++ b/arch/um/Kconfig.x86 @@ -15,7 +15,6 @@ endmenu config UML_X86 def_bool y select GENERIC_FIND_FIRST_BIT - select GENERIC_FIND_NEXT_BIT config 64BIT bool diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 483775f42d2a..da349723d411 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -64,7 +64,6 @@ config X86 select HAVE_GENERIC_HARDIRQS select HAVE_SPARSE_IRQ select GENERIC_FIND_FIRST_BIT - select GENERIC_FIND_NEXT_BIT select GENERIC_IRQ_PROBE select GENERIC_PENDING_IRQ if SMP select GENERIC_IRQ_SHOW diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 7c275f5d0df0..5d43c1f8ada8 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -20,12 +20,6 @@ config XTENSA config RWSEM_XCHGADD_ALGORITHM def_bool y -config GENERIC_FIND_NEXT_BIT - def_bool y - -config GENERIC_FIND_BIT_LE - def_bool y - config GENERIC_HWEIGHT def_bool y diff --git a/include/linux/bitops.h b/include/linux/bitops.h index 4829252d7cfa..a3ef66a2a083 100644 --- a/include/linux/bitops.h +++ b/include/linux/bitops.h @@ -148,7 +148,6 @@ static inline unsigned long __ffs64(u64 word) #ifdef __KERNEL__ -#ifdef CONFIG_GENERIC_FIND_LAST_BIT #ifndef find_last_bit /** * find_last_bit - find the last set bit in a memory region @@ -160,7 +159,6 @@ static inline unsigned long __ffs64(u64 word) extern unsigned long find_last_bit(const unsigned long *addr, unsigned long size); #endif -#endif /* CONFIG_GENERIC_FIND_LAST_BIT */ #endif /* __KERNEL__ */ #endif diff --git a/lib/Kconfig b/lib/Kconfig index 9c10e38fc609..830181cc7a83 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -19,16 +19,6 @@ config RATIONAL config GENERIC_FIND_FIRST_BIT bool -config GENERIC_FIND_NEXT_BIT - bool - -config GENERIC_FIND_BIT_LE - bool - -config GENERIC_FIND_LAST_BIT - bool - default y - config CRC_CCITT tristate "CRC-CCITT functions" help diff --git a/lib/Makefile b/lib/Makefile index 4b49a249064b..6b597fdb1898 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -12,7 +12,7 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \ idr.o int_sqrt.o extable.o prio_tree.o \ sha1.o irq_regs.o reciprocal_div.o argv_split.o \ proportions.o prio_heap.o ratelimit.o show_mem.o \ - is_single_threaded.o plist.o decompress.o + is_single_threaded.o plist.o decompress.o find_next_bit.o lib-$(CONFIG_MMU) += ioremap.o lib-$(CONFIG_SMP) += cpumask.o @@ -22,7 +22,7 @@ lib-y += kobject.o kref.o klist.o obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \ bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \ string_helpers.o gcd.o lcm.o list_sort.o uuid.o flex_array.o \ - bsearch.o + bsearch.o find_last_bit.o obj-y += kstrtox.o obj-$(CONFIG_TEST_KSTRTOX) += test-kstrtox.o @@ -39,10 +39,6 @@ obj-$(CONFIG_DEBUG_LOCKING_API_SELFTESTS) += locking-selftest.o obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock_debug.o lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o -lib-$(CONFIG_GENERIC_FIND_FIRST_BIT) += find_next_bit.o -lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find_next_bit.o -lib-$(CONFIG_GENERIC_FIND_BIT_LE) += find_next_bit.o -obj-$(CONFIG_GENERIC_FIND_LAST_BIT) += find_last_bit.o CFLAGS_hweight.o = $(subst $(quote),,$(CONFIG_ARCH_HWEIGHT_CFLAGS)) obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o diff --git a/lib/find_next_bit.c b/lib/find_next_bit.c index c02d09f37d58..4bd75a73ba00 100644 --- a/lib/find_next_bit.c +++ b/lib/find_next_bit.c @@ -16,7 +16,6 @@ #define BITOP_WORD(nr) ((nr) / BITS_PER_LONG) -#ifdef CONFIG_GENERIC_FIND_NEXT_BIT #ifndef find_next_bit /* * Find the next set bit in a memory region. @@ -107,9 +106,7 @@ found_middle: } EXPORT_SYMBOL(find_next_zero_bit); #endif -#endif /* CONFIG_GENERIC_FIND_NEXT_BIT */ -#ifdef CONFIG_GENERIC_FIND_FIRST_BIT #ifndef find_first_bit /* * Find the first set bit in a memory region. @@ -165,10 +162,8 @@ found: } EXPORT_SYMBOL(find_first_zero_bit); #endif -#endif /* CONFIG_GENERIC_FIND_FIRST_BIT */ #ifdef __BIG_ENDIAN -#ifdef CONFIG_GENERIC_FIND_BIT_LE /* include/linux/byteorder does not support "unsigned long" type */ static inline unsigned long ext2_swabp(const unsigned long * x) @@ -287,5 +282,4 @@ found_middle_swap: EXPORT_SYMBOL(find_next_bit_le); #endif -#endif /* CONFIG_GENERIC_FIND_BIT_LE */ #endif /* __BIG_ENDIAN */ -- cgit From 3474cb3cc0140f9cf6ca56983f8180b4b4c5c36a Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 10 May 2011 16:23:07 -0700 Subject: gpio: Convert gpio_is_valid to return bool Make the code a bit more readable. Instead of casting an int to an unsigned then comparing to MAX_NR_GPIOS, add a >= 0 test and let the compiler optimizer do the conversion to unsigned. The generated code should be the same. Signed-off-by: Joe Perches Acked-by: Linus Walleij Signed-off-by: Grant Likely --- include/asm-generic/gpio.h | 6 +++--- include/linux/gpio.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index ff5c66080c8c..a98b52cb970b 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -35,9 +35,9 @@ * platform data and other tables. */ -static inline int gpio_is_valid(int number) +static inline bool gpio_is_valid(int number) { - return ((unsigned)number) < ARCH_NR_GPIOS; + return number >= 0 && number < ARCH_NR_GPIOS; } struct device; @@ -212,7 +212,7 @@ extern void gpio_unexport(unsigned gpio); #else /* !CONFIG_GPIOLIB */ -static inline int gpio_is_valid(int number) +static inline bool gpio_is_valid(int number) { /* only non-negative numbers are valid */ return number >= 0; diff --git a/include/linux/gpio.h b/include/linux/gpio.h index 32720baf70f1..0f8265f8e8c3 100644 --- a/include/linux/gpio.h +++ b/include/linux/gpio.h @@ -25,9 +25,9 @@ struct gpio_chip; * warning when something is wrongly called. */ -static inline int gpio_is_valid(int number) +static inline bool gpio_is_valid(int number) { - return 0; + return false; } static inline int gpio_request(unsigned gpio, const char *label) -- cgit From 492c826b9facefa84995f4dea917e301b5ee0884 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sun, 8 May 2011 22:30:18 +0100 Subject: regulator: Remove supply_regulator_dev from machine configuration supply_regulator_dev (using a struct pointer) has been deprecated in favour of supply_regulator (using a regulator name) for quite a few releases now with a warning generated if it is used and there are no current in tree users so just remove the code. Signed-off-by: Mark Brown Signed-off-by: Liam Girdwood --- Documentation/power/regulator/machine.txt | 4 ++-- drivers/regulator/core.c | 16 ---------------- include/linux/regulator/machine.h | 3 --- 3 files changed, 2 insertions(+), 21 deletions(-) (limited to 'include/linux') diff --git a/Documentation/power/regulator/machine.txt b/Documentation/power/regulator/machine.txt index bdec39b9bd75..b42419b52e44 100644 --- a/Documentation/power/regulator/machine.txt +++ b/Documentation/power/regulator/machine.txt @@ -53,11 +53,11 @@ static struct regulator_init_data regulator1_data = { Regulator-1 supplies power to Regulator-2. This relationship must be registered with the core so that Regulator-1 is also enabled when Consumer A enables its -supply (Regulator-2). The supply regulator is set by the supply_regulator_dev +supply (Regulator-2). The supply regulator is set by the supply_regulator field below:- static struct regulator_init_data regulator2_data = { - .supply_regulator_dev = &platform_regulator1_device.dev, + .supply_regulator = "regulator_name", .constraints = { .min_uV = 1800000, .max_uV = 2000000, diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 98d25fcb3930..432faa5cb8af 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2596,14 +2596,6 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, if (ret < 0) goto scrub; - /* set supply regulator if it exists */ - if (init_data->supply_regulator && init_data->supply_regulator_dev) { - dev_err(dev, - "Supply regulator specified by both name and dev\n"); - ret = -EINVAL; - goto scrub; - } - if (init_data->supply_regulator) { struct regulator_dev *r; int found = 0; @@ -2628,14 +2620,6 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, goto scrub; } - if (init_data->supply_regulator_dev) { - dev_warn(dev, "Uses supply_regulator_dev instead of regulator_supply\n"); - ret = set_supply(rdev, - dev_get_drvdata(init_data->supply_regulator_dev)); - if (ret < 0) - goto scrub; - } - /* add consumers devices */ for (i = 0; i < init_data->num_consumer_supplies; i++) { ret = set_consumer_device_supply(rdev, diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h index c4c4fc45f856..8f1a55d99494 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -160,8 +160,6 @@ struct regulator_consumer_supply { * @supply_regulator: Parent regulator. Specified using the regulator name * as it appears in the name field in sysfs, which can * be explicitly set using the constraints field 'name'. - * @supply_regulator_dev: Parent regulator (if any) - DEPRECATED in favour - * of supply_regulator. * * @constraints: Constraints. These must be specified for the regulator to * be usable. @@ -173,7 +171,6 @@ struct regulator_consumer_supply { */ struct regulator_init_data { const char *supply_regulator; /* or NULL for system supply */ - struct device *supply_regulator_dev; /* or NULL for system supply */ struct regulation_constraints constraints; -- cgit From bf5892a8167e4aa5a9a6d72f803fde850e0c5753 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sun, 8 May 2011 22:13:37 +0100 Subject: regulator: Support voltage offsets to compensate for drops in system Some systems, particularly physically large systems used for early prototyping, may experience substantial voltage drops between the regulator and the consumers as a result of long traces in the system. With these systems voltages may need to be set higher than requested in order to ensure reliable system operation. Allow systems to work around such hardware issues by allowing constraints to supply an offset to be applied to any requested and reported voltages. This is not ideal, especially since the voltage drop may be load dependant, but is sufficient for most affected systems, it is not expected to be used in production hardware. The offset is applied after all constraint processing so constraints should be specified in terms of consumer values not physically configured values. Signed-off-by: Mark Brown Signed-off-by: Liam Girdwood --- drivers/regulator/core.c | 15 ++++++++++++--- include/linux/regulator/machine.h | 4 ++++ 2 files changed, 16 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 432faa5cb8af..58452ac0f165 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -724,6 +724,10 @@ static void print_constraints(struct regulator_dev *rdev) count += sprintf(buf + count, "at %d mV ", ret / 1000); } + if (constraints->uV_offset) + count += sprintf(buf, "%dmV offset ", + constraints->uV_offset / 1000); + if (constraints->min_uA && constraints->max_uA) { if (constraints->min_uA == constraints->max_uA) count += sprintf(buf + count, "%d mA ", @@ -1641,6 +1645,9 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, trace_regulator_set_voltage(rdev_get_name(rdev), min_uV, max_uV); + min_uV += rdev->constraints->uV_offset; + max_uV += rdev->constraints->uV_offset; + if (rdev->desc->ops->set_voltage) { ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV, &selector); @@ -1865,18 +1872,20 @@ EXPORT_SYMBOL_GPL(regulator_sync_voltage); static int _regulator_get_voltage(struct regulator_dev *rdev) { - int sel; + int sel, ret; if (rdev->desc->ops->get_voltage_sel) { sel = rdev->desc->ops->get_voltage_sel(rdev); if (sel < 0) return sel; - return rdev->desc->ops->list_voltage(rdev, sel); + ret = rdev->desc->ops->list_voltage(rdev, sel); } if (rdev->desc->ops->get_voltage) - return rdev->desc->ops->get_voltage(rdev); + ret = rdev->desc->ops->get_voltage(rdev); else return -EINVAL; + + return ret - rdev->constraints->uV_offset; } /** diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h index 8f1a55d99494..ce3127a75c88 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -68,6 +68,8 @@ struct regulator_state { * * @min_uV: Smallest voltage consumers may set. * @max_uV: Largest voltage consumers may set. + * @uV_offset: Offset applied to voltages from consumer to compensate for + * voltage drops. * * @min_uA: Smallest consumers consumers may set. * @max_uA: Largest current consumers may set. @@ -99,6 +101,8 @@ struct regulation_constraints { int min_uV; int max_uV; + int uV_offset; + /* current output range (inclusive) - for current control */ int min_uA; int max_uA; -- cgit From 27c6750ec56fd3b22c670d9333d519a322996eb2 Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Mon, 2 May 2011 16:19:46 -0500 Subject: MFD: TPS65910: Add new mfd device for TPS65910 The TPS65910 chip is a power management IC for multimedia and handheld devices. It contains the following components: - Regulators - GPIO controller - RTC The tps65910 core driver is registered as a platform driver and provides communication through I2C with the host device for the different components. Signed-off-by: Graeme Gregory Signed-off-by: Jorge Eduardo Candelaria Acked-by: Samuel Ortiz Signed-off-by: Liam Girdwood --- drivers/mfd/Kconfig | 8 + drivers/mfd/Makefile | 1 + drivers/mfd/tps65910.c | 208 ++++++++++++ include/linux/mfd/tps65910.h | 753 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 970 insertions(+) create mode 100644 drivers/mfd/tps65910.c create mode 100644 include/linux/mfd/tps65910.h (limited to 'include/linux') diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 8344fc0ab858..d67511a67fdd 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -719,6 +719,14 @@ config MFD_PM8XXX_IRQ This is required to use certain other PM 8xxx features, such as GPIO and MPP. +config MFD_TPS65910 + tristate "TPS65910 Power Management chip" + depends on I2C && GPIOLIB + select MFD_CORE + help + if you say yes here you get support for the TPS65910 series of + Power Management chips. + endif # MFD_SUPPORT menu "Multimedia Capabilities Port drivers" diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 1acb8f29a96c..f43ef5bba3ba 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -93,3 +93,4 @@ obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.o +obj-$(CONFIG_MFD_TPS65910) += tps65910.o diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c new file mode 100644 index 000000000000..dbcdfb55bb8d --- /dev/null +++ b/drivers/mfd/tps65910.c @@ -0,0 +1,208 @@ +/* + * tps65910.c -- TI TPS6591x + * + * Copyright 2010 Texas Instruments Inc. + * + * Author: Graeme Gregory + * Author: Jorge Eduardo Candelaria + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static struct mfd_cell tps65910s[] = { + { + .name = "tps65910-pmic", + }, + { + .name = "tps65910-rtc", + }, + { + .name = "tps65910-power", + }, +}; + + +static int tps65910_i2c_read(struct tps65910 *tps65910, u8 reg, + int bytes, void *dest) +{ + struct i2c_client *i2c = tps65910->i2c_client; + struct i2c_msg xfer[2]; + int ret; + + /* Write register */ + xfer[0].addr = i2c->addr; + xfer[0].flags = 0; + xfer[0].len = 1; + xfer[0].buf = ® + + /* Read data */ + xfer[1].addr = i2c->addr; + xfer[1].flags = I2C_M_RD; + xfer[1].len = bytes; + xfer[1].buf = dest; + + ret = i2c_transfer(i2c->adapter, xfer, 2); + if (ret == 2) + ret = 0; + else if (ret >= 0) + ret = -EIO; + + return ret; +} + +static int tps65910_i2c_write(struct tps65910 *tps65910, u8 reg, + int bytes, void *src) +{ + struct i2c_client *i2c = tps65910->i2c_client; + /* we add 1 byte for device register */ + u8 msg[TPS65910_MAX_REGISTER + 1]; + int ret; + + if (bytes > (TPS65910_MAX_REGISTER + 1)) + return -EINVAL; + + msg[0] = reg; + memcpy(&msg[1], src, bytes); + + ret = i2c_master_send(i2c, msg, bytes + 1); + if (ret < 0) + return ret; + if (ret != bytes + 1) + return -EIO; + return 0; +} + +int tps65910_set_bits(struct tps65910 *tps65910, u8 reg, u8 mask) +{ + u8 data; + int err; + + mutex_lock(&tps65910->io_mutex); + err = tps65910_i2c_read(tps65910, reg, 1, &data); + if (err) { + dev_err(tps65910->dev, "read from reg %x failed\n", reg); + goto out; + } + + data |= mask; + err = tps65910_i2c_write(tps65910, reg, 1, &data); + if (err) + dev_err(tps65910->dev, "write to reg %x failed\n", reg); + +out: + mutex_unlock(&tps65910->io_mutex); + return err; +} +EXPORT_SYMBOL_GPL(tps65910_set_bits); + +int tps65910_clear_bits(struct tps65910 *tps65910, u8 reg, u8 mask) +{ + u8 data; + int err; + + mutex_lock(&tps65910->io_mutex); + err = tps65910_i2c_read(tps65910, reg, 1, &data); + if (err) { + dev_err(tps65910->dev, "read from reg %x failed\n", reg); + goto out; + } + + data &= mask; + err = tps65910_i2c_write(tps65910, reg, 1, &data); + if (err) + dev_err(tps65910->dev, "write to reg %x failed\n", reg); + +out: + mutex_unlock(&tps65910->io_mutex); + return err; +} +EXPORT_SYMBOL_GPL(tps65910_clear_bits); + +static int tps65910_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct tps65910 *tps65910; + int ret = 0; + + tps65910 = kzalloc(sizeof(struct tps65910), GFP_KERNEL); + if (tps65910 == NULL) + return -ENOMEM; + + i2c_set_clientdata(i2c, tps65910); + tps65910->dev = &i2c->dev; + tps65910->i2c_client = i2c; + tps65910->read = tps65910_i2c_read; + tps65910->write = tps65910_i2c_write; + mutex_init(&tps65910->io_mutex); + + ret = mfd_add_devices(tps65910->dev, -1, + tps65910s, ARRAY_SIZE(tps65910s), + NULL, 0); + if (ret < 0) + goto err; + + return ret; + +err: + mfd_remove_devices(tps65910->dev); + kfree(tps65910); + return ret; +} + +static int tps65910_i2c_remove(struct i2c_client *i2c) +{ + struct tps65910 *tps65910 = i2c_get_clientdata(i2c); + + mfd_remove_devices(tps65910->dev); + kfree(tps65910); + + return 0; +} + +static const struct i2c_device_id tps65910_i2c_id[] = { + { "tps65910", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, tps65910_i2c_id); + + +static struct i2c_driver tps65910_i2c_driver = { + .driver = { + .name = "tps65910", + .owner = THIS_MODULE, + }, + .probe = tps65910_i2c_probe, + .remove = tps65910_i2c_remove, + .id_table = tps65910_i2c_id, +}; + +static int __init tps65910_i2c_init(void) +{ + return i2c_add_driver(&tps65910_i2c_driver); +} +/* init early so consumer devices can complete system boot */ +subsys_initcall(tps65910_i2c_init); + +static void __exit tps65910_i2c_exit(void) +{ + i2c_del_driver(&tps65910_i2c_driver); +} +module_exit(tps65910_i2c_exit); + +MODULE_AUTHOR("Graeme Gregory "); +MODULE_AUTHOR("Jorge Eduardo Candelaria "); +MODULE_DESCRIPTION("TPS6591x chip family multi-function driver"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/mfd/tps65910.h b/include/linux/mfd/tps65910.h new file mode 100644 index 000000000000..fa1b029e5499 --- /dev/null +++ b/include/linux/mfd/tps65910.h @@ -0,0 +1,753 @@ +/* + * tps65910.h -- TI TPS6591x + * + * Copyright 2010-2011 Texas Instruments Inc. + * + * Author: Graeme Gregory + * Author: Jorge Eduardo Candelaria + * Author: Arnaud Deconinck + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#ifndef __LINUX_MFD_TPS65910_H +#define __LINUX_MFD_TPS65910_H + +/* + * List of registers for component TPS65910 + * + */ + +#define TPS65910_SECONDS 0x0 +#define TPS65910_MINUTES 0x1 +#define TPS65910_HOURS 0x2 +#define TPS65910_DAYS 0x3 +#define TPS65910_MONTHS 0x4 +#define TPS65910_YEARS 0x5 +#define TPS65910_WEEKS 0x6 +#define TPS65910_ALARM_SECONDS 0x8 +#define TPS65910_ALARM_MINUTES 0x9 +#define TPS65910_ALARM_HOURS 0xA +#define TPS65910_ALARM_DAYS 0xB +#define TPS65910_ALARM_MONTHS 0xC +#define TPS65910_ALARM_YEARS 0xD +#define TPS65910_RTC_CTRL 0x10 +#define TPS65910_RTC_STATUS 0x11 +#define TPS65910_RTC_INTERRUPTS 0x12 +#define TPS65910_RTC_COMP_LSB 0x13 +#define TPS65910_RTC_COMP_MSB 0x14 +#define TPS65910_RTC_RES_PROG 0x15 +#define TPS65910_RTC_RESET_STATUS 0x16 +#define TPS65910_BCK1 0x17 +#define TPS65910_BCK2 0x18 +#define TPS65910_BCK3 0x19 +#define TPS65910_BCK4 0x1A +#define TPS65910_BCK5 0x1B +#define TPS65910_PUADEN 0x1C +#define TPS65910_REF 0x1D +#define TPS65910_VRTC 0x1E +#define TPS65910_VIO 0x20 +#define TPS65910_VDD1 0x21 +#define TPS65910_VDD1_OP 0x22 +#define TPS65910_VDD1_SR 0x23 +#define TPS65910_VDD2 0x24 +#define TPS65910_VDD2_OP 0x25 +#define TPS65910_VDD2_SR 0x26 +#define TPS65910_VDD3 0x27 +#define TPS65910_VDIG1 0x30 +#define TPS65910_VDIG2 0x31 +#define TPS65910_VAUX1 0x32 +#define TPS65910_VAUX2 0x33 +#define TPS65910_VAUX33 0x34 +#define TPS65910_VMMC 0x35 +#define TPS65910_VPLL 0x36 +#define TPS65910_VDAC 0x37 +#define TPS65910_THERM 0x38 +#define TPS65910_BBCH 0x39 +#define TPS65910_DCDCCTRL 0x3E +#define TPS65910_DEVCTRL 0x3F +#define TPS65910_DEVCTRL2 0x40 +#define TPS65910_SLEEP_KEEP_LDO_ON 0x41 +#define TPS65910_SLEEP_KEEP_RES_ON 0x42 +#define TPS65910_SLEEP_SET_LDO_OFF 0x43 +#define TPS65910_SLEEP_SET_RES_OFF 0x44 +#define TPS65910_EN1_LDO_ASS 0x45 +#define TPS65910_EN1_SMPS_ASS 0x46 +#define TPS65910_EN2_LDO_ASS 0x47 +#define TPS65910_EN2_SMPS_ASS 0x48 +#define TPS65910_EN3_LDO_ASS 0x49 +#define TPS65910_SPARE 0x4A +#define TPS65910_INT_STS 0x50 +#define TPS65910_INT_MSK 0x51 +#define TPS65910_INT_STS2 0x52 +#define TPS65910_INT_MSK2 0x53 +#define TPS65910_INT_STS3 0x54 +#define TPS65910_INT_MSK3 0x55 +#define TPS65910_GPIO0 0x60 +#define TPS65910_GPIO1 0x61 +#define TPS65910_GPIO2 0x62 +#define TPS65910_GPIO3 0x63 +#define TPS65910_GPIO4 0x64 +#define TPS65910_GPIO5 0x65 +#define TPS65910_JTAGVERNUM 0x80 +#define TPS65910_MAX_REGISTER 0x80 + +/* + * List of register bitfields for component TPS65910 + * + */ + + +/*Register BCK1 (0x80) register.RegisterDescription */ +#define BCK1_BCKUP_MASK 0xFF +#define BCK1_BCKUP_SHIFT 0 + + +/*Register BCK2 (0x80) register.RegisterDescription */ +#define BCK2_BCKUP_MASK 0xFF +#define BCK2_BCKUP_SHIFT 0 + + +/*Register BCK3 (0x80) register.RegisterDescription */ +#define BCK3_BCKUP_MASK 0xFF +#define BCK3_BCKUP_SHIFT 0 + + +/*Register BCK4 (0x80) register.RegisterDescription */ +#define BCK4_BCKUP_MASK 0xFF +#define BCK4_BCKUP_SHIFT 0 + + +/*Register BCK5 (0x80) register.RegisterDescription */ +#define BCK5_BCKUP_MASK 0xFF +#define BCK5_BCKUP_SHIFT 0 + + +/*Register PUADEN (0x80) register.RegisterDescription */ +#define PUADEN_EN3P_MASK 0x80 +#define PUADEN_EN3P_SHIFT 7 +#define PUADEN_I2CCTLP_MASK 0x40 +#define PUADEN_I2CCTLP_SHIFT 6 +#define PUADEN_I2CSRP_MASK 0x20 +#define PUADEN_I2CSRP_SHIFT 5 +#define PUADEN_PWRONP_MASK 0x10 +#define PUADEN_PWRONP_SHIFT 4 +#define PUADEN_SLEEPP_MASK 0x08 +#define PUADEN_SLEEPP_SHIFT 3 +#define PUADEN_PWRHOLDP_MASK 0x04 +#define PUADEN_PWRHOLDP_SHIFT 2 +#define PUADEN_BOOT1P_MASK 0x02 +#define PUADEN_BOOT1P_SHIFT 1 +#define PUADEN_BOOT0P_MASK 0x01 +#define PUADEN_BOOT0P_SHIFT 0 + + +/*Register REF (0x80) register.RegisterDescription */ +#define REF_VMBCH_SEL_MASK 0x0C +#define REF_VMBCH_SEL_SHIFT 2 +#define REF_ST_MASK 0x03 +#define REF_ST_SHIFT 0 + + +/*Register VRTC (0x80) register.RegisterDescription */ +#define VRTC_VRTC_OFFMASK_MASK 0x08 +#define VRTC_VRTC_OFFMASK_SHIFT 3 +#define VRTC_ST_MASK 0x03 +#define VRTC_ST_SHIFT 0 + + +/*Register VIO (0x80) register.RegisterDescription */ +#define VIO_ILMAX_MASK 0xC0 +#define VIO_ILMAX_SHIFT 6 +#define VIO_SEL_MASK 0x0C +#define VIO_SEL_SHIFT 2 +#define VIO_ST_MASK 0x03 +#define VIO_ST_SHIFT 0 + + +/*Register VDD1 (0x80) register.RegisterDescription */ +#define VDD1_VGAIN_SEL_MASK 0xC0 +#define VDD1_VGAIN_SEL_SHIFT 6 +#define VDD1_ILMAX_MASK 0x20 +#define VDD1_ILMAX_SHIFT 5 +#define VDD1_TSTEP_MASK 0x1C +#define VDD1_TSTEP_SHIFT 2 +#define VDD1_ST_MASK 0x03 +#define VDD1_ST_SHIFT 0 + + +/*Register VDD1_OP (0x80) register.RegisterDescription */ +#define VDD1_OP_CMD_MASK 0x80 +#define VDD1_OP_CMD_SHIFT 7 +#define VDD1_OP_SEL_MASK 0x7F +#define VDD1_OP_SEL_SHIFT 0 + + +/*Register VDD1_SR (0x80) register.RegisterDescription */ +#define VDD1_SR_SEL_MASK 0x7F +#define VDD1_SR_SEL_SHIFT 0 + + +/*Register VDD2 (0x80) register.RegisterDescription */ +#define VDD2_VGAIN_SEL_MASK 0xC0 +#define VDD2_VGAIN_SEL_SHIFT 6 +#define VDD2_ILMAX_MASK 0x20 +#define VDD2_ILMAX_SHIFT 5 +#define VDD2_TSTEP_MASK 0x1C +#define VDD2_TSTEP_SHIFT 2 +#define VDD2_ST_MASK 0x03 +#define VDD2_ST_SHIFT 0 + + +/*Register VDD2_OP (0x80) register.RegisterDescription */ +#define VDD2_OP_CMD_MASK 0x80 +#define VDD2_OP_CMD_SHIFT 7 +#define VDD2_OP_SEL_MASK 0x7F +#define VDD2_OP_SEL_SHIFT 0 + + +/*Register VDD2_SR (0x80) register.RegisterDescription */ +#define VDD2_SR_SEL_MASK 0x7F +#define VDD2_SR_SEL_SHIFT 0 + + +/*Register VDD3 (0x80) register.RegisterDescription */ +#define VDD3_CKINEN_MASK 0x04 +#define VDD3_CKINEN_SHIFT 2 +#define VDD3_ST_MASK 0x03 +#define VDD3_ST_SHIFT 0 + + +/*Register VDIG1 (0x80) register.RegisterDescription */ +#define VDIG1_SEL_MASK 0x0C +#define VDIG1_SEL_SHIFT 2 +#define VDIG1_ST_MASK 0x03 +#define VDIG1_ST_SHIFT 0 + + +/*Register VDIG2 (0x80) register.RegisterDescription */ +#define VDIG2_SEL_MASK 0x0C +#define VDIG2_SEL_SHIFT 2 +#define VDIG2_ST_MASK 0x03 +#define VDIG2_ST_SHIFT 0 + + +/*Register VAUX1 (0x80) register.RegisterDescription */ +#define VAUX1_SEL_MASK 0x0C +#define VAUX1_SEL_SHIFT 2 +#define VAUX1_ST_MASK 0x03 +#define VAUX1_ST_SHIFT 0 + + +/*Register VAUX2 (0x80) register.RegisterDescription */ +#define VAUX2_SEL_MASK 0x0C +#define VAUX2_SEL_SHIFT 2 +#define VAUX2_ST_MASK 0x03 +#define VAUX2_ST_SHIFT 0 + + +/*Register VAUX33 (0x80) register.RegisterDescription */ +#define VAUX33_SEL_MASK 0x0C +#define VAUX33_SEL_SHIFT 2 +#define VAUX33_ST_MASK 0x03 +#define VAUX33_ST_SHIFT 0 + + +/*Register VMMC (0x80) register.RegisterDescription */ +#define VMMC_SEL_MASK 0x0C +#define VMMC_SEL_SHIFT 2 +#define VMMC_ST_MASK 0x03 +#define VMMC_ST_SHIFT 0 + + +/*Register VPLL (0x80) register.RegisterDescription */ +#define VPLL_SEL_MASK 0x0C +#define VPLL_SEL_SHIFT 2 +#define VPLL_ST_MASK 0x03 +#define VPLL_ST_SHIFT 0 + + +/*Register VDAC (0x80) register.RegisterDescription */ +#define VDAC_SEL_MASK 0x0C +#define VDAC_SEL_SHIFT 2 +#define VDAC_ST_MASK 0x03 +#define VDAC_ST_SHIFT 0 + + +/*Register THERM (0x80) register.RegisterDescription */ +#define THERM_THERM_HD_MASK 0x20 +#define THERM_THERM_HD_SHIFT 5 +#define THERM_THERM_TS_MASK 0x10 +#define THERM_THERM_TS_SHIFT 4 +#define THERM_THERM_HDSEL_MASK 0x0C +#define THERM_THERM_HDSEL_SHIFT 2 +#define THERM_RSVD1_MASK 0x02 +#define THERM_RSVD1_SHIFT 1 +#define THERM_THERM_STATE_MASK 0x01 +#define THERM_THERM_STATE_SHIFT 0 + + +/*Register BBCH (0x80) register.RegisterDescription */ +#define BBCH_BBSEL_MASK 0x06 +#define BBCH_BBSEL_SHIFT 1 +#define BBCH_BBCHEN_MASK 0x01 +#define BBCH_BBCHEN_SHIFT 0 + + +/*Register DCDCCTRL (0x80) register.RegisterDescription */ +#define DCDCCTRL_VDD2_PSKIP_MASK 0x20 +#define DCDCCTRL_VDD2_PSKIP_SHIFT 5 +#define DCDCCTRL_VDD1_PSKIP_MASK 0x10 +#define DCDCCTRL_VDD1_PSKIP_SHIFT 4 +#define DCDCCTRL_VIO_PSKIP_MASK 0x08 +#define DCDCCTRL_VIO_PSKIP_SHIFT 3 +#define DCDCCTRL_DCDCCKEXT_MASK 0x04 +#define DCDCCTRL_DCDCCKEXT_SHIFT 2 +#define DCDCCTRL_DCDCCKSYNC_MASK 0x03 +#define DCDCCTRL_DCDCCKSYNC_SHIFT 0 + + +/*Register DEVCTRL (0x80) register.RegisterDescription */ +#define DEVCTRL_RTC_PWDN_MASK 0x40 +#define DEVCTRL_RTC_PWDN_SHIFT 6 +#define DEVCTRL_CK32K_CTRL_MASK 0x20 +#define DEVCTRL_CK32K_CTRL_SHIFT 5 +#define DEVCTRL_SR_CTL_I2C_SEL_MASK 0x10 +#define DEVCTRL_SR_CTL_I2C_SEL_SHIFT 4 +#define DEVCTRL_DEV_OFF_RST_MASK 0x08 +#define DEVCTRL_DEV_OFF_RST_SHIFT 3 +#define DEVCTRL_DEV_ON_MASK 0x04 +#define DEVCTRL_DEV_ON_SHIFT 2 +#define DEVCTRL_DEV_SLP_MASK 0x02 +#define DEVCTRL_DEV_SLP_SHIFT 1 +#define DEVCTRL_DEV_OFF_MASK 0x01 +#define DEVCTRL_DEV_OFF_SHIFT 0 + + +/*Register DEVCTRL2 (0x80) register.RegisterDescription */ +#define DEVCTRL2_TSLOT_LENGTH_MASK 0x30 +#define DEVCTRL2_TSLOT_LENGTH_SHIFT 4 +#define DEVCTRL2_SLEEPSIG_POL_MASK 0x08 +#define DEVCTRL2_SLEEPSIG_POL_SHIFT 3 +#define DEVCTRL2_PWON_LP_OFF_MASK 0x04 +#define DEVCTRL2_PWON_LP_OFF_SHIFT 2 +#define DEVCTRL2_PWON_LP_RST_MASK 0x02 +#define DEVCTRL2_PWON_LP_RST_SHIFT 1 +#define DEVCTRL2_IT_POL_MASK 0x01 +#define DEVCTRL2_IT_POL_SHIFT 0 + + +/*Register SLEEP_KEEP_LDO_ON (0x80) register.RegisterDescription */ +#define SLEEP_KEEP_LDO_ON_VDAC_KEEPON_MASK 0x80 +#define SLEEP_KEEP_LDO_ON_VDAC_KEEPON_SHIFT 7 +#define SLEEP_KEEP_LDO_ON_VPLL_KEEPON_MASK 0x40 +#define SLEEP_KEEP_LDO_ON_VPLL_KEEPON_SHIFT 6 +#define SLEEP_KEEP_LDO_ON_VAUX33_KEEPON_MASK 0x20 +#define SLEEP_KEEP_LDO_ON_VAUX33_KEEPON_SHIFT 5 +#define SLEEP_KEEP_LDO_ON_VAUX2_KEEPON_MASK 0x10 +#define SLEEP_KEEP_LDO_ON_VAUX2_KEEPON_SHIFT 4 +#define SLEEP_KEEP_LDO_ON_VAUX1_KEEPON_MASK 0x08 +#define SLEEP_KEEP_LDO_ON_VAUX1_KEEPON_SHIFT 3 +#define SLEEP_KEEP_LDO_ON_VDIG2_KEEPON_MASK 0x04 +#define SLEEP_KEEP_LDO_ON_VDIG2_KEEPON_SHIFT 2 +#define SLEEP_KEEP_LDO_ON_VDIG1_KEEPON_MASK 0x02 +#define SLEEP_KEEP_LDO_ON_VDIG1_KEEPON_SHIFT 1 +#define SLEEP_KEEP_LDO_ON_VMMC_KEEPON_MASK 0x01 +#define SLEEP_KEEP_LDO_ON_VMMC_KEEPON_SHIFT 0 + + +/*Register SLEEP_KEEP_RES_ON (0x80) register.RegisterDescription */ +#define SLEEP_KEEP_RES_ON_THERM_KEEPON_MASK 0x80 +#define SLEEP_KEEP_RES_ON_THERM_KEEPON_SHIFT 7 +#define SLEEP_KEEP_RES_ON_CLKOUT32K_KEEPON_MASK 0x40 +#define SLEEP_KEEP_RES_ON_CLKOUT32K_KEEPON_SHIFT 6 +#define SLEEP_KEEP_RES_ON_VRTC_KEEPON_MASK 0x20 +#define SLEEP_KEEP_RES_ON_VRTC_KEEPON_SHIFT 5 +#define SLEEP_KEEP_RES_ON_I2CHS_KEEPON_MASK 0x10 +#define SLEEP_KEEP_RES_ON_I2CHS_KEEPON_SHIFT 4 +#define SLEEP_KEEP_RES_ON_VDD3_KEEPON_MASK 0x08 +#define SLEEP_KEEP_RES_ON_VDD3_KEEPON_SHIFT 3 +#define SLEEP_KEEP_RES_ON_VDD2_KEEPON_MASK 0x04 +#define SLEEP_KEEP_RES_ON_VDD2_KEEPON_SHIFT 2 +#define SLEEP_KEEP_RES_ON_VDD1_KEEPON_MASK 0x02 +#define SLEEP_KEEP_RES_ON_VDD1_KEEPON_SHIFT 1 +#define SLEEP_KEEP_RES_ON_VIO_KEEPON_MASK 0x01 +#define SLEEP_KEEP_RES_ON_VIO_KEEPON_SHIFT 0 + + +/*Register SLEEP_SET_LDO_OFF (0x80) register.RegisterDescription */ +#define SLEEP_SET_LDO_OFF_VDAC_SETOFF_MASK 0x80 +#define SLEEP_SET_LDO_OFF_VDAC_SETOFF_SHIFT 7 +#define SLEEP_SET_LDO_OFF_VPLL_SETOFF_MASK 0x40 +#define SLEEP_SET_LDO_OFF_VPLL_SETOFF_SHIFT 6 +#define SLEEP_SET_LDO_OFF_VAUX33_SETOFF_MASK 0x20 +#define SLEEP_SET_LDO_OFF_VAUX33_SETOFF_SHIFT 5 +#define SLEEP_SET_LDO_OFF_VAUX2_SETOFF_MASK 0x10 +#define SLEEP_SET_LDO_OFF_VAUX2_SETOFF_SHIFT 4 +#define SLEEP_SET_LDO_OFF_VAUX1_SETOFF_MASK 0x08 +#define SLEEP_SET_LDO_OFF_VAUX1_SETOFF_SHIFT 3 +#define SLEEP_SET_LDO_OFF_VDIG2_SETOFF_MASK 0x04 +#define SLEEP_SET_LDO_OFF_VDIG2_SETOFF_SHIFT 2 +#define SLEEP_SET_LDO_OFF_VDIG1_SETOFF_MASK 0x02 +#define SLEEP_SET_LDO_OFF_VDIG1_SETOFF_SHIFT 1 +#define SLEEP_SET_LDO_OFF_VMMC_SETOFF_MASK 0x01 +#define SLEEP_SET_LDO_OFF_VMMC_SETOFF_SHIFT 0 + + +/*Register SLEEP_SET_RES_OFF (0x80) register.RegisterDescription */ +#define SLEEP_SET_RES_OFF_DEFAULT_VOLT_MASK 0x80 +#define SLEEP_SET_RES_OFF_DEFAULT_VOLT_SHIFT 7 +#define SLEEP_SET_RES_OFF_RSVD_MASK 0x60 +#define SLEEP_SET_RES_OFF_RSVD_SHIFT 5 +#define SLEEP_SET_RES_OFF_SPARE_SETOFF_MASK 0x10 +#define SLEEP_SET_RES_OFF_SPARE_SETOFF_SHIFT 4 +#define SLEEP_SET_RES_OFF_VDD3_SETOFF_MASK 0x08 +#define SLEEP_SET_RES_OFF_VDD3_SETOFF_SHIFT 3 +#define SLEEP_SET_RES_OFF_VDD2_SETOFF_MASK 0x04 +#define SLEEP_SET_RES_OFF_VDD2_SETOFF_SHIFT 2 +#define SLEEP_SET_RES_OFF_VDD1_SETOFF_MASK 0x02 +#define SLEEP_SET_RES_OFF_VDD1_SETOFF_SHIFT 1 +#define SLEEP_SET_RES_OFF_VIO_SETOFF_MASK 0x01 +#define SLEEP_SET_RES_OFF_VIO_SETOFF_SHIFT 0 + + +/*Register EN1_LDO_ASS (0x80) register.RegisterDescription */ +#define EN1_LDO_ASS_VDAC_EN1_MASK 0x80 +#define EN1_LDO_ASS_VDAC_EN1_SHIFT 7 +#define EN1_LDO_ASS_VPLL_EN1_MASK 0x40 +#define EN1_LDO_ASS_VPLL_EN1_SHIFT 6 +#define EN1_LDO_ASS_VAUX33_EN1_MASK 0x20 +#define EN1_LDO_ASS_VAUX33_EN1_SHIFT 5 +#define EN1_LDO_ASS_VAUX2_EN1_MASK 0x10 +#define EN1_LDO_ASS_VAUX2_EN1_SHIFT 4 +#define EN1_LDO_ASS_VAUX1_EN1_MASK 0x08 +#define EN1_LDO_ASS_VAUX1_EN1_SHIFT 3 +#define EN1_LDO_ASS_VDIG2_EN1_MASK 0x04 +#define EN1_LDO_ASS_VDIG2_EN1_SHIFT 2 +#define EN1_LDO_ASS_VDIG1_EN1_MASK 0x02 +#define EN1_LDO_ASS_VDIG1_EN1_SHIFT 1 +#define EN1_LDO_ASS_VMMC_EN1_MASK 0x01 +#define EN1_LDO_ASS_VMMC_EN1_SHIFT 0 + + +/*Register EN1_SMPS_ASS (0x80) register.RegisterDescription */ +#define EN1_SMPS_ASS_RSVD_MASK 0xE0 +#define EN1_SMPS_ASS_RSVD_SHIFT 5 +#define EN1_SMPS_ASS_SPARE_EN1_MASK 0x10 +#define EN1_SMPS_ASS_SPARE_EN1_SHIFT 4 +#define EN1_SMPS_ASS_VDD3_EN1_MASK 0x08 +#define EN1_SMPS_ASS_VDD3_EN1_SHIFT 3 +#define EN1_SMPS_ASS_VDD2_EN1_MASK 0x04 +#define EN1_SMPS_ASS_VDD2_EN1_SHIFT 2 +#define EN1_SMPS_ASS_VDD1_EN1_MASK 0x02 +#define EN1_SMPS_ASS_VDD1_EN1_SHIFT 1 +#define EN1_SMPS_ASS_VIO_EN1_MASK 0x01 +#define EN1_SMPS_ASS_VIO_EN1_SHIFT 0 + + +/*Register EN2_LDO_ASS (0x80) register.RegisterDescription */ +#define EN2_LDO_ASS_VDAC_EN2_MASK 0x80 +#define EN2_LDO_ASS_VDAC_EN2_SHIFT 7 +#define EN2_LDO_ASS_VPLL_EN2_MASK 0x40 +#define EN2_LDO_ASS_VPLL_EN2_SHIFT 6 +#define EN2_LDO_ASS_VAUX33_EN2_MASK 0x20 +#define EN2_LDO_ASS_VAUX33_EN2_SHIFT 5 +#define EN2_LDO_ASS_VAUX2_EN2_MASK 0x10 +#define EN2_LDO_ASS_VAUX2_EN2_SHIFT 4 +#define EN2_LDO_ASS_VAUX1_EN2_MASK 0x08 +#define EN2_LDO_ASS_VAUX1_EN2_SHIFT 3 +#define EN2_LDO_ASS_VDIG2_EN2_MASK 0x04 +#define EN2_LDO_ASS_VDIG2_EN2_SHIFT 2 +#define EN2_LDO_ASS_VDIG1_EN2_MASK 0x02 +#define EN2_LDO_ASS_VDIG1_EN2_SHIFT 1 +#define EN2_LDO_ASS_VMMC_EN2_MASK 0x01 +#define EN2_LDO_ASS_VMMC_EN2_SHIFT 0 + + +/*Register EN2_SMPS_ASS (0x80) register.RegisterDescription */ +#define EN2_SMPS_ASS_RSVD_MASK 0xE0 +#define EN2_SMPS_ASS_RSVD_SHIFT 5 +#define EN2_SMPS_ASS_SPARE_EN2_MASK 0x10 +#define EN2_SMPS_ASS_SPARE_EN2_SHIFT 4 +#define EN2_SMPS_ASS_VDD3_EN2_MASK 0x08 +#define EN2_SMPS_ASS_VDD3_EN2_SHIFT 3 +#define EN2_SMPS_ASS_VDD2_EN2_MASK 0x04 +#define EN2_SMPS_ASS_VDD2_EN2_SHIFT 2 +#define EN2_SMPS_ASS_VDD1_EN2_MASK 0x02 +#define EN2_SMPS_ASS_VDD1_EN2_SHIFT 1 +#define EN2_SMPS_ASS_VIO_EN2_MASK 0x01 +#define EN2_SMPS_ASS_VIO_EN2_SHIFT 0 + + +/*Register EN3_LDO_ASS (0x80) register.RegisterDescription */ +#define EN3_LDO_ASS_VDAC_EN3_MASK 0x80 +#define EN3_LDO_ASS_VDAC_EN3_SHIFT 7 +#define EN3_LDO_ASS_VPLL_EN3_MASK 0x40 +#define EN3_LDO_ASS_VPLL_EN3_SHIFT 6 +#define EN3_LDO_ASS_VAUX33_EN3_MASK 0x20 +#define EN3_LDO_ASS_VAUX33_EN3_SHIFT 5 +#define EN3_LDO_ASS_VAUX2_EN3_MASK 0x10 +#define EN3_LDO_ASS_VAUX2_EN3_SHIFT 4 +#define EN3_LDO_ASS_VAUX1_EN3_MASK 0x08 +#define EN3_LDO_ASS_VAUX1_EN3_SHIFT 3 +#define EN3_LDO_ASS_VDIG2_EN3_MASK 0x04 +#define EN3_LDO_ASS_VDIG2_EN3_SHIFT 2 +#define EN3_LDO_ASS_VDIG1_EN3_MASK 0x02 +#define EN3_LDO_ASS_VDIG1_EN3_SHIFT 1 +#define EN3_LDO_ASS_VMMC_EN3_MASK 0x01 +#define EN3_LDO_ASS_VMMC_EN3_SHIFT 0 + + +/*Register SPARE (0x80) register.RegisterDescription */ +#define SPARE_SPARE_MASK 0xFF +#define SPARE_SPARE_SHIFT 0 + + +/*Register INT_STS (0x80) register.RegisterDescription */ +#define INT_STS_RTC_PERIOD_IT_MASK 0x80 +#define INT_STS_RTC_PERIOD_IT_SHIFT 7 +#define INT_STS_RTC_ALARM_IT_MASK 0x40 +#define INT_STS_RTC_ALARM_IT_SHIFT 6 +#define INT_STS_HOTDIE_IT_MASK 0x20 +#define INT_STS_HOTDIE_IT_SHIFT 5 +#define INT_STS_PWRHOLD_IT_MASK 0x10 +#define INT_STS_PWRHOLD_IT_SHIFT 4 +#define INT_STS_PWRON_LP_IT_MASK 0x08 +#define INT_STS_PWRON_LP_IT_SHIFT 3 +#define INT_STS_PWRON_IT_MASK 0x04 +#define INT_STS_PWRON_IT_SHIFT 2 +#define INT_STS_VMBHI_IT_MASK 0x02 +#define INT_STS_VMBHI_IT_SHIFT 1 +#define INT_STS_VMBDCH_IT_MASK 0x01 +#define INT_STS_VMBDCH_IT_SHIFT 0 + + +/*Register INT_MSK (0x80) register.RegisterDescription */ +#define INT_MSK_RTC_PERIOD_IT_MSK_MASK 0x80 +#define INT_MSK_RTC_PERIOD_IT_MSK_SHIFT 7 +#define INT_MSK_RTC_ALARM_IT_MSK_MASK 0x40 +#define INT_MSK_RTC_ALARM_IT_MSK_SHIFT 6 +#define INT_MSK_HOTDIE_IT_MSK_MASK 0x20 +#define INT_MSK_HOTDIE_IT_MSK_SHIFT 5 +#define INT_MSK_PWRHOLD_IT_MSK_MASK 0x10 +#define INT_MSK_PWRHOLD_IT_MSK_SHIFT 4 +#define INT_MSK_PWRON_LP_IT_MSK_MASK 0x08 +#define INT_MSK_PWRON_LP_IT_MSK_SHIFT 3 +#define INT_MSK_PWRON_IT_MSK_MASK 0x04 +#define INT_MSK_PWRON_IT_MSK_SHIFT 2 +#define INT_MSK_VMBHI_IT_MSK_MASK 0x02 +#define INT_MSK_VMBHI_IT_MSK_SHIFT 1 +#define INT_MSK_VMBDCH_IT_MSK_MASK 0x01 +#define INT_MSK_VMBDCH_IT_MSK_SHIFT 0 + + +/*Register INT_STS2 (0x80) register.RegisterDescription */ +#define INT_STS2_GPIO3_F_IT_MASK 0x80 +#define INT_STS2_GPIO3_F_IT_SHIFT 7 +#define INT_STS2_GPIO3_R_IT_MASK 0x40 +#define INT_STS2_GPIO3_R_IT_SHIFT 6 +#define INT_STS2_GPIO2_F_IT_MASK 0x20 +#define INT_STS2_GPIO2_F_IT_SHIFT 5 +#define INT_STS2_GPIO2_R_IT_MASK 0x10 +#define INT_STS2_GPIO2_R_IT_SHIFT 4 +#define INT_STS2_GPIO1_F_IT_MASK 0x08 +#define INT_STS2_GPIO1_F_IT_SHIFT 3 +#define INT_STS2_GPIO1_R_IT_MASK 0x04 +#define INT_STS2_GPIO1_R_IT_SHIFT 2 +#define INT_STS2_GPIO0_F_IT_MASK 0x02 +#define INT_STS2_GPIO0_F_IT_SHIFT 1 +#define INT_STS2_GPIO0_R_IT_MASK 0x01 +#define INT_STS2_GPIO0_R_IT_SHIFT 0 + + +/*Register INT_MSK2 (0x80) register.RegisterDescription */ +#define INT_MSK2_GPIO3_F_IT_MSK_MASK 0x80 +#define INT_MSK2_GPIO3_F_IT_MSK_SHIFT 7 +#define INT_MSK2_GPIO3_R_IT_MSK_MASK 0x40 +#define INT_MSK2_GPIO3_R_IT_MSK_SHIFT 6 +#define INT_MSK2_GPIO2_F_IT_MSK_MASK 0x20 +#define INT_MSK2_GPIO2_F_IT_MSK_SHIFT 5 +#define INT_MSK2_GPIO2_R_IT_MSK_MASK 0x10 +#define INT_MSK2_GPIO2_R_IT_MSK_SHIFT 4 +#define INT_MSK2_GPIO1_F_IT_MSK_MASK 0x08 +#define INT_MSK2_GPIO1_F_IT_MSK_SHIFT 3 +#define INT_MSK2_GPIO1_R_IT_MSK_MASK 0x04 +#define INT_MSK2_GPIO1_R_IT_MSK_SHIFT 2 +#define INT_MSK2_GPIO0_F_IT_MSK_MASK 0x02 +#define INT_MSK2_GPIO0_F_IT_MSK_SHIFT 1 +#define INT_MSK2_GPIO0_R_IT_MSK_MASK 0x01 +#define INT_MSK2_GPIO0_R_IT_MSK_SHIFT 0 + + +/*Register INT_STS3 (0x80) register.RegisterDescription */ +#define INT_STS3_GPIO5_F_IT_MASK 0x08 +#define INT_STS3_GPIO5_F_IT_SHIFT 3 +#define INT_STS3_GPIO5_R_IT_MASK 0x04 +#define INT_STS3_GPIO5_R_IT_SHIFT 2 +#define INT_STS3_GPIO4_F_IT_MASK 0x02 +#define INT_STS3_GPIO4_F_IT_SHIFT 1 +#define INT_STS3_GPIO4_R_IT_MASK 0x01 +#define INT_STS3_GPIO4_R_IT_SHIFT 0 + + +/*Register INT_MSK3 (0x80) register.RegisterDescription */ +#define INT_MSK3_GPIO5_F_IT_MSK_MASK 0x08 +#define INT_MSK3_GPIO5_F_IT_MSK_SHIFT 3 +#define INT_MSK3_GPIO5_R_IT_MSK_MASK 0x04 +#define INT_MSK3_GPIO5_R_IT_MSK_SHIFT 2 +#define INT_MSK3_GPIO4_F_IT_MSK_MASK 0x02 +#define INT_MSK3_GPIO4_F_IT_MSK_SHIFT 1 +#define INT_MSK3_GPIO4_R_IT_MSK_MASK 0x01 +#define INT_MSK3_GPIO4_R_IT_MSK_SHIFT 0 + + +/*Register GPIO0 (0x80) register.RegisterDescription */ +#define GPIO0_GPIO_DEB_MASK 0x10 +#define GPIO0_GPIO_DEB_SHIFT 4 +#define GPIO0_GPIO_PUEN_MASK 0x08 +#define GPIO0_GPIO_PUEN_SHIFT 3 +#define GPIO0_GPIO_CFG_MASK 0x04 +#define GPIO0_GPIO_CFG_SHIFT 2 +#define GPIO0_GPIO_STS_MASK 0x02 +#define GPIO0_GPIO_STS_SHIFT 1 +#define GPIO0_GPIO_SET_MASK 0x01 +#define GPIO0_GPIO_SET_SHIFT 0 + + +/*Register GPIO1 (0x80) register.RegisterDescription */ +#define GPIO1_GPIO_DEB_MASK 0x10 +#define GPIO1_GPIO_DEB_SHIFT 4 +#define GPIO1_GPIO_PUEN_MASK 0x08 +#define GPIO1_GPIO_PUEN_SHIFT 3 +#define GPIO1_GPIO_CFG_MASK 0x04 +#define GPIO1_GPIO_CFG_SHIFT 2 +#define GPIO1_GPIO_STS_MASK 0x02 +#define GPIO1_GPIO_STS_SHIFT 1 +#define GPIO1_GPIO_SET_MASK 0x01 +#define GPIO1_GPIO_SET_SHIFT 0 + + +/*Register GPIO2 (0x80) register.RegisterDescription */ +#define GPIO2_GPIO_DEB_MASK 0x10 +#define GPIO2_GPIO_DEB_SHIFT 4 +#define GPIO2_GPIO_PUEN_MASK 0x08 +#define GPIO2_GPIO_PUEN_SHIFT 3 +#define GPIO2_GPIO_CFG_MASK 0x04 +#define GPIO2_GPIO_CFG_SHIFT 2 +#define GPIO2_GPIO_STS_MASK 0x02 +#define GPIO2_GPIO_STS_SHIFT 1 +#define GPIO2_GPIO_SET_MASK 0x01 +#define GPIO2_GPIO_SET_SHIFT 0 + + +/*Register GPIO3 (0x80) register.RegisterDescription */ +#define GPIO3_GPIO_DEB_MASK 0x10 +#define GPIO3_GPIO_DEB_SHIFT 4 +#define GPIO3_GPIO_PUEN_MASK 0x08 +#define GPIO3_GPIO_PUEN_SHIFT 3 +#define GPIO3_GPIO_CFG_MASK 0x04 +#define GPIO3_GPIO_CFG_SHIFT 2 +#define GPIO3_GPIO_STS_MASK 0x02 +#define GPIO3_GPIO_STS_SHIFT 1 +#define GPIO3_GPIO_SET_MASK 0x01 +#define GPIO3_GPIO_SET_SHIFT 0 + + +/*Register GPIO4 (0x80) register.RegisterDescription */ +#define GPIO4_GPIO_DEB_MASK 0x10 +#define GPIO4_GPIO_DEB_SHIFT 4 +#define GPIO4_GPIO_PUEN_MASK 0x08 +#define GPIO4_GPIO_PUEN_SHIFT 3 +#define GPIO4_GPIO_CFG_MASK 0x04 +#define GPIO4_GPIO_CFG_SHIFT 2 +#define GPIO4_GPIO_STS_MASK 0x02 +#define GPIO4_GPIO_STS_SHIFT 1 +#define GPIO4_GPIO_SET_MASK 0x01 +#define GPIO4_GPIO_SET_SHIFT 0 + + +/*Register GPIO5 (0x80) register.RegisterDescription */ +#define GPIO5_GPIO_DEB_MASK 0x10 +#define GPIO5_GPIO_DEB_SHIFT 4 +#define GPIO5_GPIO_PUEN_MASK 0x08 +#define GPIO5_GPIO_PUEN_SHIFT 3 +#define GPIO5_GPIO_CFG_MASK 0x04 +#define GPIO5_GPIO_CFG_SHIFT 2 +#define GPIO5_GPIO_STS_MASK 0x02 +#define GPIO5_GPIO_STS_SHIFT 1 +#define GPIO5_GPIO_SET_MASK 0x01 +#define GPIO5_GPIO_SET_SHIFT 0 + + +/*Register JTAGVERNUM (0x80) register.RegisterDescription */ +#define JTAGVERNUM_VERNUM_MASK 0x0F +#define JTAGVERNUM_VERNUM_SHIFT 0 + + +/* IRQ Definitions */ +#define TPS65910_IRQ_VBAT_VMBDCH 0 +#define TPS65910_IRQ_VBAT_VMHI 1 +#define TPS65910_IRQ_PWRON 2 +#define TPS65910_IRQ_PWRON_LP 3 +#define TPS65910_IRQ_PWRHOLD 4 +#define TPS65910_IRQ_HOTDIE 5 +#define TPS65910_IRQ_RTC_ALARM 6 +#define TPS65910_IRQ_RTC_PERIOD 7 +#define TPS65910_IRQ_GPIO_R 8 +#define TPS65910_IRQ_GPIO_F 9 +#define TPS65910_NUM_IRQ 10 + +/* GPIO Register Definitions */ +#define TPS65910_GPIO_DEB BIT(2) +#define TPS65910_GPIO_PUEN BIT(3) +#define TPS65910_GPIO_CFG BIT(2) +#define TPS65910_GPIO_STS BIT(1) +#define TPS65910_GPIO_SET BIT(0) + +/** + * struct tps65910_board + * Board platform data may be used to initialize regulators. + */ + +struct tps65910_board { + struct regulator_init_data *tps65910_pmic_init_data; +}; + +/** + * struct tps65910 - tps65910 sub-driver chip access routines + */ + +struct tps65910 { + struct device *dev; + struct i2c_client *i2c_client; + struct mutex io_mutex; + int (*read)(struct tps65910 *tps65910, u8 reg, int size, void *dest); + int (*write)(struct tps65910 *tps65910, u8 reg, int size, void *src); + + /* Client devices */ + struct tps65910_pmic *pmic; + struct tps65910_rtc *rtc; + struct tps65910_power *power; + + /* GPIO Handling */ + struct gpio_chip gpio; + + /* IRQ Handling */ + struct mutex irq_lock; + int chip_irq; + int irq_base; + u16 irq_mask; +}; + +struct tps65910_platform_data { + int irq_base; +}; + +int tps65910_set_bits(struct tps65910 *tps65910, u8 reg, u8 mask); +int tps65910_clear_bits(struct tps65910 *tps65910, u8 reg, u8 mask); + +#endif /* __LINUX_MFD_TPS65910_H */ -- cgit From 2537df722d338ab687d7ed91dc589265c0d14aec Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Mon, 2 May 2011 16:19:52 -0500 Subject: TPS65910: GPIO: Add GPIO driver TPS65910 has one configurable GPIO that can be used for several purposes. Subsequent versions of the TPS chip support more than one GPIO. Signed-off-by: Graeme Gregory Signed-off-by: Jorge Eduardo Candelaria Acked-by: Grant Likely Signed-off-by: Liam Girdwood --- drivers/mfd/Makefile | 2 +- drivers/mfd/tps65910-gpio.c | 91 ++++++++++++++++++++++++++++++++++++++++++++ drivers/mfd/tps65910.c | 7 ++++ include/linux/mfd/tps65910.h | 2 + 4 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 drivers/mfd/tps65910-gpio.c (limited to 'include/linux') diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index f43ef5bba3ba..c64fa8d48f45 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -93,4 +93,4 @@ obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.o -obj-$(CONFIG_MFD_TPS65910) += tps65910.o +obj-$(CONFIG_MFD_TPS65910) += tps65910.o tps65910-gpio.o diff --git a/drivers/mfd/tps65910-gpio.c b/drivers/mfd/tps65910-gpio.c new file mode 100644 index 000000000000..f3ae37652446 --- /dev/null +++ b/drivers/mfd/tps65910-gpio.c @@ -0,0 +1,91 @@ +/* + * tps65910-gpio.c -- TI TPS6591x + * + * Copyright 2010 Texas Instruments Inc. + * + * Author: Graeme Gregory + * Author: Jorge Eduardo Candelaria jedu@slimlogic.co.uk> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include + +static int tps65910_gpio_get(struct gpio_chip *gc, unsigned offset) +{ + struct tps65910 *tps65910 = container_of(gc, struct tps65910, gpio); + uint8_t val; + + tps65910->read(tps65910, TPS65910_GPIO0, 1, &val); + + if (val & GPIO0_GPIO_STS_MASK) + return 1; + + return 0; +} + +static void tps65910_gpio_set(struct gpio_chip *gc, unsigned offset, + int value) +{ + struct tps65910 *tps65910 = container_of(gc, struct tps65910, gpio); + + if (value) + tps65910_set_bits(tps65910, TPS65910_GPIO0, + GPIO0_GPIO_SET_MASK); + else + tps65910_clear_bits(tps65910, TPS65910_GPIO0, + GPIO0_GPIO_SET_MASK); +} + +static int tps65910_gpio_output(struct gpio_chip *gc, unsigned offset, + int value) +{ + struct tps65910 *tps65910 = container_of(gc, struct tps65910, gpio); + + /* Set the initial value */ + tps65910_gpio_set(gc, 0, value); + + return tps65910_set_bits(tps65910, TPS65910_GPIO0, GPIO0_GPIO_CFG_MASK); +} + +static int tps65910_gpio_input(struct gpio_chip *gc, unsigned offset) +{ + struct tps65910 *tps65910 = container_of(gc, struct tps65910, gpio); + + return tps65910_clear_bits(tps65910, TPS65910_GPIO0, + GPIO0_GPIO_CFG_MASK); +} + +void tps65910_gpio_init(struct tps65910 *tps65910, int gpio_base) +{ + int ret; + + if (!gpio_base) + return; + + tps65910->gpio.owner = THIS_MODULE; + tps65910->gpio.label = tps65910->i2c_client->name; + tps65910->gpio.dev = tps65910->dev; + tps65910->gpio.base = gpio_base; + tps65910->gpio.ngpio = 1; + tps65910->gpio.can_sleep = 1; + + tps65910->gpio.direction_input = tps65910_gpio_input; + tps65910->gpio.direction_output = tps65910_gpio_output; + tps65910->gpio.set = tps65910_gpio_set; + tps65910->gpio.get = tps65910_gpio_get; + + ret = gpiochip_add(&tps65910->gpio); + + if (ret) + dev_warn(tps65910->dev, "GPIO registration failed: %d\n", ret); +} diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c index dbcdfb55bb8d..5a6a7be1f8cf 100644 --- a/drivers/mfd/tps65910.c +++ b/drivers/mfd/tps65910.c @@ -135,8 +135,13 @@ static int tps65910_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct tps65910 *tps65910; + struct tps65910_board *pmic_plat_data; int ret = 0; + pmic_plat_data = dev_get_platdata(&i2c->dev); + if (!pmic_plat_data) + return -EINVAL; + tps65910 = kzalloc(sizeof(struct tps65910), GFP_KERNEL); if (tps65910 == NULL) return -ENOMEM; @@ -154,6 +159,8 @@ static int tps65910_i2c_probe(struct i2c_client *i2c, if (ret < 0) goto err; + tps65910_gpio_init(tps65910, pmic_plat_data->gpio_base); + return ret; err: diff --git a/include/linux/mfd/tps65910.h b/include/linux/mfd/tps65910.h index fa1b029e5499..0e01d504ab58 100644 --- a/include/linux/mfd/tps65910.h +++ b/include/linux/mfd/tps65910.h @@ -714,6 +714,7 @@ */ struct tps65910_board { + int gpio_base; struct regulator_init_data *tps65910_pmic_init_data; }; @@ -749,5 +750,6 @@ struct tps65910_platform_data { int tps65910_set_bits(struct tps65910 *tps65910, u8 reg, u8 mask); int tps65910_clear_bits(struct tps65910 *tps65910, u8 reg, u8 mask); +void tps65910_gpio_init(struct tps65910 *tps65910, int gpio_base); #endif /* __LINUX_MFD_TPS65910_H */ -- cgit From e3471bdc2784ee20a0d636c5904200c2d1148ef9 Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Mon, 2 May 2011 16:20:04 -0500 Subject: TPS65910: IRQ: Add interrupt controller This module controls the interrupt handling for the tps chip. The interrupt sources are the following: - GPIO falling/rising edge detection - Battery voltage below/above threshold - PWRON signal - PWRHOLD signal - Temperature detection - RTC alarm and periodic event Signed-off-by: Graeme Gregory Signed-off-by: Jorge Eduardo Candelaria Reviewed-by: Mark Brown Acked-by: Samuel Ortiz Signed-off-by: Liam Girdwood --- drivers/mfd/Makefile | 2 +- drivers/mfd/tps65910-irq.c | 187 +++++++++++++++++++++++++++++++++++++++++++ drivers/mfd/tps65910.c | 12 +++ include/linux/mfd/tps65910.h | 5 ++ 4 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 drivers/mfd/tps65910-irq.c (limited to 'include/linux') diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index c64fa8d48f45..bdb8eab5668b 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -93,4 +93,4 @@ obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.o -obj-$(CONFIG_MFD_TPS65910) += tps65910.o tps65910-gpio.o +obj-$(CONFIG_MFD_TPS65910) += tps65910.o tps65910-gpio.o tps65910-irq.o diff --git a/drivers/mfd/tps65910-irq.c b/drivers/mfd/tps65910-irq.c new file mode 100644 index 000000000000..b8435e045f81 --- /dev/null +++ b/drivers/mfd/tps65910-irq.c @@ -0,0 +1,187 @@ +/* + * tps65910-irq.c -- TI TPS6591x + * + * Copyright 2010 Texas Instruments Inc. + * + * Author: Graeme Gregory + * Author: Jorge Eduardo Candelaria + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static inline int irq_to_tps65910_irq(struct tps65910 *tps65910, + int irq) +{ + return (irq - tps65910->irq_base); +} + +/* + * This is a threaded IRQ handler so can access I2C/SPI. Since all + * interrupts are clear on read the IRQ line will be reasserted and + * the physical IRQ will be handled again if another interrupt is + * asserted while we run - in the normal course of events this is a + * rare occurrence so we save I2C/SPI reads. We're also assuming that + * it's rare to get lots of interrupts firing simultaneously so try to + * minimise I/O. + */ +static irqreturn_t tps65910_irq(int irq, void *irq_data) +{ + struct tps65910 *tps65910 = irq_data; + u16 irq_sts; + u16 irq_mask; + u8 reg; + int i; + + tps65910->read(tps65910, TPS65910_INT_STS, 1, ®); + irq_sts = reg; + tps65910->read(tps65910, TPS65910_INT_STS2, 1, ®); + irq_sts |= reg << 8; + + tps65910->read(tps65910, TPS65910_INT_MSK, 1, ®); + irq_mask = reg; + tps65910->read(tps65910, TPS65910_INT_MSK2, 1, ®); + irq_mask |= reg << 8; + + irq_sts &= ~irq_mask; + + if (!irq_sts) + return IRQ_NONE; + + for (i = 0; i < TPS65910_NUM_IRQ; i++) { + + if (!(irq_sts & (1 << i))) + continue; + + handle_nested_irq(tps65910->irq_base + i); + } + + /* Write the STS register back to clear IRQs we handled */ + reg = irq_sts & 0xFF; + tps65910->write(tps65910, TPS65910_INT_STS, 1, ®); + reg = irq_sts >> 8; + tps65910->write(tps65910, TPS65910_INT_STS2, 1, ®); + + return IRQ_HANDLED; +} + +static void tps65910_irq_lock(struct irq_data *data) +{ + struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data); + + mutex_lock(&tps65910->irq_lock); +} + +static void tps65910_irq_sync_unlock(struct irq_data *data) +{ + struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data); + u16 reg_mask; + u8 reg; + + tps65910->read(tps65910, TPS65910_INT_MSK, 1, ®); + reg_mask = reg; + tps65910->read(tps65910, TPS65910_INT_MSK2, 1, ®); + reg_mask |= reg << 8; + + if (tps65910->irq_mask != reg_mask) { + reg = tps65910->irq_mask & 0xFF; + tps65910->write(tps65910, TPS65910_INT_MSK, 1, ®); + reg = tps65910->irq_mask >> 8; + tps65910->write(tps65910, TPS65910_INT_MSK2, 1, ®); + } + mutex_unlock(&tps65910->irq_lock); +} + +static void tps65910_irq_enable(struct irq_data *data) +{ + struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data); + + tps65910->irq_mask &= ~( 1 << irq_to_tps65910_irq(tps65910, data->irq)); +} + +static void tps65910_irq_disable(struct irq_data *data) +{ + struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data); + + tps65910->irq_mask |= ( 1 << irq_to_tps65910_irq(tps65910, data->irq)); +} + +static struct irq_chip tps65910_irq_chip = { + .name = "tps65910", + .irq_bus_lock = tps65910_irq_lock, + .irq_bus_sync_unlock = tps65910_irq_sync_unlock, + .irq_disable = tps65910_irq_disable, + .irq_enable = tps65910_irq_enable, +}; + +int tps65910_irq_init(struct tps65910 *tps65910, int irq, + struct tps65910_platform_data *pdata) +{ + int ret, cur_irq; + int flags = IRQF_ONESHOT; + u8 reg; + + if (!irq) { + dev_warn(tps65910->dev, "No interrupt support, no core IRQ\n"); + return -EINVAL; + } + + if (!pdata || !pdata->irq_base) { + dev_warn(tps65910->dev, "No interrupt support, no IRQ base\n"); + return -EINVAL; + } + + /* Mask top level interrupts */ + reg = 0xFF; + tps65910->write(tps65910, TPS65910_INT_MSK, 1, ®); + reg = 0x03; + tps65910->write(tps65910, TPS65910_INT_MSK2, 1, ®); + + mutex_init(&tps65910->irq_lock); + tps65910->chip_irq = irq; + tps65910->irq_base = pdata->irq_base; + + /* Register with genirq */ + for (cur_irq = tps65910->irq_base; + cur_irq < TPS65910_NUM_IRQ + tps65910->irq_base; + cur_irq++) { + irq_set_chip_data(cur_irq, tps65910); + irq_set_chip_and_handler(cur_irq, &tps65910_irq_chip, + handle_edge_irq); + irq_set_nested_thread(cur_irq, 1); + + /* ARM needs us to explicitly flag the IRQ as valid + * and will set them noprobe when we do so. */ +#ifdef CONFIG_ARM + set_irq_flags(cur_irq, IRQF_VALID); +#else + irq_set_noprobe(cur_irq); +#endif + } + + ret = request_threaded_irq(irq, NULL, tps65910_irq, flags, + "tps65910", tps65910); + if (ret != 0) + dev_err(tps65910->dev, "Failed to request IRQ: %d\n", ret); + + return ret; +} + +int tps65910_irq_exit(struct tps65910 *tps65910) +{ + free_irq(tps65910->chip_irq, tps65910); + return 0; +} diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c index 5a6a7be1f8cf..bf649cf6a0ae 100644 --- a/drivers/mfd/tps65910.c +++ b/drivers/mfd/tps65910.c @@ -136,12 +136,20 @@ static int tps65910_i2c_probe(struct i2c_client *i2c, { struct tps65910 *tps65910; struct tps65910_board *pmic_plat_data; + struct tps65910_platform_data *init_data; int ret = 0; pmic_plat_data = dev_get_platdata(&i2c->dev); if (!pmic_plat_data) return -EINVAL; + init_data = kzalloc(sizeof(struct tps65910_platform_data), GFP_KERNEL); + if (init_data == NULL) + return -ENOMEM; + + init_data->irq = pmic_plat_data->irq; + init_data->irq_base = pmic_plat_data->irq; + tps65910 = kzalloc(sizeof(struct tps65910), GFP_KERNEL); if (tps65910 == NULL) return -ENOMEM; @@ -161,6 +169,10 @@ static int tps65910_i2c_probe(struct i2c_client *i2c, tps65910_gpio_init(tps65910, pmic_plat_data->gpio_base); + ret = tps65910_irq_init(tps65910, init_data->irq, init_data); + if (ret < 0) + goto err; + return ret; err: diff --git a/include/linux/mfd/tps65910.h b/include/linux/mfd/tps65910.h index 0e01d504ab58..8afe91c85587 100644 --- a/include/linux/mfd/tps65910.h +++ b/include/linux/mfd/tps65910.h @@ -715,6 +715,8 @@ struct tps65910_board { int gpio_base; + int irq; + int irq_base; struct regulator_init_data *tps65910_pmic_init_data; }; @@ -745,11 +747,14 @@ struct tps65910 { }; struct tps65910_platform_data { + int irq; int irq_base; }; int tps65910_set_bits(struct tps65910 *tps65910, u8 reg, u8 mask); int tps65910_clear_bits(struct tps65910 *tps65910, u8 reg, u8 mask); void tps65910_gpio_init(struct tps65910 *tps65910, int gpio_base); +int tps65910_irq_init(struct tps65910 *tps65910, int irq, + struct tps65910_platform_data *pdata); #endif /* __LINUX_MFD_TPS65910_H */ -- cgit From 518fb721de3685c8326e72746151b534a241feda Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Mon, 2 May 2011 16:20:08 -0500 Subject: TPS65910: Add tps65910 regulator driver The regulator module consists of 3 DCDCs and 8 LDOs. The output voltages are configurable and are meant to supply power to the main processor and other components Signed-off-by: Graeme Gregory Signed-off-by: Jorge Eduardo Candelaria Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- drivers/regulator/Kconfig | 6 + drivers/regulator/Makefile | 1 + drivers/regulator/tps65910-regulator.c | 705 +++++++++++++++++++++++++++++++++ include/linux/mfd/tps65910.h | 14 + 4 files changed, 726 insertions(+) create mode 100644 drivers/regulator/tps65910-regulator.c (limited to 'include/linux') diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index f0b13a0d1851..d7ed20f293d7 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -297,5 +297,11 @@ config REGULATOR_TPS6524X serial interface currently supported on the sequencer serial port controller. +config REGULATOR_TPS65910 + tristate "TI TPS65910 Power Regulator" + depends on MFD_TPS65910 + help + This driver supports TPS65910 voltage regulator chips. + endif diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 165ff5371e9e..3932d2ec38f3 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -42,5 +42,6 @@ obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o +obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c new file mode 100644 index 000000000000..d461fa7906b8 --- /dev/null +++ b/drivers/regulator/tps65910-regulator.c @@ -0,0 +1,705 @@ +/* + * tps65910.c -- TI tps65910 + * + * Copyright 2010 Texas Instruments Inc. + * + * Author: Graeme Gregory + * Author: Jorge Eduardo Candelaria + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TPS65910_REG_VRTC 0 +#define TPS65910_REG_VIO 1 +#define TPS65910_REG_VDD1 2 +#define TPS65910_REG_VDD2 3 +#define TPS65910_REG_VDD3 4 +#define TPS65910_REG_VDIG1 5 +#define TPS65910_REG_VDIG2 6 +#define TPS65910_REG_VPLL 7 +#define TPS65910_REG_VDAC 8 +#define TPS65910_REG_VAUX1 9 +#define TPS65910_REG_VAUX2 10 +#define TPS65910_REG_VAUX33 11 +#define TPS65910_REG_VMMC 12 + +#define TPS65910_NUM_REGULATOR 13 + +#define TPS65910_SUPPLY_STATE_ENABLED 0x1 + +/* supported VIO voltages in milivolts */ +static const u16 VIO_VSEL_table[] = { + 1500, 1800, 2500, 3300, +}; + +/* supported VIO voltages in milivolts */ +static const u16 VDD3_VSEL_table[] = { + 5000, +}; + +/* supported VDIG1 voltages in milivolts */ +static const u16 VDIG1_VSEL_table[] = { + 1200, 1500, 1800, 2700, +}; + +/* supported VDIG2 voltages in milivolts */ +static const u16 VDIG2_VSEL_table[] = { + 1000, 1100, 1200, 1800, +}; + +/* supported VPLL voltages in milivolts */ +static const u16 VPLL_VSEL_table[] = { + 1000, 1100, 1800, 2500, +}; + +/* supported VDAC voltages in milivolts */ +static const u16 VDAC_VSEL_table[] = { + 1800, 2600, 2800, 2850, +}; + +/* supported VAUX1 voltages in milivolts */ +static const u16 VAUX1_VSEL_table[] = { + 1800, 2500, 2800, 2850, +}; + +/* supported VAUX2 voltages in milivolts */ +static const u16 VAUX2_VSEL_table[] = { + 1800, 2800, 2900, 3300, +}; + +/* supported VAUX33 voltages in milivolts */ +static const u16 VAUX33_VSEL_table[] = { + 1800, 2000, 2800, 3300, +}; + +/* supported VMMC voltages in milivolts */ +static const u16 VMMC_VSEL_table[] = { + 1800, 2800, 3000, 3300, +}; + +struct tps_info { + const char *name; + unsigned min_uV; + unsigned max_uV; + u8 table_len; + const u16 *table; +}; + +static struct tps_info tps65910_regs[] = { + { + .name = "VRTC", + }, + { + .name = "VIO", + .min_uV = 1500000, + .max_uV = 3300000, + .table_len = ARRAY_SIZE(VIO_VSEL_table), + .table = VIO_VSEL_table, + }, + { + .name = "VDD1", + .min_uV = 600000, + .max_uV = 4500000, + }, + { + .name = "VDD2", + .min_uV = 600000, + .max_uV = 4500000, + }, + { + .name = "VDD3", + .min_uV = 5000000, + .max_uV = 5000000, + .table_len = ARRAY_SIZE(VDD3_VSEL_table), + .table = VDD3_VSEL_table, + }, + { + .name = "VDIG1", + .min_uV = 1200000, + .max_uV = 2700000, + .table_len = ARRAY_SIZE(VDIG1_VSEL_table), + .table = VDIG1_VSEL_table, + }, + { + .name = "VDIG2", + .min_uV = 1000000, + .max_uV = 1800000, + .table_len = ARRAY_SIZE(VDIG2_VSEL_table), + .table = VDIG2_VSEL_table, + }, + { + .name = "VPLL", + .min_uV = 1000000, + .max_uV = 2500000, + .table_len = ARRAY_SIZE(VPLL_VSEL_table), + .table = VPLL_VSEL_table, + }, + { + .name = "VDAC", + .min_uV = 1800000, + .max_uV = 2850000, + .table_len = ARRAY_SIZE(VDAC_VSEL_table), + .table = VDAC_VSEL_table, + }, + { + .name = "VAUX1", + .min_uV = 1800000, + .max_uV = 2850000, + .table_len = ARRAY_SIZE(VAUX1_VSEL_table), + .table = VAUX1_VSEL_table, + }, + { + .name = "VAUX2", + .min_uV = 1800000, + .max_uV = 3300000, + .table_len = ARRAY_SIZE(VAUX2_VSEL_table), + .table = VAUX2_VSEL_table, + }, + { + .name = "VAUX33", + .min_uV = 1800000, + .max_uV = 3300000, + .table_len = ARRAY_SIZE(VAUX33_VSEL_table), + .table = VAUX33_VSEL_table, + }, + { + .name = "VMMC", + .min_uV = 1800000, + .max_uV = 3300000, + .table_len = ARRAY_SIZE(VMMC_VSEL_table), + .table = VMMC_VSEL_table, + }, +}; + +struct tps65910_reg { + struct regulator_desc desc[TPS65910_NUM_REGULATOR]; + struct tps65910 *mfd; + struct regulator_dev *rdev[TPS65910_NUM_REGULATOR]; + struct tps_info *info[TPS65910_NUM_REGULATOR]; + struct mutex mutex; + int mode; +}; + +static inline int tps65910_read(struct tps65910_reg *pmic, u8 reg) +{ + u8 val; + int err; + + err = pmic->mfd->read(pmic->mfd, reg, 1, &val); + if (err) + return err; + + return val; +} + +static inline int tps65910_write(struct tps65910_reg *pmic, u8 reg, u8 val) +{ + return pmic->mfd->write(pmic->mfd, reg, 1, &val); +} + +static int tps65910_modify_bits(struct tps65910_reg *pmic, u8 reg, + u8 set_mask, u8 clear_mask) +{ + int err, data; + + mutex_lock(&pmic->mutex); + + data = tps65910_read(pmic, reg); + if (data < 0) { + dev_err(pmic->mfd->dev, "Read from reg 0x%x failed\n", reg); + err = data; + goto out; + } + + data &= ~clear_mask; + data |= set_mask; + err = tps65910_write(pmic, reg, data); + if (err) + dev_err(pmic->mfd->dev, "Write for reg 0x%x failed\n", reg); + +out: + mutex_unlock(&pmic->mutex); + return err; +} + +static int tps65910_reg_read(struct tps65910_reg *pmic, u8 reg) +{ + int data; + + mutex_lock(&pmic->mutex); + + data = tps65910_read(pmic, reg); + if (data < 0) + dev_err(pmic->mfd->dev, "Read from reg 0x%x failed\n", reg); + + mutex_unlock(&pmic->mutex); + return data; +} + +static int tps65910_reg_write(struct tps65910_reg *pmic, u8 reg, u8 val) +{ + int err; + + mutex_lock(&pmic->mutex); + + err = tps65910_write(pmic, reg, val); + if (err < 0) + dev_err(pmic->mfd->dev, "Write for reg 0x%x failed\n", reg); + + mutex_unlock(&pmic->mutex); + return err; +} + +static int tps65910_get_ctrl_register(int id) +{ + switch (id) { + case TPS65910_REG_VRTC: + return TPS65910_VRTC; + case TPS65910_REG_VIO: + return TPS65910_VIO; + case TPS65910_REG_VDD1: + return TPS65910_VDD1; + case TPS65910_REG_VDD2: + return TPS65910_VDD2; + case TPS65910_REG_VDD3: + return TPS65910_VDD3; + case TPS65910_REG_VDIG1: + return TPS65910_VDIG1; + case TPS65910_REG_VDIG2: + return TPS65910_VDIG2; + case TPS65910_REG_VPLL: + return TPS65910_VPLL; + case TPS65910_REG_VDAC: + return TPS65910_VDAC; + case TPS65910_REG_VAUX1: + return TPS65910_VAUX1; + case TPS65910_REG_VAUX2: + return TPS65910_VAUX2; + case TPS65910_REG_VAUX33: + return TPS65910_VAUX33; + case TPS65910_REG_VMMC: + return TPS65910_VMMC; + default: + return -EINVAL; + } +} + +static int tps65910_is_enabled(struct regulator_dev *dev) +{ + struct tps65910_reg *pmic = rdev_get_drvdata(dev); + int reg, value, id = rdev_get_id(dev); + + reg = tps65910_get_ctrl_register(id); + if (reg < 0) + return reg; + + value = tps65910_reg_read(pmic, reg); + if (value < 0) + return value; + + return value & TPS65910_SUPPLY_STATE_ENABLED; +} + +static int tps65910_enable(struct regulator_dev *dev) +{ + struct tps65910_reg *pmic = rdev_get_drvdata(dev); + struct tps65910 *mfd = pmic->mfd; + int reg, id = rdev_get_id(dev); + + reg = tps65910_get_ctrl_register(id); + if (reg < 0) + return reg; + + return tps65910_set_bits(mfd, reg, TPS65910_SUPPLY_STATE_ENABLED); +} + +static int tps65910_disable(struct regulator_dev *dev) +{ + struct tps65910_reg *pmic = rdev_get_drvdata(dev); + struct tps65910 *mfd = pmic->mfd; + int reg, id = rdev_get_id(dev); + + reg = tps65910_get_ctrl_register(id); + if (reg < 0) + return reg; + + return tps65910_clear_bits(mfd, reg, TPS65910_SUPPLY_STATE_ENABLED); +} + + +static int tps65910_set_mode(struct regulator_dev *dev, unsigned int mode) +{ + struct tps65910_reg *pmic = rdev_get_drvdata(dev); + struct tps65910 *mfd = pmic->mfd; + int reg, value, id = rdev_get_id(dev); + reg = tps65910_get_ctrl_register(id); + if (reg < 0) + return reg; + + switch (mode) { + case REGULATOR_MODE_NORMAL: + return tps65910_modify_bits(pmic, reg, LDO_ST_ON_BIT, + LDO_ST_MODE_BIT); + case REGULATOR_MODE_IDLE: + value = LDO_ST_ON_BIT | LDO_ST_MODE_BIT; + return tps65910_set_bits(mfd, reg, value); + case REGULATOR_MODE_STANDBY: + return tps65910_clear_bits(mfd, reg, LDO_ST_ON_BIT); + } + + return -EINVAL; +} + +static unsigned int tps65910_get_mode(struct regulator_dev *dev) +{ + struct tps65910_reg *pmic = rdev_get_drvdata(dev); + int reg, value, id = rdev_get_id(dev); + + reg = tps65910_get_ctrl_register(id); + if (reg < 0) + return reg; + + value = tps65910_reg_read(pmic, reg); + if (value < 0) + return value; + + if (value & LDO_ST_ON_BIT) + return REGULATOR_MODE_STANDBY; + else if (value & LDO_ST_MODE_BIT) + return REGULATOR_MODE_IDLE; + else + return REGULATOR_MODE_NORMAL; +} + +static int tps65910_get_voltage_dcdc(struct regulator_dev *dev) +{ + struct tps65910_reg *pmic = rdev_get_drvdata(dev); + int id = rdev_get_id(dev), voltage = 0; + int opvsel = 0, srvsel = 0, mult = 0, sr = 0; + + switch (id) { + case TPS65910_REG_VDD1: + opvsel = tps65910_reg_read(pmic, TPS65910_VDD1_OP); + mult = tps65910_reg_read(pmic, TPS65910_VDD1); + mult = (mult & VDD1_VGAIN_SEL_MASK) >> VDD1_VGAIN_SEL_SHIFT; + srvsel = tps65910_reg_read(pmic, TPS65910_VDD1_SR); + sr = opvsel & VDD1_OP_CMD_MASK; + opvsel &= VDD1_OP_SEL_MASK; + srvsel &= VDD1_SR_SEL_MASK; + break; + case TPS65910_REG_VDD2: + opvsel = tps65910_reg_read(pmic, TPS65910_VDD2_OP); + mult = tps65910_reg_read(pmic, TPS65910_VDD2); + mult = (mult & VDD2_VGAIN_SEL_MASK) >> VDD2_VGAIN_SEL_SHIFT; + srvsel = tps65910_reg_read(pmic, TPS65910_VDD2_SR); + sr = opvsel & VDD2_OP_CMD_MASK; + opvsel &= VDD2_OP_SEL_MASK; + srvsel &= VDD2_SR_SEL_MASK; + break; + } + + /* multiplier 0 == 1 but 2,3 normal */ + if (!mult) + mult=1; + + if (sr) { + /* Valid range is 3-75 so normalise */ + if (srvsel < 3) srvsel = 3; + if (srvsel > 75) srvsel = 75; + srvsel -= 3; + + voltage = (srvsel * VDD1_2_OFFSET + VDD1_2_MIN_VOLT) * 100; + } else { + + /* Valid range is 3-75 so normalise */ + if (opvsel < 3) opvsel = 3; + if (opvsel > 75) opvsel = 75; + opvsel -= 3; + + voltage = (opvsel * VDD1_2_OFFSET + VDD1_2_MIN_VOLT) * 100; + } + + voltage *= mult; + + return voltage; +} + +static int tps65910_get_voltage(struct regulator_dev *dev) +{ + struct tps65910_reg *pmic = rdev_get_drvdata(dev); + int reg, value, id = rdev_get_id(dev), voltage = 0; + + reg = tps65910_get_ctrl_register(id); + if (reg < 0) + return reg; + + value = tps65910_reg_read(pmic, reg); + if (value < 0) + return value; + + switch (id) { + case TPS65910_REG_VIO: + case TPS65910_REG_VDIG1: + case TPS65910_REG_VDIG2: + case TPS65910_REG_VPLL: + case TPS65910_REG_VDAC: + case TPS65910_REG_VAUX1: + case TPS65910_REG_VAUX2: + case TPS65910_REG_VAUX33: + case TPS65910_REG_VMMC: + value &= LDO_SEL_MASK; + value >>= LDO_SEL_SHIFT; + break; + default: + return -EINVAL; + } + + voltage = pmic->info[id]->table[value] * 1000; + + return voltage; +} + +static int tps65910_get_voltage_vdd3(struct regulator_dev *dev) +{ + return 5 * 1000 * 1000; +} + +static int tps65910_set_voltage_dcdc(struct regulator_dev *dev, + unsigned selector) +{ + struct tps65910_reg *pmic = rdev_get_drvdata(dev); + int id = rdev_get_id(dev), vsel; + int dcdc_mult; + + /* Split vsel into appropriate registers */ + dcdc_mult = (selector / VDD1_2_NUM_VOLTS) + 1; + if (dcdc_mult == 1) dcdc_mult--; + + vsel = (selector % VDD1_2_NUM_VOLTS) + 3; + + if (id == TPS65910_REG_VDD1) { + tps65910_modify_bits(pmic, TPS65910_VDD1, + (dcdc_mult << VDD1_VGAIN_SEL_SHIFT), + VDD1_VGAIN_SEL_MASK); + tps65910_reg_write(pmic, TPS65910_VDD1_OP, vsel); + } else { + tps65910_modify_bits(pmic, TPS65910_VDD2, + (dcdc_mult << VDD2_VGAIN_SEL_SHIFT), + VDD1_VGAIN_SEL_MASK); + tps65910_reg_write(pmic, TPS65910_VDD2_OP, vsel); + } + + return 0; +} + +static int tps65910_set_voltage(struct regulator_dev *dev, unsigned selector) +{ + struct tps65910_reg *pmic = rdev_get_drvdata(dev); + int reg, id = rdev_get_id(dev); + + reg = tps65910_get_ctrl_register(id); + if (reg < 0) + return reg; + + switch (id) { + case TPS65910_REG_VIO: + case TPS65910_REG_VDIG1: + case TPS65910_REG_VDIG2: + case TPS65910_REG_VPLL: + case TPS65910_REG_VDAC: + case TPS65910_REG_VAUX1: + case TPS65910_REG_VAUX2: + case TPS65910_REG_VAUX33: + case TPS65910_REG_VMMC: + return tps65910_modify_bits(pmic, reg, + (selector << LDO_SEL_SHIFT), LDO_SEL_MASK); + } + + return -EINVAL; +} + +static int tps65910_list_voltage_dcdc(struct regulator_dev *dev, + unsigned selector) +{ + int mult, volt; + + mult = (selector / VDD1_2_NUM_VOLTS) + 1; + + volt = VDD1_2_MIN_VOLT + (selector % VDD1_2_NUM_VOLTS) * VDD1_2_OFFSET; + + return volt * 100 * mult; +} + +static int tps65910_list_voltage(struct regulator_dev *dev, + unsigned selector) +{ + struct tps65910_reg *pmic = rdev_get_drvdata(dev); + int id = rdev_get_id(dev), voltage; + + if (id < TPS65910_REG_VIO || id > TPS65910_REG_VMMC) + return -EINVAL; + + if (selector >= pmic->info[id]->table_len) + return -EINVAL; + else + voltage = pmic->info[id]->table[selector] * 1000; + + return voltage; +} + +/* Regulator ops (except VRTC) */ +static struct regulator_ops tps65910_ops_dcdc = { + .is_enabled = tps65910_is_enabled, + .enable = tps65910_enable, + .disable = tps65910_disable, + .set_mode = tps65910_set_mode, + .get_mode = tps65910_get_mode, + .get_voltage = tps65910_get_voltage_dcdc, + .set_voltage_sel = tps65910_set_voltage_dcdc, + .list_voltage = tps65910_list_voltage_dcdc, +}; + +static struct regulator_ops tps65910_ops_vdd3 = { + .is_enabled = tps65910_is_enabled, + .enable = tps65910_enable, + .disable = tps65910_disable, + .set_mode = tps65910_set_mode, + .get_mode = tps65910_get_mode, + .get_voltage = tps65910_get_voltage_vdd3, + .list_voltage = tps65910_list_voltage, +}; + +static struct regulator_ops tps65910_ops = { + .is_enabled = tps65910_is_enabled, + .enable = tps65910_enable, + .disable = tps65910_disable, + .set_mode = tps65910_set_mode, + .get_mode = tps65910_get_mode, + .get_voltage = tps65910_get_voltage, + .set_voltage_sel = tps65910_set_voltage, + .list_voltage = tps65910_list_voltage, +}; + +static __devinit int tps65910_probe(struct platform_device *pdev) +{ + struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent); + struct tps_info *info = tps65910_regs; + struct regulator_init_data *reg_data; + struct regulator_dev *rdev; + struct tps65910_reg *pmic; + struct tps65910_board *pmic_plat_data; + static int desc_id; + int i, err; + + pmic_plat_data = dev_get_platdata(tps65910->dev); + if (!pmic_plat_data) + return -EINVAL; + + reg_data = pmic_plat_data->tps65910_pmic_init_data; + + pmic = kzalloc(sizeof(*pmic), GFP_KERNEL); + if (!pmic) + return -ENOMEM; + + mutex_init(&pmic->mutex); + pmic->mfd = tps65910; + platform_set_drvdata(pdev, pmic); + + /* Give control of all register to control port */ + tps65910_set_bits(pmic->mfd, TPS65910_DEVCTRL, + DEVCTRL_SR_CTL_I2C_SEL_MASK); + + for (i = 0; i < TPS65910_NUM_REGULATOR; i++, info++, reg_data++) { + /* Register the regulators */ + pmic->info[i] = info; + + pmic->desc[i].name = info->name; + pmic->desc[i].id = desc_id++; + pmic->desc[i].n_voltages = info->table_len; + + if ((i == TPS65910_REG_VDD1) || (i == TPS65910_REG_VDD2)) + pmic->desc[i].ops = &tps65910_ops_dcdc; + else if (i == TPS65910_REG_VDD3) + pmic->desc[i].ops = &tps65910_ops_vdd3; + else + pmic->desc[i].ops = &tps65910_ops; + + pmic->desc[i].type = REGULATOR_VOLTAGE; + pmic->desc[i].owner = THIS_MODULE; + + rdev = regulator_register(&pmic->desc[i], + tps65910->dev, reg_data, pmic); + if (IS_ERR(rdev)) { + dev_err(tps65910->dev, + "failed to register %s regulator\n", + pdev->name); + err = PTR_ERR(rdev); + goto err; + } + + /* Save regulator for cleanup */ + pmic->rdev[i] = rdev; + } + return 0; + +err: + while (--i >= 0) + regulator_unregister(pmic->rdev[i]); + + kfree(pmic); + return err; +} + +static int __devexit tps65910_remove(struct platform_device *pdev) +{ + struct tps65910_reg *tps65910_reg = platform_get_drvdata(pdev); + int i; + + for (i = 0; i < TPS65910_NUM_REGULATOR; i++) + regulator_unregister(tps65910_reg->rdev[i]); + + kfree(tps65910_reg); + return 0; +} + +static struct platform_driver tps65910_driver = { + .driver = { + .name = "tps65910-pmic", + .owner = THIS_MODULE, + }, + .probe = tps65910_probe, + .remove = __devexit_p(tps65910_remove), +}; + +static int __init tps65910_init(void) +{ + return platform_driver_register(&tps65910_driver); +} +subsys_initcall(tps65910_init); + +static void __exit tps65910_cleanup(void) +{ + platform_driver_unregister(&tps65910_driver); +} +module_exit(tps65910_cleanup); + +MODULE_AUTHOR("Graeme Gregory "); +MODULE_DESCRIPTION("TPS6507x voltage regulator driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:tps65910-pmic"); diff --git a/include/linux/mfd/tps65910.h b/include/linux/mfd/tps65910.h index 8afe91c85587..be08a0c7e7de 100644 --- a/include/linux/mfd/tps65910.h +++ b/include/linux/mfd/tps65910.h @@ -215,12 +215,26 @@ #define VDD2_SR_SEL_SHIFT 0 +/*Registers VDD1, VDD2 voltage values definitions */ +#define VDD1_2_NUM_VOLTS 73 +#define VDD1_2_MIN_VOLT 6000 +#define VDD1_2_OFFSET 125 + + /*Register VDD3 (0x80) register.RegisterDescription */ #define VDD3_CKINEN_MASK 0x04 #define VDD3_CKINEN_SHIFT 2 #define VDD3_ST_MASK 0x03 #define VDD3_ST_SHIFT 0 +/*Registers VDIG (0x80) to VDAC register.RegisterDescription */ +#define LDO_SEL_MASK 0x0C +#define LDO_SEL_SHIFT 2 +#define LDO_ST_MASK 0x03 +#define LDO_ST_SHIFT 0 +#define LDO_ST_ON_BIT 0x01 +#define LDO_ST_MODE_BIT 0x02 + /*Register VDIG1 (0x80) register.RegisterDescription */ #define VDIG1_SEL_MASK 0x0C -- cgit From ecb9c4f5956afa2ca0a20a1f99932b9ff81de854 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 16 May 2011 18:20:34 +0800 Subject: regulator: Remove MAX8997_REG_BUCK1DVS/MAX8997_REG_BUCK2DVS/MAX8997_REG_BUCK5DVS macros In current implementation, the original macro implementation assumes the caller pass the parameter starting from 1 (to match the register names in datasheet). Thus we have unneeded plus one then minus one operations when using MAX8997_REG_BUCK1DVS/MAX8997_REG_BUCK2DVS/MAX8997_REG_BUCK5DVS macros. This patch removes these macros to avoid unneeded plus one then minus one operations without reducing readability. Signed-off-by: Axel Lin Acked-by: Kyungmin Park Acked-by: MyungJoo Ham Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- drivers/regulator/max8997.c | 12 ++++++------ include/linux/mfd/max8997-private.h | 4 ---- 2 files changed, 6 insertions(+), 10 deletions(-) (limited to 'include/linux') diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c index b1c1444864b3..10d5a1d9768e 100644 --- a/drivers/regulator/max8997.c +++ b/drivers/regulator/max8997.c @@ -1032,11 +1032,11 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) /* For the safety, set max voltage before setting up */ for (i = 0; i < 8; i++) { - max8997_update_reg(i2c, MAX8997_REG_BUCK1DVS(i + 1), + max8997_update_reg(i2c, MAX8997_REG_BUCK1DVS1 + i, max_buck1, 0x3f); - max8997_update_reg(i2c, MAX8997_REG_BUCK2DVS(i + 1), + max8997_update_reg(i2c, MAX8997_REG_BUCK2DVS1 + i, max_buck2, 0x3f); - max8997_update_reg(i2c, MAX8997_REG_BUCK5DVS(i + 1), + max8997_update_reg(i2c, MAX8997_REG_BUCK5DVS1 + i, max_buck5, 0x3f); } @@ -1113,13 +1113,13 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) /* Initialize all the DVS related BUCK registers */ for (i = 0; i < 8; i++) { - max8997_update_reg(i2c, MAX8997_REG_BUCK1DVS(i + 1), + max8997_update_reg(i2c, MAX8997_REG_BUCK1DVS1 + i, max8997->buck1_vol[i], 0x3f); - max8997_update_reg(i2c, MAX8997_REG_BUCK2DVS(i + 1), + max8997_update_reg(i2c, MAX8997_REG_BUCK2DVS1 + i, max8997->buck2_vol[i], 0x3f); - max8997_update_reg(i2c, MAX8997_REG_BUCK5DVS(i + 1), + max8997_update_reg(i2c, MAX8997_REG_BUCK5DVS1 + i, max8997->buck5_vol[i], 0x3f); } diff --git a/include/linux/mfd/max8997-private.h b/include/linux/mfd/max8997-private.h index 69d1010e2e51..5ff2400ad46c 100644 --- a/include/linux/mfd/max8997-private.h +++ b/include/linux/mfd/max8997-private.h @@ -311,10 +311,6 @@ enum max8997_irq { MAX8997_IRQ_NR, }; -#define MAX8997_REG_BUCK1DVS(x) (MAX8997_REG_BUCK1DVS1 + (x) - 1) -#define MAX8997_REG_BUCK2DVS(x) (MAX8997_REG_BUCK2DVS1 + (x) - 1) -#define MAX8997_REG_BUCK5DVS(x) (MAX8997_REG_BUCK5DVS1 + (x) - 1) - #define MAX8997_NUM_GPIO 12 struct max8997_dev { struct device *dev; -- cgit From 795570561cc9c8dc7f7582ed6c4d07121b1c4831 Mon Sep 17 00:00:00 2001 From: Jorge Eduardo Candelaria Date: Mon, 16 May 2011 18:34:59 -0500 Subject: MFD: TPS65910: Add support for TPS65911 device The TPS65911 is the next generation of the TPS65910 family of PMIC chips. It adds a few features: - Watchdog Timer - PWM & LED generators - Comparators for system control status It also adds a set of Interrupts and GPIOs, among other things. The driver exports a function to identify between different versions of the tps65910 family, allowing other modules to identify the capabilities of the current chip. Signed-off-by: Jorge Eduardo Candelaria Acked-by: Samuel Ortiz Signed-off-by: Liam Girdwood --- drivers/mfd/tps65910.c | 4 +++- include/linux/mfd/tps65910.h | 46 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c index e31824870b9f..2229e66d80db 100644 --- a/drivers/mfd/tps65910.c +++ b/drivers/mfd/tps65910.c @@ -157,6 +157,7 @@ static int tps65910_i2c_probe(struct i2c_client *i2c, i2c_set_clientdata(i2c, tps65910); tps65910->dev = &i2c->dev; tps65910->i2c_client = i2c; + tps65910->id = id->driver_data; tps65910->read = tps65910_i2c_read; tps65910->write = tps65910_i2c_write; mutex_init(&tps65910->io_mutex); @@ -192,7 +193,8 @@ static int tps65910_i2c_remove(struct i2c_client *i2c) } static const struct i2c_device_id tps65910_i2c_id[] = { - { "tps65910", 0 }, + { "tps65910", TPS65910 }, + { "tps65911", TPS65911 }, { } }; MODULE_DEVICE_TABLE(i2c, tps65910_i2c_id); diff --git a/include/linux/mfd/tps65910.h b/include/linux/mfd/tps65910.h index be08a0c7e7de..6ceea0dab8d7 100644 --- a/include/linux/mfd/tps65910.h +++ b/include/linux/mfd/tps65910.h @@ -17,6 +17,14 @@ #ifndef __LINUX_MFD_TPS65910_H #define __LINUX_MFD_TPS65910_H +/* TPS chip id list */ +#define TPS65910 0 +#define TPS65911 1 + +/* TPS regulator type list */ +#define REGULATOR_LDO 0 +#define REGULATOR_DCDC 1 + /* * List of registers for component TPS65910 * @@ -96,6 +104,21 @@ #define TPS65910_JTAGVERNUM 0x80 #define TPS65910_MAX_REGISTER 0x80 +/* + * List of registers specific to TPS65911 + */ +#define TPS65911_VDDCTRL 0x27 +#define TPS65911_VDDCTRL_OP 0x28 +#define TPS65911_VDDCTRL_SR 0x29 +#define TPS65911_LDO1 0x30 +#define TPS65911_LDO2 0x31 +#define TPS65911_LDO5 0x32 +#define TPS65911_LDO8 0x33 +#define TPS65911_LDO7 0x34 +#define TPS65911_LDO6 0x35 +#define TPS65911_LDO4 0x36 +#define TPS65911_LDO3 0x37 + /* * List of register bitfields for component TPS65910 * @@ -702,6 +725,23 @@ #define JTAGVERNUM_VERNUM_SHIFT 0 +/* Register VDDCTRL (0x27) bit definitions */ +#define VDDCTRL_ST_MASK 0x03 +#define VDDCTRL_ST_SHIFT 0 + + +/*Register VDDCTRL_OP (0x28) bit definitios */ +#define VDDCTRL_OP_CMD_MASK 0x80 +#define VDDCTRL_OP_CMD_SHIFT 7 +#define VDDCTRL_OP_SEL_MASK 0x7F +#define VDDCTRL_OP_SEL_SHIFT 0 + + +/*Register VDDCTRL_SR (0x29) bit definitions */ +#define VDDCTRL_SR_SEL_MASK 0x7F +#define VDDCTRL_SR_SEL_SHIFT 0 + + /* IRQ Definitions */ #define TPS65910_IRQ_VBAT_VMBDCH 0 #define TPS65910_IRQ_VBAT_VMHI 1 @@ -742,6 +782,7 @@ struct tps65910 { struct device *dev; struct i2c_client *i2c_client; struct mutex io_mutex; + unsigned int id; int (*read)(struct tps65910 *tps65910, u8 reg, int size, void *dest); int (*write)(struct tps65910 *tps65910, u8 reg, int size, void *src); @@ -771,4 +812,9 @@ void tps65910_gpio_init(struct tps65910 *tps65910, int gpio_base); int tps65910_irq_init(struct tps65910 *tps65910, int irq, struct tps65910_platform_data *pdata); +static inline int tps65910_chip_id(struct tps65910 *tps65910) +{ + return tps65910->id; +} + #endif /* __LINUX_MFD_TPS65910_H */ -- cgit From a320e3c3d6351814afa5182159df88d2637e0f6f Mon Sep 17 00:00:00 2001 From: Jorge Eduardo Candelaria Date: Mon, 16 May 2011 18:35:03 -0500 Subject: regulator: tps65911: Add new chip version The tps65911 chip introduces new features, including changes in the regulator module. - VDD1 and VDD2 remain unchanged. - VDD3 is now named VDDCTRL and has a wider voltage range. - LDOs are now named LDO1...8 and voltage ranges are sequential, making LDOs easier to handle. Signed-off-by: Jorge Eduardo Candelaria Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- drivers/regulator/tps65910-regulator.c | 357 +++++++++++++++++++++++++++++---- include/linux/mfd/tps65910.h | 10 +- 2 files changed, 332 insertions(+), 35 deletions(-) (limited to 'include/linux') diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 048ba47e058f..55dd4e6650db 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -39,8 +39,17 @@ #define TPS65910_REG_VAUX33 11 #define TPS65910_REG_VMMC 12 -#define TPS65910_NUM_REGULATOR 13 +#define TPS65911_REG_VDDCTRL 4 +#define TPS65911_REG_LDO1 5 +#define TPS65911_REG_LDO2 6 +#define TPS65911_REG_LDO3 7 +#define TPS65911_REG_LDO4 8 +#define TPS65911_REG_LDO5 9 +#define TPS65911_REG_LDO6 10 +#define TPS65911_REG_LDO7 11 +#define TPS65911_REG_LDO8 12 +#define TPS65910_NUM_REGULATOR 13 #define TPS65910_SUPPLY_STATE_ENABLED 0x1 /* supported VIO voltages in milivolts */ @@ -48,7 +57,9 @@ static const u16 VIO_VSEL_table[] = { 1500, 1800, 2500, 3300, }; -/* supported VIO voltages in milivolts */ +/* VSEL tables for TPS65910 specific LDOs and dcdc's */ + +/* supported VDD3 voltages in milivolts */ static const u16 VDD3_VSEL_table[] = { 5000, }; @@ -187,6 +198,71 @@ static struct tps_info tps65910_regs[] = { }, }; +static struct tps_info tps65911_regs[] = { + { + .name = "VIO", + .min_uV = 1500000, + .max_uV = 3300000, + .table_len = ARRAY_SIZE(VIO_VSEL_table), + .table = VIO_VSEL_table, + }, + { + .name = "VDD1", + .min_uV = 600000, + .max_uV = 4500000, + }, + { + .name = "VDD2", + .min_uV = 600000, + .max_uV = 4500000, + }, + { + .name = "VDDCTRL", + .min_uV = 600000, + .max_uV = 1400000, + }, + { + .name = "LDO1", + .min_uV = 1000000, + .max_uV = 3300000, + }, + { + .name = "LDO2", + .min_uV = 1000000, + .max_uV = 3300000, + }, + { + .name = "LDO3", + .min_uV = 1000000, + .max_uV = 3300000, + }, + { + .name = "LDO4", + .min_uV = 1000000, + .max_uV = 3300000, + }, + { + .name = "LDO5", + .min_uV = 1000000, + .max_uV = 3300000, + }, + { + .name = "LDO6", + .min_uV = 1000000, + .max_uV = 3300000, + }, + { + .name = "LDO7", + .min_uV = 1000000, + .max_uV = 3300000, + }, + { + .name = "LDO8", + .min_uV = 1000000, + .max_uV = 3300000, + }, +}; + struct tps65910_reg { struct regulator_desc desc[TPS65910_NUM_REGULATOR]; struct tps65910 *mfd; @@ -194,6 +270,7 @@ struct tps65910_reg { struct tps_info *info[TPS65910_NUM_REGULATOR]; struct mutex mutex; int mode; + int (*get_ctrl_reg)(int); }; static inline int tps65910_read(struct tps65910_reg *pmic, u8 reg) @@ -300,12 +377,46 @@ static int tps65910_get_ctrl_register(int id) } } +static int tps65911_get_ctrl_register(int id) +{ + switch (id) { + case TPS65910_REG_VRTC: + return TPS65910_VRTC; + case TPS65910_REG_VIO: + return TPS65910_VIO; + case TPS65910_REG_VDD1: + return TPS65910_VDD1; + case TPS65910_REG_VDD2: + return TPS65910_VDD2; + case TPS65911_REG_VDDCTRL: + return TPS65911_VDDCTRL; + case TPS65911_REG_LDO1: + return TPS65911_LDO1; + case TPS65911_REG_LDO2: + return TPS65911_LDO2; + case TPS65911_REG_LDO3: + return TPS65911_LDO3; + case TPS65911_REG_LDO4: + return TPS65911_LDO4; + case TPS65911_REG_LDO5: + return TPS65911_LDO5; + case TPS65911_REG_LDO6: + return TPS65911_LDO6; + case TPS65911_REG_LDO7: + return TPS65911_LDO7; + case TPS65911_REG_LDO8: + return TPS65911_LDO8; + default: + return -EINVAL; + } +} + static int tps65910_is_enabled(struct regulator_dev *dev) { struct tps65910_reg *pmic = rdev_get_drvdata(dev); int reg, value, id = rdev_get_id(dev); - reg = tps65910_get_ctrl_register(id); + reg = pmic->get_ctrl_reg(id); if (reg < 0) return reg; @@ -322,7 +433,7 @@ static int tps65910_enable(struct regulator_dev *dev) struct tps65910 *mfd = pmic->mfd; int reg, id = rdev_get_id(dev); - reg = tps65910_get_ctrl_register(id); + reg = pmic->get_ctrl_reg(id); if (reg < 0) return reg; @@ -335,7 +446,7 @@ static int tps65910_disable(struct regulator_dev *dev) struct tps65910 *mfd = pmic->mfd; int reg, id = rdev_get_id(dev); - reg = tps65910_get_ctrl_register(id); + reg = pmic->get_ctrl_reg(id); if (reg < 0) return reg; @@ -348,7 +459,8 @@ static int tps65910_set_mode(struct regulator_dev *dev, unsigned int mode) struct tps65910_reg *pmic = rdev_get_drvdata(dev); struct tps65910 *mfd = pmic->mfd; int reg, value, id = rdev_get_id(dev); - reg = tps65910_get_ctrl_register(id); + + reg = pmic->get_ctrl_reg(id); if (reg < 0) return reg; @@ -371,7 +483,7 @@ static unsigned int tps65910_get_mode(struct regulator_dev *dev) struct tps65910_reg *pmic = rdev_get_drvdata(dev); int reg, value, id = rdev_get_id(dev); - reg = tps65910_get_ctrl_register(id); + reg = pmic->get_ctrl_reg(id); if (reg < 0) return reg; @@ -391,7 +503,7 @@ static int tps65910_get_voltage_dcdc(struct regulator_dev *dev) { struct tps65910_reg *pmic = rdev_get_drvdata(dev); int id = rdev_get_id(dev), voltage = 0; - int opvsel = 0, srvsel = 0, mult = 0, sr = 0; + int opvsel = 0, srvsel = 0, vselmax = 0, mult = 0, sr = 0; switch (id) { case TPS65910_REG_VDD1: @@ -402,6 +514,7 @@ static int tps65910_get_voltage_dcdc(struct regulator_dev *dev) sr = opvsel & VDD1_OP_CMD_MASK; opvsel &= VDD1_OP_SEL_MASK; srvsel &= VDD1_SR_SEL_MASK; + vselmax = 75; break; case TPS65910_REG_VDD2: opvsel = tps65910_reg_read(pmic, TPS65910_VDD2_OP); @@ -411,6 +524,15 @@ static int tps65910_get_voltage_dcdc(struct regulator_dev *dev) sr = opvsel & VDD2_OP_CMD_MASK; opvsel &= VDD2_OP_SEL_MASK; srvsel &= VDD2_SR_SEL_MASK; + vselmax = 75; + break; + case TPS65911_REG_VDDCTRL: + opvsel = tps65910_reg_read(pmic, TPS65911_VDDCTRL_OP); + srvsel = tps65910_reg_read(pmic, TPS65911_VDDCTRL_SR); + sr = opvsel & VDDCTRL_OP_CMD_MASK; + opvsel &= VDDCTRL_OP_SEL_MASK; + srvsel &= VDDCTRL_SR_SEL_MASK; + vselmax = 64; break; } @@ -419,17 +541,21 @@ static int tps65910_get_voltage_dcdc(struct regulator_dev *dev) mult=1; if (sr) { - /* Valid range is 3-75 so normalise */ - if (srvsel < 3) srvsel = 3; - if (srvsel > 75) srvsel = 75; + /* normalise to valid range */ + if (srvsel < 3) + srvsel = 3; + if (srvsel > vselmax) + srvsel = vselmax; srvsel -= 3; voltage = (srvsel * VDD1_2_OFFSET + VDD1_2_MIN_VOLT) * 100; } else { - /* Valid range is 3-75 so normalise */ - if (opvsel < 3) opvsel = 3; - if (opvsel > 75) opvsel = 75; + /* normalise to valid range*/ + if (opvsel < 3) + opvsel = 3; + if (opvsel > vselmax) + opvsel = vselmax; opvsel -= 3; voltage = (opvsel * VDD1_2_OFFSET + VDD1_2_MIN_VOLT) * 100; @@ -445,7 +571,7 @@ static int tps65910_get_voltage(struct regulator_dev *dev) struct tps65910_reg *pmic = rdev_get_drvdata(dev); int reg, value, id = rdev_get_id(dev), voltage = 0; - reg = tps65910_get_ctrl_register(id); + reg = pmic->get_ctrl_reg(id); if (reg < 0) return reg; @@ -480,29 +606,88 @@ static int tps65910_get_voltage_vdd3(struct regulator_dev *dev) return 5 * 1000 * 1000; } +static int tps65911_get_voltage(struct regulator_dev *dev) +{ + struct tps65910_reg *pmic = rdev_get_drvdata(dev); + int step_mv, id = rdev_get_id(dev); + u8 value, reg; + + reg = pmic->get_ctrl_reg(id); + + value = tps65910_reg_read(pmic, reg); + + switch (id) { + case TPS65911_REG_LDO1: + case TPS65911_REG_LDO2: + case TPS65911_REG_LDO4: + value &= LDO1_SEL_MASK; + value >>= LDO_SEL_SHIFT; + /* The first 5 values of the selector correspond to 1V */ + if (value < 5) + value = 0; + else + value -= 4; + + step_mv = 50; + break; + case TPS65911_REG_LDO3: + case TPS65911_REG_LDO5: + case TPS65911_REG_LDO6: + case TPS65911_REG_LDO7: + case TPS65911_REG_LDO8: + value &= LDO3_SEL_MASK; + value >>= LDO_SEL_SHIFT; + /* The first 3 values of the selector correspond to 1V */ + if (value < 3) + value = 0; + else + value -= 2; + + step_mv = 100; + break; + case TPS65910_REG_VIO: + return pmic->info[id]->table[value] * 1000; + break; + default: + return -EINVAL; + } + + return (LDO_MIN_VOLT + value * step_mv) * 1000; +} + static int tps65910_set_voltage_dcdc(struct regulator_dev *dev, unsigned selector) { struct tps65910_reg *pmic = rdev_get_drvdata(dev); int id = rdev_get_id(dev), vsel; - int dcdc_mult; + int dcdc_mult = 0; - /* Split vsel into appropriate registers */ - dcdc_mult = (selector / VDD1_2_NUM_VOLTS) + 1; - if (dcdc_mult == 1) dcdc_mult--; - - vsel = (selector % VDD1_2_NUM_VOLTS) + 3; + switch (id) { + case TPS65910_REG_VDD1: + dcdc_mult = (selector / VDD1_2_NUM_VOLTS) + 1; + if (dcdc_mult == 1) + dcdc_mult--; + vsel = (selector % VDD1_2_NUM_VOLTS) + 3; - if (id == TPS65910_REG_VDD1) { tps65910_modify_bits(pmic, TPS65910_VDD1, (dcdc_mult << VDD1_VGAIN_SEL_SHIFT), VDD1_VGAIN_SEL_MASK); tps65910_reg_write(pmic, TPS65910_VDD1_OP, vsel); - } else { + break; + case TPS65910_REG_VDD2: + dcdc_mult = (selector / VDD1_2_NUM_VOLTS) + 1; + if (dcdc_mult == 1) + dcdc_mult--; + vsel = (selector % VDD1_2_NUM_VOLTS) + 3; + tps65910_modify_bits(pmic, TPS65910_VDD2, (dcdc_mult << VDD2_VGAIN_SEL_SHIFT), VDD1_VGAIN_SEL_MASK); tps65910_reg_write(pmic, TPS65910_VDD2_OP, vsel); + break; + case TPS65911_REG_VDDCTRL: + vsel = selector; + tps65910_reg_write(pmic, TPS65911_VDDCTRL_OP, vsel); } return 0; @@ -513,7 +698,7 @@ static int tps65910_set_voltage(struct regulator_dev *dev, unsigned selector) struct tps65910_reg *pmic = rdev_get_drvdata(dev); int reg, id = rdev_get_id(dev); - reg = tps65910_get_ctrl_register(id); + reg = pmic->get_ctrl_reg(id); if (reg < 0) return reg; @@ -534,14 +719,49 @@ static int tps65910_set_voltage(struct regulator_dev *dev, unsigned selector) return -EINVAL; } +static int tps65911_set_voltage(struct regulator_dev *dev, unsigned selector) +{ + struct tps65910_reg *pmic = rdev_get_drvdata(dev); + int reg, id = rdev_get_id(dev); + + reg = pmic->get_ctrl_reg(id); + if (reg < 0) + return reg; + + switch (id) { + case TPS65911_REG_LDO1: + case TPS65911_REG_LDO2: + case TPS65911_REG_LDO4: + return tps65910_modify_bits(pmic, reg, + (selector << LDO_SEL_SHIFT), LDO1_SEL_MASK); + case TPS65911_REG_LDO3: + case TPS65911_REG_LDO5: + case TPS65911_REG_LDO6: + case TPS65911_REG_LDO7: + case TPS65911_REG_LDO8: + case TPS65910_REG_VIO: + return tps65910_modify_bits(pmic, reg, + (selector << LDO_SEL_SHIFT), LDO3_SEL_MASK); + } + + return -EINVAL; +} + + static int tps65910_list_voltage_dcdc(struct regulator_dev *dev, unsigned selector) { - int mult, volt; - - mult = (selector / VDD1_2_NUM_VOLTS) + 1; + int volt, mult = 1, id = rdev_get_id(dev); - volt = VDD1_2_MIN_VOLT + (selector % VDD1_2_NUM_VOLTS) * VDD1_2_OFFSET; + switch (id) { + case TPS65910_REG_VDD1: + case TPS65910_REG_VDD2: + mult = (selector / VDD1_2_NUM_VOLTS) + 1; + volt = VDD1_2_MIN_VOLT + + (selector % VDD1_2_NUM_VOLTS) * VDD1_2_OFFSET; + case TPS65911_REG_VDDCTRL: + volt = VDDCTRL_MIN_VOLT + (selector * VDDCTRL_OFFSET); + } return volt * 100 * mult; } @@ -563,6 +783,45 @@ static int tps65910_list_voltage(struct regulator_dev *dev, return voltage; } +static int tps65911_list_voltage(struct regulator_dev *dev, unsigned selector) +{ + struct tps65910_reg *pmic = rdev_get_drvdata(dev); + int step_mv = 0, id = rdev_get_id(dev); + + switch(id) { + case TPS65911_REG_LDO1: + case TPS65911_REG_LDO2: + case TPS65911_REG_LDO4: + /* The first 5 values of the selector correspond to 1V */ + if (selector < 5) + selector = 0; + else + selector -= 4; + + step_mv = 50; + break; + case TPS65911_REG_LDO3: + case TPS65911_REG_LDO5: + case TPS65911_REG_LDO6: + case TPS65911_REG_LDO7: + case TPS65911_REG_LDO8: + /* The first 3 values of the selector correspond to 1V */ + if (selector < 3) + selector = 0; + else + selector -= 2; + + step_mv = 100; + break; + case TPS65910_REG_VIO: + return pmic->info[id]->table[selector] * 1000; + default: + return -EINVAL; + } + + return (LDO_MIN_VOLT + selector * step_mv) * 1000; +} + /* Regulator ops (except VRTC) */ static struct regulator_ops tps65910_ops_dcdc = { .is_enabled = tps65910_is_enabled, @@ -596,10 +855,21 @@ static struct regulator_ops tps65910_ops = { .list_voltage = tps65910_list_voltage, }; +static struct regulator_ops tps65911_ops = { + .is_enabled = tps65910_is_enabled, + .enable = tps65910_enable, + .disable = tps65910_disable, + .set_mode = tps65910_set_mode, + .get_mode = tps65910_get_mode, + .get_voltage = tps65911_get_voltage, + .set_voltage_sel = tps65911_set_voltage, + .list_voltage = tps65911_list_voltage, +}; + static __devinit int tps65910_probe(struct platform_device *pdev) { struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent); - struct tps_info *info = tps65910_regs; + struct tps_info *info; struct regulator_init_data *reg_data; struct regulator_dev *rdev; struct tps65910_reg *pmic; @@ -624,6 +894,18 @@ static __devinit int tps65910_probe(struct platform_device *pdev) tps65910_set_bits(pmic->mfd, TPS65910_DEVCTRL, DEVCTRL_SR_CTL_I2C_SEL_MASK); + switch(tps65910_chip_id(tps65910)) { + case TPS65910: + pmic->get_ctrl_reg = &tps65910_get_ctrl_register; + info = tps65910_regs; + case TPS65911: + pmic->get_ctrl_reg = &tps65911_get_ctrl_register; + info = tps65911_regs; + default: + pr_err("Invalid tps chip version\n"); + return -ENODEV; + } + for (i = 0; i < TPS65910_NUM_REGULATOR; i++, info++, reg_data++) { /* Register the regulators */ pmic->info[i] = info; @@ -632,12 +914,19 @@ static __devinit int tps65910_probe(struct platform_device *pdev) pmic->desc[i].id = i; pmic->desc[i].n_voltages = info->table_len; - if ((i == TPS65910_REG_VDD1) || (i == TPS65910_REG_VDD2)) + if (i == TPS65910_REG_VDD1 || i == TPS65910_REG_VDD2) { pmic->desc[i].ops = &tps65910_ops_dcdc; - else if (i == TPS65910_REG_VDD3) - pmic->desc[i].ops = &tps65910_ops_vdd3; - else - pmic->desc[i].ops = &tps65910_ops; + } else if (i == TPS65910_REG_VDD3) { + if (tps65910_chip_id(tps65910) == TPS65910) + pmic->desc[i].ops = &tps65910_ops_vdd3; + else + pmic->desc[i].ops = &tps65910_ops_dcdc; + } else { + if (tps65910_chip_id(tps65910) == TPS65910) + pmic->desc[i].ops = &tps65910_ops; + else + pmic->desc[i].ops = &tps65911_ops; + } pmic->desc[i].type = REGULATOR_VOLTAGE; pmic->desc[i].owner = THIS_MODULE; diff --git a/include/linux/mfd/tps65910.h b/include/linux/mfd/tps65910.h index 6ceea0dab8d7..20359e669ae7 100644 --- a/include/linux/mfd/tps65910.h +++ b/include/linux/mfd/tps65910.h @@ -232,7 +232,6 @@ #define VDD2_OP_SEL_MASK 0x7F #define VDD2_OP_SEL_SHIFT 0 - /*Register VDD2_SR (0x80) register.RegisterDescription */ #define VDD2_SR_SEL_MASK 0x7F #define VDD2_SR_SEL_SHIFT 0 @@ -249,6 +248,8 @@ #define VDD3_CKINEN_SHIFT 2 #define VDD3_ST_MASK 0x03 #define VDD3_ST_SHIFT 0 +#define VDDCTRL_MIN_VOLT 6000 +#define VDDCTRL_OFFSET 125 /*Registers VDIG (0x80) to VDAC register.RegisterDescription */ #define LDO_SEL_MASK 0x0C @@ -259,6 +260,13 @@ #define LDO_ST_MODE_BIT 0x02 +/* Registers LDO1 to LDO8 in tps65910 */ +#define LDO1_SEL_MASK 0xFC +#define LDO3_SEL_MASK 0x7C +#define LDO_MIN_VOLT 1000 +#define LDO_MAX_VOLT 3300; + + /*Register VDIG1 (0x80) register.RegisterDescription */ #define VDIG1_SEL_MASK 0x0C #define VDIG1_SEL_SHIFT 2 -- cgit From a2974732ca7614aaf0baf9d6dd3ad893d50ce1c5 Mon Sep 17 00:00:00 2001 From: Jorge Eduardo Candelaria Date: Mon, 16 May 2011 18:35:07 -0500 Subject: TPS65911: Add new irq definitions TPS65911 adds new interrupt sources, as well as two new registers to handle them, one for interrupt status and one for interrupt masking. The added irqs are: -VMBCH2 - Low and High threshold -GPIO1-8 - Rising and falling edge detection -WTCHDG - Watchdog interrupt -PWRDN - PWRDN reset interrupt The code should handle these new registers only when the chip version is TPS65911. Signed-off-by: Jorge Eduardo Candelaria Acked-by: Samuel Ortiz Signed-off-by: Liam Girdwood --- drivers/mfd/tps65910-irq.c | 57 ++++++++++++++++++++++++++++++++++---------- include/linux/mfd/tps65910.h | 32 ++++++++++++++++++++++++- 2 files changed, 75 insertions(+), 14 deletions(-) (limited to 'include/linux') diff --git a/drivers/mfd/tps65910-irq.c b/drivers/mfd/tps65910-irq.c index b8435e045f81..2bfad5c86cc7 100644 --- a/drivers/mfd/tps65910-irq.c +++ b/drivers/mfd/tps65910-irq.c @@ -41,8 +41,8 @@ static inline int irq_to_tps65910_irq(struct tps65910 *tps65910, static irqreturn_t tps65910_irq(int irq, void *irq_data) { struct tps65910 *tps65910 = irq_data; - u16 irq_sts; - u16 irq_mask; + u32 irq_sts; + u32 irq_mask; u8 reg; int i; @@ -50,18 +50,28 @@ static irqreturn_t tps65910_irq(int irq, void *irq_data) irq_sts = reg; tps65910->read(tps65910, TPS65910_INT_STS2, 1, ®); irq_sts |= reg << 8; + switch (tps65910_chip_id(tps65910)) { + case TPS65911: + tps65910->read(tps65910, TPS65910_INT_STS3, 1, ®); + irq_sts |= reg << 16; + } tps65910->read(tps65910, TPS65910_INT_MSK, 1, ®); irq_mask = reg; tps65910->read(tps65910, TPS65910_INT_MSK2, 1, ®); irq_mask |= reg << 8; + switch (tps65910_chip_id(tps65910)) { + case TPS65911: + tps65910->read(tps65910, TPS65910_INT_MSK3, 1, ®); + irq_mask |= reg << 16; + } irq_sts &= ~irq_mask; if (!irq_sts) return IRQ_NONE; - for (i = 0; i < TPS65910_NUM_IRQ; i++) { + for (i = 0; i < tps65910->irq_num; i++) { if (!(irq_sts & (1 << i))) continue; @@ -71,9 +81,15 @@ static irqreturn_t tps65910_irq(int irq, void *irq_data) /* Write the STS register back to clear IRQs we handled */ reg = irq_sts & 0xFF; + irq_sts >>= 8; tps65910->write(tps65910, TPS65910_INT_STS, 1, ®); - reg = irq_sts >> 8; + reg = irq_sts & 0xFF; tps65910->write(tps65910, TPS65910_INT_STS2, 1, ®); + switch (tps65910_chip_id(tps65910)) { + case TPS65911: + reg = irq_sts >> 8; + tps65910->write(tps65910, TPS65910_INT_STS3, 1, ®); + } return IRQ_HANDLED; } @@ -88,19 +104,29 @@ static void tps65910_irq_lock(struct irq_data *data) static void tps65910_irq_sync_unlock(struct irq_data *data) { struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data); - u16 reg_mask; + u32 reg_mask; u8 reg; tps65910->read(tps65910, TPS65910_INT_MSK, 1, ®); reg_mask = reg; tps65910->read(tps65910, TPS65910_INT_MSK2, 1, ®); reg_mask |= reg << 8; + switch (tps65910_chip_id(tps65910)) { + case TPS65911: + tps65910->read(tps65910, TPS65910_INT_MSK3, 1, ®); + reg_mask |= reg << 16; + } if (tps65910->irq_mask != reg_mask) { reg = tps65910->irq_mask & 0xFF; tps65910->write(tps65910, TPS65910_INT_MSK, 1, ®); - reg = tps65910->irq_mask >> 8; + reg = tps65910->irq_mask >> 8 & 0xFF; tps65910->write(tps65910, TPS65910_INT_MSK2, 1, ®); + switch (tps65910_chip_id(tps65910)) { + case TPS65911: + reg = tps65910->irq_mask >> 16; + tps65910->write(tps65910, TPS65910_INT_MSK3, 1, ®); + } } mutex_unlock(&tps65910->irq_lock); } @@ -132,7 +158,6 @@ int tps65910_irq_init(struct tps65910 *tps65910, int irq, { int ret, cur_irq; int flags = IRQF_ONESHOT; - u8 reg; if (!irq) { dev_warn(tps65910->dev, "No interrupt support, no core IRQ\n"); @@ -144,19 +169,22 @@ int tps65910_irq_init(struct tps65910 *tps65910, int irq, return -EINVAL; } - /* Mask top level interrupts */ - reg = 0xFF; - tps65910->write(tps65910, TPS65910_INT_MSK, 1, ®); - reg = 0x03; - tps65910->write(tps65910, TPS65910_INT_MSK2, 1, ®); + tps65910->irq_mask = 0xFFFFFF; mutex_init(&tps65910->irq_lock); tps65910->chip_irq = irq; tps65910->irq_base = pdata->irq_base; + switch (tps65910_chip_id(tps65910)) { + case TPS65910: + tps65910->irq_num = TPS65910_NUM_IRQ; + case TPS65911: + tps65910->irq_num = TPS65911_NUM_IRQ; + } + /* Register with genirq */ for (cur_irq = tps65910->irq_base; - cur_irq < TPS65910_NUM_IRQ + tps65910->irq_base; + cur_irq < tps65910->irq_num + tps65910->irq_base; cur_irq++) { irq_set_chip_data(cur_irq, tps65910); irq_set_chip_and_handler(cur_irq, &tps65910_irq_chip, @@ -174,6 +202,9 @@ int tps65910_irq_init(struct tps65910 *tps65910, int irq, ret = request_threaded_irq(irq, NULL, tps65910_irq, flags, "tps65910", tps65910); + + irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW); + if (ret != 0) dev_err(tps65910->dev, "Failed to request IRQ: %d\n", ret); diff --git a/include/linux/mfd/tps65910.h b/include/linux/mfd/tps65910.h index 20359e669ae7..32bb7b81f713 100644 --- a/include/linux/mfd/tps65910.h +++ b/include/linux/mfd/tps65910.h @@ -763,6 +763,35 @@ #define TPS65910_IRQ_GPIO_F 9 #define TPS65910_NUM_IRQ 10 +#define TPS65911_IRQ_VBAT_VMBDCH 0 +#define TPS65911_IRQ_VBAT_VMBDCH2L 1 +#define TPS65911_IRQ_VBAT_VMBDCH2H 2 +#define TPS65911_IRQ_VBAT_VMHI 3 +#define TPS65911_IRQ_PWRON 4 +#define TPS65911_IRQ_PWRON_LP 5 +#define TPS65911_IRQ_PWRHOLD_F 6 +#define TPS65911_IRQ_PWRHOLD_R 7 +#define TPS65911_IRQ_HOTDIE 8 +#define TPS65911_IRQ_RTC_ALARM 9 +#define TPS65911_IRQ_RTC_PERIOD 10 +#define TPS65911_IRQ_GPIO0_R 11 +#define TPS65911_IRQ_GPIO0_F 12 +#define TPS65911_IRQ_GPIO1_R 13 +#define TPS65911_IRQ_GPIO1_F 14 +#define TPS65911_IRQ_GPIO2_R 15 +#define TPS65911_IRQ_GPIO2_F 16 +#define TPS65911_IRQ_GPIO3_R 17 +#define TPS65911_IRQ_GPIO3_F 18 +#define TPS65911_IRQ_GPIO4_R 19 +#define TPS65911_IRQ_GPIO4_F 20 +#define TPS65911_IRQ_GPIO5_R 21 +#define TPS65911_IRQ_GPIO5_F 22 +#define TPS65911_IRQ_WTCHDG 23 +#define TPS65911_IRQ_PWRDN 24 + +#define TPS65911_NUM_IRQ 25 + + /* GPIO Register Definitions */ #define TPS65910_GPIO_DEB BIT(2) #define TPS65910_GPIO_PUEN BIT(3) @@ -806,7 +835,8 @@ struct tps65910 { struct mutex irq_lock; int chip_irq; int irq_base; - u16 irq_mask; + int irq_num; + u32 irq_mask; }; struct tps65910_platform_data { -- cgit From 11ad14f86a7847b084d3e3f114180be39b1c7322 Mon Sep 17 00:00:00 2001 From: Jorge Eduardo Candelaria Date: Mon, 16 May 2011 18:35:42 -0500 Subject: TPS65911: Add support for added GPIO lines GPIO 1 to 8 are added for TPS65911 chip version. The gpio driver now handles more than one gpio lines. Subsequent versions of the chip family can add new GPIO lines with minimal driver changes. Signed-off-by: Jorge Eduardo Candelaria Acked-by: Grant Likely Signed-off-by: Liam Girdwood --- drivers/gpio/tps65910-gpio.c | 29 +++++++++----- include/linux/mfd/tps65910.h | 90 +++++++------------------------------------- 2 files changed, 33 insertions(+), 86 deletions(-) (limited to 'include/linux') diff --git a/drivers/gpio/tps65910-gpio.c b/drivers/gpio/tps65910-gpio.c index f3ae37652446..8d1ddfdd63eb 100644 --- a/drivers/gpio/tps65910-gpio.c +++ b/drivers/gpio/tps65910-gpio.c @@ -25,9 +25,9 @@ static int tps65910_gpio_get(struct gpio_chip *gc, unsigned offset) struct tps65910 *tps65910 = container_of(gc, struct tps65910, gpio); uint8_t val; - tps65910->read(tps65910, TPS65910_GPIO0, 1, &val); + tps65910->read(tps65910, TPS65910_GPIO0 + offset, 1, &val); - if (val & GPIO0_GPIO_STS_MASK) + if (val & GPIO_STS_MASK) return 1; return 0; @@ -39,11 +39,11 @@ static void tps65910_gpio_set(struct gpio_chip *gc, unsigned offset, struct tps65910 *tps65910 = container_of(gc, struct tps65910, gpio); if (value) - tps65910_set_bits(tps65910, TPS65910_GPIO0, - GPIO0_GPIO_SET_MASK); + tps65910_set_bits(tps65910, TPS65910_GPIO0 + offset, + GPIO_SET_MASK); else - tps65910_clear_bits(tps65910, TPS65910_GPIO0, - GPIO0_GPIO_SET_MASK); + tps65910_clear_bits(tps65910, TPS65910_GPIO0 + offset, + GPIO_SET_MASK); } static int tps65910_gpio_output(struct gpio_chip *gc, unsigned offset, @@ -54,15 +54,16 @@ static int tps65910_gpio_output(struct gpio_chip *gc, unsigned offset, /* Set the initial value */ tps65910_gpio_set(gc, 0, value); - return tps65910_set_bits(tps65910, TPS65910_GPIO0, GPIO0_GPIO_CFG_MASK); + return tps65910_set_bits(tps65910, TPS65910_GPIO0 + offset, + GPIO_CFG_MASK); } static int tps65910_gpio_input(struct gpio_chip *gc, unsigned offset) { struct tps65910 *tps65910 = container_of(gc, struct tps65910, gpio); - return tps65910_clear_bits(tps65910, TPS65910_GPIO0, - GPIO0_GPIO_CFG_MASK); + return tps65910_clear_bits(tps65910, TPS65910_GPIO0 + offset, + GPIO_CFG_MASK); } void tps65910_gpio_init(struct tps65910 *tps65910, int gpio_base) @@ -76,7 +77,15 @@ void tps65910_gpio_init(struct tps65910 *tps65910, int gpio_base) tps65910->gpio.label = tps65910->i2c_client->name; tps65910->gpio.dev = tps65910->dev; tps65910->gpio.base = gpio_base; - tps65910->gpio.ngpio = 1; + + switch(tps65910_chip_id(tps65910)) { + case TPS65910: + tps65910->gpio.ngpio = 6; + case TPS65911: + tps65910->gpio.ngpio = 9; + default: + return; + } tps65910->gpio.can_sleep = 1; tps65910->gpio.direction_input = tps65910_gpio_input; diff --git a/include/linux/mfd/tps65910.h b/include/linux/mfd/tps65910.h index 32bb7b81f713..5f770064e0c5 100644 --- a/include/linux/mfd/tps65910.h +++ b/include/linux/mfd/tps65910.h @@ -101,6 +101,9 @@ #define TPS65910_GPIO3 0x63 #define TPS65910_GPIO4 0x64 #define TPS65910_GPIO5 0x65 +#define TPS65910_GPIO6 0x66 +#define TPS65910_GPIO7 0x67 +#define TPS65910_GPIO8 0x68 #define TPS65910_JTAGVERNUM 0x80 #define TPS65910_MAX_REGISTER 0x80 @@ -650,82 +653,17 @@ #define INT_MSK3_GPIO4_R_IT_MSK_SHIFT 0 -/*Register GPIO0 (0x80) register.RegisterDescription */ -#define GPIO0_GPIO_DEB_MASK 0x10 -#define GPIO0_GPIO_DEB_SHIFT 4 -#define GPIO0_GPIO_PUEN_MASK 0x08 -#define GPIO0_GPIO_PUEN_SHIFT 3 -#define GPIO0_GPIO_CFG_MASK 0x04 -#define GPIO0_GPIO_CFG_SHIFT 2 -#define GPIO0_GPIO_STS_MASK 0x02 -#define GPIO0_GPIO_STS_SHIFT 1 -#define GPIO0_GPIO_SET_MASK 0x01 -#define GPIO0_GPIO_SET_SHIFT 0 - - -/*Register GPIO1 (0x80) register.RegisterDescription */ -#define GPIO1_GPIO_DEB_MASK 0x10 -#define GPIO1_GPIO_DEB_SHIFT 4 -#define GPIO1_GPIO_PUEN_MASK 0x08 -#define GPIO1_GPIO_PUEN_SHIFT 3 -#define GPIO1_GPIO_CFG_MASK 0x04 -#define GPIO1_GPIO_CFG_SHIFT 2 -#define GPIO1_GPIO_STS_MASK 0x02 -#define GPIO1_GPIO_STS_SHIFT 1 -#define GPIO1_GPIO_SET_MASK 0x01 -#define GPIO1_GPIO_SET_SHIFT 0 - - -/*Register GPIO2 (0x80) register.RegisterDescription */ -#define GPIO2_GPIO_DEB_MASK 0x10 -#define GPIO2_GPIO_DEB_SHIFT 4 -#define GPIO2_GPIO_PUEN_MASK 0x08 -#define GPIO2_GPIO_PUEN_SHIFT 3 -#define GPIO2_GPIO_CFG_MASK 0x04 -#define GPIO2_GPIO_CFG_SHIFT 2 -#define GPIO2_GPIO_STS_MASK 0x02 -#define GPIO2_GPIO_STS_SHIFT 1 -#define GPIO2_GPIO_SET_MASK 0x01 -#define GPIO2_GPIO_SET_SHIFT 0 - - -/*Register GPIO3 (0x80) register.RegisterDescription */ -#define GPIO3_GPIO_DEB_MASK 0x10 -#define GPIO3_GPIO_DEB_SHIFT 4 -#define GPIO3_GPIO_PUEN_MASK 0x08 -#define GPIO3_GPIO_PUEN_SHIFT 3 -#define GPIO3_GPIO_CFG_MASK 0x04 -#define GPIO3_GPIO_CFG_SHIFT 2 -#define GPIO3_GPIO_STS_MASK 0x02 -#define GPIO3_GPIO_STS_SHIFT 1 -#define GPIO3_GPIO_SET_MASK 0x01 -#define GPIO3_GPIO_SET_SHIFT 0 - - -/*Register GPIO4 (0x80) register.RegisterDescription */ -#define GPIO4_GPIO_DEB_MASK 0x10 -#define GPIO4_GPIO_DEB_SHIFT 4 -#define GPIO4_GPIO_PUEN_MASK 0x08 -#define GPIO4_GPIO_PUEN_SHIFT 3 -#define GPIO4_GPIO_CFG_MASK 0x04 -#define GPIO4_GPIO_CFG_SHIFT 2 -#define GPIO4_GPIO_STS_MASK 0x02 -#define GPIO4_GPIO_STS_SHIFT 1 -#define GPIO4_GPIO_SET_MASK 0x01 -#define GPIO4_GPIO_SET_SHIFT 0 - - -/*Register GPIO5 (0x80) register.RegisterDescription */ -#define GPIO5_GPIO_DEB_MASK 0x10 -#define GPIO5_GPIO_DEB_SHIFT 4 -#define GPIO5_GPIO_PUEN_MASK 0x08 -#define GPIO5_GPIO_PUEN_SHIFT 3 -#define GPIO5_GPIO_CFG_MASK 0x04 -#define GPIO5_GPIO_CFG_SHIFT 2 -#define GPIO5_GPIO_STS_MASK 0x02 -#define GPIO5_GPIO_STS_SHIFT 1 -#define GPIO5_GPIO_SET_MASK 0x01 -#define GPIO5_GPIO_SET_SHIFT 0 +/*Register GPIO (0x80) register.RegisterDescription */ +#define GPIO_DEB_MASK 0x10 +#define GPIO_DEB_SHIFT 4 +#define GPIO_PUEN_MASK 0x08 +#define GPIO_PUEN_SHIFT 3 +#define GPIO_CFG_MASK 0x04 +#define GPIO_CFG_SHIFT 2 +#define GPIO_STS_MASK 0x02 +#define GPIO_STS_SHIFT 1 +#define GPIO_SET_MASK 0x01 +#define GPIO_SET_SHIFT 0 /*Register JTAGVERNUM (0x80) register.RegisterDescription */ -- cgit From 6851ad3ab3461966adfffe8789372fe8256da792 Mon Sep 17 00:00:00 2001 From: Jorge Eduardo Candelaria Date: Mon, 16 May 2011 18:35:48 -0500 Subject: TPS65911: Comparator: Add comparator driver This driver adds functionality to the tps65911 chip driver. Two of the comparators are configurable by software and measures VCCS voltage to detect high or low voltage scenarios. Signed-off-by: Jorge Eduardo Candelaria Acked-by: Samuel Ortiz Signed-off-by: Liam Girdwood --- drivers/mfd/tps65911-comparator.c | 188 ++++++++++++++++++++++++++++++++++++++ include/linux/mfd/tps65910.h | 4 + 2 files changed, 192 insertions(+) create mode 100644 drivers/mfd/tps65911-comparator.c (limited to 'include/linux') diff --git a/drivers/mfd/tps65911-comparator.c b/drivers/mfd/tps65911-comparator.c new file mode 100644 index 000000000000..3d2dc56a3d40 --- /dev/null +++ b/drivers/mfd/tps65911-comparator.c @@ -0,0 +1,188 @@ +/* + * tps65910.c -- TI TPS6591x + * + * Copyright 2010 Texas Instruments Inc. + * + * Author: Jorge Eduardo Candelaria + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define COMP 0 +#define COMP1 1 +#define COMP2 2 + +/* Comparator 1 voltage selection table in milivolts */ +static const u16 COMP_VSEL_TABLE[] = { + 0, 2500, 2500, 2500, 2500, 2550, 2600, 2650, + 2700, 2750, 2800, 2850, 2900, 2950, 3000, 3050, + 3100, 3150, 3200, 3250, 3300, 3350, 3400, 3450, + 3500, +}; + +struct comparator { + const char *name; + int reg; + int uV_max; + const u16 *vsel_table; +}; + +static struct comparator tps_comparators[] = { + { + .name = "COMP1", + .reg = TPS65911_VMBCH, + .uV_max = 3500, + .vsel_table = COMP_VSEL_TABLE, + }, + { + .name = "COMP2", + .reg = TPS65911_VMBCH2, + .uV_max = 3500, + .vsel_table = COMP_VSEL_TABLE, + }, +}; + +static int comp_threshold_set(struct tps65910 *tps65910, int id, int voltage) +{ + struct comparator tps_comp = tps_comparators[id]; + int curr_voltage = 0; + int ret; + u8 index = 0, val; + + if (id == COMP) + return 0; + + while (curr_voltage < tps_comp.uV_max) { + curr_voltage = tps_comp.vsel_table[index]; + if (curr_voltage >= voltage) + break; + else if (curr_voltage < voltage) + index ++; + } + + if (curr_voltage > tps_comp.uV_max) + return -EINVAL; + + val = index << 1; + ret = tps65910->write(tps65910, tps_comp.reg, 1, &val); + + return ret; +} + +static int comp_threshold_get(struct tps65910 *tps65910, int id) +{ + struct comparator tps_comp = tps_comparators[id]; + int ret; + u8 val; + + if (id == COMP) + return 0; + + ret = tps65910->read(tps65910, tps_comp.reg, 1, &val); + if (ret < 0) + return ret; + + val >>= 1; + return tps_comp.vsel_table[val]; +} + +static ssize_t comp_threshold_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tps65910 *tps65910 = dev_get_drvdata(dev->parent); + struct attribute comp_attr = attr->attr; + int id, uVolt; + + if (!strcmp(comp_attr.name, "comp1_threshold")) + id = COMP1; + else if (!strcmp(comp_attr.name, "comp2_threshold")) + id = COMP2; + else + return -EINVAL; + + uVolt = comp_threshold_get(tps65910, id); + + return sprintf(buf, "%d\n", uVolt); +} + +static DEVICE_ATTR(comp1_threshold, S_IRUGO, comp_threshold_show, NULL); +static DEVICE_ATTR(comp2_threshold, S_IRUGO, comp_threshold_show, NULL); + +static __devinit int tps65911_comparator_probe(struct platform_device *pdev) +{ + struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent); + struct tps65910_platform_data *pdata = dev_get_platdata(tps65910->dev); + int ret; + + ret = comp_threshold_set(tps65910, COMP1, pdata->vmbch_threshold); + if (ret < 0) { + dev_err(&pdev->dev, "cannot set COMP1 threshold\n"); + return ret; + } + + ret = comp_threshold_set(tps65910, COMP2, pdata->vmbch2_threshold); + if (ret < 0) { + dev_err(&pdev->dev, "cannot set COMP2 theshold\n"); + return ret; + } + + /* Create sysfs entry */ + ret = device_create_file(&pdev->dev, &dev_attr_comp1_threshold); + if (ret < 0) + dev_err(&pdev->dev, "failed to add COMP1 sysfs file\n"); + + ret = device_create_file(&pdev->dev, &dev_attr_comp2_threshold); + if (ret < 0) + dev_err(&pdev->dev, "failed to add COMP2 sysfs file\n"); + + return ret; +} + +static __devexit int tps65911_comparator_remove(struct platform_device *pdev) +{ + struct tps65910 *tps65910; + + tps65910 = dev_get_drvdata(pdev->dev.parent); + + return 0; +} + +static struct platform_driver tps65911_comparator_driver = { + .driver = { + .name = "tps65911-comparator", + .owner = THIS_MODULE, + }, + .probe = tps65911_comparator_probe, + .remove = __devexit_p(tps65911_comparator_remove), +}; + +static int __init tps65911_comparator_init(void) +{ + return platform_driver_register(&tps65911_comparator_driver); +} +subsys_initcall(tps65911_comparator_init); + +static void __exit tps65911_comparator_exit(void) +{ + platform_driver_unregister(&tps65911_comparator_driver); +} +module_exit(tps65911_comparator_exit); + +MODULE_AUTHOR("Jorge Eduardo Candelaria "); +MODULE_DESCRIPTION("TPS65911 comparator driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:tps65911-comparator"); diff --git a/include/linux/mfd/tps65910.h b/include/linux/mfd/tps65910.h index 5f770064e0c5..8bb85b930c07 100644 --- a/include/linux/mfd/tps65910.h +++ b/include/linux/mfd/tps65910.h @@ -121,6 +121,8 @@ #define TPS65911_LDO6 0x35 #define TPS65911_LDO4 0x36 #define TPS65911_LDO3 0x37 +#define TPS65911_VMBCH 0x6A +#define TPS65911_VMBCH2 0x6B /* * List of register bitfields for component TPS65910 @@ -746,6 +748,8 @@ struct tps65910_board { int gpio_base; int irq; int irq_base; + int vmbch_threshold; + int vmbch2_threshold; struct regulator_init_data *tps65910_pmic_init_data; }; -- cgit From aa38572954ade525817fe88c54faebf85e5a61c0 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 27 May 2011 06:53:02 -0400 Subject: fs: pass exact type of data dirties to ->dirty_inode Tell the filesystem if we just updated timestamp (I_DIRTY_SYNC) or anything else, so that the filesystem can track internally if it needs to push out a transaction for fdatasync or not. This is just the prototype change with no user for it yet. I plan to push large XFS changes for the next merge window, and getting this trivial infrastructure in this window would help a lot to avoid tree interdependencies. Also remove incorrect comments that ->dirty_inode can't block. That has been changed a long time ago, and many implementations rely on it. Signed-off-by: Christoph Hellwig Signed-off-by: Al Viro --- Documentation/filesystems/Locking | 4 ++-- Documentation/filesystems/vfs.txt | 2 +- fs/btrfs/ctree.h | 2 +- fs/btrfs/inode.c | 2 +- fs/ext3/inode.c | 2 +- fs/ext4/ext4.h | 2 +- fs/ext4/inode.c | 2 +- fs/fs-writeback.c | 5 +---- fs/jffs2/fs.c | 2 +- fs/jffs2/os-linux.h | 2 +- fs/jfs/inode.c | 2 +- fs/jfs/jfs_inode.h | 2 +- fs/nilfs2/inode.c | 2 +- fs/nilfs2/nilfs.h | 2 +- fs/reiserfs/super.c | 2 +- fs/ubifs/super.c | 2 +- fs/xfs/linux-2.6/xfs_super.c | 3 ++- include/linux/ext3_fs.h | 2 +- include/linux/fs.h | 2 +- 19 files changed, 21 insertions(+), 23 deletions(-) (limited to 'include/linux') diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index 61b31acb9176..57d827d6071d 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking @@ -104,7 +104,7 @@ of the locking scheme for directory operations. prototypes: struct inode *(*alloc_inode)(struct super_block *sb); void (*destroy_inode)(struct inode *); - void (*dirty_inode) (struct inode *); + void (*dirty_inode) (struct inode *, int flags); int (*write_inode) (struct inode *, struct writeback_control *wbc); int (*drop_inode) (struct inode *); void (*evict_inode) (struct inode *); @@ -126,7 +126,7 @@ locking rules: s_umount alloc_inode: destroy_inode: -dirty_inode: (must not sleep) +dirty_inode: write_inode: drop_inode: !!!inode->i_lock!!! evict_inode: diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index 21a7dc467bba..88b9f5519af9 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt @@ -211,7 +211,7 @@ struct super_operations { struct inode *(*alloc_inode)(struct super_block *sb); void (*destroy_inode)(struct inode *); - void (*dirty_inode) (struct inode *); + void (*dirty_inode) (struct inode *, int flags); int (*write_inode) (struct inode *, int); void (*drop_inode) (struct inode *); void (*delete_inode) (struct inode *); diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 8f4b81de3ae2..d2177e7ad647 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -2522,7 +2522,7 @@ int btrfs_readpage(struct file *file, struct page *page); void btrfs_evict_inode(struct inode *inode); void btrfs_put_inode(struct inode *inode); int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc); -void btrfs_dirty_inode(struct inode *inode); +void btrfs_dirty_inode(struct inode *inode, int flags); struct inode *btrfs_alloc_inode(struct super_block *sb); void btrfs_destroy_inode(struct inode *inode); int btrfs_drop_inode(struct inode *inode); diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 7cd8ab0ef04d..ecff7d7a505f 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -4396,7 +4396,7 @@ int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc) * FIXME, needs more benchmarking...there are no reasons other than performance * to keep or drop this code. */ -void btrfs_dirty_inode(struct inode *inode) +void btrfs_dirty_inode(struct inode *inode, int flags) { struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_trans_handle *trans; diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 68b2e43d7c35..3451d23c3bae 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c @@ -3392,7 +3392,7 @@ int ext3_mark_inode_dirty(handle_t *handle, struct inode *inode) * so would cause a commit on atime updates, which we don't bother doing. * We handle synchronous inodes at the highest possible level. */ -void ext3_dirty_inode(struct inode *inode) +void ext3_dirty_inode(struct inode *inode, int flags) { handle_t *current_handle = ext3_journal_current_handle(); handle_t *handle; diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index a74b89c09f90..1921392cd708 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -1813,7 +1813,7 @@ extern int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry, extern void ext4_evict_inode(struct inode *); extern void ext4_clear_inode(struct inode *); extern int ext4_sync_inode(handle_t *, struct inode *); -extern void ext4_dirty_inode(struct inode *); +extern void ext4_dirty_inode(struct inode *, int); extern int ext4_change_inode_journal_flag(struct inode *, int); extern int ext4_get_inode_loc(struct inode *, struct ext4_iloc *); extern int ext4_can_truncate(struct inode *inode); diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 50d0e9c64584..a5763e3505ba 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -5733,7 +5733,7 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode) * so would cause a commit on atime updates, which we don't bother doing. * We handle synchronous inodes at the highest possible level. */ -void ext4_dirty_inode(struct inode *inode) +void ext4_dirty_inode(struct inode *inode, int flags) { handle_t *handle; diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 34591ee804b5..0f015a0468de 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -1007,9 +1007,6 @@ static noinline void block_dump___mark_inode_dirty(struct inode *inode) * In short, make sure you hash any inodes _before_ you start marking * them dirty. * - * This function *must* be atomic for the I_DIRTY_PAGES case - - * set_page_dirty() is called under spinlock in several places. - * * Note that for blockdevs, inode->dirtied_when represents the dirtying time of * the block-special inode (/dev/hda1) itself. And the ->dirtied_when field of * the kernel-internal blockdev inode represents the dirtying time of the @@ -1028,7 +1025,7 @@ void __mark_inode_dirty(struct inode *inode, int flags) */ if (flags & (I_DIRTY_SYNC | I_DIRTY_DATASYNC)) { if (sb->s_op->dirty_inode) - sb->s_op->dirty_inode(inode); + sb->s_op->dirty_inode(inode, flags); } /* diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c index e896e67767eb..46ad619b6124 100644 --- a/fs/jffs2/fs.c +++ b/fs/jffs2/fs.c @@ -357,7 +357,7 @@ error: return ERR_PTR(ret); } -void jffs2_dirty_inode(struct inode *inode) +void jffs2_dirty_inode(struct inode *inode, int flags) { struct iattr iattr; diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h index 00bae7cc2e48..65c6c43ca482 100644 --- a/fs/jffs2/os-linux.h +++ b/fs/jffs2/os-linux.h @@ -172,7 +172,7 @@ int jffs2_setattr (struct dentry *, struct iattr *); int jffs2_do_setattr (struct inode *, struct iattr *); struct inode *jffs2_iget(struct super_block *, unsigned long); void jffs2_evict_inode (struct inode *); -void jffs2_dirty_inode(struct inode *inode); +void jffs2_dirty_inode(struct inode *inode, int flags); struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_inode *ri); int jffs2_statfs (struct dentry *, struct kstatfs *); diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c index eddbb373209e..109655904bbc 100644 --- a/fs/jfs/inode.c +++ b/fs/jfs/inode.c @@ -173,7 +173,7 @@ void jfs_evict_inode(struct inode *inode) dquot_drop(inode); } -void jfs_dirty_inode(struct inode *inode) +void jfs_dirty_inode(struct inode *inode, int flags) { static int noisy = 5; diff --git a/fs/jfs/jfs_inode.h b/fs/jfs/jfs_inode.h index 155e91eff07d..ec2fb8b945fc 100644 --- a/fs/jfs/jfs_inode.h +++ b/fs/jfs/jfs_inode.h @@ -28,7 +28,7 @@ extern struct inode *jfs_iget(struct super_block *, unsigned long); extern int jfs_commit_inode(struct inode *, int); extern int jfs_write_inode(struct inode *, struct writeback_control *); extern void jfs_evict_inode(struct inode *); -extern void jfs_dirty_inode(struct inode *); +extern void jfs_dirty_inode(struct inode *, int); extern void jfs_truncate(struct inode *); extern void jfs_truncate_nolock(struct inode *, loff_t); extern void jfs_free_zero_link(struct inode *); diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index 587f18432832..b954878ad6ce 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c @@ -917,7 +917,7 @@ int nilfs_mark_inode_dirty(struct inode *inode) * construction. This function can be called both as a single operation * and as a part of indivisible file operations. */ -void nilfs_dirty_inode(struct inode *inode) +void nilfs_dirty_inode(struct inode *inode, int flags) { struct nilfs_transaction_info ti; struct nilfs_mdt_info *mdi = NILFS_MDT(inode); diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h index a9c6a531f80c..f02b9ad43a21 100644 --- a/fs/nilfs2/nilfs.h +++ b/fs/nilfs2/nilfs.h @@ -269,7 +269,7 @@ int nilfs_load_inode_block(struct inode *inode, struct buffer_head **pbh); extern int nilfs_inode_dirty(struct inode *); int nilfs_set_file_dirty(struct inode *inode, unsigned nr_dirty); extern int nilfs_mark_inode_dirty(struct inode *); -extern void nilfs_dirty_inode(struct inode *); +extern void nilfs_dirty_inode(struct inode *, int flags); int nilfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, __u64 start, __u64 len); diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index b216ff6be1c9..aa91089162cb 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -568,7 +568,7 @@ static void destroy_inodecache(void) } /* we don't mark inodes dirty, we just log them */ -static void reiserfs_dirty_inode(struct inode *inode) +static void reiserfs_dirty_inode(struct inode *inode, int flags) { struct reiserfs_transaction_handle th; diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 6db0bdaa9f74..1ab0d22e4c94 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c @@ -382,7 +382,7 @@ done: end_writeback(inode); } -static void ubifs_dirty_inode(struct inode *inode) +static void ubifs_dirty_inode(struct inode *inode, int flags) { struct ubifs_inode *ui = ubifs_inode(inode); diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 98b9c91fcdf1..1e3a7ce804dc 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c @@ -925,7 +925,8 @@ xfs_fs_inode_init_once( */ STATIC void xfs_fs_dirty_inode( - struct inode *inode) + struct inode *inode, + int flags) { barrier(); XFS_I(inode)->i_update_core = 1; diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h index 85c1d302c12e..5e06acf95d0f 100644 --- a/include/linux/ext3_fs.h +++ b/include/linux/ext3_fs.h @@ -909,7 +909,7 @@ extern int ext3_setattr (struct dentry *, struct iattr *); extern void ext3_evict_inode (struct inode *); extern int ext3_sync_inode (handle_t *, struct inode *); extern void ext3_discard_reservation (struct inode *); -extern void ext3_dirty_inode(struct inode *); +extern void ext3_dirty_inode(struct inode *, int); extern int ext3_change_inode_journal_flag(struct inode *, int); extern int ext3_get_inode_loc(struct inode *, struct ext3_iloc *); extern int ext3_can_truncate(struct inode *inode); diff --git a/include/linux/fs.h b/include/linux/fs.h index 241609346dfb..573028df050d 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1618,7 +1618,7 @@ struct super_operations { struct inode *(*alloc_inode)(struct super_block *sb); void (*destroy_inode)(struct inode *); - void (*dirty_inode) (struct inode *); + void (*dirty_inode) (struct inode *, int flags); int (*write_inode) (struct inode *, struct writeback_control *wbc); int (*drop_inode) (struct inode *); void (*evict_inode) (struct inode *); -- cgit From 9d931dd2ed62c14d7bf7c4c3ab3ef7610c46ca9b Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 26 May 2011 16:30:57 -0400 Subject: net: Kill ether_table[] declaration. This got missed back in 2006 when Jes Sorensen deleted net/ethernet/sysctl_net_ether.c Signed-off-by: David S. Miller --- include/linux/if_ether.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h index 0f1325d98295..0065ffd3226b 100644 --- a/include/linux/if_ether.h +++ b/include/linux/if_ether.h @@ -132,10 +132,6 @@ static inline struct ethhdr *eth_hdr(const struct sk_buff *skb) int eth_header_parse(const struct sk_buff *skb, unsigned char *haddr); -#ifdef CONFIG_SYSCTL -extern struct ctl_table ether_table[]; -#endif - int mac_pton(const char *s, u8 *mac); extern ssize_t sysfs_format_mac(char *buf, const unsigned char *addr, int len); -- cgit From bee95250f015ffc3a6efb99516489e70d1b52da2 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 26 May 2011 16:40:37 -0400 Subject: net: Add linux/sysctl.h includes where needed. Several networking headers were depending upon the implicit linux/sysctl.h include they get when including linux/net.h Add explicit includes. Signed-off-by: David S. Miller --- include/linux/netfilter.h | 1 + include/net/net_namespace.h | 1 + 2 files changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h index 7fa95df60146..857f5026ced6 100644 --- a/include/linux/netfilter.h +++ b/include/linux/netfilter.h @@ -13,6 +13,7 @@ #endif #include #include +#include /* Responses from hook functions. */ #define NF_DROP 0 diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index 3ae491932bc8..07a60e8b749e 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include -- cgit From c5c177b4aca83338781e72be2e6dd1601c560cb3 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 27 May 2011 13:41:33 -0400 Subject: net: Kill ratelimit.h dependency in linux/net.h Ingo Molnar noticed that we have this unnecessary ratelimit.h dependency in linux/net.h, which hid compilation problems from people doing builds only with CONFIG_NET enabled. Move this stuff out to a seperate net/net_ratelimit.h file and include that in the only two places where this thing is needed. Signed-off-by: David S. Miller Acked-by: Ingo Molnar --- include/linux/net.h | 6 ------ include/net/net_ratelimit.h | 8 ++++++++ net/core/sysctl_net_core.c | 1 + net/core/utils.c | 1 + 4 files changed, 10 insertions(+), 6 deletions(-) create mode 100644 include/net/net_ratelimit.h (limited to 'include/linux') diff --git a/include/linux/net.h b/include/linux/net.h index 1da55e9b6f01..b29923006b11 100644 --- a/include/linux/net.h +++ b/include/linux/net.h @@ -289,11 +289,5 @@ extern int kernel_sock_shutdown(struct socket *sock, MODULE_ALIAS("net-pf-" __stringify(pf) "-proto-" __stringify(proto) \ "-type-" __stringify(type)) -#ifdef CONFIG_SYSCTL -#include -#include -extern struct ratelimit_state net_ratelimit_state; -#endif - #endif /* __KERNEL__ */ #endif /* _LINUX_NET_H */ diff --git a/include/net/net_ratelimit.h b/include/net/net_ratelimit.h new file mode 100644 index 000000000000..7727b4247daf --- /dev/null +++ b/include/net/net_ratelimit.h @@ -0,0 +1,8 @@ +#ifndef _LINUX_NET_RATELIMIT_H +#define _LINUX_NET_RATELIMIT_H + +#include + +extern struct ratelimit_state net_ratelimit_state; + +#endif /* _LINUX_NET_RATELIMIT_H */ diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c index a829e3f60aeb..77a65f031488 100644 --- a/net/core/sysctl_net_core.c +++ b/net/core/sysctl_net_core.c @@ -17,6 +17,7 @@ #include #include +#include #ifdef CONFIG_RPS static int rps_sock_flow_sysctl(ctl_table *table, int write, diff --git a/net/core/utils.c b/net/core/utils.c index 2012bc797f9c..386e263f6066 100644 --- a/net/core/utils.c +++ b/net/core/utils.c @@ -27,6 +27,7 @@ #include #include +#include #include #include -- cgit From 176e21ee2ec89cae8d45cf1a850ea45a45428fb8 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 9 May 2011 15:22:44 -0400 Subject: SUNRPC: Support for RPC over AF_LOCAL transports TI-RPC introduces the capability of performing RPC over AF_LOCAL sockets. It uses this mainly for registering and unregistering local RPC services securely with the local rpcbind, but we could also conceivably use it as a generic upcall mechanism. This patch provides a client-side only implementation for the moment. We might also consider a server-side implementation to provide AF_LOCAL access to NLM (for statd downcalls, and such like). Autobinding is not supported on kernel AF_LOCAL transports at this time. Kernel ULPs must specify the pathname of the remote endpoint when an AF_LOCAL transport is created. rpcbind supports registering services available via AF_LOCAL, so the kernel could handle it with some adjustment to ->rpcbind and ->set_port. But we don't need this feature for doing upcalls via well-known named sockets. This has not been tested with ULPs that move a substantial amount of data. Thus, I can't attest to how robust the write_space and congestion management logic is. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust --- include/linux/sunrpc/msg_prot.h | 1 + include/linux/sunrpc/xprt.h | 3 +- net/sunrpc/clnt.c | 8 + net/sunrpc/xprtsock.c | 395 +++++++++++++++++++++++++++++++++++++++- 4 files changed, 403 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/sunrpc/msg_prot.h b/include/linux/sunrpc/msg_prot.h index 77e624883393..c68a147939a6 100644 --- a/include/linux/sunrpc/msg_prot.h +++ b/include/linux/sunrpc/msg_prot.h @@ -145,6 +145,7 @@ typedef __be32 rpc_fraghdr; #define RPCBIND_NETID_TCP "tcp" #define RPCBIND_NETID_UDP6 "udp6" #define RPCBIND_NETID_TCP6 "tcp6" +#define RPCBIND_NETID_LOCAL "local" /* * Note that RFC 1833 does not put any size restrictions on the diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h index a0f998c07c65..81cce3b3ee66 100644 --- a/include/linux/sunrpc/xprt.h +++ b/include/linux/sunrpc/xprt.h @@ -141,7 +141,8 @@ enum xprt_transports { XPRT_TRANSPORT_UDP = IPPROTO_UDP, XPRT_TRANSPORT_TCP = IPPROTO_TCP, XPRT_TRANSPORT_BC_TCP = IPPROTO_TCP | XPRT_TRANSPORT_BC, - XPRT_TRANSPORT_RDMA = 256 + XPRT_TRANSPORT_RDMA = 256, + XPRT_TRANSPORT_LOCAL = 257, }; struct rpc_xprt { diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 08ed49629b86..b84d7395535e 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -28,7 +28,9 @@ #include #include #include +#include #include +#include #include #include @@ -294,6 +296,8 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args) * up a string representation of the passed-in address. */ if (args->servername == NULL) { + struct sockaddr_un *sun = + (struct sockaddr_un *)args->address; struct sockaddr_in *sin = (struct sockaddr_in *)args->address; struct sockaddr_in6 *sin6 = @@ -301,6 +305,10 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args) servername[0] = '\0'; switch (args->address->sa_family) { + case AF_LOCAL: + snprintf(servername, sizeof(servername), "%s", + sun->sun_path); + break; case AF_INET: snprintf(servername, sizeof(servername), "%pI4", &sin->sin_addr.s_addr); diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 079366974e1f..72abb7358933 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -19,6 +19,7 @@ */ #include +#include #include #include #include @@ -28,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -45,6 +47,9 @@ #include #include "sunrpc.h" + +static void xs_close(struct rpc_xprt *xprt); + /* * xprtsock tunables */ @@ -261,6 +266,11 @@ static inline struct sockaddr *xs_addr(struct rpc_xprt *xprt) return (struct sockaddr *) &xprt->addr; } +static inline struct sockaddr_un *xs_addr_un(struct rpc_xprt *xprt) +{ + return (struct sockaddr_un *) &xprt->addr; +} + static inline struct sockaddr_in *xs_addr_in(struct rpc_xprt *xprt) { return (struct sockaddr_in *) &xprt->addr; @@ -276,23 +286,34 @@ static void xs_format_common_peer_addresses(struct rpc_xprt *xprt) struct sockaddr *sap = xs_addr(xprt); struct sockaddr_in6 *sin6; struct sockaddr_in *sin; + struct sockaddr_un *sun; char buf[128]; - (void)rpc_ntop(sap, buf, sizeof(buf)); - xprt->address_strings[RPC_DISPLAY_ADDR] = kstrdup(buf, GFP_KERNEL); - switch (sap->sa_family) { + case AF_LOCAL: + sun = xs_addr_un(xprt); + strlcpy(buf, sun->sun_path, sizeof(buf)); + xprt->address_strings[RPC_DISPLAY_ADDR] = + kstrdup(buf, GFP_KERNEL); + break; case AF_INET: + (void)rpc_ntop(sap, buf, sizeof(buf)); + xprt->address_strings[RPC_DISPLAY_ADDR] = + kstrdup(buf, GFP_KERNEL); sin = xs_addr_in(xprt); snprintf(buf, sizeof(buf), "%08x", ntohl(sin->sin_addr.s_addr)); break; case AF_INET6: + (void)rpc_ntop(sap, buf, sizeof(buf)); + xprt->address_strings[RPC_DISPLAY_ADDR] = + kstrdup(buf, GFP_KERNEL); sin6 = xs_addr_in6(xprt); snprintf(buf, sizeof(buf), "%pi6", &sin6->sin6_addr); break; default: BUG(); } + xprt->address_strings[RPC_DISPLAY_HEX_ADDR] = kstrdup(buf, GFP_KERNEL); } @@ -505,6 +526,60 @@ static inline void xs_encode_stream_record_marker(struct xdr_buf *buf) *base = cpu_to_be32(RPC_LAST_STREAM_FRAGMENT | reclen); } +/** + * xs_local_send_request - write an RPC request to an AF_LOCAL socket + * @task: RPC task that manages the state of an RPC request + * + * Return values: + * 0: The request has been sent + * EAGAIN: The socket was blocked, please call again later to + * complete the request + * ENOTCONN: Caller needs to invoke connect logic then call again + * other: Some other error occured, the request was not sent + */ +static int xs_local_send_request(struct rpc_task *task) +{ + struct rpc_rqst *req = task->tk_rqstp; + struct rpc_xprt *xprt = req->rq_xprt; + struct sock_xprt *transport = + container_of(xprt, struct sock_xprt, xprt); + struct xdr_buf *xdr = &req->rq_snd_buf; + int status; + + xs_encode_stream_record_marker(&req->rq_snd_buf); + + xs_pktdump("packet data:", + req->rq_svec->iov_base, req->rq_svec->iov_len); + + status = xs_sendpages(transport->sock, NULL, 0, + xdr, req->rq_bytes_sent); + dprintk("RPC: %s(%u) = %d\n", + __func__, xdr->len - req->rq_bytes_sent, status); + if (likely(status >= 0)) { + req->rq_bytes_sent += status; + req->rq_xmit_bytes_sent += status; + if (likely(req->rq_bytes_sent >= req->rq_slen)) { + req->rq_bytes_sent = 0; + return 0; + } + status = -EAGAIN; + } + + switch (status) { + case -EAGAIN: + status = xs_nospace(task); + break; + default: + dprintk("RPC: sendmsg returned unrecognized error %d\n", + -status); + case -EPIPE: + xs_close(xprt); + status = -ENOTCONN; + } + + return status; +} + /** * xs_udp_send_request - write an RPC request to a UDP socket * @task: address of RPC task that manages the state of an RPC request @@ -788,6 +863,88 @@ static inline struct rpc_xprt *xprt_from_sock(struct sock *sk) return (struct rpc_xprt *) sk->sk_user_data; } +static int xs_local_copy_to_xdr(struct xdr_buf *xdr, struct sk_buff *skb) +{ + struct xdr_skb_reader desc = { + .skb = skb, + .offset = sizeof(rpc_fraghdr), + .count = skb->len - sizeof(rpc_fraghdr), + }; + + if (xdr_partial_copy_from_skb(xdr, 0, &desc, xdr_skb_read_bits) < 0) + return -1; + if (desc.count) + return -1; + return 0; +} + +/** + * xs_local_data_ready - "data ready" callback for AF_LOCAL sockets + * @sk: socket with data to read + * @len: how much data to read + * + * Currently this assumes we can read the whole reply in a single gulp. + */ +static void xs_local_data_ready(struct sock *sk, int len) +{ + struct rpc_task *task; + struct rpc_xprt *xprt; + struct rpc_rqst *rovr; + struct sk_buff *skb; + int err, repsize, copied; + u32 _xid; + __be32 *xp; + + read_lock_bh(&sk->sk_callback_lock); + dprintk("RPC: %s...\n", __func__); + xprt = xprt_from_sock(sk); + if (xprt == NULL) + goto out; + + skb = skb_recv_datagram(sk, 0, 1, &err); + if (skb == NULL) + goto out; + + if (xprt->shutdown) + goto dropit; + + repsize = skb->len - sizeof(rpc_fraghdr); + if (repsize < 4) { + dprintk("RPC: impossible RPC reply size %d\n", repsize); + goto dropit; + } + + /* Copy the XID from the skb... */ + xp = skb_header_pointer(skb, sizeof(rpc_fraghdr), sizeof(_xid), &_xid); + if (xp == NULL) + goto dropit; + + /* Look up and lock the request corresponding to the given XID */ + spin_lock(&xprt->transport_lock); + rovr = xprt_lookup_rqst(xprt, *xp); + if (!rovr) + goto out_unlock; + task = rovr->rq_task; + + copied = rovr->rq_private_buf.buflen; + if (copied > repsize) + copied = repsize; + + if (xs_local_copy_to_xdr(&rovr->rq_private_buf, skb)) { + dprintk("RPC: sk_buff copy failed\n"); + goto out_unlock; + } + + xprt_complete_rqst(task, copied); + + out_unlock: + spin_unlock(&xprt->transport_lock); + dropit: + skb_free_datagram(sk, skb); + out: + read_unlock_bh(&sk->sk_callback_lock); +} + /** * xs_udp_data_ready - "data ready" callback for UDP sockets * @sk: socket with data to read @@ -1573,11 +1730,31 @@ static int xs_bind(struct sock_xprt *transport, struct socket *sock) return err; } +/* + * We don't support autobind on AF_LOCAL sockets + */ +static void xs_local_rpcbind(struct rpc_task *task) +{ + xprt_set_bound(task->tk_xprt); +} + +static void xs_local_set_port(struct rpc_xprt *xprt, unsigned short port) +{ +} #ifdef CONFIG_DEBUG_LOCK_ALLOC static struct lock_class_key xs_key[2]; static struct lock_class_key xs_slock_key[2]; +static inline void xs_reclassify_socketu(struct socket *sock) +{ + struct sock *sk = sock->sk; + + BUG_ON(sock_owned_by_user(sk)); + sock_lock_init_class_and_name(sk, "slock-AF_LOCAL-RPC", + &xs_slock_key[1], "sk_lock-AF_LOCAL-RPC", &xs_key[1]); +} + static inline void xs_reclassify_socket4(struct socket *sock) { struct sock *sk = sock->sk; @@ -1599,6 +1776,9 @@ static inline void xs_reclassify_socket6(struct socket *sock) static inline void xs_reclassify_socket(int family, struct socket *sock) { switch (family) { + case AF_LOCAL: + xs_reclassify_socketu(sock); + break; case AF_INET: xs_reclassify_socket4(sock); break; @@ -1608,6 +1788,10 @@ static inline void xs_reclassify_socket(int family, struct socket *sock) } } #else +static inline void xs_reclassify_socketu(struct socket *sock) +{ +} + static inline void xs_reclassify_socket4(struct socket *sock) { } @@ -1646,6 +1830,94 @@ out: return ERR_PTR(err); } +static int xs_local_finish_connecting(struct rpc_xprt *xprt, + struct socket *sock) +{ + struct sock_xprt *transport = container_of(xprt, struct sock_xprt, + xprt); + + if (!transport->inet) { + struct sock *sk = sock->sk; + + write_lock_bh(&sk->sk_callback_lock); + + xs_save_old_callbacks(transport, sk); + + sk->sk_user_data = xprt; + sk->sk_data_ready = xs_local_data_ready; + sk->sk_write_space = xs_udp_write_space; + sk->sk_error_report = xs_error_report; + sk->sk_allocation = GFP_ATOMIC; + + xprt_clear_connected(xprt); + + /* Reset to new socket */ + transport->sock = sock; + transport->inet = sk; + + write_unlock_bh(&sk->sk_callback_lock); + } + + /* Tell the socket layer to start connecting... */ + xprt->stat.connect_count++; + xprt->stat.connect_start = jiffies; + return kernel_connect(sock, xs_addr(xprt), xprt->addrlen, 0); +} + +/** + * xs_local_setup_socket - create AF_LOCAL socket, connect to a local endpoint + * @xprt: RPC transport to connect + * @transport: socket transport to connect + * @create_sock: function to create a socket of the correct type + * + * Invoked by a work queue tasklet. + */ +static void xs_local_setup_socket(struct work_struct *work) +{ + struct sock_xprt *transport = + container_of(work, struct sock_xprt, connect_worker.work); + struct rpc_xprt *xprt = &transport->xprt; + struct socket *sock; + int status = -EIO; + + if (xprt->shutdown) + goto out; + + clear_bit(XPRT_CONNECTION_ABORT, &xprt->state); + status = __sock_create(xprt->xprt_net, AF_LOCAL, + SOCK_STREAM, 0, &sock, 1); + if (status < 0) { + dprintk("RPC: can't create AF_LOCAL " + "transport socket (%d).\n", -status); + goto out; + } + xs_reclassify_socketu(sock); + + dprintk("RPC: worker connecting xprt %p via AF_LOCAL to %s\n", + xprt, xprt->address_strings[RPC_DISPLAY_ADDR]); + + status = xs_local_finish_connecting(xprt, sock); + switch (status) { + case 0: + dprintk("RPC: xprt %p connected to %s\n", + xprt, xprt->address_strings[RPC_DISPLAY_ADDR]); + xprt_set_connected(xprt); + break; + case -ENOENT: + dprintk("RPC: xprt %p: socket %s does not exist\n", + xprt, xprt->address_strings[RPC_DISPLAY_ADDR]); + break; + default: + printk(KERN_ERR "%s: unhandled error (%d) connecting to %s\n", + __func__, -status, + xprt->address_strings[RPC_DISPLAY_ADDR]); + } + +out: + xprt_clear_connecting(xprt); + xprt_wake_pending_tasks(xprt, status); +} + static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) { struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); @@ -1929,6 +2201,32 @@ static void xs_connect(struct rpc_task *task) } } +/** + * xs_local_print_stats - display AF_LOCAL socket-specifc stats + * @xprt: rpc_xprt struct containing statistics + * @seq: output file + * + */ +static void xs_local_print_stats(struct rpc_xprt *xprt, struct seq_file *seq) +{ + long idle_time = 0; + + if (xprt_connected(xprt)) + idle_time = (long)(jiffies - xprt->last_used) / HZ; + + seq_printf(seq, "\txprt:\tlocal %lu %lu %lu %ld %lu %lu %lu " + "%llu %llu\n", + xprt->stat.bind_count, + xprt->stat.connect_count, + xprt->stat.connect_time, + idle_time, + xprt->stat.sends, + xprt->stat.recvs, + xprt->stat.bad_xids, + xprt->stat.req_u, + xprt->stat.bklog_u); +} + /** * xs_udp_print_stats - display UDP socket-specifc stats * @xprt: rpc_xprt struct containing statistics @@ -2099,6 +2397,21 @@ static void bc_destroy(struct rpc_xprt *xprt) { } +static struct rpc_xprt_ops xs_local_ops = { + .reserve_xprt = xprt_reserve_xprt, + .release_xprt = xs_tcp_release_xprt, + .rpcbind = xs_local_rpcbind, + .set_port = xs_local_set_port, + .connect = xs_connect, + .buf_alloc = rpc_malloc, + .buf_free = rpc_free, + .send_request = xs_local_send_request, + .set_retrans_timeout = xprt_set_retrans_timeout_def, + .close = xs_close, + .destroy = xs_destroy, + .print_stats = xs_local_print_stats, +}; + static struct rpc_xprt_ops xs_udp_ops = { .set_buffer_size = xs_udp_set_buffer_size, .reserve_xprt = xprt_reserve_xprt_cong, @@ -2160,6 +2473,8 @@ static int xs_init_anyaddr(const int family, struct sockaddr *sap) }; switch (family) { + case AF_LOCAL: + break; case AF_INET: memcpy(sap, &sin, sizeof(sin)); break; @@ -2207,6 +2522,70 @@ static struct rpc_xprt *xs_setup_xprt(struct xprt_create *args, return xprt; } +static const struct rpc_timeout xs_local_default_timeout = { + .to_initval = 10 * HZ, + .to_maxval = 10 * HZ, + .to_retries = 2, +}; + +/** + * xs_setup_local - Set up transport to use an AF_LOCAL socket + * @args: rpc transport creation arguments + * + * AF_LOCAL is a "tpi_cots_ord" transport, just like TCP + */ +static struct rpc_xprt *xs_setup_local(struct xprt_create *args) +{ + struct sockaddr_un *sun = (struct sockaddr_un *)args->dstaddr; + struct sock_xprt *transport; + struct rpc_xprt *xprt; + struct rpc_xprt *ret; + + xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries); + if (IS_ERR(xprt)) + return xprt; + transport = container_of(xprt, struct sock_xprt, xprt); + + xprt->prot = 0; + xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32); + xprt->max_payload = RPC_MAX_FRAGMENT_SIZE; + + xprt->bind_timeout = XS_BIND_TO; + xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; + xprt->idle_timeout = XS_IDLE_DISC_TO; + + xprt->ops = &xs_local_ops; + xprt->timeout = &xs_local_default_timeout; + + switch (sun->sun_family) { + case AF_LOCAL: + if (sun->sun_path[0] != '/') { + dprintk("RPC: bad AF_LOCAL address: %s\n", + sun->sun_path); + ret = ERR_PTR(-EINVAL); + goto out_err; + } + xprt_set_bound(xprt); + INIT_DELAYED_WORK(&transport->connect_worker, + xs_local_setup_socket); + xs_format_peer_addresses(xprt, "local", RPCBIND_NETID_LOCAL); + break; + default: + ret = ERR_PTR(-EAFNOSUPPORT); + goto out_err; + } + + dprintk("RPC: set up xprt to %s via AF_LOCAL\n", + xprt->address_strings[RPC_DISPLAY_ADDR]); + + if (try_module_get(THIS_MODULE)) + return xprt; + ret = ERR_PTR(-EINVAL); +out_err: + xprt_free(xprt); + return ret; +} + static const struct rpc_timeout xs_udp_default_timeout = { .to_initval = 5 * HZ, .to_maxval = 30 * HZ, @@ -2448,6 +2827,14 @@ out_err: return ret; } +static struct xprt_class xs_local_transport = { + .list = LIST_HEAD_INIT(xs_local_transport.list), + .name = "named UNIX socket", + .owner = THIS_MODULE, + .ident = XPRT_TRANSPORT_LOCAL, + .setup = xs_setup_local, +}; + static struct xprt_class xs_udp_transport = { .list = LIST_HEAD_INIT(xs_udp_transport.list), .name = "udp", @@ -2483,6 +2870,7 @@ int init_socket_xprt(void) sunrpc_table_header = register_sysctl_table(sunrpc_table); #endif + xprt_register_transport(&xs_local_transport); xprt_register_transport(&xs_udp_transport); xprt_register_transport(&xs_tcp_transport); xprt_register_transport(&xs_bc_tcp_transport); @@ -2503,6 +2891,7 @@ void cleanup_socket_xprt(void) } #endif + xprt_unregister_transport(&xs_local_transport); xprt_unregister_transport(&xs_udp_transport); xprt_unregister_transport(&xs_tcp_transport); xprt_unregister_transport(&xs_bc_tcp_transport); -- cgit From 7c295975a85b049385dfe0d5ee0d4d543619fbdc Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 25 May 2011 16:20:31 -0700 Subject: gpio: make gpio_{request,free}_array gpio array parameter const gpio_{request,free}_array should not (and do not) modify the passed gpio array, so make the parameter const. Signed-off-by: Lars-Peter Clausen Acked-by: Eric Miao Acked-by: Wolfram Sang Signed-off-by: Andrew Morton Signed-off-by: Grant Likely --- drivers/gpio/gpiolib.c | 4 ++-- include/asm-generic/gpio.h | 4 ++-- include/linux/gpio.h | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 137a8ca67822..a971e3d043ba 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1296,7 +1296,7 @@ EXPORT_SYMBOL_GPL(gpio_request_one); * @array: array of the 'struct gpio' * @num: how many GPIOs in the array */ -int gpio_request_array(struct gpio *array, size_t num) +int gpio_request_array(const struct gpio *array, size_t num) { int i, err; @@ -1319,7 +1319,7 @@ EXPORT_SYMBOL_GPL(gpio_request_array); * @array: array of the 'struct gpio' * @num: how many GPIOs in the array */ -void gpio_free_array(struct gpio *array, size_t num) +void gpio_free_array(const struct gpio *array, size_t num) { while (num--) gpio_free((array++)->gpio); diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index a98b52cb970b..fcdcb5d5c995 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -193,8 +193,8 @@ struct gpio { }; extern int gpio_request_one(unsigned gpio, unsigned long flags, const char *label); -extern int gpio_request_array(struct gpio *array, size_t num); -extern void gpio_free_array(struct gpio *array, size_t num); +extern int gpio_request_array(const struct gpio *array, size_t num); +extern void gpio_free_array(const struct gpio *array, size_t num); #ifdef CONFIG_GPIO_SYSFS diff --git a/include/linux/gpio.h b/include/linux/gpio.h index 0f8265f8e8c3..32d47e710661 100644 --- a/include/linux/gpio.h +++ b/include/linux/gpio.h @@ -41,7 +41,7 @@ static inline int gpio_request_one(unsigned gpio, return -ENOSYS; } -static inline int gpio_request_array(struct gpio *array, size_t num) +static inline int gpio_request_array(const struct gpio *array, size_t num) { return -ENOSYS; } @@ -54,7 +54,7 @@ static inline void gpio_free(unsigned gpio) WARN_ON(1); } -static inline void gpio_free_array(struct gpio *array, size_t num) +static inline void gpio_free_array(const struct gpio *array, size_t num) { might_sleep(); -- cgit From 1e1b6c511d1b23cb7c3b619d82fc7bd9f620565d Mon Sep 17 00:00:00 2001 From: KOSAKI Motohiro Date: Thu, 19 May 2011 15:08:58 +0900 Subject: cpuset: Fix cpuset_cpus_allowed_fallback(), don't update tsk->rt.nr_cpus_allowed The rule is, we have to update tsk->rt.nr_cpus_allowed if we change tsk->cpus_allowed. Otherwise RT scheduler may confuse. Signed-off-by: KOSAKI Motohiro Cc: Oleg Nesterov Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/4DD4B3FA.5060901@jp.fujitsu.com Signed-off-by: Ingo Molnar --- include/linux/cpuset.h | 2 +- include/linux/sched.h | 7 +++++++ kernel/cpuset.c | 4 ++-- kernel/kthread.c | 4 ++-- kernel/sched.c | 19 ++++++++++++------- 5 files changed, 24 insertions(+), 12 deletions(-) (limited to 'include/linux') diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h index f20eb8f16025..e9eaec522655 100644 --- a/include/linux/cpuset.h +++ b/include/linux/cpuset.h @@ -146,7 +146,7 @@ static inline void cpuset_cpus_allowed(struct task_struct *p, static inline int cpuset_cpus_allowed_fallback(struct task_struct *p) { - cpumask_copy(&p->cpus_allowed, cpu_possible_mask); + do_set_cpus_allowed(p, cpu_possible_mask); return cpumask_any(cpu_active_mask); } diff --git a/include/linux/sched.h b/include/linux/sched.h index dc8871295a5a..8da84b7bc1b8 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1841,9 +1841,16 @@ static inline void rcu_copy_process(struct task_struct *p) #endif #ifdef CONFIG_SMP +extern void do_set_cpus_allowed(struct task_struct *p, + const struct cpumask *new_mask); + extern int set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask); #else +static inline void do_set_cpus_allowed(struct task_struct *p, + const struct cpumask *new_mask) +{ +} static inline int set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask) { diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 1ceeb049c827..9c9b7545c810 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c @@ -2190,7 +2190,7 @@ int cpuset_cpus_allowed_fallback(struct task_struct *tsk) rcu_read_lock(); cs = task_cs(tsk); if (cs) - cpumask_copy(&tsk->cpus_allowed, cs->cpus_allowed); + do_set_cpus_allowed(tsk, cs->cpus_allowed); rcu_read_unlock(); /* @@ -2217,7 +2217,7 @@ int cpuset_cpus_allowed_fallback(struct task_struct *tsk) * Like above we can temporary set any mask and rely on * set_cpus_allowed_ptr() as synchronization point. */ - cpumask_copy(&tsk->cpus_allowed, cpu_possible_mask); + do_set_cpus_allowed(tsk, cpu_possible_mask); cpu = cpumask_any(cpu_active_mask); } diff --git a/kernel/kthread.c b/kernel/kthread.c index 3b34d2732bce..4ba7cccb4994 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -202,8 +202,8 @@ void kthread_bind(struct task_struct *p, unsigned int cpu) return; } - p->cpus_allowed = cpumask_of_cpu(cpu); - p->rt.nr_cpus_allowed = 1; + /* It's safe because the task is inactive. */ + do_set_cpus_allowed(p, cpumask_of(cpu)); p->flags |= PF_THREAD_BOUND; } EXPORT_SYMBOL(kthread_bind); diff --git a/kernel/sched.c b/kernel/sched.c index a80ee911900e..cbb3a0eee58e 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -5860,7 +5860,7 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu) idle->state = TASK_RUNNING; idle->se.exec_start = sched_clock(); - cpumask_copy(&idle->cpus_allowed, cpumask_of(cpu)); + do_set_cpus_allowed(idle, cpumask_of(cpu)); /* * We're having a chicken and egg problem, even though we are * holding rq->lock, the cpu isn't yet set to this cpu so the @@ -5948,6 +5948,16 @@ static inline void sched_init_granularity(void) } #ifdef CONFIG_SMP +void do_set_cpus_allowed(struct task_struct *p, const struct cpumask *new_mask) +{ + if (p->sched_class && p->sched_class->set_cpus_allowed) + p->sched_class->set_cpus_allowed(p, new_mask); + else { + cpumask_copy(&p->cpus_allowed, new_mask); + p->rt.nr_cpus_allowed = cpumask_weight(new_mask); + } +} + /* * This is how migration works: * @@ -5993,12 +6003,7 @@ int set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask) goto out; } - if (p->sched_class->set_cpus_allowed) - p->sched_class->set_cpus_allowed(p, new_mask); - else { - cpumask_copy(&p->cpus_allowed, new_mask); - p->rt.nr_cpus_allowed = cpumask_weight(new_mask); - } + do_set_cpus_allowed(p, new_mask); /* Can the task run on the task's current CPU? If so, we're done */ if (cpumask_test_cpu(task_cpu(p), new_mask)) -- cgit From 55c2945aa9d4d907ec5ca4f6a4e30ae908d8d30d Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Wed, 11 May 2011 05:33:33 -0700 Subject: atomic: Add atomic_or() An atomic_or() function is needed by TREE_RCU to avoid deadlock, so add a generic version. Signed-off-by: Paul E. McKenney Signed-off-by: Paul E. McKenney Signed-off-by: Ingo Molnar --- include/linux/atomic.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'include/linux') diff --git a/include/linux/atomic.h b/include/linux/atomic.h index 96c038e43d66..ee456c79b0e6 100644 --- a/include/linux/atomic.h +++ b/include/linux/atomic.h @@ -34,4 +34,17 @@ static inline int atomic_inc_not_zero_hint(atomic_t *v, int hint) } #endif +#ifndef CONFIG_ARCH_HAS_ATOMIC_OR +static inline void atomic_or(int i, atomic_t *v) +{ + int old; + int new; + + do { + old = atomic_read(v); + new = old | i; + } while (atomic_cmpxchg(v, old, new) != old); +} +#endif /* #ifndef CONFIG_ARCH_HAS_ATOMIC_OR */ + #endif /* _LINUX_ATOMIC_H */ -- cgit From 69b4573296469fd3f70cf7044693074980517067 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Sat, 28 May 2011 08:25:51 -0700 Subject: Cache xattr security drop check for write v2 Some recent benchmarking on btrfs showed that a major scaling bottleneck on large systems on btrfs is currently the xattr lookup on every write. Why xattr lookup on every write I hear you ask? write wants to drop suid and security related xattrs that could set o capabilities for executables. To do that it currently looks up security.capability on EVERY write (even for non executables) to decide whether to drop it or not. In btrfs this causes an additional tree walk, hitting some per file system locks and quite bad scalability. In a simple read workload on a 8S system I saw over 90% CPU time in spinlocks related to that. Chris Mason tells me this is also a problem in ext4, where it hits the global mbcache lock. This patch adds a simple per inode to avoid this problem. We only do the lookup once per file and then if there is no xattr cache the decision. All xattr changes clear the flag. I also used the same flag to avoid the suid check, although that one is pretty cheap. A file system can also set this flag when it creates the inode, if it has a cheap way to do so. This is done for some common file systems in followon patches. With this patch a major part of the lock contention disappears for btrfs. Some testing on smaller systems didn't show significant performance changes, but at least it helps the larger systems and is generally more efficient. v2: Rename is_sgid. add file system helper. Cc: chris.mason@oracle.com Cc: josef@redhat.com Cc: viro@zeniv.linux.org.uk Cc: agruen@linbit.com Cc: Serge E. Hallyn Signed-off-by: Andi Kleen Signed-off-by: Al Viro --- fs/attr.c | 7 +++++++ fs/xattr.c | 7 +++++-- include/linux/fs.h | 13 +++++++++++++ mm/filemap.c | 14 ++++++++++++-- 4 files changed, 37 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/fs/attr.c b/fs/attr.c index 91dbe2a107f2..caf2aa521e2b 100644 --- a/fs/attr.c +++ b/fs/attr.c @@ -175,6 +175,13 @@ int notify_change(struct dentry * dentry, struct iattr * attr) return -EPERM; } + if ((ia_valid & ATTR_MODE)) { + mode_t amode = attr->ia_mode; + /* Flag setting protected by i_mutex */ + if (is_sxid(amode)) + inode->i_flags &= ~S_NOSEC; + } + now = current_fs_time(inode->i_sb); attr->ia_ctime = now; diff --git a/fs/xattr.c b/fs/xattr.c index 4be2e7666d02..f060663ab70c 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -91,7 +91,11 @@ int __vfs_setxattr_noperm(struct dentry *dentry, const char *name, { struct inode *inode = dentry->d_inode; int error = -EOPNOTSUPP; + int issec = !strncmp(name, XATTR_SECURITY_PREFIX, + XATTR_SECURITY_PREFIX_LEN); + if (issec) + inode->i_flags &= ~S_NOSEC; if (inode->i_op->setxattr) { error = inode->i_op->setxattr(dentry, name, value, size, flags); if (!error) { @@ -99,8 +103,7 @@ int __vfs_setxattr_noperm(struct dentry *dentry, const char *name, security_inode_post_setxattr(dentry, name, value, size, flags); } - } else if (!strncmp(name, XATTR_SECURITY_PREFIX, - XATTR_SECURITY_PREFIX_LEN)) { + } else if (issec) { const char *suffix = name + XATTR_SECURITY_PREFIX_LEN; error = security_inode_setsecurity(inode, suffix, value, size, flags); diff --git a/include/linux/fs.h b/include/linux/fs.h index 573028df050d..c55d6b7cd5d6 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -237,6 +237,7 @@ struct inodes_stat_t { #define S_PRIVATE 512 /* Inode is fs-internal */ #define S_IMA 1024 /* Inode has an associated IMA struct */ #define S_AUTOMOUNT 2048 /* Automount/referral quasi-directory */ +#define S_NOSEC 4096 /* no suid or xattr security attributes */ /* * Note that nosuid etc flags are inode-specific: setting some file-system @@ -273,6 +274,7 @@ struct inodes_stat_t { #define IS_PRIVATE(inode) ((inode)->i_flags & S_PRIVATE) #define IS_IMA(inode) ((inode)->i_flags & S_IMA) #define IS_AUTOMOUNT(inode) ((inode)->i_flags & S_AUTOMOUNT) +#define IS_NOSEC(inode) ((inode)->i_flags & S_NOSEC) /* the read-only stuff doesn't really belong here, but any other place is probably as bad and I don't want to create yet another include file. */ @@ -2582,5 +2584,16 @@ int __init get_filesystem_list(char *buf); #define OPEN_FMODE(flag) ((__force fmode_t)(((flag + 1) & O_ACCMODE) | \ (flag & __FMODE_NONOTIFY))) +static inline int is_sxid(mode_t mode) +{ + return (mode & S_ISUID) || ((mode & S_ISGID) && (mode & S_IXGRP)); +} + +static inline void inode_has_no_xattr(struct inode *inode) +{ + if (!is_sxid(inode->i_mode)) + inode->i_flags |= S_NOSEC; +} + #endif /* __KERNEL__ */ #endif /* _LINUX_FS_H */ diff --git a/mm/filemap.c b/mm/filemap.c index dac95a24deac..d7b10578a64b 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1982,16 +1982,26 @@ static int __remove_suid(struct dentry *dentry, int kill) int file_remove_suid(struct file *file) { struct dentry *dentry = file->f_path.dentry; - int killsuid = should_remove_suid(dentry); - int killpriv = security_inode_need_killpriv(dentry); + struct inode *inode = dentry->d_inode; + int killsuid; + int killpriv; int error = 0; + /* Fast path for nothing security related */ + if (IS_NOSEC(inode)) + return 0; + + killsuid = should_remove_suid(dentry); + killpriv = security_inode_need_killpriv(dentry); + if (killpriv < 0) return killpriv; if (killpriv) error = security_inode_killpriv(dentry); if (!error && killsuid) error = __remove_suid(dentry, killsuid); + if (!error) + inode->i_flags |= S_NOSEC; return error; } -- cgit From 333c5ae9948194428fe6c5ef5c088304fc98263b Mon Sep 17 00:00:00 2001 From: Tim Chen Date: Fri, 11 Feb 2011 12:49:04 -0800 Subject: idle governor: Avoid lock acquisition to read pm_qos before entering idle Thanks to the reviews and comments by Rafael, James, Mark and Andi. Here's version 2 of the patch incorporating your comments and also some update to my previous patch comments. I noticed that before entering idle state, the menu idle governor will look up the current pm_qos target value according to the list of qos requests received. This look up currently needs the acquisition of a lock to access the list of qos requests to find the qos target value, slowing down the entrance into idle state due to contention by multiple cpus to access this list. The contention is severe when there are a lot of cpus waking and going into idle. For example, for a simple workload that has 32 pair of processes ping ponging messages to each other, where 64 cpu cores are active in test system, I see the following profile with 37.82% of cpu cycles spent in contention of pm_qos_lock: - 37.82% swapper [kernel.kallsyms] [k] _raw_spin_lock_irqsave - _raw_spin_lock_irqsave - 95.65% pm_qos_request menu_select cpuidle_idle_call - cpu_idle 99.98% start_secondary A better approach will be to cache the updated pm_qos target value so reading it does not require lock acquisition as in the patch below. With this patch the contention for pm_qos_lock is removed and I saw a 2.2X increase in throughput for my message passing workload. cc: stable@kernel.org Signed-off-by: Tim Chen Acked-by: Andi Kleen Acked-by: James Bottomley Acked-by: mark gross Signed-off-by: Len Brown --- include/linux/pm_qos_params.h | 4 ++++ kernel/pm_qos_params.c | 37 +++++++++++++++++++++++++------------ 2 files changed, 29 insertions(+), 12 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pm_qos_params.h b/include/linux/pm_qos_params.h index 77cbddb3784c..a7d87f911cab 100644 --- a/include/linux/pm_qos_params.h +++ b/include/linux/pm_qos_params.h @@ -16,6 +16,10 @@ #define PM_QOS_NUM_CLASSES 4 #define PM_QOS_DEFAULT_VALUE -1 +#define PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC) +#define PM_QOS_NETWORK_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC) +#define PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE 0 + struct pm_qos_request_list { struct plist_node list; int pm_qos_class; diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c index aeaa7f846821..6a8fad82a3ad 100644 --- a/kernel/pm_qos_params.c +++ b/kernel/pm_qos_params.c @@ -53,11 +53,17 @@ enum pm_qos_type { PM_QOS_MIN /* return the smallest value */ }; +/* + * Note: The lockless read path depends on the CPU accessing + * target_value atomically. Atomic access is only guaranteed on all CPU + * types linux supports for 32 bit quantites + */ struct pm_qos_object { struct plist_head requests; struct blocking_notifier_head *notifiers; struct miscdevice pm_qos_power_miscdev; char *name; + s32 target_value; /* Do not change to 64 bit */ s32 default_value; enum pm_qos_type type; }; @@ -70,7 +76,8 @@ static struct pm_qos_object cpu_dma_pm_qos = { .requests = PLIST_HEAD_INIT(cpu_dma_pm_qos.requests, pm_qos_lock), .notifiers = &cpu_dma_lat_notifier, .name = "cpu_dma_latency", - .default_value = 2000 * USEC_PER_SEC, + .target_value = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE, + .default_value = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE, .type = PM_QOS_MIN, }; @@ -79,7 +86,8 @@ static struct pm_qos_object network_lat_pm_qos = { .requests = PLIST_HEAD_INIT(network_lat_pm_qos.requests, pm_qos_lock), .notifiers = &network_lat_notifier, .name = "network_latency", - .default_value = 2000 * USEC_PER_SEC, + .target_value = PM_QOS_NETWORK_LAT_DEFAULT_VALUE, + .default_value = PM_QOS_NETWORK_LAT_DEFAULT_VALUE, .type = PM_QOS_MIN }; @@ -89,7 +97,8 @@ static struct pm_qos_object network_throughput_pm_qos = { .requests = PLIST_HEAD_INIT(network_throughput_pm_qos.requests, pm_qos_lock), .notifiers = &network_throughput_notifier, .name = "network_throughput", - .default_value = 0, + .target_value = PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE, + .default_value = PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE, .type = PM_QOS_MAX, }; @@ -132,6 +141,16 @@ static inline int pm_qos_get_value(struct pm_qos_object *o) } } +static inline s32 pm_qos_read_value(struct pm_qos_object *o) +{ + return o->target_value; +} + +static inline void pm_qos_set_value(struct pm_qos_object *o, s32 value) +{ + o->target_value = value; +} + static void update_target(struct pm_qos_object *o, struct plist_node *node, int del, int value) { @@ -156,6 +175,7 @@ static void update_target(struct pm_qos_object *o, struct plist_node *node, plist_add(node, &o->requests); } curr_value = pm_qos_get_value(o); + pm_qos_set_value(o, curr_value); spin_unlock_irqrestore(&pm_qos_lock, flags); if (prev_value != curr_value) @@ -190,18 +210,11 @@ static int find_pm_qos_object_by_minor(int minor) * pm_qos_request - returns current system wide qos expectation * @pm_qos_class: identification of which qos value is requested * - * This function returns the current target value in an atomic manner. + * This function returns the current target value. */ int pm_qos_request(int pm_qos_class) { - unsigned long flags; - int value; - - spin_lock_irqsave(&pm_qos_lock, flags); - value = pm_qos_get_value(pm_qos_array[pm_qos_class]); - spin_unlock_irqrestore(&pm_qos_lock, flags); - - return value; + return pm_qos_read_value(pm_qos_array[pm_qos_class]); } EXPORT_SYMBOL_GPL(pm_qos_request); -- cgit From a43a9d93d40a69eceeb4e4a4c860cc20186d475c Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Sun, 29 May 2011 12:40:50 +0200 Subject: [S390] mm: fix storage key handling page_get_storage_key() and page_set_storage_key() expect a page address and not its page frame number. This got inconsistent with 2d42552d "[S390] merge page_test_dirty and page_clear_dirty". Result is that we read/write storage keys from random pages and do not have a working dirty bit tracking at all. E.g. SetPageUpdate() doesn't clear the dirty bit of requested pages, which for example ext4 doesn't like very much and panics after a while. Unable to handle kernel paging request at virtual user address (null) Oops: 0004 [#1] PREEMPT SMP DEBUG_PAGEALLOC Modules linked in: CPU: 1 Not tainted 2.6.39-07551-g139f37f-dirty #152 Process flush-94:0 (pid: 1576, task: 000000003eb34538, ksp: 000000003c287b70) Krnl PSW : 0704c00180000000 0000000000316b12 (jbd2_journal_file_inode+0x10e/0x138) R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:3 CC:0 PM:0 EA:3 Krnl GPRS: 0000000000000000 0000000000000000 0000000000000000 0700000000000000 0000000000316a62 000000003eb34cd0 0000000000000025 000000003c287b88 0000000000000001 000000003c287a70 000000003f1ec678 000000003f1ec000 0000000000000000 000000003e66ec00 0000000000316a62 000000003c287988 Krnl Code: 0000000000316b04: f0a0000407f4 srp 4(11,%r0),2036,0 0000000000316b0a: b9020022 ltgr %r2,%r2 0000000000316b0e: a7740015 brc 7,316b38 >0000000000316b12: e3d0c0000024 stg %r13,0(%r12) 0000000000316b18: 4120c010 la %r2,16(%r12) 0000000000316b1c: 4130d060 la %r3,96(%r13) 0000000000316b20: e340d0600004 lg %r4,96(%r13) 0000000000316b26: c0e50002b567 brasl %r14,36d5f4 Call Trace: ([<0000000000316a62>] jbd2_journal_file_inode+0x5e/0x138) [<00000000002da13c>] mpage_da_map_and_submit+0x2e8/0x42c [<00000000002daac2>] ext4_da_writepages+0x2da/0x504 [<00000000002597e8>] writeback_single_inode+0xf8/0x268 [<0000000000259f06>] writeback_sb_inodes+0xd2/0x18c [<000000000025a700>] writeback_inodes_wb+0x80/0x168 [<000000000025aa92>] wb_writeback+0x2aa/0x324 [<000000000025abde>] wb_do_writeback+0xd2/0x274 [<000000000025ae3a>] bdi_writeback_thread+0xba/0x1c4 [<00000000001737be>] kthread+0xa6/0xb0 [<000000000056c1da>] kernel_thread_starter+0x6/0xc [<000000000056c1d4>] kernel_thread_starter+0x0/0xc INFO: lockdep is turned off. Last Breaking-Event-Address: [<0000000000316a8a>] jbd2_journal_file_inode+0x86/0x138 Reported-by: Sebastian Ott Signed-off-by: Heiko Carstens --- arch/s390/include/asm/pgtable.h | 16 ++++++++-------- include/linux/page-flags.h | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'include/linux') diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index c4773a2ef3d3..e4efacfe1b63 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -577,16 +577,16 @@ static inline void pgste_set_unlock(pte_t *ptep, pgste_t pgste) static inline pgste_t pgste_update_all(pte_t *ptep, pgste_t pgste) { #ifdef CONFIG_PGSTE - unsigned long pfn, bits; + unsigned long address, bits; unsigned char skey; - pfn = pte_val(*ptep) >> PAGE_SHIFT; - skey = page_get_storage_key(pfn); + address = pte_val(*ptep) & PAGE_MASK; + skey = page_get_storage_key(address); bits = skey & (_PAGE_CHANGED | _PAGE_REFERENCED); /* Clear page changed & referenced bit in the storage key */ if (bits) { skey ^= bits; - page_set_storage_key(pfn, skey, 1); + page_set_storage_key(address, skey, 1); } /* Transfer page changed & referenced bit to guest bits in pgste */ pgste_val(pgste) |= bits << 48; /* RCP_GR_BIT & RCP_GC_BIT */ @@ -628,16 +628,16 @@ static inline pgste_t pgste_update_young(pte_t *ptep, pgste_t pgste) static inline void pgste_set_pte(pte_t *ptep, pgste_t pgste) { #ifdef CONFIG_PGSTE - unsigned long pfn; + unsigned long address; unsigned long okey, nkey; - pfn = pte_val(*ptep) >> PAGE_SHIFT; - okey = nkey = page_get_storage_key(pfn); + address = pte_val(*ptep) & PAGE_MASK; + okey = nkey = page_get_storage_key(address); nkey &= ~(_PAGE_ACC_BITS | _PAGE_FP_BIT); /* Set page access key and fetch protection bit from pgste */ nkey |= (pgste_val(pgste) & (RCP_ACC_BITS | RCP_FP_BIT)) >> 56; if (okey != nkey) - page_set_storage_key(pfn, nkey, 1); + page_set_storage_key(address, nkey, 1); #endif } diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index 79a6700b7162..6081493db68f 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h @@ -308,7 +308,7 @@ static inline void SetPageUptodate(struct page *page) { #ifdef CONFIG_S390 if (!test_and_set_bit(PG_uptodate, &page->flags)) - page_set_storage_key(page_to_pfn(page), PAGE_DEFAULT_KEY, 0); + page_set_storage_key(page_to_phys(page), PAGE_DEFAULT_KEY, 0); #else /* * Memory barrier must be issued before setting the PG_uptodate bit, -- cgit From 4c2593270133708698d4b8cea2dab469479ad13b Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Sun, 29 May 2011 12:52:55 +0100 Subject: dm table: allow targets to support discards internally Permit a target to support discards regardless of whether or not all its underlying devices do. Signed-off-by: Mike Snitzer Signed-off-by: Alasdair G Kergon --- drivers/md/dm-table.c | 6 +++++- include/linux/device-mapper.h | 6 ++++++ 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index cb8380c9767f..215e112d153e 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -1346,7 +1346,8 @@ bool dm_table_supports_discards(struct dm_table *t) return 0; /* - * Ensure that at least one underlying device supports discards. + * Unless any target used by the table set discards_supported, + * require at least one underlying device to support discards. * t->devices includes internal dm devices such as mirror logs * so we need to use iterate_devices here, which targets * supporting discard must provide. @@ -1354,6 +1355,9 @@ bool dm_table_supports_discards(struct dm_table *t) while (i < dm_table_get_num_targets(t)) { ti = dm_table_get_target(t, i++); + if (ti->discards_supported) + return 1; + if (ti->type->iterate_devices && ti->type->iterate_devices(ti, device_discard_capable, NULL)) return 1; diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 32a4423710f5..4427e0454051 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -191,6 +191,12 @@ struct dm_target { /* Used to provide an error string from the ctr */ char *error; + + /* + * Set if this target needs to receive discards regardless of + * whether or not its underlying devices have support. + */ + unsigned discards_supported:1; }; /* Each target can link one of these into the table */ -- cgit From bda8efec5c706a672e0714d341a342e811f0262a Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Sun, 29 May 2011 13:03:09 +0100 Subject: dm io: use fixed initial mempool size Replace the arbitrary calculation of an initial io struct mempool size with a constant. The code calculated the number of reserved structures based on the request size and used a "magic" multiplication constant of 4. This patch changes it to reserve a fixed number - itself still chosen quite arbitrarily. Further testing might show if there is a better number to choose. Note that if there is no memory pressure, we can still allocate an arbitrary number of "struct io" structures. One structure is enough to process the whole request. Signed-off-by: Mikulas Patocka Signed-off-by: Alasdair G Kergon --- drivers/md/dm-io.c | 27 +++++---------------------- drivers/md/dm-kcopyd.c | 2 +- drivers/md/dm-log.c | 3 +-- drivers/md/dm-raid1.c | 3 +-- drivers/md/dm-snap-persistent.c | 13 +------------ include/linux/dm-io.h | 3 +-- 6 files changed, 10 insertions(+), 41 deletions(-) (limited to 'include/linux') diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c index 76a5af00a26b..2067288f61f9 100644 --- a/drivers/md/dm-io.c +++ b/drivers/md/dm-io.c @@ -19,6 +19,8 @@ #define DM_MSG_PREFIX "io" #define DM_IO_MAX_REGIONS BITS_PER_LONG +#define MIN_IOS 16 +#define MIN_BIOS 16 struct dm_io_client { mempool_t *pool; @@ -40,34 +42,22 @@ struct io { static struct kmem_cache *_dm_io_cache; -/* - * io contexts are only dynamically allocated for asynchronous - * io. Since async io is likely to be the majority of io we'll - * have the same number of io contexts as bios! (FIXME: must reduce this). - */ - -static unsigned int pages_to_ios(unsigned int pages) -{ - return 4 * pages; /* too many ? */ -} - /* * Create a client with mempool and bioset. */ -struct dm_io_client *dm_io_client_create(unsigned num_pages) +struct dm_io_client *dm_io_client_create(void) { - unsigned ios = pages_to_ios(num_pages); struct dm_io_client *client; client = kmalloc(sizeof(*client), GFP_KERNEL); if (!client) return ERR_PTR(-ENOMEM); - client->pool = mempool_create_slab_pool(ios, _dm_io_cache); + client->pool = mempool_create_slab_pool(MIN_IOS, _dm_io_cache); if (!client->pool) goto bad; - client->bios = bioset_create(16, 0); + client->bios = bioset_create(MIN_BIOS, 0); if (!client->bios) goto bad; @@ -81,13 +71,6 @@ struct dm_io_client *dm_io_client_create(unsigned num_pages) } EXPORT_SYMBOL(dm_io_client_create); -int dm_io_client_resize(unsigned num_pages, struct dm_io_client *client) -{ - return mempool_resize(client->pool, pages_to_ios(num_pages), - GFP_KERNEL); -} -EXPORT_SYMBOL(dm_io_client_resize); - void dm_io_client_destroy(struct dm_io_client *client) { mempool_destroy(client->pool); diff --git a/drivers/md/dm-kcopyd.c b/drivers/md/dm-kcopyd.c index 5dfbdcb40a47..719693340d1d 100644 --- a/drivers/md/dm-kcopyd.c +++ b/drivers/md/dm-kcopyd.c @@ -667,7 +667,7 @@ int dm_kcopyd_client_create(unsigned min_pages, if (r) goto bad_client_pages; - kc->io_client = dm_io_client_create(min_pages); + kc->io_client = dm_io_client_create(); if (IS_ERR(kc->io_client)) { r = PTR_ERR(kc->io_client); goto bad_io_client; diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c index a1f321889676..948e3f4925bf 100644 --- a/drivers/md/dm-log.c +++ b/drivers/md/dm-log.c @@ -449,8 +449,7 @@ static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti, lc->io_req.mem.type = DM_IO_VMA; lc->io_req.notify.fn = NULL; - lc->io_req.client = dm_io_client_create(dm_div_up(buf_size, - PAGE_SIZE)); + lc->io_req.client = dm_io_client_create(); if (IS_ERR(lc->io_req.client)) { r = PTR_ERR(lc->io_req.client); DMWARN("couldn't allocate disk io client"); diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 976ad4688afc..53089aa11387 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -22,7 +22,6 @@ #define DM_MSG_PREFIX "raid1" #define MAX_RECOVERY 1 /* Maximum number of regions recovered in parallel. */ -#define DM_IO_PAGES 64 #define DM_KCOPYD_PAGES 64 #define DM_RAID1_HANDLE_ERRORS 0x01 @@ -887,7 +886,7 @@ static struct mirror_set *alloc_context(unsigned int nr_mirrors, return NULL; } - ms->io_client = dm_io_client_create(DM_IO_PAGES); + ms->io_client = dm_io_client_create(); if (IS_ERR(ms->io_client)) { ti->error = "Error creating dm_io client"; mempool_destroy(ms->read_record_pool); diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c index 95891dfcbca0..135c2f1fdbfc 100644 --- a/drivers/md/dm-snap-persistent.c +++ b/drivers/md/dm-snap-persistent.c @@ -154,11 +154,6 @@ struct pstore { struct workqueue_struct *metadata_wq; }; -static unsigned sectors_to_pages(unsigned sectors) -{ - return DIV_ROUND_UP(sectors, PAGE_SIZE >> 9); -} - static int alloc_area(struct pstore *ps) { int r = -ENOMEM; @@ -318,8 +313,7 @@ static int read_header(struct pstore *ps, int *new_snapshot) chunk_size_supplied = 0; } - ps->io_client = dm_io_client_create(sectors_to_pages(ps->store-> - chunk_size)); + ps->io_client = dm_io_client_create(); if (IS_ERR(ps->io_client)) return PTR_ERR(ps->io_client); @@ -368,11 +362,6 @@ static int read_header(struct pstore *ps, int *new_snapshot) return r; } - r = dm_io_client_resize(sectors_to_pages(ps->store->chunk_size), - ps->io_client); - if (r) - return r; - r = alloc_area(ps); return r; diff --git a/include/linux/dm-io.h b/include/linux/dm-io.h index 5c9186b93fff..f4b0aa3126f5 100644 --- a/include/linux/dm-io.h +++ b/include/linux/dm-io.h @@ -69,8 +69,7 @@ struct dm_io_request { * * Create/destroy may block. */ -struct dm_io_client *dm_io_client_create(unsigned num_pages); -int dm_io_client_resize(unsigned num_pages, struct dm_io_client *client); +struct dm_io_client *dm_io_client_create(void); void dm_io_client_destroy(struct dm_io_client *client); /* -- cgit From 5f43ba2950414dc0abf4ac44c397d88069056746 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Sun, 29 May 2011 13:03:11 +0100 Subject: dm kcopyd: reserve fewer pages Reserve just the minimum of pages needed to process one job. Because we allocate pages from page allocator, we don't need to reserve a large number of pages. The maximum job size is SUB_JOB_SIZE and we calculate the number of reserved pages based on this. Signed-off-by: Mikulas Patocka Signed-off-by: Alasdair G Kergon --- drivers/md/dm-kcopyd.c | 6 +++--- drivers/md/dm-raid1.c | 3 +-- drivers/md/dm-snap.c | 7 +------ include/linux/dm-kcopyd.h | 3 +-- 4 files changed, 6 insertions(+), 13 deletions(-) (limited to 'include/linux') diff --git a/drivers/md/dm-kcopyd.c b/drivers/md/dm-kcopyd.c index 719693340d1d..579647f8b4d2 100644 --- a/drivers/md/dm-kcopyd.c +++ b/drivers/md/dm-kcopyd.c @@ -30,6 +30,7 @@ #define SUB_JOB_SIZE 128 #define SPLIT_COUNT 8 #define MIN_JOBS 8 +#define RESERVE_PAGES (DIV_ROUND_UP(SUB_JOB_SIZE << SECTOR_SHIFT, PAGE_SIZE)) /*----------------------------------------------------------------- * Each kcopyd client has its own little pool of preallocated @@ -636,8 +637,7 @@ int kcopyd_cancel(struct kcopyd_job *job, int block) /*----------------------------------------------------------------- * Client setup *---------------------------------------------------------------*/ -int dm_kcopyd_client_create(unsigned min_pages, - struct dm_kcopyd_client **result) +int dm_kcopyd_client_create(struct dm_kcopyd_client **result) { int r = -ENOMEM; struct dm_kcopyd_client *kc; @@ -663,7 +663,7 @@ int dm_kcopyd_client_create(unsigned min_pages, kc->pages = NULL; kc->nr_reserved_pages = kc->nr_free_pages = 0; - r = client_reserve_pages(kc, min_pages); + r = client_reserve_pages(kc, RESERVE_PAGES); if (r) goto bad_client_pages; diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 53089aa11387..9defad045418 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -22,7 +22,6 @@ #define DM_MSG_PREFIX "raid1" #define MAX_RECOVERY 1 /* Maximum number of regions recovered in parallel. */ -#define DM_KCOPYD_PAGES 64 #define DM_RAID1_HANDLE_ERRORS 0x01 #define errors_handled(p) ((p)->features & DM_RAID1_HANDLE_ERRORS) @@ -1116,7 +1115,7 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv) goto err_destroy_wq; } - r = dm_kcopyd_client_create(DM_KCOPYD_PAGES, &ms->kcopyd_client); + r = dm_kcopyd_client_create(&ms->kcopyd_client); if (r) goto err_destroy_wq; diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index a2d330942cb2..5a2296de84a3 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -39,11 +39,6 @@ static const char dm_snapshot_merge_target_name[] = "snapshot-merge"; */ #define SNAPSHOT_COPY_PRIORITY 2 -/* - * Reserve 1MB for each snapshot initially (with minimum of 1 page). - */ -#define SNAPSHOT_PAGES (((1UL << 20) >> PAGE_SHIFT) ? : 1) - /* * The size of the mempool used to track chunks in use. */ @@ -1116,7 +1111,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) goto bad_hash_tables; } - r = dm_kcopyd_client_create(SNAPSHOT_PAGES, &s->kcopyd_client); + r = dm_kcopyd_client_create(&s->kcopyd_client); if (r) { ti->error = "Could not create kcopyd client"; goto bad_kcopyd; diff --git a/include/linux/dm-kcopyd.h b/include/linux/dm-kcopyd.h index 5db216311695..312513d4741a 100644 --- a/include/linux/dm-kcopyd.h +++ b/include/linux/dm-kcopyd.h @@ -25,8 +25,7 @@ * To use kcopyd you must first create a dm_kcopyd_client object. */ struct dm_kcopyd_client; -int dm_kcopyd_client_create(unsigned num_pages, - struct dm_kcopyd_client **result); +int dm_kcopyd_client_create(struct dm_kcopyd_client **result); void dm_kcopyd_client_destroy(struct dm_kcopyd_client *kc); /* -- cgit From fa34ce73072f90ecd90dcc43f29d82e70e5f8676 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Sun, 29 May 2011 13:03:13 +0100 Subject: dm kcopyd: return client directly and not through a pointer Return client directly from dm_kcopyd_client_create, not through a parameter, making it consistent with dm_io_client_create. Signed-off-by: Mikulas Patocka Signed-off-by: Alasdair G Kergon --- drivers/md/dm-kcopyd.c | 9 ++++----- drivers/md/dm-raid1.c | 6 ++++-- drivers/md/dm-snap.c | 5 +++-- include/linux/dm-kcopyd.h | 2 +- 4 files changed, 12 insertions(+), 10 deletions(-) (limited to 'include/linux') diff --git a/drivers/md/dm-kcopyd.c b/drivers/md/dm-kcopyd.c index 579647f8b4d2..819e37eaaeba 100644 --- a/drivers/md/dm-kcopyd.c +++ b/drivers/md/dm-kcopyd.c @@ -637,14 +637,14 @@ int kcopyd_cancel(struct kcopyd_job *job, int block) /*----------------------------------------------------------------- * Client setup *---------------------------------------------------------------*/ -int dm_kcopyd_client_create(struct dm_kcopyd_client **result) +struct dm_kcopyd_client *dm_kcopyd_client_create(void) { int r = -ENOMEM; struct dm_kcopyd_client *kc; kc = kmalloc(sizeof(*kc), GFP_KERNEL); if (!kc) - return -ENOMEM; + return ERR_PTR(-ENOMEM); spin_lock_init(&kc->job_lock); INIT_LIST_HEAD(&kc->complete_jobs); @@ -676,8 +676,7 @@ int dm_kcopyd_client_create(struct dm_kcopyd_client **result) init_waitqueue_head(&kc->destroyq); atomic_set(&kc->nr_jobs, 0); - *result = kc; - return 0; + return kc; bad_io_client: client_free_pages(kc); @@ -688,7 +687,7 @@ bad_workqueue: bad_slab: kfree(kc); - return r; + return ERR_PTR(r); } EXPORT_SYMBOL(dm_kcopyd_client_create); diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 9defad045418..9bfd057be686 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -1115,9 +1115,11 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv) goto err_destroy_wq; } - r = dm_kcopyd_client_create(&ms->kcopyd_client); - if (r) + ms->kcopyd_client = dm_kcopyd_client_create(); + if (IS_ERR(ms->kcopyd_client)) { + r = PTR_ERR(ms->kcopyd_client); goto err_destroy_wq; + } wakeup_mirrord(ms); return 0; diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 5a2296de84a3..9ecff5f3023a 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -1111,8 +1111,9 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) goto bad_hash_tables; } - r = dm_kcopyd_client_create(&s->kcopyd_client); - if (r) { + s->kcopyd_client = dm_kcopyd_client_create(); + if (IS_ERR(s->kcopyd_client)) { + r = PTR_ERR(s->kcopyd_client); ti->error = "Could not create kcopyd client"; goto bad_kcopyd; } diff --git a/include/linux/dm-kcopyd.h b/include/linux/dm-kcopyd.h index 312513d4741a..298d587e349b 100644 --- a/include/linux/dm-kcopyd.h +++ b/include/linux/dm-kcopyd.h @@ -25,7 +25,7 @@ * To use kcopyd you must first create a dm_kcopyd_client object. */ struct dm_kcopyd_client; -int dm_kcopyd_client_create(struct dm_kcopyd_client **result); +struct dm_kcopyd_client *dm_kcopyd_client_create(void); void dm_kcopyd_client_destroy(struct dm_kcopyd_client *kc); /* -- cgit From f7da7a129d57bfe0f74573dc03531c63e1360fae Mon Sep 17 00:00:00 2001 From: Benny Halevy Date: Thu, 19 May 2011 14:16:47 -0400 Subject: SUNRPC: introduce xdr_init_decode_pages Initialize xdr_stream and xdr_buf using an array of page pointers and length of buffer. Signed-off-by: Benny Halevy --- fs/nfs/dir.c | 9 ++------- fs/nfs/nfs4filelayout.c | 9 ++------- fs/nfs/nfs4filelayoutdev.c | 9 ++------- include/linux/sunrpc/xdr.h | 2 ++ net/sunrpc/xdr.c | 19 +++++++++++++++++++ 5 files changed, 27 insertions(+), 21 deletions(-) (limited to 'include/linux') diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 7237672216c8..f673a9e1d95d 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -512,12 +512,7 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en struct page **xdr_pages, struct page *page, unsigned int buflen) { struct xdr_stream stream; - struct xdr_buf buf = { - .pages = xdr_pages, - .page_len = buflen, - .buflen = buflen, - .len = buflen, - }; + struct xdr_buf buf; struct page *scratch; struct nfs_cache_array *array; unsigned int count = 0; @@ -527,7 +522,7 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en if (scratch == NULL) return -ENOMEM; - xdr_init_decode(&stream, &buf, NULL); + xdr_init_decode_pages(&stream, &buf, xdr_pages, buflen); xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE); do { diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c index 501a9b86b318..33bda24e8cd2 100644 --- a/fs/nfs/nfs4filelayout.c +++ b/fs/nfs/nfs4filelayout.c @@ -510,12 +510,7 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo, gfp_t gfp_flags) { struct xdr_stream stream; - struct xdr_buf buf = { - .pages = lgr->layoutp->pages, - .page_len = lgr->layoutp->len, - .buflen = lgr->layoutp->len, - .len = lgr->layoutp->len, - }; + struct xdr_buf buf; struct page *scratch; __be32 *p; uint32_t nfl_util; @@ -527,7 +522,7 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo, if (!scratch) return -ENOMEM; - xdr_init_decode(&stream, &buf, NULL); + xdr_init_decode_pages(&stream, &buf, lgr->layoutp->pages, lgr->layoutp->len); xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE); /* 20 = ufl_util (4), first_stripe_index (4), pattern_offset (8), diff --git a/fs/nfs/nfs4filelayoutdev.c b/fs/nfs/nfs4filelayoutdev.c index 5914659c8ec5..3b7bf1377264 100644 --- a/fs/nfs/nfs4filelayoutdev.c +++ b/fs/nfs/nfs4filelayoutdev.c @@ -308,12 +308,7 @@ decode_device(struct inode *ino, struct pnfs_device *pdev, gfp_t gfp_flags) u8 max_stripe_index; struct nfs4_file_layout_dsaddr *dsaddr = NULL; struct xdr_stream stream; - struct xdr_buf buf = { - .pages = pdev->pages, - .page_len = pdev->pglen, - .buflen = pdev->pglen, - .len = pdev->pglen, - }; + struct xdr_buf buf; struct page *scratch; /* set up xdr stream */ @@ -321,7 +316,7 @@ decode_device(struct inode *ino, struct pnfs_device *pdev, gfp_t gfp_flags) if (!scratch) goto out_err; - xdr_init_decode(&stream, &buf, NULL); + xdr_init_decode_pages(&stream, &buf, pdev->pages, pdev->pglen); xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE); /* Get the stripe count (number of stripe index) */ diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h index fc84b7a19ca3..a20970ef9e4e 100644 --- a/include/linux/sunrpc/xdr.h +++ b/include/linux/sunrpc/xdr.h @@ -216,6 +216,8 @@ extern __be32 *xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes); extern void xdr_write_pages(struct xdr_stream *xdr, struct page **pages, unsigned int base, unsigned int len); extern void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p); +extern void xdr_init_decode_pages(struct xdr_stream *xdr, struct xdr_buf *buf, + struct page **pages, unsigned int len); extern void xdr_set_scratch_buffer(struct xdr_stream *xdr, void *buf, size_t buflen); extern __be32 *xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes); extern void xdr_read_pages(struct xdr_stream *xdr, unsigned int len); diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index 679cd674b81d..f008c14ad34c 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c @@ -638,6 +638,25 @@ void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p) } EXPORT_SYMBOL_GPL(xdr_init_decode); +/** + * xdr_init_decode - Initialize an xdr_stream for decoding data. + * @xdr: pointer to xdr_stream struct + * @buf: pointer to XDR buffer from which to decode data + * @pages: list of pages to decode into + * @len: length in bytes of buffer in pages + */ +void xdr_init_decode_pages(struct xdr_stream *xdr, struct xdr_buf *buf, + struct page **pages, unsigned int len) +{ + memset(buf, 0, sizeof(*buf)); + buf->pages = pages; + buf->page_len = len; + buf->buflen = len; + buf->len = len; + xdr_init_decode(xdr, buf, NULL); +} +EXPORT_SYMBOL_GPL(xdr_init_decode_pages); + static __be32 * __xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes) { __be32 *p = xdr->p; -- cgit From 38b7c401f6ade50543f246c4bc2c971edf2b19dd Mon Sep 17 00:00:00 2001 From: Benny Halevy Date: Sun, 22 May 2011 19:49:32 +0300 Subject: pnfs-obj: pnfs_osd XDR definitions * Add the pnfs_osd_xdr.h header * defintions the pnfs_osd_layout structure including all it's sub-types and constants. * Declare the pnfs_osd_xdr_decode_layout API + all needed inline helpers. * Define the pnfs_osd_deviceaddr structure and all its subtypes and constants. * Declare API for decoding of a pnfs_osd_deviceaddr from XDR stream. * Define the pnfs_osd_ioerr structure, its substructures and constants. * Declare API for encoding of a pnfs_osd_ioerr into XDR stream. * Define the pnfs_osd_layoutupdate structure and its substructures. * Declare API for encoding of a pnfs_osd_layoutupdate into XDR stream. [Remove server definitions] Signed-off-by: Boaz Harrosh Signed-off-by: Benny Halevy --- include/linux/pnfs_osd_xdr.h | 345 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 345 insertions(+) create mode 100644 include/linux/pnfs_osd_xdr.h (limited to 'include/linux') diff --git a/include/linux/pnfs_osd_xdr.h b/include/linux/pnfs_osd_xdr.h new file mode 100644 index 000000000000..76efbdd01622 --- /dev/null +++ b/include/linux/pnfs_osd_xdr.h @@ -0,0 +1,345 @@ +/* + * pNFS-osd on-the-wire data structures + * + * Copyright (C) 2007 Panasas Inc. [year of first publication] + * All rights reserved. + * + * Benny Halevy + * Boaz Harrosh + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * See the file COPYING included with this distribution for more details. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Panasas company nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __PNFS_OSD_XDR_H__ +#define __PNFS_OSD_XDR_H__ + +#include +#include +#include + +#define PNFS_OSD_OSDNAME_MAXSIZE 256 + +/* + * draft-ietf-nfsv4-minorversion-22 + * draft-ietf-nfsv4-pnfs-obj-12 + */ + +/* Layout Structure */ + +enum pnfs_osd_raid_algorithm4 { + PNFS_OSD_RAID_0 = 1, + PNFS_OSD_RAID_4 = 2, + PNFS_OSD_RAID_5 = 3, + PNFS_OSD_RAID_PQ = 4 /* Reed-Solomon P+Q */ +}; + +/* struct pnfs_osd_data_map4 { + * uint32_t odm_num_comps; + * length4 odm_stripe_unit; + * uint32_t odm_group_width; + * uint32_t odm_group_depth; + * uint32_t odm_mirror_cnt; + * pnfs_osd_raid_algorithm4 odm_raid_algorithm; + * }; + */ +struct pnfs_osd_data_map { + u32 odm_num_comps; + u64 odm_stripe_unit; + u32 odm_group_width; + u32 odm_group_depth; + u32 odm_mirror_cnt; + u32 odm_raid_algorithm; +}; + +/* struct pnfs_osd_objid4 { + * deviceid4 oid_device_id; + * uint64_t oid_partition_id; + * uint64_t oid_object_id; + * }; + */ +struct pnfs_osd_objid { + struct nfs4_deviceid oid_device_id; + u64 oid_partition_id; + u64 oid_object_id; +}; + +/* For printout. I use: + * kprint("dev(%llx:%llx)", _DEVID_LO(pointer), _DEVID_HI(pointer)); + * BE style + */ +#define _DEVID_LO(oid_device_id) \ + (unsigned long long)be64_to_cpup((__be64 *)(oid_device_id)->data) + +#define _DEVID_HI(oid_device_id) \ + (unsigned long long)be64_to_cpup(((__be64 *)(oid_device_id)->data) + 1) + +static inline int +pnfs_osd_objid_xdr_sz(void) +{ + return (NFS4_DEVICEID4_SIZE / 4) + 2 + 2; +} + +enum pnfs_osd_version { + PNFS_OSD_MISSING = 0, + PNFS_OSD_VERSION_1 = 1, + PNFS_OSD_VERSION_2 = 2 +}; + +struct pnfs_osd_opaque_cred { + u32 cred_len; + void *cred; +}; + +enum pnfs_osd_cap_key_sec { + PNFS_OSD_CAP_KEY_SEC_NONE = 0, + PNFS_OSD_CAP_KEY_SEC_SSV = 1, +}; + +/* struct pnfs_osd_object_cred4 { + * pnfs_osd_objid4 oc_object_id; + * pnfs_osd_version4 oc_osd_version; + * pnfs_osd_cap_key_sec4 oc_cap_key_sec; + * opaque oc_capability_key<>; + * opaque oc_capability<>; + * }; + */ +struct pnfs_osd_object_cred { + struct pnfs_osd_objid oc_object_id; + u32 oc_osd_version; + u32 oc_cap_key_sec; + struct pnfs_osd_opaque_cred oc_cap_key; + struct pnfs_osd_opaque_cred oc_cap; +}; + +/* struct pnfs_osd_layout4 { + * pnfs_osd_data_map4 olo_map; + * uint32_t olo_comps_index; + * pnfs_osd_object_cred4 olo_components<>; + * }; + */ +struct pnfs_osd_layout { + struct pnfs_osd_data_map olo_map; + u32 olo_comps_index; + u32 olo_num_comps; + struct pnfs_osd_object_cred *olo_comps; +}; + +/* Device Address */ +enum pnfs_osd_targetid_type { + OBJ_TARGET_ANON = 1, + OBJ_TARGET_SCSI_NAME = 2, + OBJ_TARGET_SCSI_DEVICE_ID = 3, +}; + +/* union pnfs_osd_targetid4 switch (pnfs_osd_targetid_type4 oti_type) { + * case OBJ_TARGET_SCSI_NAME: + * string oti_scsi_name<>; + * + * case OBJ_TARGET_SCSI_DEVICE_ID: + * opaque oti_scsi_device_id<>; + * + * default: + * void; + * }; + * + * union pnfs_osd_targetaddr4 switch (bool ota_available) { + * case TRUE: + * netaddr4 ota_netaddr; + * case FALSE: + * void; + * }; + * + * struct pnfs_osd_deviceaddr4 { + * pnfs_osd_targetid4 oda_targetid; + * pnfs_osd_targetaddr4 oda_targetaddr; + * uint64_t oda_lun; + * opaque oda_systemid<>; + * pnfs_osd_object_cred4 oda_root_obj_cred; + * opaque oda_osdname<>; + * }; + */ +struct pnfs_osd_targetid { + u32 oti_type; + struct nfs4_string oti_scsi_device_id; +}; + +enum { PNFS_OSD_TARGETID_MAX = 1 + PNFS_OSD_OSDNAME_MAXSIZE / 4 }; + +/* struct netaddr4 { + * // see struct rpcb in RFC1833 + * string r_netid<>; // network id + * string r_addr<>; // universal address + * }; + */ +struct pnfs_osd_net_addr { + struct nfs4_string r_netid; + struct nfs4_string r_addr; +}; + +struct pnfs_osd_targetaddr { + u32 ota_available; + struct pnfs_osd_net_addr ota_netaddr; +}; + +enum { + NETWORK_ID_MAX = 16 / 4, + UNIVERSAL_ADDRESS_MAX = 64 / 4, + PNFS_OSD_TARGETADDR_MAX = 3 + NETWORK_ID_MAX + UNIVERSAL_ADDRESS_MAX, +}; + +struct pnfs_osd_deviceaddr { + struct pnfs_osd_targetid oda_targetid; + struct pnfs_osd_targetaddr oda_targetaddr; + u8 oda_lun[8]; + struct nfs4_string oda_systemid; + struct pnfs_osd_object_cred oda_root_obj_cred; + struct nfs4_string oda_osdname; +}; + +enum { + ODA_OSDNAME_MAX = PNFS_OSD_OSDNAME_MAXSIZE / 4, + PNFS_OSD_DEVICEADDR_MAX = + PNFS_OSD_TARGETID_MAX + PNFS_OSD_TARGETADDR_MAX + + 2 /*oda_lun*/ + + 1 + OSD_SYSTEMID_LEN + + 1 + ODA_OSDNAME_MAX, +}; + +/* LAYOUTCOMMIT: layoutupdate */ + +/* union pnfs_osd_deltaspaceused4 switch (bool dsu_valid) { + * case TRUE: + * int64_t dsu_delta; + * case FALSE: + * void; + * }; + * + * struct pnfs_osd_layoutupdate4 { + * pnfs_osd_deltaspaceused4 olu_delta_space_used; + * bool olu_ioerr_flag; + * }; + */ +struct pnfs_osd_layoutupdate { + u32 dsu_valid; + s64 dsu_delta; + u32 olu_ioerr_flag; +}; + +/* LAYOUTRETURN: I/O Rrror Report */ + +enum pnfs_osd_errno { + PNFS_OSD_ERR_EIO = 1, + PNFS_OSD_ERR_NOT_FOUND = 2, + PNFS_OSD_ERR_NO_SPACE = 3, + PNFS_OSD_ERR_BAD_CRED = 4, + PNFS_OSD_ERR_NO_ACCESS = 5, + PNFS_OSD_ERR_UNREACHABLE = 6, + PNFS_OSD_ERR_RESOURCE = 7 +}; + +/* struct pnfs_osd_ioerr4 { + * pnfs_osd_objid4 oer_component; + * length4 oer_comp_offset; + * length4 oer_comp_length; + * bool oer_iswrite; + * pnfs_osd_errno4 oer_errno; + * }; + */ +struct pnfs_osd_ioerr { + struct pnfs_osd_objid oer_component; + u64 oer_comp_offset; + u64 oer_comp_length; + u32 oer_iswrite; + u32 oer_errno; +}; + +/* OSD XDR API */ +/* Layout helpers */ +/* Layout decoding is done in two parts: + * 1. First Call pnfs_osd_xdr_decode_layout_map to read in only the header part + * of the layout. @iter members need not be initialized. + * Returned: + * @layout members are set. (@layout->olo_comps set to NULL). + * + * Zero on success, or negative error if passed xdr is broken. + * + * 2. 2nd Call pnfs_osd_xdr_decode_layout_comp() in a loop until it returns + * false, to decode the next component. + * Returned: + * true if there is more to decode or false if we are done or error. + * + * Example: + * struct pnfs_osd_xdr_decode_layout_iter iter; + * struct pnfs_osd_layout layout; + * struct pnfs_osd_object_cred comp; + * int status; + * + * status = pnfs_osd_xdr_decode_layout_map(&layout, &iter, xdr); + * if (unlikely(status)) + * goto err; + * while(pnfs_osd_xdr_decode_layout_comp(&comp, &iter, xdr, &status)) { + * // All of @comp strings point to inside the xdr_buffer + * // or scrach buffer. Copy them out to user memory eg. + * copy_single_comp(dest_comp++, &comp); + * } + * if (unlikely(status)) + * goto err; + */ + +struct pnfs_osd_xdr_decode_layout_iter { + unsigned total_comps; + unsigned decoded_comps; +}; + +extern int pnfs_osd_xdr_decode_layout_map(struct pnfs_osd_layout *layout, + struct pnfs_osd_xdr_decode_layout_iter *iter, struct xdr_stream *xdr); + +extern bool pnfs_osd_xdr_decode_layout_comp(struct pnfs_osd_object_cred *comp, + struct pnfs_osd_xdr_decode_layout_iter *iter, struct xdr_stream *xdr, + int *err); + +/* Device Info helpers */ + +/* Note: All strings inside @deviceaddr point to space inside @p. + * @p should stay valid while @deviceaddr is in use. + */ +extern void pnfs_osd_xdr_decode_deviceaddr( + struct pnfs_osd_deviceaddr *deviceaddr, __be32 *p); + +/* layoutupdate (layout_commit) xdr helpers */ +extern int +pnfs_osd_xdr_encode_layoutupdate(struct xdr_stream *xdr, + struct pnfs_osd_layoutupdate *lou); + +/* osd_ioerror encoding/decoding (layout_return) */ +/* Client */ +extern __be32 *pnfs_osd_xdr_ioerr_reserve_space(struct xdr_stream *xdr); +extern void pnfs_osd_xdr_encode_ioerr(__be32 *p, struct pnfs_osd_ioerr *ioerr); + +#endif /* __PNFS_OSD_XDR_H__ */ -- cgit From d20581aa4be11407c9eeeb75992df5ef176bba0f Mon Sep 17 00:00:00 2001 From: Benny Halevy Date: Sun, 22 May 2011 19:52:03 +0300 Subject: pnfs: support for non-rpc layout drivers Non-rpc layout driver such as for objects and blocks implement their own I/O path and error handling logic. Therefore bypass NFS-based error handling for these layout drivers. [fix lseg ref-count bugs, and null de-refs] [Fall out from: non-rpc layout drivers] Signed-off-by: Boaz Harrosh [get rid of PNFS_USE_RPC_CODE] [get rid of __nfs4_write_done_cb] [revert useless change in nfs4_write_done_cb] Signed-off-by: Benny Halevy --- fs/nfs/internal.h | 1 + fs/nfs/nfs4proc.c | 13 ++++++++++--- fs/nfs/pnfs.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++- fs/nfs/pnfs.h | 2 ++ include/linux/nfs_xdr.h | 2 ++ 5 files changed, 62 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index ce118ce885dd..bcf0f0ff5eeb 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -310,6 +310,7 @@ extern int nfs_migrate_page(struct address_space *, #endif /* nfs4proc.c */ +extern void __nfs4_read_done_cb(struct nfs_read_data *); extern void nfs4_reset_read(struct rpc_task *task, struct nfs_read_data *data); extern int nfs4_init_client(struct nfs_client *clp, const struct rpc_timeout *timeparms, diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index cf1b339c3937..92c8bc4b5f97 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -3175,6 +3175,11 @@ static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle, return err; } +void __nfs4_read_done_cb(struct nfs_read_data *data) +{ + nfs_invalidate_atime(data->inode); +} + static int nfs4_read_done_cb(struct rpc_task *task, struct nfs_read_data *data) { struct nfs_server *server = NFS_SERVER(data->inode); @@ -3184,7 +3189,7 @@ static int nfs4_read_done_cb(struct rpc_task *task, struct nfs_read_data *data) return -EAGAIN; } - nfs_invalidate_atime(data->inode); + __nfs4_read_done_cb(data); if (task->tk_status > 0) renew_lease(server, data->timestamp); return 0; @@ -3198,7 +3203,8 @@ static int nfs4_read_done(struct rpc_task *task, struct nfs_read_data *data) if (!nfs4_sequence_done(task, &data->res.seq_res)) return -EAGAIN; - return data->read_done_cb(task, data); + return data->read_done_cb ? data->read_done_cb(task, data) : + nfs4_read_done_cb(task, data); } static void nfs4_proc_read_setup(struct nfs_read_data *data, struct rpc_message *msg) @@ -3243,7 +3249,8 @@ static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data) { if (!nfs4_sequence_done(task, &data->res.seq_res)) return -EAGAIN; - return data->write_done_cb(task, data); + return data->write_done_cb ? data->write_done_cb(task, data) : + nfs4_write_done_cb(task, data); } /* Reset the the nfs_write_data to send the write to the MDS. */ diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index ef535f2a2c74..171662114fdd 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -243,7 +243,7 @@ put_lseg_common(struct pnfs_layout_segment *lseg) { struct inode *inode = lseg->pls_layout->plh_inode; - BUG_ON(test_bit(NFS_LSEG_VALID, &lseg->pls_flags)); + WARN_ON(test_bit(NFS_LSEG_VALID, &lseg->pls_flags)); list_del_init(&lseg->pls_list); if (list_empty(&lseg->pls_layout->plh_segs)) { set_bit(NFS_LAYOUT_DESTROYED, &lseg->pls_layout->plh_flags); @@ -1054,6 +1054,29 @@ pnfs_pageio_init_write(struct nfs_pageio_descriptor *pgio, struct inode *inode) pgio->pg_test = (ld && ld->pg_test) ? pnfs_write_pg_test : NULL; } +/* + * Called by non rpc-based layout drivers + */ +int +pnfs_ld_write_done(struct nfs_write_data *data) +{ + int status; + + if (!data->pnfs_error) { + pnfs_set_layoutcommit(data); + data->mds_ops->rpc_call_done(&data->task, data); + data->mds_ops->rpc_release(data); + return 0; + } + + dprintk("%s: pnfs_error=%d, retry via MDS\n", __func__, + data->pnfs_error); + status = nfs_initiate_write(data, NFS_CLIENT(data->inode), + data->mds_ops, NFS_FILE_SYNC); + return status ? : -EAGAIN; +} +EXPORT_SYMBOL_GPL(pnfs_ld_write_done); + enum pnfs_try_status pnfs_try_to_write_data(struct nfs_write_data *wdata, const struct rpc_call_ops *call_ops, int how) @@ -1078,6 +1101,29 @@ pnfs_try_to_write_data(struct nfs_write_data *wdata, return trypnfs; } +/* + * Called by non rpc-based layout drivers + */ +int +pnfs_ld_read_done(struct nfs_read_data *data) +{ + int status; + + if (!data->pnfs_error) { + __nfs4_read_done_cb(data); + data->mds_ops->rpc_call_done(&data->task, data); + data->mds_ops->rpc_release(data); + return 0; + } + + dprintk("%s: pnfs_error=%d, retry via MDS\n", __func__, + data->pnfs_error); + status = nfs_initiate_read(data, NFS_CLIENT(data->inode), + data->mds_ops); + return status ? : -EAGAIN; +} +EXPORT_SYMBOL_GPL(pnfs_ld_read_done); + /* * Call the appropriate parallel I/O subsystem read function. */ diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h index 925d6ef8ba79..0383e66e71f0 100644 --- a/fs/nfs/pnfs.h +++ b/fs/nfs/pnfs.h @@ -165,6 +165,8 @@ void pnfs_roc_set_barrier(struct inode *ino, u32 barrier); bool pnfs_roc_drain(struct inode *ino, u32 *barrier); void pnfs_set_layoutcommit(struct nfs_write_data *wdata); int pnfs_layoutcommit_inode(struct inode *inode, bool sync); +int pnfs_ld_write_done(struct nfs_write_data *); +int pnfs_ld_read_done(struct nfs_read_data *); /* pnfs_dev.c */ struct nfs4_deviceid_node { diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 7e371f7df9c4..7c8ff0984a84 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -1087,6 +1087,7 @@ struct nfs_read_data { const struct rpc_call_ops *mds_ops; int (*read_done_cb) (struct rpc_task *task, struct nfs_read_data *data); __u64 mds_offset; + int pnfs_error; struct page *page_array[NFS_PAGEVEC_SIZE]; }; @@ -1112,6 +1113,7 @@ struct nfs_write_data { unsigned long timestamp; /* For lease renewal */ #endif __u64 mds_offset; /* Filelayout dense stripe */ + int pnfs_error; struct page *page_array[NFS_PAGEVEC_SIZE]; }; -- cgit From cbe8260369c9f88eafa035cd327dc3e02fad528c Mon Sep 17 00:00:00 2001 From: Benny Halevy Date: Sun, 22 May 2011 19:52:37 +0300 Subject: pnfs: layoutreturn NFSv4.1 LAYOUTRETURN implementation Currently, does not support layout-type payload encoding. Signed-off-by: Alexandros Batsakis Signed-off-by: Andy Adamson Signed-off-by: Andy Adamson Signed-off-by: Dean Hildebrand Signed-off-by: Fred Isaman Signed-off-by: Fred Isaman Signed-off-by: Marc Eshel Signed-off-by: Zhang Jingwang [call pnfs_return_layout right before pnfs_destroy_layout] [remove assert_spin_locked from pnfs_clear_lseg_list] [remove wait parameter from the layoutreturn path.] [remove return_type field from nfs4_layoutreturn_args] [remove range from nfs4_layoutreturn_args] [no need to send layoutcommit from _pnfs_return_layout] [don't wait on sync layoutreturn] [fix layout stateid in layoutreturn args] [fixed NULL deref in _pnfs_return_layout] [removed recaim member of nfs4_layoutreturn_args] Signed-off-by: Benny Halevy --- fs/nfs/inode.c | 3 +- fs/nfs/nfs4proc.c | 82 +++++++++++++++++++++++++++++++++++ fs/nfs/nfs4xdr.c | 111 +++++++++++++++++++++++++++++++++++++++++++++--- fs/nfs/pnfs.c | 45 ++++++++++++++++++++ fs/nfs/pnfs.h | 18 ++++++++ include/linux/nfs4.h | 1 + include/linux/nfs_xdr.h | 21 +++++++++ 7 files changed, 274 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 57bb31ad7a5e..e9c6d9f8f7e8 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -1424,9 +1424,10 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) */ void nfs4_evict_inode(struct inode *inode) { - pnfs_destroy_layout(NFS_I(inode)); truncate_inode_pages(&inode->i_data, 0); end_writeback(inode); + pnfs_return_layout(inode); + pnfs_destroy_layout(NFS_I(inode)); /* If we are holding a delegation, return it! */ nfs_inode_return_delegation_noreclaim(inode); /* First call standard NFS clear_inode() code */ diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 92c8bc4b5f97..5b4124e4c22f 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -5673,6 +5673,88 @@ int nfs4_proc_layoutget(struct nfs4_layoutget *lgp) return status; } +static void +nfs4_layoutreturn_prepare(struct rpc_task *task, void *calldata) +{ + struct nfs4_layoutreturn *lrp = calldata; + + dprintk("--> %s\n", __func__); + if (nfs41_setup_sequence(lrp->clp->cl_session, &lrp->args.seq_args, + &lrp->res.seq_res, 0, task)) + return; + rpc_call_start(task); +} + +static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata) +{ + struct nfs4_layoutreturn *lrp = calldata; + struct nfs_server *server; + + dprintk("--> %s\n", __func__); + + if (!nfs4_sequence_done(task, &lrp->res.seq_res)) + return; + + server = NFS_SERVER(lrp->args.inode); + if (nfs4_async_handle_error(task, server, NULL) == -EAGAIN) { + nfs_restart_rpc(task, lrp->clp); + return; + } + if (task->tk_status == 0) { + struct pnfs_layout_hdr *lo = NFS_I(lrp->args.inode)->layout; + + if (lrp->res.lrs_present) { + spin_lock(&lo->plh_inode->i_lock); + pnfs_set_layout_stateid(lo, &lrp->res.stateid, true); + spin_unlock(&lo->plh_inode->i_lock); + } else + BUG_ON(!list_empty(&lo->plh_segs)); + } + dprintk("<-- %s\n", __func__); +} + +static void nfs4_layoutreturn_release(void *calldata) +{ + struct nfs4_layoutreturn *lrp = calldata; + + dprintk("--> %s\n", __func__); + put_layout_hdr(NFS_I(lrp->args.inode)->layout); + kfree(calldata); + dprintk("<-- %s\n", __func__); +} + +static const struct rpc_call_ops nfs4_layoutreturn_call_ops = { + .rpc_call_prepare = nfs4_layoutreturn_prepare, + .rpc_call_done = nfs4_layoutreturn_done, + .rpc_release = nfs4_layoutreturn_release, +}; + +int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp) +{ + struct rpc_task *task; + struct rpc_message msg = { + .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LAYOUTRETURN], + .rpc_argp = &lrp->args, + .rpc_resp = &lrp->res, + }; + struct rpc_task_setup task_setup_data = { + .rpc_client = lrp->clp->cl_rpcclient, + .rpc_message = &msg, + .callback_ops = &nfs4_layoutreturn_call_ops, + .callback_data = lrp, + }; + int status; + + dprintk("--> %s\n", __func__); + task = rpc_run_task(&task_setup_data); + if (IS_ERR(task)) + return PTR_ERR(task); + status = task->tk_status; + dprintk("<-- %s status=%d\n", __func__, status); + rpc_put_task(task); + return status; +} + static int _nfs4_proc_getdeviceinfo(struct nfs_server *server, struct pnfs_device *pdev) { diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index c3ccd2c46834..f24212064356 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -338,7 +338,11 @@ static int nfs4_stat_to_errno(int); 1 /* layoutupdate4 layout type */ + \ 1 /* NULL filelayout layoutupdate4 payload */) #define decode_layoutcommit_maxsz (op_decode_hdr_maxsz + 3) - +#define encode_layoutreturn_maxsz (8 + op_encode_hdr_maxsz + \ + encode_stateid_maxsz + \ + 1 /* FIXME: opaque lrf_body always empty at the moment */) +#define decode_layoutreturn_maxsz (op_decode_hdr_maxsz + \ + 1 + decode_stateid_maxsz) #else /* CONFIG_NFS_V4_1 */ #define encode_sequence_maxsz 0 #define decode_sequence_maxsz 0 @@ -760,7 +764,14 @@ static int nfs4_stat_to_errno(int); decode_putfh_maxsz + \ decode_layoutcommit_maxsz + \ decode_getattr_maxsz) - +#define NFS4_enc_layoutreturn_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ + encode_putfh_maxsz + \ + encode_layoutreturn_maxsz) +#define NFS4_dec_layoutreturn_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ + decode_putfh_maxsz + \ + decode_layoutreturn_maxsz) const u32 nfs41_maxwrite_overhead = ((RPC_MAX_HEADER_WITH_AUTH + compound_encode_hdr_maxsz + @@ -1889,6 +1900,31 @@ encode_layoutcommit(struct xdr_stream *xdr, hdr->replen += decode_layoutcommit_maxsz; return 0; } + +static void +encode_layoutreturn(struct xdr_stream *xdr, + const struct nfs4_layoutreturn_args *args, + struct compound_hdr *hdr) +{ + __be32 *p; + + p = reserve_space(xdr, 20); + *p++ = cpu_to_be32(OP_LAYOUTRETURN); + *p++ = cpu_to_be32(0); /* reclaim. always 0 for now */ + *p++ = cpu_to_be32(args->layout_type); + *p++ = cpu_to_be32(IOMODE_ANY); + *p = cpu_to_be32(RETURN_FILE); + p = reserve_space(xdr, 16 + NFS4_STATEID_SIZE); + p = xdr_encode_hyper(p, 0); + p = xdr_encode_hyper(p, NFS4_MAX_UINT64); + spin_lock(&args->inode->i_lock); + xdr_encode_opaque_fixed(p, &args->stateid.data, NFS4_STATEID_SIZE); + spin_unlock(&args->inode->i_lock); + p = reserve_space(xdr, 4); + *p = cpu_to_be32(0); + hdr->nops++; + hdr->replen += decode_layoutreturn_maxsz; +} #endif /* CONFIG_NFS_V4_1 */ /* @@ -2706,9 +2742,9 @@ static void nfs4_xdr_enc_layoutget(struct rpc_rqst *req, /* * Encode LAYOUTCOMMIT request */ -static int nfs4_xdr_enc_layoutcommit(struct rpc_rqst *req, - struct xdr_stream *xdr, - struct nfs4_layoutcommit_args *args) +static void nfs4_xdr_enc_layoutcommit(struct rpc_rqst *req, + struct xdr_stream *xdr, + struct nfs4_layoutcommit_args *args) { struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), @@ -2720,7 +2756,24 @@ static int nfs4_xdr_enc_layoutcommit(struct rpc_rqst *req, encode_layoutcommit(xdr, args, &hdr); encode_getfattr(xdr, args->bitmask, &hdr); encode_nops(&hdr); - return 0; +} + +/* + * Encode LAYOUTRETURN request + */ +static void nfs4_xdr_enc_layoutreturn(struct rpc_rqst *req, + struct xdr_stream *xdr, + struct nfs4_layoutreturn_args *args) +{ + struct compound_hdr hdr = { + .minorversion = nfs4_xdr_minorversion(&args->seq_args), + }; + + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_putfh(xdr, NFS_FH(args->inode), &hdr); + encode_layoutreturn(xdr, args, &hdr); + encode_nops(&hdr); } #endif /* CONFIG_NFS_V4_1 */ @@ -5203,6 +5256,27 @@ out_overflow: return -EIO; } +static int decode_layoutreturn(struct xdr_stream *xdr, + struct nfs4_layoutreturn_res *res) +{ + __be32 *p; + int status; + + status = decode_op_hdr(xdr, OP_LAYOUTRETURN); + if (status) + return status; + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) + goto out_overflow; + res->lrs_present = be32_to_cpup(p); + if (res->lrs_present) + status = decode_stateid(xdr, &res->stateid); + return status; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +} + static int decode_layoutcommit(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs4_layoutcommit_res *res) @@ -6319,6 +6393,30 @@ out: return status; } +/* + * Decode LAYOUTRETURN response + */ +static int nfs4_xdr_dec_layoutreturn(struct rpc_rqst *rqstp, + struct xdr_stream *xdr, + struct nfs4_layoutreturn_res *res) +{ + struct compound_hdr hdr; + int status; + + status = decode_compound_hdr(xdr, &hdr); + if (status) + goto out; + status = decode_sequence(xdr, &res->seq_res, rqstp); + if (status) + goto out; + status = decode_putfh(xdr); + if (status) + goto out; + status = decode_layoutreturn(xdr, res); +out: + return status; +} + /* * Decode LAYOUTCOMMIT response */ @@ -6547,6 +6645,7 @@ struct rpc_procinfo nfs4_procedures[] = { PROC(GETDEVICEINFO, enc_getdeviceinfo, dec_getdeviceinfo), PROC(LAYOUTGET, enc_layoutget, dec_layoutget), PROC(LAYOUTCOMMIT, enc_layoutcommit, dec_layoutcommit), + PROC(LAYOUTRETURN, enc_layoutreturn, dec_layoutreturn), #endif /* CONFIG_NFS_V4_1 */ }; diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 171662114fdd..00b128241746 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -619,6 +619,51 @@ out_err_free: return NULL; } +/* Initiates a LAYOUTRETURN(FILE) */ +int +_pnfs_return_layout(struct inode *ino) +{ + struct pnfs_layout_hdr *lo = NULL; + struct nfs_inode *nfsi = NFS_I(ino); + LIST_HEAD(tmp_list); + struct nfs4_layoutreturn *lrp; + nfs4_stateid stateid; + int status = 0; + + dprintk("--> %s\n", __func__); + + spin_lock(&ino->i_lock); + lo = nfsi->layout; + if (!lo || !mark_matching_lsegs_invalid(lo, &tmp_list, NULL)) { + spin_unlock(&ino->i_lock); + dprintk("%s: no layout segments to return\n", __func__); + goto out; + } + stateid = nfsi->layout->plh_stateid; + /* Reference matched in nfs4_layoutreturn_release */ + get_layout_hdr(lo); + spin_unlock(&ino->i_lock); + pnfs_free_lseg_list(&tmp_list); + + WARN_ON(test_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)); + + lrp = kzalloc(sizeof(*lrp), GFP_KERNEL); + if (unlikely(lrp == NULL)) { + status = -ENOMEM; + goto out; + } + + lrp->args.stateid = stateid; + lrp->args.layout_type = NFS_SERVER(ino)->pnfs_curr_ld->id; + lrp->args.inode = ino; + lrp->clp = NFS_SERVER(ino)->nfs_client; + + status = nfs4_proc_layoutreturn(lrp); +out: + dprintk("<-- %s status: %d\n", __func__, status); + return status; +} + bool pnfs_roc(struct inode *ino) { struct pnfs_layout_hdr *lo; diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h index 0383e66e71f0..c34f7a0e3bc2 100644 --- a/fs/nfs/pnfs.h +++ b/fs/nfs/pnfs.h @@ -129,6 +129,7 @@ extern void pnfs_unregister_layoutdriver(struct pnfs_layoutdriver_type *); extern int nfs4_proc_getdeviceinfo(struct nfs_server *server, struct pnfs_device *dev); extern int nfs4_proc_layoutget(struct nfs4_layoutget *lgp); +extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp); /* pnfs.c */ void get_layout_hdr(struct pnfs_layout_hdr *lo); @@ -165,6 +166,7 @@ void pnfs_roc_set_barrier(struct inode *ino, u32 barrier); bool pnfs_roc_drain(struct inode *ino, u32 *barrier); void pnfs_set_layoutcommit(struct nfs_write_data *wdata); int pnfs_layoutcommit_inode(struct inode *inode, bool sync); +int _pnfs_return_layout(struct inode *); int pnfs_ld_write_done(struct nfs_write_data *); int pnfs_ld_read_done(struct nfs_read_data *); @@ -256,6 +258,17 @@ static inline void pnfs_clear_request_commit(struct nfs_page *req) put_lseg(req->wb_commit_lseg); } +static inline int pnfs_return_layout(struct inode *ino) +{ + struct nfs_inode *nfsi = NFS_I(ino); + struct nfs_server *nfss = NFS_SERVER(ino); + + if (pnfs_enabled_sb(nfss) && nfsi->layout) + return _pnfs_return_layout(ino); + + return 0; +} + #else /* CONFIG_NFS_V4_1 */ static inline void pnfs_destroy_all_layouts(struct nfs_client *clp) @@ -298,6 +311,11 @@ pnfs_try_to_write_data(struct nfs_write_data *data, return PNFS_NOT_ATTEMPTED; } +static inline int pnfs_return_layout(struct inode *ino) +{ + return 0; +} + static inline bool pnfs_roc(struct inode *ino) { diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index 178fafe0ff93..9376eaf26e15 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h @@ -562,6 +562,7 @@ enum { NFSPROC4_CLNT_LAYOUTGET, NFSPROC4_CLNT_GETDEVICEINFO, NFSPROC4_CLNT_LAYOUTCOMMIT, + NFSPROC4_CLNT_LAYOUTRETURN, }; /* nfs41 types */ diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 7c8ff0984a84..5e8444a11adf 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -269,6 +269,27 @@ struct nfs4_layoutcommit_data { struct nfs4_layoutcommit_res res; }; +struct nfs4_layoutreturn_args { + __u32 layout_type; + struct inode *inode; + nfs4_stateid stateid; + struct nfs4_sequence_args seq_args; +}; + +struct nfs4_layoutreturn_res { + struct nfs4_sequence_res seq_res; + u32 lrs_present; + nfs4_stateid stateid; +}; + +struct nfs4_layoutreturn { + struct nfs4_layoutreturn_args args; + struct nfs4_layoutreturn_res res; + struct rpc_cred *cred; + struct nfs_client *clp; + int rpc_status; +}; + /* * Arguments to the open call. */ -- cgit From 18ad0a9f2ccd260d37dd6bc5fa04c7819def4c84 Mon Sep 17 00:00:00 2001 From: Benny Halevy Date: Wed, 25 May 2011 21:03:56 +0300 Subject: NFSv4.1: change pg_test return type to bool Signed-off-by: Benny Halevy --- fs/nfs/nfs4filelayout.c | 6 +++--- fs/nfs/objlayout/objio_osd.c | 7 +++---- fs/nfs/pagelist.c | 22 +++++++++++----------- fs/nfs/pnfs.c | 4 ++-- fs/nfs/pnfs.h | 4 ++-- include/linux/nfs_page.h | 2 +- 6 files changed, 22 insertions(+), 23 deletions(-) (limited to 'include/linux') diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c index 33bda24e8cd2..24f05720daf1 100644 --- a/fs/nfs/nfs4filelayout.c +++ b/fs/nfs/nfs4filelayout.c @@ -651,10 +651,10 @@ filelayout_alloc_lseg(struct pnfs_layout_hdr *layoutid, /* * filelayout_pg_test(). Called by nfs_can_coalesce_requests() * - * return 1 : coalesce page - * return 0 : don't coalesce page + * return true : coalesce page + * return false : don't coalesce page */ -int +bool filelayout_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, struct nfs_page *req) { diff --git a/fs/nfs/objlayout/objio_osd.c b/fs/nfs/objlayout/objio_osd.c index 3be124160e97..8c2bd3eb8e8d 100644 --- a/fs/nfs/objlayout/objio_osd.c +++ b/fs/nfs/objlayout/objio_osd.c @@ -991,14 +991,13 @@ ssize_t objio_write_pagelist(struct objlayout_io_state *ol_state, bool stable) /* * objlayout_pg_test(). Called by nfs_can_coalesce_requests() * - * return 1 : coalesce page - * return 0 : don't coalesce page + * return true iff coalesce page */ -int +bool objlayout_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, struct nfs_page *req) { - return 1; + return true; } static struct pnfs_layoutdriver_type objlayout_type = { diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index b8704fedcd16..5344371a257c 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c @@ -244,29 +244,29 @@ void nfs_pageio_init(struct nfs_pageio_descriptor *desc, * * Return 'true' if this is the case, else return 'false'. */ -static int nfs_can_coalesce_requests(struct nfs_page *prev, - struct nfs_page *req, - struct nfs_pageio_descriptor *pgio) +static bool nfs_can_coalesce_requests(struct nfs_page *prev, + struct nfs_page *req, + struct nfs_pageio_descriptor *pgio) { if (req->wb_context->cred != prev->wb_context->cred) - return 0; + return false; if (req->wb_lock_context->lockowner != prev->wb_lock_context->lockowner) - return 0; + return false; if (req->wb_context->state != prev->wb_context->state) - return 0; + return false; if (req->wb_index != (prev->wb_index + 1)) - return 0; + return false; if (req->wb_pgbase != 0) - return 0; + return false; if (prev->wb_pgbase + prev->wb_bytes != PAGE_CACHE_SIZE) - return 0; + return false; /* * Non-whole file layouts need to check that req is inside of * pgio->pg_lseg. */ if (pgio->pg_test && !pgio->pg_test(pgio, prev, req)) - return 0; - return 1; + return false; + return true; } /** diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 568ab0eef677..212fc292761a 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -1043,7 +1043,7 @@ out_forget_reply: goto out; } -int +bool pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, struct nfs_page *req) { @@ -1070,7 +1070,7 @@ pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, } else if (pgio->pg_lseg && req_offset(req) > end_offset(pgio->pg_lseg->pls_range.offset, pgio->pg_lseg->pls_range.length)) - return 0; + return false; return NFS_SERVER(pgio->pg_inode)->pnfs_curr_ld->pg_test(pgio, prev, req); } diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h index c056688ee92b..65daae59c8ae 100644 --- a/fs/nfs/pnfs.h +++ b/fs/nfs/pnfs.h @@ -87,7 +87,7 @@ struct pnfs_layoutdriver_type { void (*free_lseg) (struct pnfs_layout_segment *lseg); /* test for nfs page cache coalescing */ - int (*pg_test)(struct nfs_pageio_descriptor *, struct nfs_page *, struct nfs_page *); + bool (*pg_test)(struct nfs_pageio_descriptor *, struct nfs_page *, struct nfs_page *); /* Returns true if layoutdriver wants to divert this request to * driver's commit routine. @@ -158,7 +158,7 @@ enum pnfs_try_status pnfs_try_to_write_data(struct nfs_write_data *, const struct rpc_call_ops *, int); enum pnfs_try_status pnfs_try_to_read_data(struct nfs_read_data *, const struct rpc_call_ops *); -int pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, struct nfs_page *req); +bool pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, struct nfs_page *req); int pnfs_layout_process(struct nfs4_layoutget *lgp); void pnfs_free_lseg_list(struct list_head *tmp_list); void pnfs_destroy_layout(struct nfs_inode *); diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h index 91af2e49fa3a..3a34e80ae92f 100644 --- a/include/linux/nfs_page.h +++ b/include/linux/nfs_page.h @@ -68,7 +68,7 @@ struct nfs_pageio_descriptor { int pg_ioflags; int pg_error; struct pnfs_layout_segment *pg_lseg; - int (*pg_test)(struct nfs_pageio_descriptor *, struct nfs_page *, struct nfs_page *); + bool (*pg_test)(struct nfs_pageio_descriptor *, struct nfs_page *, struct nfs_page *); }; #define NFS_WBACK_BUSY(req) (test_bit(PG_BUSY,&(req)->wb_flags)) -- cgit From 6345d24daf0c1fffe6642081d783cdf653ebaa5c Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 29 May 2011 11:32:28 -0700 Subject: mm: Fix boot crash in mm_alloc() Thomas Gleixner reports that we now have a boot crash triggered by CONFIG_CPUMASK_OFFSTACK=y: BUG: unable to handle kernel NULL pointer dereference at (null) IP: [] find_next_bit+0x55/0xb0 Call Trace: [] cpumask_any_but+0x2a/0x70 [] flush_tlb_mm+0x2b/0x80 [] pud_populate+0x35/0x50 [] pgd_alloc+0x9a/0xf0 [] mm_init+0xec/0x120 [] mm_alloc+0x53/0xd0 which was introduced by commit de03c72cfce5 ("mm: convert mm->cpu_vm_cpumask into cpumask_var_t"), and is due to wrong ordering of mm_init() vs mm_init_cpumask Thomas wrote a patch to just fix the ordering of initialization, but I hate the new double allocation in the fork path, so I ended up instead doing some more radical surgery to clean it all up. Reported-by: Thomas Gleixner Reported-by: Ingo Molnar Cc: KOSAKI Motohiro Cc: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mm_types.h | 14 ++++++++++++-- include/linux/sched.h | 1 - init/main.c | 2 +- kernel/fork.c | 42 ++++++++++-------------------------------- 4 files changed, 23 insertions(+), 36 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 2a78aae78c69..027935c86c68 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -264,6 +264,8 @@ struct mm_struct { struct linux_binfmt *binfmt; + cpumask_var_t cpu_vm_mask_var; + /* Architecture-specific MM context */ mm_context_t context; @@ -311,10 +313,18 @@ struct mm_struct { #ifdef CONFIG_TRANSPARENT_HUGEPAGE pgtable_t pmd_huge_pte; /* protected by page_table_lock */ #endif - - cpumask_var_t cpu_vm_mask_var; +#ifdef CONFIG_CPUMASK_OFFSTACK + struct cpumask cpumask_allocation; +#endif }; +static inline void mm_init_cpumask(struct mm_struct *mm) +{ +#ifdef CONFIG_CPUMASK_OFFSTACK + mm->cpu_vm_mask_var = &mm->cpumask_allocation; +#endif +} + /* Future-safe accessor for struct mm_struct's cpu_vm_mask. */ static inline cpumask_t *mm_cpumask(struct mm_struct *mm) { diff --git a/include/linux/sched.h b/include/linux/sched.h index bcddd0138105..2a8621c4be1e 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -2194,7 +2194,6 @@ static inline void mmdrop(struct mm_struct * mm) if (unlikely(atomic_dec_and_test(&mm->mm_count))) __mmdrop(mm); } -extern int mm_init_cpumask(struct mm_struct *mm, struct mm_struct *oldmm); /* mmput gets rid of the mappings and all user-space */ extern void mmput(struct mm_struct *); diff --git a/init/main.c b/init/main.c index d2f1e086bf33..cafba67c13bf 100644 --- a/init/main.c +++ b/init/main.c @@ -487,6 +487,7 @@ asmlinkage void __init start_kernel(void) printk(KERN_NOTICE "%s", linux_banner); setup_arch(&command_line); mm_init_owner(&init_mm, &init_task); + mm_init_cpumask(&init_mm); setup_command_line(command_line); setup_nr_cpu_ids(); setup_per_cpu_areas(); @@ -510,7 +511,6 @@ asmlinkage void __init start_kernel(void) sort_main_extable(); trap_init(); mm_init(); - BUG_ON(mm_init_cpumask(&init_mm, 0)); /* * Set up the scheduler prior starting any interrupts (such as the diff --git a/kernel/fork.c b/kernel/fork.c index ca406d916713..0276c30401a0 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -484,20 +484,6 @@ static void mm_init_aio(struct mm_struct *mm) #endif } -int mm_init_cpumask(struct mm_struct *mm, struct mm_struct *oldmm) -{ -#ifdef CONFIG_CPUMASK_OFFSTACK - if (!alloc_cpumask_var(&mm->cpu_vm_mask_var, GFP_KERNEL)) - return -ENOMEM; - - if (oldmm) - cpumask_copy(mm_cpumask(mm), mm_cpumask(oldmm)); - else - memset(mm_cpumask(mm), 0, cpumask_size()); -#endif - return 0; -} - static struct mm_struct * mm_init(struct mm_struct * mm, struct task_struct *p) { atomic_set(&mm->mm_users, 1); @@ -538,17 +524,8 @@ struct mm_struct * mm_alloc(void) return NULL; memset(mm, 0, sizeof(*mm)); - mm = mm_init(mm, current); - if (!mm) - return NULL; - - if (mm_init_cpumask(mm, NULL)) { - mm_free_pgd(mm); - free_mm(mm); - return NULL; - } - - return mm; + mm_init_cpumask(mm); + return mm_init(mm, current); } /* @@ -559,7 +536,6 @@ struct mm_struct * mm_alloc(void) void __mmdrop(struct mm_struct *mm) { BUG_ON(mm == &init_mm); - free_cpumask_var(mm->cpu_vm_mask_var); mm_free_pgd(mm); destroy_context(mm); mmu_notifier_mm_destroy(mm); @@ -753,6 +729,7 @@ struct mm_struct *dup_mm(struct task_struct *tsk) goto fail_nomem; memcpy(mm, oldmm, sizeof(*mm)); + mm_init_cpumask(mm); /* Initializing for Swap token stuff */ mm->token_priority = 0; @@ -765,9 +742,6 @@ struct mm_struct *dup_mm(struct task_struct *tsk) if (!mm_init(mm, tsk)) goto fail_nomem; - if (mm_init_cpumask(mm, oldmm)) - goto fail_nocpumask; - if (init_new_context(tsk, mm)) goto fail_nocontext; @@ -794,9 +768,6 @@ fail_nomem: return NULL; fail_nocontext: - free_cpumask_var(mm->cpu_vm_mask_var); - -fail_nocpumask: /* * If init_new_context() failed, we cannot use mmput() to free the mm * because it calls destroy_context() @@ -1591,6 +1562,13 @@ void __init proc_caches_init(void) fs_cachep = kmem_cache_create("fs_cache", sizeof(struct fs_struct), 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL); + /* + * FIXME! The "sizeof(struct mm_struct)" currently includes the + * whole struct cpumask for the OFFSTACK case. We could change + * this to *only* allocate as much of it as required by the + * maximum number of CPU's we can ever have. The cpumask_allocation + * is at the end of the structure, exactly for that reason. + */ mm_cachep = kmem_cache_create("mm_struct", sizeof(struct mm_struct), ARCH_MIN_MMSTRUCT_ALIGN, SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL); -- cgit