Re: [PATCH] mac80211: aead api to reduce redundancy
Hi Johannes, Thanks for your time on reviewing this. I will make changes following your review. See details below. By the way, I'm still struggling on how to run unit tests. It might take time for me to make it run on my machine. 2017-10-02 8:04 GMT-04:00 Johannes Berg: > Please use "v2" tag or so in the subject line, having the same patch > again is really not helpful. > > The next should be v3, obviously. Thanks for your patience to point this out. I will follow your instruction. > >> +++ b/net/mac80211/aead_api.c >> @@ -1,7 +1,4 @@ >> -/* >> - * Copyright 2014-2015, Qualcomm Atheros, Inc. >> - * >> - * This program is free software; you can redistribute it and/or >> modify >> +/* This program is free software; you can redistribute it and/or >> modify > > I see no reason to make this change, why remove copyright? Hmm... good question. The reason is, aes_ccm.c and aes_gcm.c was almost exact copy of each other. But they have different copyright information. The copyright of aes_ccm.c was: Copyright 2006, Devicescape Software, Inc. Copyright 2003-2004, Instant802 Networks, Inc. and the copyright of aes_gcm.c was: Copyright 2014-2015, Qualcomm Atheros, Inc. I just don't know how to write the copyright for the new aead_api.c, so I does not put anything there. These copyright information are still at aes_ccm.h and aes_gcm.h What's your opinion on writing these copyright information? Do I write all of them? like: Copyright 2014-2015, Qualcomm Atheros, Inc. Copyright 2006, Devicescape Software, Inc. Copyright 2003-2004, Instant802 Networks, Inc. > >> +++ b/net/mac80211/wpa.c >> @@ -464,7 +464,8 @@ static int ccmp_encrypt_skb(struct >> ieee80211_tx_data *tx, struct sk_buff *skb, >> pos += IEEE80211_CCMP_HDR_LEN; >> ccmp_special_blocks(skb, pn, b_0, aad); >> return ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, >> pos, len, >> - skb_put(skb, mic_len), >> mic_len); >> + skb_put(skb, >> + key->u.ccmp.tfm- >> >authsize)); >> } > > I see no reason for the change from mic_len to authsize here? This was because I was planning to put it to crypto directory, then I changed it to the same name as in other crypto api. Now that it will goes to the mac80211, I think it is time to revert this change. > >> @@ -540,10 +541,11 @@ ieee80211_crypto_ccmp_decrypt(struct >> ieee80211_rx_data *rx, >> ccmp_special_blocks(skb, pn, b_0, aad); >> >> if (ieee80211_aes_ccm_decrypt( >> - key->u.ccmp.tfm, b_0, aad, >> - skb->data + hdrlen + >> IEEE80211_CCMP_HDR_LEN, >> - data_len, >> - skb->data + skb->len - mic_len, mic_len)) >> + key->u.ccmp.tfm, b_0, aad, >> + skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN, >> + data_len, >> + skb->data + skb->len - >> key->u.ccmp.tfm->authsize >> + )) >> return RX_DROP_UNUSABLE; > > That's a really really strange way of writing this ... > > Please reformat. OK, I will reformat it. > > johannes
Re: [PATCH] mac80211: aead api to reduce redundancy
Hi Johannes, Thanks for your time on reviewing this. I will make changes following your review. See details below. By the way, I'm still struggling on how to run unit tests. It might take time for me to make it run on my machine. 2017-10-02 8:04 GMT-04:00 Johannes Berg : > Please use "v2" tag or so in the subject line, having the same patch > again is really not helpful. > > The next should be v3, obviously. Thanks for your patience to point this out. I will follow your instruction. > >> +++ b/net/mac80211/aead_api.c >> @@ -1,7 +1,4 @@ >> -/* >> - * Copyright 2014-2015, Qualcomm Atheros, Inc. >> - * >> - * This program is free software; you can redistribute it and/or >> modify >> +/* This program is free software; you can redistribute it and/or >> modify > > I see no reason to make this change, why remove copyright? Hmm... good question. The reason is, aes_ccm.c and aes_gcm.c was almost exact copy of each other. But they have different copyright information. The copyright of aes_ccm.c was: Copyright 2006, Devicescape Software, Inc. Copyright 2003-2004, Instant802 Networks, Inc. and the copyright of aes_gcm.c was: Copyright 2014-2015, Qualcomm Atheros, Inc. I just don't know how to write the copyright for the new aead_api.c, so I does not put anything there. These copyright information are still at aes_ccm.h and aes_gcm.h What's your opinion on writing these copyright information? Do I write all of them? like: Copyright 2014-2015, Qualcomm Atheros, Inc. Copyright 2006, Devicescape Software, Inc. Copyright 2003-2004, Instant802 Networks, Inc. > >> +++ b/net/mac80211/wpa.c >> @@ -464,7 +464,8 @@ static int ccmp_encrypt_skb(struct >> ieee80211_tx_data *tx, struct sk_buff *skb, >> pos += IEEE80211_CCMP_HDR_LEN; >> ccmp_special_blocks(skb, pn, b_0, aad); >> return ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, >> pos, len, >> - skb_put(skb, mic_len), >> mic_len); >> + skb_put(skb, >> + key->u.ccmp.tfm- >> >authsize)); >> } > > I see no reason for the change from mic_len to authsize here? This was because I was planning to put it to crypto directory, then I changed it to the same name as in other crypto api. Now that it will goes to the mac80211, I think it is time to revert this change. > >> @@ -540,10 +541,11 @@ ieee80211_crypto_ccmp_decrypt(struct >> ieee80211_rx_data *rx, >> ccmp_special_blocks(skb, pn, b_0, aad); >> >> if (ieee80211_aes_ccm_decrypt( >> - key->u.ccmp.tfm, b_0, aad, >> - skb->data + hdrlen + >> IEEE80211_CCMP_HDR_LEN, >> - data_len, >> - skb->data + skb->len - mic_len, mic_len)) >> + key->u.ccmp.tfm, b_0, aad, >> + skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN, >> + data_len, >> + skb->data + skb->len - >> key->u.ccmp.tfm->authsize >> + )) >> return RX_DROP_UNUSABLE; > > That's a really really strange way of writing this ... > > Please reformat. OK, I will reformat it. > > johannes
Re: [PATCH 3/5] dmaengine: Support for querying maximum trasnfer length (of an SG element)
On Mon, Oct 02, 2017 at 02:24:12PM +0300, Peter Ujfalusi wrote: > > > > Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. > Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki > > On 2017-09-26 19:54, Vinod Koul wrote: > >>> > >>> not another callback :) > >>> > >>> on a serious note, why shouldn't this be one more capability in > >>> dma_slave_caps. looking at next patch it seems static > >> > >> It is not really static, the size in bytes depends on the dev_width and > >> the maxburst: > >> dev_width * burst * (SZ_64K - 1); > > > > well DMAengines work on FIFOs, in above you are giving length as SZ_64K - 1 > > 'items' which IIUC in DMAengine terms for bytes would always refer wrt width > > used and burst applied. > > I think we can live with this and let the user to figure out what to do > with this information. Right, plus a macro for conversion :) SO that users dont code buggy conversions all over the place > But I'm having hard time to figure out a good name for this. It is not > the number of SGs we can support, but the number of 'items' within one > SG that we have the limit. It could be: > u32 max_bursts_per_sg; this looks fine, another candidate I would use is words_per_sg and while at it why tie it to sg? should we make it words_per_txn but then people should not confuse with txn represented by a descriptor which can have multiple > > which would also apply to period length (for cyclic) in a similar way. > > > Return length in bytes does make sense (from user PoV), but then you need to > > "know" the applied width and burst. How do you decide those? > > The number of items works eDMA and sDMA, but we also have the cpp41. It > is a packet DMA and it has no understanding of bursts, address widths or > any of the 'traditional' things. It only cares about the number of bytes > we want to transfer and it has limitation of 4194303 bytes (21bits for > length). This is again per SG. How this could report the > 'max_bursts_per_sg' ? hmmm that is intresting case, is this number coming from USB side? > This was one of the reasons that I have settled with the callback. > > What we can also do is to code this within the DMA drivers itself. > > When setting up the transfer and we realize that one of the SG will not > going to fit, we destroy what we have done so far, pass the sg list > along with length/sg limit to create a new sg list where all sg item's > length is under the limit. Then using this new sg list we can set up the > transfer. > > I'm not sure how hard is to do the sg list optimization, I see that > sg_split() is not what we want so we might need to code this in > dmaengine or in the scatterlist code. > > We certainly don't want to verify all slave_sg transfers proactively to > avoid adding latency when it is not necessary. latency would be added at prepare, not when submitting.. -- ~Vinod
Re: [PATCH 3/5] dmaengine: Support for querying maximum trasnfer length (of an SG element)
On Mon, Oct 02, 2017 at 02:24:12PM +0300, Peter Ujfalusi wrote: > > > > Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. > Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki > > On 2017-09-26 19:54, Vinod Koul wrote: > >>> > >>> not another callback :) > >>> > >>> on a serious note, why shouldn't this be one more capability in > >>> dma_slave_caps. looking at next patch it seems static > >> > >> It is not really static, the size in bytes depends on the dev_width and > >> the maxburst: > >> dev_width * burst * (SZ_64K - 1); > > > > well DMAengines work on FIFOs, in above you are giving length as SZ_64K - 1 > > 'items' which IIUC in DMAengine terms for bytes would always refer wrt width > > used and burst applied. > > I think we can live with this and let the user to figure out what to do > with this information. Right, plus a macro for conversion :) SO that users dont code buggy conversions all over the place > But I'm having hard time to figure out a good name for this. It is not > the number of SGs we can support, but the number of 'items' within one > SG that we have the limit. It could be: > u32 max_bursts_per_sg; this looks fine, another candidate I would use is words_per_sg and while at it why tie it to sg? should we make it words_per_txn but then people should not confuse with txn represented by a descriptor which can have multiple > > which would also apply to period length (for cyclic) in a similar way. > > > Return length in bytes does make sense (from user PoV), but then you need to > > "know" the applied width and burst. How do you decide those? > > The number of items works eDMA and sDMA, but we also have the cpp41. It > is a packet DMA and it has no understanding of bursts, address widths or > any of the 'traditional' things. It only cares about the number of bytes > we want to transfer and it has limitation of 4194303 bytes (21bits for > length). This is again per SG. How this could report the > 'max_bursts_per_sg' ? hmmm that is intresting case, is this number coming from USB side? > This was one of the reasons that I have settled with the callback. > > What we can also do is to code this within the DMA drivers itself. > > When setting up the transfer and we realize that one of the SG will not > going to fit, we destroy what we have done so far, pass the sg list > along with length/sg limit to create a new sg list where all sg item's > length is under the limit. Then using this new sg list we can set up the > transfer. > > I'm not sure how hard is to do the sg list optimization, I see that > sg_split() is not what we want so we might need to code this in > dmaengine or in the scatterlist code. > > We certainly don't want to verify all slave_sg transfers proactively to > avoid adding latency when it is not necessary. latency would be added at prepare, not when submitting.. -- ~Vinod
Re: [for-next][PATCH 15/16] ftrace: Add freeing algorithm to free ftrace_mod_maps
Hi Steve, On Sat, Oct 7, 2017 at 6:32 AM, Steven Rostedtwrote: > On Fri, 6 Oct 2017 23:41:25 -0700 > "Joel Fernandes (Google)" wrote: > >> Hi Steve, >> >> On Fri, Oct 6, 2017 at 11:07 AM, Steven Rostedt wrote: >> > From: "Steven Rostedt (VMware)" >> > >> > The ftrace_mod_map is a descriptor to save module init function names in >> > case they were traced, and the trace output needs to reference the function >> > name from the function address. But after the function is unloaded, it >> > the maps should be freed, as the rest of the function names are as well. >> >> Just checking for my understanding of this patch - wouldn't this also >> mean that if there were any look ups of the init functions that may be >> needed at trace output time, then those look ups wont be possible any >> more after module is unloaded? > > Yes. That's true for all functions in the module. When a module is > unloaded, all references to it in kallsyms is also freed. Try it on a > current kernel. Trace a function in a module, then unload that module. > The trace data will just show the ip hex address of the module function > after that. > I tried your core branch and I see some weirdness with the filters: Here's the code for the module: #include #include #include void bar(void) { printk(KERN_INFO "bar!\n"); } void foo(void) { printk(KERN_INFO "foo!\n"); bar(); } static int __init hello_init(void) { printk(KERN_INFO "Hello world!\n"); foo(); return 0; } static void __exit hello_cleanup(void) { printk(KERN_INFO "Cleaning up module.\n"); } module_init(hello_init); module_exit(hello_cleanup); Following is a run with function tracing, during the first run I see foo and bar are setup in the filters. After that when I unload and load the module, I see that only "bar" is in the filters: bash-4.3# echo '*:mod:test' > /d/tracing/set_ftrace_filter bash-4.3# echo function > /d/tracing/current_tracer bash-4.3# cat /d/tracing/set_ftrace_filter *:mod:test bash-4.3# modprobe test bash-4.3# cat /d/tracing/trace # tracer: function # # _-=> irqs-off # / _=> need-resched #| / _---=> hardirq/softirq #|| / _--=> preempt-depth #||| / delay # TASK-PID CPU# TIMESTAMP FUNCTION # | | | | | modprobe-1050 [003] 1.653000: hello_init <-do_one_initcall bash-4.3# cat /d/tracing/set_ftrace_filter bar [test] foo [test] bash-4.3# rmmod test bash-4.3# cat /d/tracing/set_ftrace_filter bash-4.3# sleep 2 bash-4.3# modprobe test bash-4.3# cat /d/tracing/trace # tracer: function # # _-=> irqs-off # / _=> need-resched #| / _---=> hardirq/softirq #|| / _--=> preempt-depth #||| / delay # TASK-PID CPU# TIMESTAMP FUNCTION # | | | | | modprobe-1050 [003] 1.653000: bar <-do_one_initcall bash-4.3# cat /d/tracing/set_ftrace_filter bar [test] <--- bar is still in the filter list bash-4.3# Interestingly this also shows that the symbol conversion can be unreliable if another module was loaded into the same address, in this case 'bar' was loaded at the same address as 'hello_init' the second time so during the second cat of the trace file, it shows a different symbol name. Also could you let me know what is the correct behavior of the filters after a module being traced is unloaded, are the filters supposed to be setup again after the module is unloaded, before the module can be loaded again? Also I wasn't able to see the call from hello_init -> bar and bar -> foo so I'm not fully sure if that's a bug or I did something wrong. I'm happy to try out anything you suggest. >> I guess having a reference somehow on the ftrace_mod_map descriptor if >> there are any entries in the trace buffer that need it can help >> prevent that but it could be too expensive for not much return since >> most likely the user wouldn't unload modules before trace collection >> in normal usage. > > Right, I have thought about this, and I haven't come up with an > inexpensive way to do this. As this has been the default operation of > all module functions, and I haven't heard much complaining about it (I > think I may have had a single complaint), I didn't put too much effort > into it. > I need to look at the approach that Jessica sent me. Perhaps there's Yes, I think that approach is better. But I think it would have the same issue (that if the init sections are freed and say used by
Re: [for-next][PATCH 15/16] ftrace: Add freeing algorithm to free ftrace_mod_maps
Hi Steve, On Sat, Oct 7, 2017 at 6:32 AM, Steven Rostedt wrote: > On Fri, 6 Oct 2017 23:41:25 -0700 > "Joel Fernandes (Google)" wrote: > >> Hi Steve, >> >> On Fri, Oct 6, 2017 at 11:07 AM, Steven Rostedt wrote: >> > From: "Steven Rostedt (VMware)" >> > >> > The ftrace_mod_map is a descriptor to save module init function names in >> > case they were traced, and the trace output needs to reference the function >> > name from the function address. But after the function is unloaded, it >> > the maps should be freed, as the rest of the function names are as well. >> >> Just checking for my understanding of this patch - wouldn't this also >> mean that if there were any look ups of the init functions that may be >> needed at trace output time, then those look ups wont be possible any >> more after module is unloaded? > > Yes. That's true for all functions in the module. When a module is > unloaded, all references to it in kallsyms is also freed. Try it on a > current kernel. Trace a function in a module, then unload that module. > The trace data will just show the ip hex address of the module function > after that. > I tried your core branch and I see some weirdness with the filters: Here's the code for the module: #include #include #include void bar(void) { printk(KERN_INFO "bar!\n"); } void foo(void) { printk(KERN_INFO "foo!\n"); bar(); } static int __init hello_init(void) { printk(KERN_INFO "Hello world!\n"); foo(); return 0; } static void __exit hello_cleanup(void) { printk(KERN_INFO "Cleaning up module.\n"); } module_init(hello_init); module_exit(hello_cleanup); Following is a run with function tracing, during the first run I see foo and bar are setup in the filters. After that when I unload and load the module, I see that only "bar" is in the filters: bash-4.3# echo '*:mod:test' > /d/tracing/set_ftrace_filter bash-4.3# echo function > /d/tracing/current_tracer bash-4.3# cat /d/tracing/set_ftrace_filter *:mod:test bash-4.3# modprobe test bash-4.3# cat /d/tracing/trace # tracer: function # # _-=> irqs-off # / _=> need-resched #| / _---=> hardirq/softirq #|| / _--=> preempt-depth #||| / delay # TASK-PID CPU# TIMESTAMP FUNCTION # | | | | | modprobe-1050 [003] 1.653000: hello_init <-do_one_initcall bash-4.3# cat /d/tracing/set_ftrace_filter bar [test] foo [test] bash-4.3# rmmod test bash-4.3# cat /d/tracing/set_ftrace_filter bash-4.3# sleep 2 bash-4.3# modprobe test bash-4.3# cat /d/tracing/trace # tracer: function # # _-=> irqs-off # / _=> need-resched #| / _---=> hardirq/softirq #|| / _--=> preempt-depth #||| / delay # TASK-PID CPU# TIMESTAMP FUNCTION # | | | | | modprobe-1050 [003] 1.653000: bar <-do_one_initcall bash-4.3# cat /d/tracing/set_ftrace_filter bar [test] <--- bar is still in the filter list bash-4.3# Interestingly this also shows that the symbol conversion can be unreliable if another module was loaded into the same address, in this case 'bar' was loaded at the same address as 'hello_init' the second time so during the second cat of the trace file, it shows a different symbol name. Also could you let me know what is the correct behavior of the filters after a module being traced is unloaded, are the filters supposed to be setup again after the module is unloaded, before the module can be loaded again? Also I wasn't able to see the call from hello_init -> bar and bar -> foo so I'm not fully sure if that's a bug or I did something wrong. I'm happy to try out anything you suggest. >> I guess having a reference somehow on the ftrace_mod_map descriptor if >> there are any entries in the trace buffer that need it can help >> prevent that but it could be too expensive for not much return since >> most likely the user wouldn't unload modules before trace collection >> in normal usage. > > Right, I have thought about this, and I haven't come up with an > inexpensive way to do this. As this has been the default operation of > all module functions, and I haven't heard much complaining about it (I > think I may have had a single complaint), I didn't put too much effort > into it. > I need to look at the approach that Jessica sent me. Perhaps there's Yes, I think that approach is better. But I think it would have the same issue (that if the init sections are freed and say used by other loaded modules), then the trace output would incorrectly show a different symbol
[PATCH 2/2] ata: ahci_sunxi: add support for R40 SATA controller
Allwinner R40 SoC has an AHCI SATA controller like the one in A10/A20, but with a reset control and two dedicated VDD pins for this controller (one 1.2v and one 2.5v). Add support for it. Signed-off-by: Icenowy Zheng--- drivers/ata/ahci_sunxi.c | 118 +-- 1 file changed, 115 insertions(+), 3 deletions(-) diff --git a/drivers/ata/ahci_sunxi.c b/drivers/ata/ahci_sunxi.c index b26437430163..a650fd6508be 100644 --- a/drivers/ata/ahci_sunxi.c +++ b/drivers/ata/ahci_sunxi.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "ahci.h" #define DRV_NAME "ahci-sunxi" @@ -58,6 +59,19 @@ MODULE_PARM_DESC(enable_pmp, #define AHCI_P0PHYCR 0x0178 #define AHCI_P0PHYSR 0x017c +struct ahci_sunxi_quirks { + bool has_reset; + bool has_vdd1v2; + bool has_vdd2v5; +}; + +struct ahci_sunxi_data { + const struct ahci_sunxi_quirks *quirks; + struct reset_control *reset; + struct regulator *vdd1v2; + struct regulator *vdd2v5; +}; + static void sunxi_clrbits(void __iomem *reg, u32 clr_val) { u32 reg_val; @@ -179,17 +193,69 @@ static int ahci_sunxi_probe(struct platform_device *pdev) { struct device *dev = >dev; struct ahci_host_priv *hpriv; + struct ahci_sunxi_data *data; int rc; + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->quirks = of_device_get_match_data(dev); + if (!data->quirks) + return -EINVAL; + + if (data->quirks->has_reset) { + data->reset = devm_reset_control_get(dev, NULL); + if (IS_ERR(data->reset)) { + dev_err(dev, "Failed to get reset\n"); + return PTR_ERR(data->reset); + } + } + + if (data->quirks->has_vdd1v2) { + data->vdd1v2 = devm_regulator_get(dev, "vdd1v2"); + if (IS_ERR(data->vdd1v2)) { + dev_err(dev, "Failed to get 1.2v VDD regulator\n"); + return PTR_ERR(data->vdd1v2); + } + } + + if (data->quirks->has_vdd2v5) { + data->vdd2v5 = devm_regulator_get(dev, "vdd2v5"); + if (IS_ERR(data->vdd2v5)) { + dev_err(dev, "Failed to get 2.5v VDD regulator\n"); + return PTR_ERR(data->vdd2v5); + } + } + hpriv = ahci_platform_get_resources(pdev); if (IS_ERR(hpriv)) return PTR_ERR(hpriv); + hpriv->plat_data = data; hpriv->start_engine = ahci_sunxi_start_engine; + if (data->quirks->has_vdd1v2) { + rc = regulator_enable(data->vdd1v2); + if (rc) + return rc; + } + + if (data->quirks->has_vdd2v5) { + rc = regulator_enable(data->vdd2v5); + if (rc) + goto disable_vdd1v2; + } + + if (data->quirks->has_reset) { + rc = reset_control_deassert(data->reset); + if (rc) + goto disable_vdd2v5; + } + rc = ahci_platform_enable_resources(hpriv); if (rc) - return rc; + goto assert_reset; rc = ahci_sunxi_phy_init(dev, hpriv->mmio); if (rc) @@ -215,6 +281,35 @@ static int ahci_sunxi_probe(struct platform_device *pdev) disable_resources: ahci_platform_disable_resources(hpriv); +assert_reset: + if (data->quirks->has_reset) + reset_control_assert(data->reset); +disable_vdd2v5: + if (data->quirks->has_vdd2v5) + regulator_disable(data->vdd2v5); +disable_vdd1v2: + if (data->quirks->has_vdd1v2) + regulator_disable(data->vdd1v2); + return rc; +} + +static int ahci_sunxi_remove(struct platform_device *pdev) +{ + struct device *dev = >dev; + struct ata_host *host = dev_get_drvdata(dev); + struct ahci_host_priv *hpriv = host->private_data; + struct ahci_sunxi_data *data = hpriv->plat_data; + int rc; + + rc = ata_platform_remove_one(pdev); + + if (data->quirks->has_reset) + reset_control_assert(data->reset); + if (data->quirks->has_vdd2v5) + regulator_disable(data->vdd2v5); + if (data->quirks->has_vdd1v2) + regulator_disable(data->vdd1v2); + return rc; } @@ -248,15 +343,32 @@ static int ahci_sunxi_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(ahci_sunxi_pm_ops, ahci_platform_suspend, ahci_sunxi_resume); +static const struct ahci_sunxi_quirks sun4i_a10_ahci_quirks = { + /* Nothing special */ +}; + +static const struct ahci_sunxi_quirks sun8i_r40_ahci_quirks = { + .has_reset = true, + .has_vdd1v2 = true, + .has_vdd2v5 = true, +}; + static const struct
[PATCH 1/2] dt-bindings: add binding for Allwinner R40 SATA AHCI controller
The Allwinner R40 SoC contains a SATA AHCI controller like the one in A10/A20 SoCs, however a reset control and two power supplies are added to it. Add a binding document for it. As a dedicated binding document is needed now for the A10/A20/R40 AHCI controller, drop the A10 compatible line from generic platform AHCI controller binding document. Signed-off-by: Icenowy Zheng--- .../devicetree/bindings/ata/ahci-platform.txt | 1 - .../bindings/ata/allwinner,sun4i-a10-ahci.txt | 40 ++ 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/ata/allwinner,sun4i-a10-ahci.txt diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt index fedc213b5f1a..da6818b2c204 100644 --- a/Documentation/devicetree/bindings/ata/ahci-platform.txt +++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt @@ -9,7 +9,6 @@ PHYs. Required properties: - compatible: compatible string, one of: - - "allwinner,sun4i-a10-ahci" - "brcm,iproc-ahci" - "hisilicon,hisi-ahci" - "cavium,octeon-7130-ahci" diff --git a/Documentation/devicetree/bindings/ata/allwinner,sun4i-a10-ahci.txt b/Documentation/devicetree/bindings/ata/allwinner,sun4i-a10-ahci.txt new file mode 100644 index ..0eea78c14ad3 --- /dev/null +++ b/Documentation/devicetree/bindings/ata/allwinner,sun4i-a10-ahci.txt @@ -0,0 +1,40 @@ +Allwinner A10/A20/R40 SoC SATA AHCI Controller + +Required properties: +- compatible: compatible string, one of: + - "allwinner,sun4i-a10-ahci" + - "allwinner,sun8i-r40-ahci" +- interrupts: the SATA IRQ +- reg : the register mapping +- clocks: the clocks needed by SATA controller, usually contains + an AHB clock and a mod clock + +Optional properties: +- target-supply : regulator for SATA target power + +Required properties for the following compatibles: + - "allwinner,sun8i-r40-ahci" +- resets: the reset control needed by SATA controller +- vdd1v2-supply : regulator for SATA controller's 1.2V VDD +- vdd2v5-supply : regulator for SATA controller's 2.5V VDD + + +Examples for A10: + ahci: sata@1c18000 { + compatible = "allwinner,sun4i-a10-ahci"; + reg = <0x01c18000 0x1000>; + interrupts = <56>; + clocks = < 0>, <_gates 25>; + target-supply = <_ahci_5v>; + }; + +Examples for R40: + ahci: sata@1c18000 { + compatible = "allwinner,sun8i-r40-ahci"; + reg = <0x01c18000 0x1000>; + interrupts = ; + clocks = < CLK_SATA>, < CLK_BUS_SATA>; + resets = < RST_BUS_SATA>; + vdd1v2-supply = <_eldo3>; + vdd2v5-supply = <_dldo4>; + }; -- 2.13.6
[PATCH 2/2] ata: ahci_sunxi: add support for R40 SATA controller
Allwinner R40 SoC has an AHCI SATA controller like the one in A10/A20, but with a reset control and two dedicated VDD pins for this controller (one 1.2v and one 2.5v). Add support for it. Signed-off-by: Icenowy Zheng --- drivers/ata/ahci_sunxi.c | 118 +-- 1 file changed, 115 insertions(+), 3 deletions(-) diff --git a/drivers/ata/ahci_sunxi.c b/drivers/ata/ahci_sunxi.c index b26437430163..a650fd6508be 100644 --- a/drivers/ata/ahci_sunxi.c +++ b/drivers/ata/ahci_sunxi.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "ahci.h" #define DRV_NAME "ahci-sunxi" @@ -58,6 +59,19 @@ MODULE_PARM_DESC(enable_pmp, #define AHCI_P0PHYCR 0x0178 #define AHCI_P0PHYSR 0x017c +struct ahci_sunxi_quirks { + bool has_reset; + bool has_vdd1v2; + bool has_vdd2v5; +}; + +struct ahci_sunxi_data { + const struct ahci_sunxi_quirks *quirks; + struct reset_control *reset; + struct regulator *vdd1v2; + struct regulator *vdd2v5; +}; + static void sunxi_clrbits(void __iomem *reg, u32 clr_val) { u32 reg_val; @@ -179,17 +193,69 @@ static int ahci_sunxi_probe(struct platform_device *pdev) { struct device *dev = >dev; struct ahci_host_priv *hpriv; + struct ahci_sunxi_data *data; int rc; + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->quirks = of_device_get_match_data(dev); + if (!data->quirks) + return -EINVAL; + + if (data->quirks->has_reset) { + data->reset = devm_reset_control_get(dev, NULL); + if (IS_ERR(data->reset)) { + dev_err(dev, "Failed to get reset\n"); + return PTR_ERR(data->reset); + } + } + + if (data->quirks->has_vdd1v2) { + data->vdd1v2 = devm_regulator_get(dev, "vdd1v2"); + if (IS_ERR(data->vdd1v2)) { + dev_err(dev, "Failed to get 1.2v VDD regulator\n"); + return PTR_ERR(data->vdd1v2); + } + } + + if (data->quirks->has_vdd2v5) { + data->vdd2v5 = devm_regulator_get(dev, "vdd2v5"); + if (IS_ERR(data->vdd2v5)) { + dev_err(dev, "Failed to get 2.5v VDD regulator\n"); + return PTR_ERR(data->vdd2v5); + } + } + hpriv = ahci_platform_get_resources(pdev); if (IS_ERR(hpriv)) return PTR_ERR(hpriv); + hpriv->plat_data = data; hpriv->start_engine = ahci_sunxi_start_engine; + if (data->quirks->has_vdd1v2) { + rc = regulator_enable(data->vdd1v2); + if (rc) + return rc; + } + + if (data->quirks->has_vdd2v5) { + rc = regulator_enable(data->vdd2v5); + if (rc) + goto disable_vdd1v2; + } + + if (data->quirks->has_reset) { + rc = reset_control_deassert(data->reset); + if (rc) + goto disable_vdd2v5; + } + rc = ahci_platform_enable_resources(hpriv); if (rc) - return rc; + goto assert_reset; rc = ahci_sunxi_phy_init(dev, hpriv->mmio); if (rc) @@ -215,6 +281,35 @@ static int ahci_sunxi_probe(struct platform_device *pdev) disable_resources: ahci_platform_disable_resources(hpriv); +assert_reset: + if (data->quirks->has_reset) + reset_control_assert(data->reset); +disable_vdd2v5: + if (data->quirks->has_vdd2v5) + regulator_disable(data->vdd2v5); +disable_vdd1v2: + if (data->quirks->has_vdd1v2) + regulator_disable(data->vdd1v2); + return rc; +} + +static int ahci_sunxi_remove(struct platform_device *pdev) +{ + struct device *dev = >dev; + struct ata_host *host = dev_get_drvdata(dev); + struct ahci_host_priv *hpriv = host->private_data; + struct ahci_sunxi_data *data = hpriv->plat_data; + int rc; + + rc = ata_platform_remove_one(pdev); + + if (data->quirks->has_reset) + reset_control_assert(data->reset); + if (data->quirks->has_vdd2v5) + regulator_disable(data->vdd2v5); + if (data->quirks->has_vdd1v2) + regulator_disable(data->vdd1v2); + return rc; } @@ -248,15 +343,32 @@ static int ahci_sunxi_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(ahci_sunxi_pm_ops, ahci_platform_suspend, ahci_sunxi_resume); +static const struct ahci_sunxi_quirks sun4i_a10_ahci_quirks = { + /* Nothing special */ +}; + +static const struct ahci_sunxi_quirks sun8i_r40_ahci_quirks = { + .has_reset = true, + .has_vdd1v2 = true, + .has_vdd2v5 = true, +}; + static const struct of_device_id
[PATCH 1/2] dt-bindings: add binding for Allwinner R40 SATA AHCI controller
The Allwinner R40 SoC contains a SATA AHCI controller like the one in A10/A20 SoCs, however a reset control and two power supplies are added to it. Add a binding document for it. As a dedicated binding document is needed now for the A10/A20/R40 AHCI controller, drop the A10 compatible line from generic platform AHCI controller binding document. Signed-off-by: Icenowy Zheng --- .../devicetree/bindings/ata/ahci-platform.txt | 1 - .../bindings/ata/allwinner,sun4i-a10-ahci.txt | 40 ++ 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/ata/allwinner,sun4i-a10-ahci.txt diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt index fedc213b5f1a..da6818b2c204 100644 --- a/Documentation/devicetree/bindings/ata/ahci-platform.txt +++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt @@ -9,7 +9,6 @@ PHYs. Required properties: - compatible: compatible string, one of: - - "allwinner,sun4i-a10-ahci" - "brcm,iproc-ahci" - "hisilicon,hisi-ahci" - "cavium,octeon-7130-ahci" diff --git a/Documentation/devicetree/bindings/ata/allwinner,sun4i-a10-ahci.txt b/Documentation/devicetree/bindings/ata/allwinner,sun4i-a10-ahci.txt new file mode 100644 index ..0eea78c14ad3 --- /dev/null +++ b/Documentation/devicetree/bindings/ata/allwinner,sun4i-a10-ahci.txt @@ -0,0 +1,40 @@ +Allwinner A10/A20/R40 SoC SATA AHCI Controller + +Required properties: +- compatible: compatible string, one of: + - "allwinner,sun4i-a10-ahci" + - "allwinner,sun8i-r40-ahci" +- interrupts: the SATA IRQ +- reg : the register mapping +- clocks: the clocks needed by SATA controller, usually contains + an AHB clock and a mod clock + +Optional properties: +- target-supply : regulator for SATA target power + +Required properties for the following compatibles: + - "allwinner,sun8i-r40-ahci" +- resets: the reset control needed by SATA controller +- vdd1v2-supply : regulator for SATA controller's 1.2V VDD +- vdd2v5-supply : regulator for SATA controller's 2.5V VDD + + +Examples for A10: + ahci: sata@1c18000 { + compatible = "allwinner,sun4i-a10-ahci"; + reg = <0x01c18000 0x1000>; + interrupts = <56>; + clocks = < 0>, <_gates 25>; + target-supply = <_ahci_5v>; + }; + +Examples for R40: + ahci: sata@1c18000 { + compatible = "allwinner,sun8i-r40-ahci"; + reg = <0x01c18000 0x1000>; + interrupts = ; + clocks = < CLK_SATA>, < CLK_BUS_SATA>; + resets = < RST_BUS_SATA>; + vdd1v2-supply = <_eldo3>; + vdd2v5-supply = <_dldo4>; + }; -- 2.13.6
[PATCH 6/6] ARM: sun8i: v40: enable USB host ports for Banana Pi M2 Berry
Banana Pi M2 Berry has an on-board USB Hub that provides 4 USB Type-A ports, and it's connected to the USB1 port of the SoC. Enable it. Signed-off-by: Icenowy Zheng--- arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts | 13 + 1 file changed, 13 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts b/arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts index fe16fc0eb518..45c17c8c5915 100644 --- a/arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts +++ b/arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts @@ -87,6 +87,10 @@ }; }; + { + status = "okay"; +}; + { status = "okay"; @@ -98,6 +102,10 @@ }; }; + { + status = "okay"; +}; + #include "axp22x.dtsi" _aldo3 { @@ -171,3 +179,8 @@ pinctrl-0 = <_pb_pins>; status = "okay"; }; + + { + usb1_vbus-supply = <_vcc5v0>; + status = "okay"; +}; -- 2.13.6
[PATCH 6/6] ARM: sun8i: v40: enable USB host ports for Banana Pi M2 Berry
Banana Pi M2 Berry has an on-board USB Hub that provides 4 USB Type-A ports, and it's connected to the USB1 port of the SoC. Enable it. Signed-off-by: Icenowy Zheng --- arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts | 13 + 1 file changed, 13 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts b/arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts index fe16fc0eb518..45c17c8c5915 100644 --- a/arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts +++ b/arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts @@ -87,6 +87,10 @@ }; }; + { + status = "okay"; +}; + { status = "okay"; @@ -98,6 +102,10 @@ }; }; + { + status = "okay"; +}; + #include "axp22x.dtsi" _aldo3 { @@ -171,3 +179,8 @@ pinctrl-0 = <_pb_pins>; status = "okay"; }; + + { + usb1_vbus-supply = <_vcc5v0>; + status = "okay"; +}; -- 2.13.6
[PATCH 4/6] ARM: sun8i: v40: add 5V regulator for Banana Pi M2 Berry
On the Banana Pi M2 Berry board, the 5V power output (used by HDMI, SATA and USB) is controlled via a GPIO. Add regulator node for it. Signed-off-by: Icenowy Zheng--- arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts | 9 + 1 file changed, 9 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts b/arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts index 8a69be2a0842..fe16fc0eb518 100644 --- a/arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts +++ b/arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts @@ -72,6 +72,15 @@ }; }; + reg_vcc5v0: vcc5v0 { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0"; + regulator-min-microvolt = <500>; + regulator-max-microvolt = <500>; + gpio = < 7 23 GPIO_ACTIVE_HIGH>; /* PH23 */ + enable-active-high; + }; + wifi_pwrseq: wifi_pwrseq { compatible = "mmc-pwrseq-simple"; reset-gpios = < 6 10 GPIO_ACTIVE_LOW>; /* PG10 WIFI_EN */ -- 2.13.6
[PATCH 2/6] ARM: sun8i: r40: add USB host port nodes for R40
From: Icenowy ZhengAllwinner R40 SoC features a USB OTG port and two USB HOST ports. Add support for the host ports in the DTSI file. The OTG controller still cannot work with existing compatibles, and needs more investigation. So it's not added yet. Signed-off-by: Icenowy Zheng --- arch/arm/boot/dts/sun8i-r40.dtsi | 78 1 file changed, 78 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-r40.dtsi b/arch/arm/boot/dts/sun8i-r40.dtsi index d5a6745409ae..f6c917cbbaac 100644 --- a/arch/arm/boot/dts/sun8i-r40.dtsi +++ b/arch/arm/boot/dts/sun8i-r40.dtsi @@ -173,6 +173,84 @@ #size-cells = <0>; }; + usbphy: phy@1c13400 { + compatible = "allwinner,sun8i-r40-usb-phy"; + reg = <0x01c13400 0x14>, + <0x01c14800 0x4>, + <0x01c19800 0x4>, + <0x01c1c800 0x4>; + reg-names = "phy_ctrl", + "pmu0", + "pmu1", + "pmu2"; + clocks = < CLK_USB_PHY0>, +< CLK_USB_PHY1>, +< CLK_USB_PHY2>; + clock-names = "usb0_phy", + "usb1_phy", + "usb2_phy"; + resets = < RST_USB_PHY0>, +< RST_USB_PHY1>, +< RST_USB_PHY2>; + reset-names = "usb0_reset", + "usb1_reset", + "usb2_reset"; + status = "disabled"; + #phy-cells = <1>; + }; + + ehci1: usb@1c19000 { + compatible = "allwinner,sun8i-r40-ehci", "generic-ehci"; + reg = <0x01c19000 0x100>; + interrupts = ; + clocks = < CLK_BUS_OHCI1>, +< CLK_BUS_EHCI1>, +< CLK_USB_OHCI1>; + resets = < RST_BUS_OHCI1>, +< RST_BUS_EHCI1>; + phys = < 1>; + phy-names = "usb"; + status = "disabled"; + }; + + ohci1: usb@1c19400 { + compatible = "allwinner,sun8i-r40-ohci", "generic-ohci"; + reg = <0x01c19400 0x100>; + interrupts = ; + clocks = < CLK_BUS_OHCI1>, +< CLK_USB_OHCI1>; + resets = < RST_BUS_OHCI1>; + phys = < 1>; + phy-names = "usb"; + status = "disabled"; + }; + + ehci2: usb@1c1c000 { + compatible = "allwinner,sun8i-r40-ehci", "generic-ehci"; + reg = <0x01c1c000 0x100>; + interrupts = ; + clocks = < CLK_BUS_OHCI2>, +< CLK_BUS_EHCI2>, +< CLK_USB_OHCI2>; + resets = < RST_BUS_OHCI2>, +< RST_BUS_EHCI2>; + phys = < 2>; + phy-names = "usb"; + status = "disabled"; + }; + + ohci2: usb@1c1c400 { + compatible = "allwinner,sun8i-r40-ohci", "generic-ohci"; + reg = <0x01c1c400 0x100>; + interrupts = ; + clocks = < CLK_BUS_OHCI2>, +< CLK_USB_OHCI2>; + resets = < RST_BUS_OHCI2>; + phys = < 2>; + phy-names = "usb"; + status = "disabled"; + }; + ccu: clock@1c2 { compatible = "allwinner,sun8i-r40-ccu"; reg = <0x01c2 0x400>; -- 2.13.6
[PATCH 3/6] ARM: sun8i: r40: add 5V regulator for Banana Pi M2 Ultra
On newer revisions of the Banana Pi M2 Ultra boards, the 5V power output (used by HDMI, SATA and USB) is controller via a GPIO. Add the regulator node for it. Older revisions just have the 5V power output always on, and the GPIO is reserved on these boards. So it won't affect the older revisions. Signed-off-by: Icenowy Zheng--- arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts | 9 + 1 file changed, 9 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts b/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts index 7b52608cebe6..035599d870b9 100644 --- a/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts +++ b/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts @@ -78,6 +78,15 @@ }; }; + reg_vcc5v0: vcc5v0 { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0"; + regulator-min-microvolt = <500>; + regulator-max-microvolt = <500>; + gpio = < 7 23 GPIO_ACTIVE_HIGH>; /* PH23 */ + enable-active-high; + }; + wifi_pwrseq: wifi_pwrseq { compatible = "mmc-pwrseq-simple"; reset-gpios = < 6 10 GPIO_ACTIVE_LOW>; /* PG10 WIFI_EN */ -- 2.13.6
[PATCH 2/6] ARM: sun8i: r40: add USB host port nodes for R40
From: Icenowy Zheng Allwinner R40 SoC features a USB OTG port and two USB HOST ports. Add support for the host ports in the DTSI file. The OTG controller still cannot work with existing compatibles, and needs more investigation. So it's not added yet. Signed-off-by: Icenowy Zheng --- arch/arm/boot/dts/sun8i-r40.dtsi | 78 1 file changed, 78 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-r40.dtsi b/arch/arm/boot/dts/sun8i-r40.dtsi index d5a6745409ae..f6c917cbbaac 100644 --- a/arch/arm/boot/dts/sun8i-r40.dtsi +++ b/arch/arm/boot/dts/sun8i-r40.dtsi @@ -173,6 +173,84 @@ #size-cells = <0>; }; + usbphy: phy@1c13400 { + compatible = "allwinner,sun8i-r40-usb-phy"; + reg = <0x01c13400 0x14>, + <0x01c14800 0x4>, + <0x01c19800 0x4>, + <0x01c1c800 0x4>; + reg-names = "phy_ctrl", + "pmu0", + "pmu1", + "pmu2"; + clocks = < CLK_USB_PHY0>, +< CLK_USB_PHY1>, +< CLK_USB_PHY2>; + clock-names = "usb0_phy", + "usb1_phy", + "usb2_phy"; + resets = < RST_USB_PHY0>, +< RST_USB_PHY1>, +< RST_USB_PHY2>; + reset-names = "usb0_reset", + "usb1_reset", + "usb2_reset"; + status = "disabled"; + #phy-cells = <1>; + }; + + ehci1: usb@1c19000 { + compatible = "allwinner,sun8i-r40-ehci", "generic-ehci"; + reg = <0x01c19000 0x100>; + interrupts = ; + clocks = < CLK_BUS_OHCI1>, +< CLK_BUS_EHCI1>, +< CLK_USB_OHCI1>; + resets = < RST_BUS_OHCI1>, +< RST_BUS_EHCI1>; + phys = < 1>; + phy-names = "usb"; + status = "disabled"; + }; + + ohci1: usb@1c19400 { + compatible = "allwinner,sun8i-r40-ohci", "generic-ohci"; + reg = <0x01c19400 0x100>; + interrupts = ; + clocks = < CLK_BUS_OHCI1>, +< CLK_USB_OHCI1>; + resets = < RST_BUS_OHCI1>; + phys = < 1>; + phy-names = "usb"; + status = "disabled"; + }; + + ehci2: usb@1c1c000 { + compatible = "allwinner,sun8i-r40-ehci", "generic-ehci"; + reg = <0x01c1c000 0x100>; + interrupts = ; + clocks = < CLK_BUS_OHCI2>, +< CLK_BUS_EHCI2>, +< CLK_USB_OHCI2>; + resets = < RST_BUS_OHCI2>, +< RST_BUS_EHCI2>; + phys = < 2>; + phy-names = "usb"; + status = "disabled"; + }; + + ohci2: usb@1c1c400 { + compatible = "allwinner,sun8i-r40-ohci", "generic-ohci"; + reg = <0x01c1c400 0x100>; + interrupts = ; + clocks = < CLK_BUS_OHCI2>, +< CLK_USB_OHCI2>; + resets = < RST_BUS_OHCI2>; + phys = < 2>; + phy-names = "usb"; + status = "disabled"; + }; + ccu: clock@1c2 { compatible = "allwinner,sun8i-r40-ccu"; reg = <0x01c2 0x400>; -- 2.13.6
[PATCH 3/6] ARM: sun8i: r40: add 5V regulator for Banana Pi M2 Ultra
On newer revisions of the Banana Pi M2 Ultra boards, the 5V power output (used by HDMI, SATA and USB) is controller via a GPIO. Add the regulator node for it. Older revisions just have the 5V power output always on, and the GPIO is reserved on these boards. So it won't affect the older revisions. Signed-off-by: Icenowy Zheng --- arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts | 9 + 1 file changed, 9 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts b/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts index 7b52608cebe6..035599d870b9 100644 --- a/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts +++ b/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts @@ -78,6 +78,15 @@ }; }; + reg_vcc5v0: vcc5v0 { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0"; + regulator-min-microvolt = <500>; + regulator-max-microvolt = <500>; + gpio = < 7 23 GPIO_ACTIVE_HIGH>; /* PH23 */ + enable-active-high; + }; + wifi_pwrseq: wifi_pwrseq { compatible = "mmc-pwrseq-simple"; reset-gpios = < 6 10 GPIO_ACTIVE_LOW>; /* PG10 WIFI_EN */ -- 2.13.6
[PATCH 4/6] ARM: sun8i: v40: add 5V regulator for Banana Pi M2 Berry
On the Banana Pi M2 Berry board, the 5V power output (used by HDMI, SATA and USB) is controlled via a GPIO. Add regulator node for it. Signed-off-by: Icenowy Zheng --- arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts | 9 + 1 file changed, 9 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts b/arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts index 8a69be2a0842..fe16fc0eb518 100644 --- a/arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts +++ b/arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts @@ -72,6 +72,15 @@ }; }; + reg_vcc5v0: vcc5v0 { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0"; + regulator-min-microvolt = <500>; + regulator-max-microvolt = <500>; + gpio = < 7 23 GPIO_ACTIVE_HIGH>; /* PH23 */ + enable-active-high; + }; + wifi_pwrseq: wifi_pwrseq { compatible = "mmc-pwrseq-simple"; reset-gpios = < 6 10 GPIO_ACTIVE_LOW>; /* PG10 WIFI_EN */ -- 2.13.6
[PATCH 5/6] ARM: sun8i: r40: enable USB host for Banana Pi M2 Ultra
From: Icenowy ZhengBanana Pi M2 Ultra board features two USB host ports, connected to the two USB host ports on the SoC. Add support for them. Signed-off-by: Icenowy Zheng --- arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts | 22 ++ 1 file changed, 22 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts b/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts index 035599d870b9..8c5efe2a9881 100644 --- a/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts +++ b/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts @@ -93,6 +93,14 @@ }; }; + { + status = "okay"; +}; + + { + status = "okay"; +}; + { status = "okay"; @@ -180,8 +188,22 @@ status = "okay"; }; + { + status = "okay"; +}; + + { + status = "okay"; +}; + { pinctrl-names = "default"; pinctrl-0 = <_pb_pins>; status = "okay"; }; + + { + usb1_vbus-supply = <_vcc5v0>; + usb2_vbus-supply = <_vcc5v0>; + status = "okay"; +}; -- 2.13.6
[PATCH 5/6] ARM: sun8i: r40: enable USB host for Banana Pi M2 Ultra
From: Icenowy Zheng Banana Pi M2 Ultra board features two USB host ports, connected to the two USB host ports on the SoC. Add support for them. Signed-off-by: Icenowy Zheng --- arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts | 22 ++ 1 file changed, 22 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts b/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts index 035599d870b9..8c5efe2a9881 100644 --- a/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts +++ b/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts @@ -93,6 +93,14 @@ }; }; + { + status = "okay"; +}; + + { + status = "okay"; +}; + { status = "okay"; @@ -180,8 +188,22 @@ status = "okay"; }; + { + status = "okay"; +}; + + { + status = "okay"; +}; + { pinctrl-names = "default"; pinctrl-0 = <_pb_pins>; status = "okay"; }; + + { + usb1_vbus-supply = <_vcc5v0>; + usb2_vbus-supply = <_vcc5v0>; + status = "okay"; +}; -- 2.13.6
[PATCH 0/6] Allwinner R40 USB host support
This patchset adds support for the USB host ports on Allwiner R40, and enable them on Banana Pi M2 Ultra and Berry boards. The first patch adds R40 support to the USB PHY driver. The second patch adds USB PHY and EHCI/OHCI nodes to the R40 DTSI. The thrid and fourth patch adds 5V regulator for the two boards, and the fifth and sixth patch finally adds USB host ports support. Icenowy Zheng (6): phy: sun4i-usb: add support for R40 USB PHY ARM: sun8i: r40: add USB host port nodes for R40 ARM: sun8i: r40: add 5V regulator for Banana Pi M2 Ultra ARM: sun8i: v40: add 5V regulator for Banana Pi M2 Berry ARM: sun8i: r40: enable USB host for Banana Pi M2 Ultra ARM: sun8i: v40: enable USB host ports for Banana Pi M2 Berry .../devicetree/bindings/phy/sun4i-usb-phy.txt | 1 + arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts | 31 + arch/arm/boot/dts/sun8i-r40.dtsi | 78 ++ arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts | 22 ++ drivers/phy/allwinner/phy-sun4i-usb.c | 12 5 files changed, 144 insertions(+) -- 2.13.6
[PATCH 0/6] Allwinner R40 USB host support
This patchset adds support for the USB host ports on Allwiner R40, and enable them on Banana Pi M2 Ultra and Berry boards. The first patch adds R40 support to the USB PHY driver. The second patch adds USB PHY and EHCI/OHCI nodes to the R40 DTSI. The thrid and fourth patch adds 5V regulator for the two boards, and the fifth and sixth patch finally adds USB host ports support. Icenowy Zheng (6): phy: sun4i-usb: add support for R40 USB PHY ARM: sun8i: r40: add USB host port nodes for R40 ARM: sun8i: r40: add 5V regulator for Banana Pi M2 Ultra ARM: sun8i: v40: add 5V regulator for Banana Pi M2 Berry ARM: sun8i: r40: enable USB host for Banana Pi M2 Ultra ARM: sun8i: v40: enable USB host ports for Banana Pi M2 Berry .../devicetree/bindings/phy/sun4i-usb-phy.txt | 1 + arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts | 31 + arch/arm/boot/dts/sun8i-r40.dtsi | 78 ++ arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts | 22 ++ drivers/phy/allwinner/phy-sun4i-usb.c | 12 5 files changed, 144 insertions(+) -- 2.13.6
[PATCH 1/6] phy: sun4i-usb: add support for R40 USB PHY
Allwinner R40 features a USB PHY like the one in A64, but with 3 PHYs. Add support for it. Signed-off-by: Icenowy Zheng--- Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt | 1 + drivers/phy/allwinner/phy-sun4i-usb.c | 12 2 files changed, 13 insertions(+) diff --git a/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt b/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt index cbc7847dbf6c..0f00abd40a50 100644 --- a/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt +++ b/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt @@ -11,6 +11,7 @@ Required properties: * allwinner,sun8i-a33-usb-phy * allwinner,sun8i-a83t-usb-phy * allwinner,sun8i-h3-usb-phy + * allwinner,sun8i-r40-usb-phy * allwinner,sun8i-v3s-usb-phy * allwinner,sun50i-a64-usb-phy - reg : a list of offset + length pairs diff --git a/drivers/phy/allwinner/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c index 1161e11fb3cf..9df7a2c9ca75 100644 --- a/drivers/phy/allwinner/phy-sun4i-usb.c +++ b/drivers/phy/allwinner/phy-sun4i-usb.c @@ -112,6 +112,7 @@ enum sun4i_usb_phy_type { sun8i_a33_phy, sun8i_a83t_phy, sun8i_h3_phy, + sun8i_r40_phy, sun8i_v3s_phy, sun50i_a64_phy, }; @@ -919,6 +920,16 @@ static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = { .phy0_dual_route = true, }; +static const struct sun4i_usb_phy_cfg sun8i_r40_cfg = { + .num_phys = 3, + .type = sun8i_r40_phy, + .disc_thresh = 3, + .phyctl_offset = REG_PHYCTL_A33, + .dedicated_clocks = true, + .enable_pmu_unk1 = true, + .phy0_dual_route = true, +}; + static const struct sun4i_usb_phy_cfg sun8i_v3s_cfg = { .num_phys = 1, .type = sun8i_v3s_phy, @@ -947,6 +958,7 @@ static const struct of_device_id sun4i_usb_phy_of_match[] = { { .compatible = "allwinner,sun8i-a33-usb-phy", .data = _a33_cfg }, { .compatible = "allwinner,sun8i-a83t-usb-phy", .data = _a83t_cfg }, { .compatible = "allwinner,sun8i-h3-usb-phy", .data = _h3_cfg }, + { .compatible = "allwinner,sun8i-r40-usb-phy", .data = _r40_cfg }, { .compatible = "allwinner,sun8i-v3s-usb-phy", .data = _v3s_cfg }, { .compatible = "allwinner,sun50i-a64-usb-phy", .data = _a64_cfg}, -- 2.13.6
[PATCH 1/6] phy: sun4i-usb: add support for R40 USB PHY
Allwinner R40 features a USB PHY like the one in A64, but with 3 PHYs. Add support for it. Signed-off-by: Icenowy Zheng --- Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt | 1 + drivers/phy/allwinner/phy-sun4i-usb.c | 12 2 files changed, 13 insertions(+) diff --git a/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt b/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt index cbc7847dbf6c..0f00abd40a50 100644 --- a/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt +++ b/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt @@ -11,6 +11,7 @@ Required properties: * allwinner,sun8i-a33-usb-phy * allwinner,sun8i-a83t-usb-phy * allwinner,sun8i-h3-usb-phy + * allwinner,sun8i-r40-usb-phy * allwinner,sun8i-v3s-usb-phy * allwinner,sun50i-a64-usb-phy - reg : a list of offset + length pairs diff --git a/drivers/phy/allwinner/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c index 1161e11fb3cf..9df7a2c9ca75 100644 --- a/drivers/phy/allwinner/phy-sun4i-usb.c +++ b/drivers/phy/allwinner/phy-sun4i-usb.c @@ -112,6 +112,7 @@ enum sun4i_usb_phy_type { sun8i_a33_phy, sun8i_a83t_phy, sun8i_h3_phy, + sun8i_r40_phy, sun8i_v3s_phy, sun50i_a64_phy, }; @@ -919,6 +920,16 @@ static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = { .phy0_dual_route = true, }; +static const struct sun4i_usb_phy_cfg sun8i_r40_cfg = { + .num_phys = 3, + .type = sun8i_r40_phy, + .disc_thresh = 3, + .phyctl_offset = REG_PHYCTL_A33, + .dedicated_clocks = true, + .enable_pmu_unk1 = true, + .phy0_dual_route = true, +}; + static const struct sun4i_usb_phy_cfg sun8i_v3s_cfg = { .num_phys = 1, .type = sun8i_v3s_phy, @@ -947,6 +958,7 @@ static const struct of_device_id sun4i_usb_phy_of_match[] = { { .compatible = "allwinner,sun8i-a33-usb-phy", .data = _a33_cfg }, { .compatible = "allwinner,sun8i-a83t-usb-phy", .data = _a83t_cfg }, { .compatible = "allwinner,sun8i-h3-usb-phy", .data = _h3_cfg }, + { .compatible = "allwinner,sun8i-r40-usb-phy", .data = _r40_cfg }, { .compatible = "allwinner,sun8i-v3s-usb-phy", .data = _v3s_cfg }, { .compatible = "allwinner,sun50i-a64-usb-phy", .data = _a64_cfg}, -- 2.13.6
[PATCH] staging/rtl8188eu: Fix a possible sleep-in-atomic bug in rtw_disassoc_cmd
The driver may sleep under a spinlock, and the function call path is: rtw_set_802_11_bssid(acquire the spinlock) rtw_disassoc_cmd kzalloc(GFP_KERNEL) --> may sleep To fix it, GFP_KERNEL is replaced with GFP_ATOMIC. This bug is found by my static analysis tool and my code review. Signed-off-by: Jia-Ju Bai--- drivers/staging/rtl8188eu/core/rtw_cmd.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_cmd.c b/drivers/staging/rtl8188eu/core/rtw_cmd.c index 9461bce..65083a7 100644 --- a/drivers/staging/rtl8188eu/core/rtw_cmd.c +++ b/drivers/staging/rtl8188eu/core/rtw_cmd.c @@ -508,7 +508,7 @@ u8 rtw_disassoc_cmd(struct adapter *padapter, u32 deauth_timeout_ms, bool enqueu if (enqueue) { /* need enqueue, prepare cmd_obj and enqueue */ - cmdobj = kzalloc(sizeof(*cmdobj), GFP_KERNEL); + cmdobj = kzalloc(sizeof(*cmdobj), GFP_ATOMIC); if (!cmdobj) { res = _FAIL; kfree(param); -- 1.7.9.5
[PATCH] staging/rtl8188eu: Fix a possible sleep-in-atomic bug in rtw_disassoc_cmd
The driver may sleep under a spinlock, and the function call path is: rtw_set_802_11_bssid(acquire the spinlock) rtw_disassoc_cmd kzalloc(GFP_KERNEL) --> may sleep To fix it, GFP_KERNEL is replaced with GFP_ATOMIC. This bug is found by my static analysis tool and my code review. Signed-off-by: Jia-Ju Bai --- drivers/staging/rtl8188eu/core/rtw_cmd.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_cmd.c b/drivers/staging/rtl8188eu/core/rtw_cmd.c index 9461bce..65083a7 100644 --- a/drivers/staging/rtl8188eu/core/rtw_cmd.c +++ b/drivers/staging/rtl8188eu/core/rtw_cmd.c @@ -508,7 +508,7 @@ u8 rtw_disassoc_cmd(struct adapter *padapter, u32 deauth_timeout_ms, bool enqueu if (enqueue) { /* need enqueue, prepare cmd_obj and enqueue */ - cmdobj = kzalloc(sizeof(*cmdobj), GFP_KERNEL); + cmdobj = kzalloc(sizeof(*cmdobj), GFP_ATOMIC); if (!cmdobj) { res = _FAIL; kfree(param); -- 1.7.9.5
[PATCH] arch/x86: remove redundant null checks before kmem_cache_destroy
Remove redundant null checks before calling kmem_cache_destroy. Found with make coccicheck M=arch/x86/kvm on linux-next tag next-20170929. Signed-off-by: Tim Hansen--- arch/x86/kvm/mmu.c | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index eca30c1eb1d9..a6c7177326c5 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -5463,10 +5463,8 @@ static struct shrinker mmu_shrinker = { static void mmu_destroy_caches(void) { - if (pte_list_desc_cache) - kmem_cache_destroy(pte_list_desc_cache); - if (mmu_page_header_cache) - kmem_cache_destroy(mmu_page_header_cache); + kmem_cache_destroy(pte_list_desc_cache); + kmem_cache_destroy(mmu_page_header_cache); } int kvm_mmu_module_init(void) -- 2.14.2
[PATCH] arch/x86: remove redundant null checks before kmem_cache_destroy
Remove redundant null checks before calling kmem_cache_destroy. Found with make coccicheck M=arch/x86/kvm on linux-next tag next-20170929. Signed-off-by: Tim Hansen --- arch/x86/kvm/mmu.c | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index eca30c1eb1d9..a6c7177326c5 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -5463,10 +5463,8 @@ static struct shrinker mmu_shrinker = { static void mmu_destroy_caches(void) { - if (pte_list_desc_cache) - kmem_cache_destroy(pte_list_desc_cache); - if (mmu_page_header_cache) - kmem_cache_destroy(mmu_page_header_cache); + kmem_cache_destroy(pte_list_desc_cache); + kmem_cache_destroy(mmu_page_header_cache); } int kvm_mmu_module_init(void) -- 2.14.2
[PATCH 2/2] KVM: X86: XCR0 should be set to the fixed value on vCPU reset
From: Wanpeng LiSDM section 2.6 mentioned: After reset, all bits (except bit 0) in XCR0 are cleared to zero; XCR0[0] is set to 1. This patch sets XCRO to the 0x1 after vCPU reset. Cc: Paolo Bonzini Cc: Radim Krčmář Signed-off-by: Wanpeng Li --- arch/x86/kvm/x86.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index b0d2915..c784cd6 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -7816,6 +7816,8 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) vcpu->arch.regs_avail = ~0; vcpu->arch.regs_dirty = ~0; + vcpu->arch.xcr0 = XFEATURE_MASK_FP; + kvm_x86_ops->vcpu_reset(vcpu, init_event); } -- 2.7.4
[PATCH 2/2] KVM: X86: XCR0 should be set to the fixed value on vCPU reset
From: Wanpeng Li SDM section 2.6 mentioned: After reset, all bits (except bit 0) in XCR0 are cleared to zero; XCR0[0] is set to 1. This patch sets XCRO to the 0x1 after vCPU reset. Cc: Paolo Bonzini Cc: Radim Krčmář Signed-off-by: Wanpeng Li --- arch/x86/kvm/x86.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index b0d2915..c784cd6 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -7816,6 +7816,8 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) vcpu->arch.regs_avail = ~0; vcpu->arch.regs_dirty = ~0; + vcpu->arch.xcr0 = XFEATURE_MASK_FP; + kvm_x86_ops->vcpu_reset(vcpu, init_event); } -- 2.7.4
[PATCH 1/2] KVM: VMX: Don't expose unrestricted_guest is enabled if ept is disabled
From: Wanpeng LiSDM mentioned: "If either the “unrestricted guest” VM-execution control or the “mode-based execute control for EPT” VM- execution control is 1, the “enable EPT” VM-execution control must also be 1." However, we can still observe unrestricted_guest is Y after inserting the kvm-intel.ko w/ ept=N. It depends on later starts a guest in order that the function vmx_compute_secondary_exec_control() can be executed, then both the module parameter and exec control fields will be amended. This patch fixes it by amending module parameter immediately during vmcs data setup. Cc: Paolo Bonzini Cc: Radim Krčmář Signed-off-by: Wanpeng Li --- arch/x86/kvm/vmx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 244e366..3e664ca 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -6737,7 +6737,7 @@ static __init int hardware_setup(void) if (!cpu_has_vmx_ept_ad_bits() || !enable_ept) enable_ept_ad_bits = 0; - if (!cpu_has_vmx_unrestricted_guest()) + if (!cpu_has_vmx_unrestricted_guest() || !enable_ept) enable_unrestricted_guest = 0; if (!cpu_has_vmx_flexpriority()) -- 2.7.4
[PATCH 1/2] KVM: VMX: Don't expose unrestricted_guest is enabled if ept is disabled
From: Wanpeng Li SDM mentioned: "If either the “unrestricted guest” VM-execution control or the “mode-based execute control for EPT” VM- execution control is 1, the “enable EPT” VM-execution control must also be 1." However, we can still observe unrestricted_guest is Y after inserting the kvm-intel.ko w/ ept=N. It depends on later starts a guest in order that the function vmx_compute_secondary_exec_control() can be executed, then both the module parameter and exec control fields will be amended. This patch fixes it by amending module parameter immediately during vmcs data setup. Cc: Paolo Bonzini Cc: Radim Krčmář Signed-off-by: Wanpeng Li --- arch/x86/kvm/vmx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 244e366..3e664ca 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -6737,7 +6737,7 @@ static __init int hardware_setup(void) if (!cpu_has_vmx_ept_ad_bits() || !enable_ept) enable_ept_ad_bits = 0; - if (!cpu_has_vmx_unrestricted_guest()) + if (!cpu_has_vmx_unrestricted_guest() || !enable_ept) enable_unrestricted_guest = 0; if (!cpu_has_vmx_flexpriority()) -- 2.7.4
Re: [RESEND PATCH] gpio: omap: Fix lost edge interrupts
On 10/7/17 4:18 AM, Linus Walleij wrote: On Tue, Oct 3, 2017 at 6:17 PM, Grygorii Strashkowrote: Now acking of edge irqs happens the following way: - omap_gpio_irq_handler - "isr" = read irq status - omap_clear_gpio_irqbank(bank, isr_saved & ~level_mask); ^ clear edge status, so irq can be accepted - loop while "isr" generic_handle_irq() - handle_edge_irq() - desc->irq_data.chip->irq_ack(>irq_data); - omap_gpio_ack_irq() it might be that at this moment edge IRQ was triggered again and it will be cleared and IRQ will be lost. Use handle_simple_irq and clear edge interrupts early without disabling them in omap_gpio_irq_handler to avoid loosing interrupts. [1] https://urldefense.proofpoint.com/v2/url?u=https-3A__marc.info_-3Fl-3Dlinux-2Domap-26m-3D149004465313534-26w-3D2=DwIBaQ=RoP1YumCXCgaWHvlZYR8PQcxBKCX5YTpkKY057SbK10=XBn1JQGPwR8CsE7xpP3wPlG6DQU7qw8ym65xieNZ4hY=GC9UD4RPcq1Ss-JanXn4japAFhT1w4RZlq9WqDLSw_o=smHFYjIN3O5THK4qP413bHMnr8PaWUv4xyUbbTwXHk4= This link doesn't need to be part of the changelog. Signed-off-by: Grygorii Strashko Signed-off-by: Ladislav Michl Patch applied for fixes. I guess it is the right thing to do? Other maintainers need to tell me if I should hold it back. Am fine with it after Grygorii's reasoning. Regards, Santosh
Re: [RESEND PATCH] gpio: omap: Fix lost edge interrupts
On 10/7/17 4:18 AM, Linus Walleij wrote: On Tue, Oct 3, 2017 at 6:17 PM, Grygorii Strashko wrote: Now acking of edge irqs happens the following way: - omap_gpio_irq_handler - "isr" = read irq status - omap_clear_gpio_irqbank(bank, isr_saved & ~level_mask); ^ clear edge status, so irq can be accepted - loop while "isr" generic_handle_irq() - handle_edge_irq() - desc->irq_data.chip->irq_ack(>irq_data); - omap_gpio_ack_irq() it might be that at this moment edge IRQ was triggered again and it will be cleared and IRQ will be lost. Use handle_simple_irq and clear edge interrupts early without disabling them in omap_gpio_irq_handler to avoid loosing interrupts. [1] https://urldefense.proofpoint.com/v2/url?u=https-3A__marc.info_-3Fl-3Dlinux-2Domap-26m-3D149004465313534-26w-3D2=DwIBaQ=RoP1YumCXCgaWHvlZYR8PQcxBKCX5YTpkKY057SbK10=XBn1JQGPwR8CsE7xpP3wPlG6DQU7qw8ym65xieNZ4hY=GC9UD4RPcq1Ss-JanXn4japAFhT1w4RZlq9WqDLSw_o=smHFYjIN3O5THK4qP413bHMnr8PaWUv4xyUbbTwXHk4= This link doesn't need to be part of the changelog. Signed-off-by: Grygorii Strashko Signed-off-by: Ladislav Michl Patch applied for fixes. I guess it is the right thing to do? Other maintainers need to tell me if I should hold it back. Am fine with it after Grygorii's reasoning. Regards, Santosh
Re: [PATCH review for 4.4 14/24] dmaengine: sun6i: allow build on ARM64 platforms (sun50i)
于 2017年10月8日 GMT+08:00 上午6:37:46, "Levin, Alexander (Sasha Levin)"写到: >From: Icenowy Zheng > >[ Upstream commit c429ceb1e18252122ba96b52e689dcf87103c186 ] > >As 64-bit Allwinner H5 SoC has the same DMA engine with H3, the DMA >driver should be allowed to be built for ARM64, in order to make it >work on H5. There's no H5 support in 4.4/4.9. This patch can be ignored. > >Signed-off-by: Icenowy Zheng >Acked-by: Maxime Ripard >Acked-by: Chen-Yu Tsai >Signed-off-by: Vinod Koul >Signed-off-by: Sasha Levin >--- > drivers/dma/Kconfig | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig >index e6cd1a32025a..27b7b3a9bdd2 100644 >--- a/drivers/dma/Kconfig >+++ b/drivers/dma/Kconfig >@@ -158,7 +158,7 @@ config DMA_SUN4I > > config DMA_SUN6I > tristate "Allwinner A31 SoCs DMA support" >- depends on MACH_SUN6I || MACH_SUN8I || COMPILE_TEST >+ depends on MACH_SUN6I || MACH_SUN8I || (ARM64 && ARCH_SUNXI) || >COMPILE_TEST > depends on RESET_CONTROLLER > select DMA_ENGINE > select DMA_VIRTUAL_CHANNELS
Re: [PATCH review for 4.4 14/24] dmaengine: sun6i: allow build on ARM64 platforms (sun50i)
于 2017年10月8日 GMT+08:00 上午6:37:46, "Levin, Alexander (Sasha Levin)" 写到: >From: Icenowy Zheng > >[ Upstream commit c429ceb1e18252122ba96b52e689dcf87103c186 ] > >As 64-bit Allwinner H5 SoC has the same DMA engine with H3, the DMA >driver should be allowed to be built for ARM64, in order to make it >work on H5. There's no H5 support in 4.4/4.9. This patch can be ignored. > >Signed-off-by: Icenowy Zheng >Acked-by: Maxime Ripard >Acked-by: Chen-Yu Tsai >Signed-off-by: Vinod Koul >Signed-off-by: Sasha Levin >--- > drivers/dma/Kconfig | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig >index e6cd1a32025a..27b7b3a9bdd2 100644 >--- a/drivers/dma/Kconfig >+++ b/drivers/dma/Kconfig >@@ -158,7 +158,7 @@ config DMA_SUN4I > > config DMA_SUN6I > tristate "Allwinner A31 SoCs DMA support" >- depends on MACH_SUN6I || MACH_SUN8I || COMPILE_TEST >+ depends on MACH_SUN6I || MACH_SUN8I || (ARM64 && ARCH_SUNXI) || >COMPILE_TEST > depends on RESET_CONTROLLER > select DMA_ENGINE > select DMA_VIRTUAL_CHANNELS
Re: [BUG] fs/super: a possible sleep-in-atomic bug in put_super
On Sun, Oct 08, 2017 at 01:56:08AM +0100, Al Viro wrote: > What's more, we need to be careful about resize vs. drain. Right now it's > on list_lrus_mutex, but if we drop that around actual resize of an individual > list_lru, we'll need something else. Would there be any problem if we > took memcg_cache_ids_sem shared in memcg_offline_kmem()? > > The first problem is not fatal - we can e.g. use the sign of the field used > to store the number of ->memcg_lrus elements (i.e. stashed value of > memcg_nr_cache_ids at allocation or last resize) to indicate that actual > freeing is left for resizer... Ugh. That spinlock would have to be held over too much work, or bounced back and forth a lot on memcg shutdowns ;-/ Gets especially nasty if we want list_lru_destroy() callable from rcu callbacks. Oh, well... I still suspect that locking there is too heavy, but it looks like I don't have a better replacement. What are the realistic numbers of memcg on a big system?
Re: [BUG] fs/super: a possible sleep-in-atomic bug in put_super
On Sun, Oct 08, 2017 at 01:56:08AM +0100, Al Viro wrote: > What's more, we need to be careful about resize vs. drain. Right now it's > on list_lrus_mutex, but if we drop that around actual resize of an individual > list_lru, we'll need something else. Would there be any problem if we > took memcg_cache_ids_sem shared in memcg_offline_kmem()? > > The first problem is not fatal - we can e.g. use the sign of the field used > to store the number of ->memcg_lrus elements (i.e. stashed value of > memcg_nr_cache_ids at allocation or last resize) to indicate that actual > freeing is left for resizer... Ugh. That spinlock would have to be held over too much work, or bounced back and forth a lot on memcg shutdowns ;-/ Gets especially nasty if we want list_lru_destroy() callable from rcu callbacks. Oh, well... I still suspect that locking there is too heavy, but it looks like I don't have a better replacement. What are the realistic numbers of memcg on a big system?
Re: [PATCH] fs/afs/flock and fs/locks: Fix possible sleep-in-atomic bugs in posix_lock_file
On Sat, Oct 07, 2017 at 06:36:57AM -0400, Jeff Layton wrote: > On Sat, 2017-10-07 at 17:55 +0800, Jia-Ju Bai wrote: > > The kernel may sleep under a spinlock, and the function call paths are: > > afs_do_unlk (acquire the spinlock) > > posix_lock_file > > posix_lock_inode (fs/locks.c) > > locks_get_lock_context > > kmem_cache_alloc(GFP_KERNEL) --> may sleep > > > > afs_do_setlk (acquire the spinlock) > > posix_lock_file > > posix_lock_inode (fs/locks.c) > > locks_get_lock_context > > kmem_cache_alloc(GFP_KERNEL) --> may sleep > > > > To fix them, GFP_KERNEL is replaced with GFP_ATOMIC. > > These bugs are found by my static analysis tool and my code review. > > > > Signed-off-by: Jia-Ju Bai> > --- > > fs/locks.c |2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > diff --git a/fs/locks.c b/fs/locks.c > > index 1bd71c4..975cc62 100644 > > --- a/fs/locks.c > > +++ b/fs/locks.c > > @@ -222,7 +222,7 @@ struct file_lock_list_struct { > > if (likely(ctx) || type == F_UNLCK) > > goto out; > > > > - ctx = kmem_cache_alloc(flctx_cache, GFP_KERNEL); > > + ctx = kmem_cache_alloc(flctx_cache, GFP_ATOMIC); > > if (!ctx) > > goto out; > > > > NAK > > This needs to be fixed in the AFS code. It should not be calling these > functions with a spinlock held. Agreed. >From a quick look at afs_do_setlk: am I misreading something, or is it actually trying to do an rpc call to the server while holding i_lock? I wonder if this is the fault of the BKL conversion: 72f98e72551f "locks: turn lock_flocks into a spinlock" claims "nothing depends on lock_flocks using the BKL any more, so we can do the switch over to a private spinlock." But this code, with lots of blockers, was under lock_flocks(). Does that mean nobody's tested fcntl locking over afs since that change in 2010? --b.
Re: [PATCH] fs/afs/flock and fs/locks: Fix possible sleep-in-atomic bugs in posix_lock_file
On Sat, Oct 07, 2017 at 06:36:57AM -0400, Jeff Layton wrote: > On Sat, 2017-10-07 at 17:55 +0800, Jia-Ju Bai wrote: > > The kernel may sleep under a spinlock, and the function call paths are: > > afs_do_unlk (acquire the spinlock) > > posix_lock_file > > posix_lock_inode (fs/locks.c) > > locks_get_lock_context > > kmem_cache_alloc(GFP_KERNEL) --> may sleep > > > > afs_do_setlk (acquire the spinlock) > > posix_lock_file > > posix_lock_inode (fs/locks.c) > > locks_get_lock_context > > kmem_cache_alloc(GFP_KERNEL) --> may sleep > > > > To fix them, GFP_KERNEL is replaced with GFP_ATOMIC. > > These bugs are found by my static analysis tool and my code review. > > > > Signed-off-by: Jia-Ju Bai > > --- > > fs/locks.c |2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > diff --git a/fs/locks.c b/fs/locks.c > > index 1bd71c4..975cc62 100644 > > --- a/fs/locks.c > > +++ b/fs/locks.c > > @@ -222,7 +222,7 @@ struct file_lock_list_struct { > > if (likely(ctx) || type == F_UNLCK) > > goto out; > > > > - ctx = kmem_cache_alloc(flctx_cache, GFP_KERNEL); > > + ctx = kmem_cache_alloc(flctx_cache, GFP_ATOMIC); > > if (!ctx) > > goto out; > > > > NAK > > This needs to be fixed in the AFS code. It should not be calling these > functions with a spinlock held. Agreed. >From a quick look at afs_do_setlk: am I misreading something, or is it actually trying to do an rpc call to the server while holding i_lock? I wonder if this is the fault of the BKL conversion: 72f98e72551f "locks: turn lock_flocks into a spinlock" claims "nothing depends on lock_flocks using the BKL any more, so we can do the switch over to a private spinlock." But this code, with lots of blockers, was under lock_flocks(). Does that mean nobody's tested fcntl locking over afs since that change in 2010? --b.
Re: [PATCH v2 3/5] kernel/locking: Use atomic_cond_read_acquire when spinning in qrwlock
On Fri, Oct 06, 2017 at 01:34:40PM +, Will Deacon wrote: > The qrwlock slowpaths involve spinning when either a prospective reader > is waiting for a concurrent writer to drain, or a prospective writer is > waiting for concurrent readers to drain. In both of these situations, > atomic_cond_read_acquire can be used to avoid busy-waiting and make use > of any backoff functionality provided by the architecture. > > This patch replaces the open-code loops and rspin_until_writer_unlock > implementation with atomic_cond_read_acquire. The write mode transition > zero to _QW_WAITING is left alone, since (a) this doesn't need acquire > semantics and (b) should be fast. > > Cc: Peter Zijlstra> Cc: Ingo Molnar > Cc: Waiman Long > Cc: Boqun Feng > Cc: "Paul E. McKenney" > Signed-off-by: Will Deacon > --- > kernel/locking/qrwlock.c | 47 +++ > 1 file changed, 11 insertions(+), 36 deletions(-) > > diff --git a/kernel/locking/qrwlock.c b/kernel/locking/qrwlock.c > index 1af791e37348..b7ea4647c74d 100644 > --- a/kernel/locking/qrwlock.c > +++ b/kernel/locking/qrwlock.c > @@ -24,23 +24,6 @@ > #include > > /** > - * rspin_until_writer_unlock - inc reader count & spin until writer is gone > - * @lock : Pointer to queue rwlock structure > - * @writer: Current queue rwlock writer status byte > - * > - * In interrupt context or at the head of the queue, the reader will just > - * increment the reader count & wait until the writer releases the lock. > - */ > -static __always_inline void > -rspin_until_writer_unlock(struct qrwlock *lock, u32 cnts) > -{ > - while ((cnts & _QW_WMASK) == _QW_LOCKED) { > - cpu_relax(); > - cnts = atomic_read_acquire(>cnts); > - } > -} > - > -/** > * queued_read_lock_slowpath - acquire read lock of a queue rwlock > * @lock: Pointer to queue rwlock structure > * @cnts: Current qrwlock lock value > @@ -53,13 +36,12 @@ void queued_read_lock_slowpath(struct qrwlock *lock, u32 > cnts) So the second parameter(@cnts) could be removed entirely, right? Any reason we still keep it? Regards, Boqun > if (unlikely(in_interrupt())) { > /* >* Readers in interrupt context will get the lock immediately > - * if the writer is just waiting (not holding the lock yet). > - * The rspin_until_writer_unlock() function returns immediately > - * in this case. Otherwise, they will spin (with ACQUIRE > - * semantics) until the lock is available without waiting in > - * the queue. > + * if the writer is just waiting (not holding the lock yet), > + * so spin with ACQUIRE semantics until the lock is available > + * without waiting in the queue. >*/ > - rspin_until_writer_unlock(lock, cnts); > + atomic_cond_read_acquire(>cnts, (VAL & _QW_WMASK) > + != _QW_LOCKED); > return; > } > atomic_sub(_QR_BIAS, >cnts); > @@ -68,14 +50,14 @@ void queued_read_lock_slowpath(struct qrwlock *lock, u32 > cnts) >* Put the reader into the wait queue >*/ > arch_spin_lock(>wait_lock); > + atomic_add(_QR_BIAS, >cnts); > > /* >* The ACQUIRE semantics of the following spinning code ensure >* that accesses can't leak upwards out of our subsequent critical >* section in the case that the lock is currently held for write. >*/ > - cnts = atomic_fetch_add_acquire(_QR_BIAS, >cnts); > - rspin_until_writer_unlock(lock, cnts); > + atomic_cond_read_acquire(>cnts, (VAL & _QW_WMASK) != _QW_LOCKED); > > /* >* Signal the next one in queue to become queue head [...] signature.asc Description: PGP signature
Re: [PATCH v2 3/5] kernel/locking: Use atomic_cond_read_acquire when spinning in qrwlock
On Fri, Oct 06, 2017 at 01:34:40PM +, Will Deacon wrote: > The qrwlock slowpaths involve spinning when either a prospective reader > is waiting for a concurrent writer to drain, or a prospective writer is > waiting for concurrent readers to drain. In both of these situations, > atomic_cond_read_acquire can be used to avoid busy-waiting and make use > of any backoff functionality provided by the architecture. > > This patch replaces the open-code loops and rspin_until_writer_unlock > implementation with atomic_cond_read_acquire. The write mode transition > zero to _QW_WAITING is left alone, since (a) this doesn't need acquire > semantics and (b) should be fast. > > Cc: Peter Zijlstra > Cc: Ingo Molnar > Cc: Waiman Long > Cc: Boqun Feng > Cc: "Paul E. McKenney" > Signed-off-by: Will Deacon > --- > kernel/locking/qrwlock.c | 47 +++ > 1 file changed, 11 insertions(+), 36 deletions(-) > > diff --git a/kernel/locking/qrwlock.c b/kernel/locking/qrwlock.c > index 1af791e37348..b7ea4647c74d 100644 > --- a/kernel/locking/qrwlock.c > +++ b/kernel/locking/qrwlock.c > @@ -24,23 +24,6 @@ > #include > > /** > - * rspin_until_writer_unlock - inc reader count & spin until writer is gone > - * @lock : Pointer to queue rwlock structure > - * @writer: Current queue rwlock writer status byte > - * > - * In interrupt context or at the head of the queue, the reader will just > - * increment the reader count & wait until the writer releases the lock. > - */ > -static __always_inline void > -rspin_until_writer_unlock(struct qrwlock *lock, u32 cnts) > -{ > - while ((cnts & _QW_WMASK) == _QW_LOCKED) { > - cpu_relax(); > - cnts = atomic_read_acquire(>cnts); > - } > -} > - > -/** > * queued_read_lock_slowpath - acquire read lock of a queue rwlock > * @lock: Pointer to queue rwlock structure > * @cnts: Current qrwlock lock value > @@ -53,13 +36,12 @@ void queued_read_lock_slowpath(struct qrwlock *lock, u32 > cnts) So the second parameter(@cnts) could be removed entirely, right? Any reason we still keep it? Regards, Boqun > if (unlikely(in_interrupt())) { > /* >* Readers in interrupt context will get the lock immediately > - * if the writer is just waiting (not holding the lock yet). > - * The rspin_until_writer_unlock() function returns immediately > - * in this case. Otherwise, they will spin (with ACQUIRE > - * semantics) until the lock is available without waiting in > - * the queue. > + * if the writer is just waiting (not holding the lock yet), > + * so spin with ACQUIRE semantics until the lock is available > + * without waiting in the queue. >*/ > - rspin_until_writer_unlock(lock, cnts); > + atomic_cond_read_acquire(>cnts, (VAL & _QW_WMASK) > + != _QW_LOCKED); > return; > } > atomic_sub(_QR_BIAS, >cnts); > @@ -68,14 +50,14 @@ void queued_read_lock_slowpath(struct qrwlock *lock, u32 > cnts) >* Put the reader into the wait queue >*/ > arch_spin_lock(>wait_lock); > + atomic_add(_QR_BIAS, >cnts); > > /* >* The ACQUIRE semantics of the following spinning code ensure >* that accesses can't leak upwards out of our subsequent critical >* section in the case that the lock is currently held for write. >*/ > - cnts = atomic_fetch_add_acquire(_QR_BIAS, >cnts); > - rspin_until_writer_unlock(lock, cnts); > + atomic_cond_read_acquire(>cnts, (VAL & _QW_WMASK) != _QW_LOCKED); > > /* >* Signal the next one in queue to become queue head [...] signature.asc Description: PGP signature
Re: [BUG] fs/super: a possible sleep-in-atomic bug in put_super
On Sat, Oct 07, 2017 at 10:14:44PM +0100, Al Viro wrote: > 1) coallocate struct list_lru and array of struct list_lru_node > hanging off it. Turn all existing variables and struct members of that > type into pointers. init would allocate and return a pointer, destroy > would free (and leave it for callers to clear their pointers, of course). Better yet, keep list_lru containing just the pointer to list_lru_node array. And put that array into the tail of struct list_lru_nodes. That way normal accesses are kept exactly as-is and we don't need to update the users of that thing at all. > 4) have lru_list_destroy() check (under list_lru_mutex) whether it's > being asked to kill the currently resized one. If it is, do > victim->list.prev->next = victim->list.next; > victim->list.next->prev = victim->list.prev; > victim->list.prev = NULL; Doesn't work, unfortunately - it needs to stay on the list and be marked in some other way. > and bugger off, otherwise act as now. Turn the loop in > memcg_update_all_list_lrus() into > mutex_lock(_lrus_mutex); > lru = list_lrus.next; > while (lru != _lrus) { > currently_resized = list_entry(lru, struct list_lru, list); > mutex_unlock(_lrus_mutex); > ret = memcg_update_list_lru(lru, old_size, new_size); > mutex_lock(_lrus_mutex); > if (unlikely(!lru->prev)) { > lru = lru->next; ... because this might very well be pointing to already freed object. > free currently_resized as list_lru_destroy() would have > continue; What's more, we need to be careful about resize vs. drain. Right now it's on list_lrus_mutex, but if we drop that around actual resize of an individual list_lru, we'll need something else. Would there be any problem if we took memcg_cache_ids_sem shared in memcg_offline_kmem()? The first problem is not fatal - we can e.g. use the sign of the field used to store the number of ->memcg_lrus elements (i.e. stashed value of memcg_nr_cache_ids at allocation or last resize) to indicate that actual freeing is left for resizer...
Re: [BUG] fs/super: a possible sleep-in-atomic bug in put_super
On Sat, Oct 07, 2017 at 10:14:44PM +0100, Al Viro wrote: > 1) coallocate struct list_lru and array of struct list_lru_node > hanging off it. Turn all existing variables and struct members of that > type into pointers. init would allocate and return a pointer, destroy > would free (and leave it for callers to clear their pointers, of course). Better yet, keep list_lru containing just the pointer to list_lru_node array. And put that array into the tail of struct list_lru_nodes. That way normal accesses are kept exactly as-is and we don't need to update the users of that thing at all. > 4) have lru_list_destroy() check (under list_lru_mutex) whether it's > being asked to kill the currently resized one. If it is, do > victim->list.prev->next = victim->list.next; > victim->list.next->prev = victim->list.prev; > victim->list.prev = NULL; Doesn't work, unfortunately - it needs to stay on the list and be marked in some other way. > and bugger off, otherwise act as now. Turn the loop in > memcg_update_all_list_lrus() into > mutex_lock(_lrus_mutex); > lru = list_lrus.next; > while (lru != _lrus) { > currently_resized = list_entry(lru, struct list_lru, list); > mutex_unlock(_lrus_mutex); > ret = memcg_update_list_lru(lru, old_size, new_size); > mutex_lock(_lrus_mutex); > if (unlikely(!lru->prev)) { > lru = lru->next; ... because this might very well be pointing to already freed object. > free currently_resized as list_lru_destroy() would have > continue; What's more, we need to be careful about resize vs. drain. Right now it's on list_lrus_mutex, but if we drop that around actual resize of an individual list_lru, we'll need something else. Would there be any problem if we took memcg_cache_ids_sem shared in memcg_offline_kmem()? The first problem is not fatal - we can e.g. use the sign of the field used to store the number of ->memcg_lrus elements (i.e. stashed value of memcg_nr_cache_ids at allocation or last resize) to indicate that actual freeing is left for resizer...
Re: [PATCH] pinctrl: cherryview: fix issues caused by dynamic gpio irqs mapping
On Tue, Oct 3, 2017 at 7:00 PM, Grygorii Strashkowrote: > New GPIO IRQs are allocated and mapped dynamically by default when > GPIO IRQ infrastructure is used by cherryview-pinctrl driver. > This causes issues on some Intel platforms [1][2] with broken BIOS which > hardcodes Linux IRQ numbers in their ACPI tables. > > On such platforms cherryview-pinctrl driver should allocate and map all > GPIO IRQs at probe time. > Side effect - "Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n" > can be seen at boot log. > > NOTE. It still may fail if boot sequence will changed and some interrupt > controller will be probed before cherryview-pinctrl which will shift Linux IRQ > numbering (expected with CONFIG_SPARCE_IRQ enabled). > > [1] https://bugzilla.kernel.org/show_bug.cgi?id=194945 > [2] https://lkml.org/lkml/2017/9/28/153 > Cc: Andy Shevchenko > Cc: Chris Gorman > Cc: Mika Westerberg > Cc: Heikki Krogerus > Signed-off-by: Grygorii Strashko > Reported-by: Chris Gorman > Reported-by: Mika Westerberg OK patch applied for fixes. But I'mm still very sceptical about this. Look at the following (just from grep irq_base drivers/gpio/): drivers/gpio/gpio-ml-ioh.c: static int ioh_gpio_to_irq(struct gpio_chip *gpio, unsigned offset) { struct ioh_gpio *chip = gpiochip_get_data(gpio); return chip->irq_base + offset; } (...) ch = irq - chip->irq_base; if (irq <= chip->irq_base + 7) { im_reg = >reg->regs[chip->ch].im_0; im_pos = ch; (...) drivers/gpio/gpio-sta2x11.c: static int gsta_gpio_to_irq(struct gpio_chip *gpio, unsigned offset) { struct gsta_gpio *chip = gpiochip_get_data(gpio); return chip->irq_base + offset; } (etc) The thing is that the lines you deleted from gpiolib were the only thing ever assigning chip->irq_base. This patch, if performed properly should have removed the .irq_base field from struct gpio_chip altogether without regressions. As it is not, anything using .irq_base is regressing. Either you need to convince me you can quickfix all of these users, or we need to simply revert this change. Yours, Linus Walleij
Re: [PATCH] pinctrl: cherryview: fix issues caused by dynamic gpio irqs mapping
On Tue, Oct 3, 2017 at 7:00 PM, Grygorii Strashko wrote: > New GPIO IRQs are allocated and mapped dynamically by default when > GPIO IRQ infrastructure is used by cherryview-pinctrl driver. > This causes issues on some Intel platforms [1][2] with broken BIOS which > hardcodes Linux IRQ numbers in their ACPI tables. > > On such platforms cherryview-pinctrl driver should allocate and map all > GPIO IRQs at probe time. > Side effect - "Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n" > can be seen at boot log. > > NOTE. It still may fail if boot sequence will changed and some interrupt > controller will be probed before cherryview-pinctrl which will shift Linux IRQ > numbering (expected with CONFIG_SPARCE_IRQ enabled). > > [1] https://bugzilla.kernel.org/show_bug.cgi?id=194945 > [2] https://lkml.org/lkml/2017/9/28/153 > Cc: Andy Shevchenko > Cc: Chris Gorman > Cc: Mika Westerberg > Cc: Heikki Krogerus > Signed-off-by: Grygorii Strashko > Reported-by: Chris Gorman > Reported-by: Mika Westerberg OK patch applied for fixes. But I'mm still very sceptical about this. Look at the following (just from grep irq_base drivers/gpio/): drivers/gpio/gpio-ml-ioh.c: static int ioh_gpio_to_irq(struct gpio_chip *gpio, unsigned offset) { struct ioh_gpio *chip = gpiochip_get_data(gpio); return chip->irq_base + offset; } (...) ch = irq - chip->irq_base; if (irq <= chip->irq_base + 7) { im_reg = >reg->regs[chip->ch].im_0; im_pos = ch; (...) drivers/gpio/gpio-sta2x11.c: static int gsta_gpio_to_irq(struct gpio_chip *gpio, unsigned offset) { struct gsta_gpio *chip = gpiochip_get_data(gpio); return chip->irq_base + offset; } (etc) The thing is that the lines you deleted from gpiolib were the only thing ever assigning chip->irq_base. This patch, if performed properly should have removed the .irq_base field from struct gpio_chip altogether without regressions. As it is not, anything using .irq_base is regressing. Either you need to convince me you can quickfix all of these users, or we need to simply revert this change. Yours, Linus Walleij
Re: [RFT PATCH v2] gpiolib: allow gpio irqchip to map irqs dynamically
On Thu, Sep 28, 2017 at 10:33 AM, Mika Westerbergwrote: > On Fri, Jul 21, 2017 at 11:49:00AM -0500, Grygorii Strashko wrote: >> Now IRQ mappings are always created for all (allowed) GPIOs in gpiochip in >> gpiochip_irqchip_add_key() which goes against the idea of SPARSE_IRQ and, >> as result, leads to: >> - increasing of memory consumption for IRQ descriptors most of which will >> never ever be used (espessially on platform with a high number of GPIOs). >> (sizeof(struct irq_desc) == 256 on my tested platforms) >> - imposibility to use GPIO irqchip APIs by gpio drivers when HW implements >> GPIO IRQ functionality as IRQ crossbar/router which has only limited >> number of IRQ outputs (example from [1], all GPIOs can be mapped on only 8 >> IRQs). >> >> Hence, remove static IRQ mapping code from gpiochip_irqchip_add_key() and >> instead replace irq_find_mapping() with irq_create_mapping() in >> gpiochip_to_irq(). Also add additional gpiochip_irqchip_irq_valid() calls >> in gpiochip_to_irq() and gpiochip_irq_map(). >> >> After this change gpio2irq mapping will happen the following way when GPIO >> irqchip APIs are used by gpio driver: >> - IRQ mappings will be created statically if driver passes first_irq>0 >> vlaue in gpiochip_irqchip_add_key(). >> - IRQ mappings will be created dynamically from gpio_to_irq() or >> of_irq_get(). >> >> Tested on am335x-evm and dra72-evm-revc. >> - dra72-evm-revc: number of created irq mappings decreased from 402 -> 135 >> Mem savings 267*256 = 68352 (66kB) >> - am335x-evm: number of created irq mappings decreased from 188 -> 63 >> Mem savings 125*256 = 32000 (31kB) >> >> [1] https://lkml.org/lkml/2017/6/15/428 >> Signed-off-by: Grygorii Strashko > > Hi Grygorii, > > It looks like dc749a09ea5e41 ("gpiolib: allow gpio irqchip to map irqs > dynamically") broke the quirk we added for some Intel Cherryview > systems [1]. Basically after this keyboard of those systems stopped > working again. It seems like we need to revert this change. I have also noted the following: - /* -* Prepare the mapping since the irqchip shall be orthogonal to -* any gpiochip calls. If the first_irq was zero, this is -* necessary to allocate descriptors for all IRQs. -*/ - for (offset = 0; offset < gpiochip->ngpio; offset++) { - if (!gpiochip_irqchip_irq_valid(gpiochip, offset)) - continue; - irq_base = irq_create_mapping(gpiochip->irqdomain, offset); - if (!irq_base_set) { - /* -* Store the base into the gpiochip to be used when -* unmapping the irqs. -*/ - gpiochip->irq_base = irq_base; - irq_base_set = true; - } Note assignment of gpiochip->irq_base. A whole slew of drivers use this. We cannot merge a change like this without also fixing all the users of .irq_base, as it will cause regressions on them. Yours, Linus Walleij
Re: [RFT PATCH v2] gpiolib: allow gpio irqchip to map irqs dynamically
On Thu, Sep 28, 2017 at 10:33 AM, Mika Westerberg wrote: > On Fri, Jul 21, 2017 at 11:49:00AM -0500, Grygorii Strashko wrote: >> Now IRQ mappings are always created for all (allowed) GPIOs in gpiochip in >> gpiochip_irqchip_add_key() which goes against the idea of SPARSE_IRQ and, >> as result, leads to: >> - increasing of memory consumption for IRQ descriptors most of which will >> never ever be used (espessially on platform with a high number of GPIOs). >> (sizeof(struct irq_desc) == 256 on my tested platforms) >> - imposibility to use GPIO irqchip APIs by gpio drivers when HW implements >> GPIO IRQ functionality as IRQ crossbar/router which has only limited >> number of IRQ outputs (example from [1], all GPIOs can be mapped on only 8 >> IRQs). >> >> Hence, remove static IRQ mapping code from gpiochip_irqchip_add_key() and >> instead replace irq_find_mapping() with irq_create_mapping() in >> gpiochip_to_irq(). Also add additional gpiochip_irqchip_irq_valid() calls >> in gpiochip_to_irq() and gpiochip_irq_map(). >> >> After this change gpio2irq mapping will happen the following way when GPIO >> irqchip APIs are used by gpio driver: >> - IRQ mappings will be created statically if driver passes first_irq>0 >> vlaue in gpiochip_irqchip_add_key(). >> - IRQ mappings will be created dynamically from gpio_to_irq() or >> of_irq_get(). >> >> Tested on am335x-evm and dra72-evm-revc. >> - dra72-evm-revc: number of created irq mappings decreased from 402 -> 135 >> Mem savings 267*256 = 68352 (66kB) >> - am335x-evm: number of created irq mappings decreased from 188 -> 63 >> Mem savings 125*256 = 32000 (31kB) >> >> [1] https://lkml.org/lkml/2017/6/15/428 >> Signed-off-by: Grygorii Strashko > > Hi Grygorii, > > It looks like dc749a09ea5e41 ("gpiolib: allow gpio irqchip to map irqs > dynamically") broke the quirk we added for some Intel Cherryview > systems [1]. Basically after this keyboard of those systems stopped > working again. It seems like we need to revert this change. I have also noted the following: - /* -* Prepare the mapping since the irqchip shall be orthogonal to -* any gpiochip calls. If the first_irq was zero, this is -* necessary to allocate descriptors for all IRQs. -*/ - for (offset = 0; offset < gpiochip->ngpio; offset++) { - if (!gpiochip_irqchip_irq_valid(gpiochip, offset)) - continue; - irq_base = irq_create_mapping(gpiochip->irqdomain, offset); - if (!irq_base_set) { - /* -* Store the base into the gpiochip to be used when -* unmapping the irqs. -*/ - gpiochip->irq_base = irq_base; - irq_base_set = true; - } Note assignment of gpiochip->irq_base. A whole slew of drivers use this. We cannot merge a change like this without also fixing all the users of .irq_base, as it will cause regressions on them. Yours, Linus Walleij
Re: [PATCH] MAINTAINERS: Add git repository to Renesas pinctrl driver section
On Wed, Oct 4, 2017 at 1:35 PM, Geert Uytterhoevenwrote: > Signed-off-by: Geert Uytterhoeven Patch applied with Simon's tag. Yours, Linus Walleij
Re: [PATCH] MAINTAINERS: Add git repository to Renesas pinctrl driver section
On Wed, Oct 4, 2017 at 1:35 PM, Geert Uytterhoeven wrote: > Signed-off-by: Geert Uytterhoeven Patch applied with Simon's tag. Yours, Linus Walleij
Prize
USA Internet Command Protocol 2017 has selected your e-mail ID as lucky winner of US$800,000.00 out of US$350,000.000.00 shared worldwide for 100.000 e-mail Users. Forward your lucky number USAL77720 with your profile to the mandated payment center via any of the below internet software ip e-mails only. E-mail-: youripnews763-alertenews-abc-01016-wn-hlo.worldwide-$$$@yahoo.com or E-mail-: q112233324-+1+2+800+1+2+800+1+2+800+$$$u.s.a-corporate.age...@yahoo.com for payment. Authorized Delivery
Prize
USA Internet Command Protocol 2017 has selected your e-mail ID as lucky winner of US$800,000.00 out of US$350,000.000.00 shared worldwide for 100.000 e-mail Users. Forward your lucky number USAL77720 with your profile to the mandated payment center via any of the below internet software ip e-mails only. E-mail-: youripnews763-alertenews-abc-01016-wn-hlo.worldwide-$$$@yahoo.com or E-mail-: q112233324-+1+2+800+1+2+800+1+2+800+$$$u.s.a-corporate.age...@yahoo.com for payment. Authorized Delivery
Re: [PATCH] dt-bindings: pinctrl: Move mcp23s08 from gpio
On Thu, Oct 5, 2017 at 9:50 AM, Lars Poeschelwrote: > The mcp23s08 driver was moved from gpio to pinctrl. This moves it's > devicetree binding doc as well. So driver and binding doc are in sync > again. > > Signed-off-by: Lars Poeschel Are there no new references to the generic pin control binding needed as well? Linus Walleij
Re: [PATCH] dt-bindings: pinctrl: Move mcp23s08 from gpio
On Thu, Oct 5, 2017 at 9:50 AM, Lars Poeschel wrote: > The mcp23s08 driver was moved from gpio to pinctrl. This moves it's > devicetree binding doc as well. So driver and binding doc are in sync > again. > > Signed-off-by: Lars Poeschel Are there no new references to the generic pin control binding needed as well? Linus Walleij
[PATCH] iio: adc: dln2-adc: fix build error
From: Randy DunlapThe dln2-adc driver uses interface(s) that are controlled by the IIO_TRIGGERED_BUFFER Kconfig symbol, so the driver needs to select that symbol to prevent the build error. drivers/iio/adc/dln2-adc.o: In function `dln2_adc_probe': dln2-adc.c:(.text+0x528): undefined reference to `devm_iio_triggered_buffer_setup' Signed-off-by: Randy Dunlap Reported-by: kbuild test robot Cc: Jonathan Cameron Cc: linux-...@vger.kernel.org Cc: Jack Andersen --- drivers/iio/adc/Kconfig |2 ++ 1 file changed, 2 insertions(+) --- lnx-414-rc3.orig/drivers/iio/adc/Kconfig +++ lnx-414-rc3/drivers/iio/adc/Kconfig @@ -243,6 +243,8 @@ config DA9150_GPADC config DLN2_ADC tristate "Diolan DLN-2 ADC driver support" depends on MFD_DLN2 + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER help Say yes here to build support for Diolan DLN-2 ADC.
[PATCH] iio: adc: dln2-adc: fix build error
From: Randy Dunlap The dln2-adc driver uses interface(s) that are controlled by the IIO_TRIGGERED_BUFFER Kconfig symbol, so the driver needs to select that symbol to prevent the build error. drivers/iio/adc/dln2-adc.o: In function `dln2_adc_probe': dln2-adc.c:(.text+0x528): undefined reference to `devm_iio_triggered_buffer_setup' Signed-off-by: Randy Dunlap Reported-by: kbuild test robot Cc: Jonathan Cameron Cc: linux-...@vger.kernel.org Cc: Jack Andersen --- drivers/iio/adc/Kconfig |2 ++ 1 file changed, 2 insertions(+) --- lnx-414-rc3.orig/drivers/iio/adc/Kconfig +++ lnx-414-rc3/drivers/iio/adc/Kconfig @@ -243,6 +243,8 @@ config DA9150_GPADC config DLN2_ADC tristate "Diolan DLN-2 ADC driver support" depends on MFD_DLN2 + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER help Say yes here to build support for Diolan DLN-2 ADC.
[PATCH 2/3] sched/fair: Introduce scaled capacity awareness in select_idle_sibling code path
While looking for CPUs to place running tasks on, the scheduler completely ignores the capacity stolen away by RT/IRQ tasks. This patch changes that behavior to also take the scaled capacity into account. Signed-off-by: Rohit Jain--- kernel/sched/fair.c | 37 - 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index eaede50..5b1f7b9 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -6004,7 +6004,7 @@ static int select_idle_core(struct task_struct *p, struct sched_domain *sd, int for_each_cpu(cpu, cpu_smt_mask(core)) { cpumask_clear_cpu(cpu, cpus); - if (!idle_cpu(cpu)) + if (!idle_cpu(cpu) || !full_capacity(cpu)) idle = false; } @@ -6025,7 +6025,8 @@ static int select_idle_core(struct task_struct *p, struct sched_domain *sd, int */ static int select_idle_smt(struct task_struct *p, struct sched_domain *sd, int target) { - int cpu; + int cpu, backup_cpu = -1; + unsigned int backup_cap = 0; if (!static_branch_likely(_smt_present)) return -1; @@ -6033,11 +6034,17 @@ static int select_idle_smt(struct task_struct *p, struct sched_domain *sd, int t for_each_cpu(cpu, cpu_smt_mask(target)) { if (!cpumask_test_cpu(cpu, >cpus_allowed)) continue; - if (idle_cpu(cpu)) - return cpu; + if (idle_cpu(cpu)) { + if (full_capacity(cpu)) + return cpu; + if (capacity_of(cpu) > backup_cap) { + backup_cap = capacity_of(cpu); + backup_cpu = cpu; + } + } } - return -1; + return backup_cpu; } #else /* CONFIG_SCHED_SMT */ @@ -6066,6 +6073,8 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int t u64 time, cost; s64 delta; int cpu, nr = INT_MAX; + int backup_cpu = -1; + unsigned int backup_cap = 0; this_sd = rcu_dereference(*this_cpu_ptr(_llc)); if (!this_sd) @@ -6096,10 +6105,19 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int t return -1; if (!cpumask_test_cpu(cpu, >cpus_allowed)) continue; - if (idle_cpu(cpu)) - break; + if (idle_cpu(cpu)) { + if (full_capacity(cpu)) { + backup_cpu = -1; + break; + } else if (capacity_of(cpu) > backup_cap) { + backup_cap = capacity_of(cpu); + backup_cpu = cpu; + } + } } + if (backup_cpu >= 0) + cpu = backup_cpu; time = local_clock() - time; cost = this_sd->avg_scan_cost; delta = (s64)(time - cost) / 8; @@ -6116,13 +6134,14 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target) struct sched_domain *sd; int i; - if (idle_cpu(target)) + if (idle_cpu(target) && full_capacity(target)) return target; /* * If the previous cpu is cache affine and idle, don't be stupid. */ - if (prev != target && cpus_share_cache(prev, target) && idle_cpu(prev)) + if (prev != target && cpus_share_cache(prev, target) && idle_cpu(prev) + && full_capacity(prev)) return prev; sd = rcu_dereference(per_cpu(sd_llc, target)); -- 2.7.4
[PATCH 2/3] sched/fair: Introduce scaled capacity awareness in select_idle_sibling code path
While looking for CPUs to place running tasks on, the scheduler completely ignores the capacity stolen away by RT/IRQ tasks. This patch changes that behavior to also take the scaled capacity into account. Signed-off-by: Rohit Jain --- kernel/sched/fair.c | 37 - 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index eaede50..5b1f7b9 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -6004,7 +6004,7 @@ static int select_idle_core(struct task_struct *p, struct sched_domain *sd, int for_each_cpu(cpu, cpu_smt_mask(core)) { cpumask_clear_cpu(cpu, cpus); - if (!idle_cpu(cpu)) + if (!idle_cpu(cpu) || !full_capacity(cpu)) idle = false; } @@ -6025,7 +6025,8 @@ static int select_idle_core(struct task_struct *p, struct sched_domain *sd, int */ static int select_idle_smt(struct task_struct *p, struct sched_domain *sd, int target) { - int cpu; + int cpu, backup_cpu = -1; + unsigned int backup_cap = 0; if (!static_branch_likely(_smt_present)) return -1; @@ -6033,11 +6034,17 @@ static int select_idle_smt(struct task_struct *p, struct sched_domain *sd, int t for_each_cpu(cpu, cpu_smt_mask(target)) { if (!cpumask_test_cpu(cpu, >cpus_allowed)) continue; - if (idle_cpu(cpu)) - return cpu; + if (idle_cpu(cpu)) { + if (full_capacity(cpu)) + return cpu; + if (capacity_of(cpu) > backup_cap) { + backup_cap = capacity_of(cpu); + backup_cpu = cpu; + } + } } - return -1; + return backup_cpu; } #else /* CONFIG_SCHED_SMT */ @@ -6066,6 +6073,8 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int t u64 time, cost; s64 delta; int cpu, nr = INT_MAX; + int backup_cpu = -1; + unsigned int backup_cap = 0; this_sd = rcu_dereference(*this_cpu_ptr(_llc)); if (!this_sd) @@ -6096,10 +6105,19 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int t return -1; if (!cpumask_test_cpu(cpu, >cpus_allowed)) continue; - if (idle_cpu(cpu)) - break; + if (idle_cpu(cpu)) { + if (full_capacity(cpu)) { + backup_cpu = -1; + break; + } else if (capacity_of(cpu) > backup_cap) { + backup_cap = capacity_of(cpu); + backup_cpu = cpu; + } + } } + if (backup_cpu >= 0) + cpu = backup_cpu; time = local_clock() - time; cost = this_sd->avg_scan_cost; delta = (s64)(time - cost) / 8; @@ -6116,13 +6134,14 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target) struct sched_domain *sd; int i; - if (idle_cpu(target)) + if (idle_cpu(target) && full_capacity(target)) return target; /* * If the previous cpu is cache affine and idle, don't be stupid. */ - if (prev != target && cpus_share_cache(prev, target) && idle_cpu(prev)) + if (prev != target && cpus_share_cache(prev, target) && idle_cpu(prev) + && full_capacity(prev)) return prev; sd = rcu_dereference(per_cpu(sd_llc, target)); -- 2.7.4
[PATCH 3/3] sched/fair: Introduce scaled capacity awareness in wake_affine_idle code path
wake_affine_idle returns true if the CPU can run the task. Since it is ignoring capacity, adding that check there to only return true if the CPU is full_capacity. Signed-off-by: Rohit Jain--- kernel/sched/fair.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 5b1f7b9..f4761f2 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -5660,7 +5660,7 @@ static bool wake_affine_idle(struct sched_domain *sd, struct task_struct *p, int this_cpu, int prev_cpu, int sync) { - if (idle_cpu(this_cpu)) + if (idle_cpu(this_cpu) && full_capacity(this_cpu)) return true; if (sync && cpu_rq(this_cpu)->nr_running == 1) -- 2.7.4
[PATCH 3/3] sched/fair: Introduce scaled capacity awareness in wake_affine_idle code path
wake_affine_idle returns true if the CPU can run the task. Since it is ignoring capacity, adding that check there to only return true if the CPU is full_capacity. Signed-off-by: Rohit Jain --- kernel/sched/fair.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 5b1f7b9..f4761f2 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -5660,7 +5660,7 @@ static bool wake_affine_idle(struct sched_domain *sd, struct task_struct *p, int this_cpu, int prev_cpu, int sync) { - if (idle_cpu(this_cpu)) + if (idle_cpu(this_cpu) && full_capacity(this_cpu)) return true; if (sync && cpu_rq(this_cpu)->nr_running == 1) -- 2.7.4
[PATCH 1/3] sched/fair: Introduce scaled capacity awareness in find_idlest_cpu code path
While looking for idle CPUs for a waking task, we should also account for the delays caused due to the bandwidth reduction by RT/IRQ tasks. This patch does that by trying to find a higher capacity CPU with minimum wake up latency. Signed-off-by: Rohit Jain--- kernel/sched/fair.c | 27 --- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 0107280..eaede50 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -5579,6 +5579,11 @@ static unsigned long capacity_orig_of(int cpu) return cpu_rq(cpu)->cpu_capacity_orig; } +static inline bool full_capacity(int cpu) +{ + return (capacity_of(cpu) >= (capacity_orig_of(cpu)*768 >> 10)); +} + static unsigned long cpu_avg_load_per_task(int cpu) { struct rq *rq = cpu_rq(cpu); @@ -5865,8 +5870,10 @@ find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu) unsigned long load, min_load = ULONG_MAX; unsigned int min_exit_latency = UINT_MAX; u64 latest_idle_timestamp = 0; + unsigned int backup_cap = 0; int least_loaded_cpu = this_cpu; int shallowest_idle_cpu = -1; + int shallowest_idle_cpu_backup = -1; int i; /* Check if we have any choice: */ @@ -5876,6 +5883,7 @@ find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu) /* Traverse only the allowed CPUs */ for_each_cpu_and(i, sched_group_span(group), >cpus_allowed) { if (idle_cpu(i)) { + int idle_candidate = -1; struct rq *rq = cpu_rq(i); struct cpuidle_state *idle = idle_get_state(rq); if (idle && idle->exit_latency < min_exit_latency) { @@ -5886,7 +5894,7 @@ find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu) */ min_exit_latency = idle->exit_latency; latest_idle_timestamp = rq->idle_stamp; - shallowest_idle_cpu = i; + idle_candidate = i; } else if ((!idle || idle->exit_latency == min_exit_latency) && rq->idle_stamp > latest_idle_timestamp) { /* @@ -5895,7 +5903,16 @@ find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu) * a warmer cache. */ latest_idle_timestamp = rq->idle_stamp; - shallowest_idle_cpu = i; + idle_candidate = i; + } + + if (idle_candidate != -1) { + if (full_capacity(idle_candidate)) { + shallowest_idle_cpu = idle_candidate; + } else if (capacity_of(idle_candidate) > backup_cap) { + shallowest_idle_cpu_backup = idle_candidate; + backup_cap = capacity_of(idle_candidate); + } } } else if (shallowest_idle_cpu == -1) { load = weighted_cpuload(cpu_rq(i)); @@ -5906,7 +5923,11 @@ find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu) } } - return shallowest_idle_cpu != -1 ? shallowest_idle_cpu : least_loaded_cpu; + if (shallowest_idle_cpu != -1) + return shallowest_idle_cpu; + + return (shallowest_idle_cpu_backup != -1 ? + shallowest_idle_cpu_backup : least_loaded_cpu); } #ifdef CONFIG_SCHED_SMT -- 2.7.4
[PATCH 1/3] sched/fair: Introduce scaled capacity awareness in find_idlest_cpu code path
While looking for idle CPUs for a waking task, we should also account for the delays caused due to the bandwidth reduction by RT/IRQ tasks. This patch does that by trying to find a higher capacity CPU with minimum wake up latency. Signed-off-by: Rohit Jain --- kernel/sched/fair.c | 27 --- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 0107280..eaede50 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -5579,6 +5579,11 @@ static unsigned long capacity_orig_of(int cpu) return cpu_rq(cpu)->cpu_capacity_orig; } +static inline bool full_capacity(int cpu) +{ + return (capacity_of(cpu) >= (capacity_orig_of(cpu)*768 >> 10)); +} + static unsigned long cpu_avg_load_per_task(int cpu) { struct rq *rq = cpu_rq(cpu); @@ -5865,8 +5870,10 @@ find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu) unsigned long load, min_load = ULONG_MAX; unsigned int min_exit_latency = UINT_MAX; u64 latest_idle_timestamp = 0; + unsigned int backup_cap = 0; int least_loaded_cpu = this_cpu; int shallowest_idle_cpu = -1; + int shallowest_idle_cpu_backup = -1; int i; /* Check if we have any choice: */ @@ -5876,6 +5883,7 @@ find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu) /* Traverse only the allowed CPUs */ for_each_cpu_and(i, sched_group_span(group), >cpus_allowed) { if (idle_cpu(i)) { + int idle_candidate = -1; struct rq *rq = cpu_rq(i); struct cpuidle_state *idle = idle_get_state(rq); if (idle && idle->exit_latency < min_exit_latency) { @@ -5886,7 +5894,7 @@ find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu) */ min_exit_latency = idle->exit_latency; latest_idle_timestamp = rq->idle_stamp; - shallowest_idle_cpu = i; + idle_candidate = i; } else if ((!idle || idle->exit_latency == min_exit_latency) && rq->idle_stamp > latest_idle_timestamp) { /* @@ -5895,7 +5903,16 @@ find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu) * a warmer cache. */ latest_idle_timestamp = rq->idle_stamp; - shallowest_idle_cpu = i; + idle_candidate = i; + } + + if (idle_candidate != -1) { + if (full_capacity(idle_candidate)) { + shallowest_idle_cpu = idle_candidate; + } else if (capacity_of(idle_candidate) > backup_cap) { + shallowest_idle_cpu_backup = idle_candidate; + backup_cap = capacity_of(idle_candidate); + } } } else if (shallowest_idle_cpu == -1) { load = weighted_cpuload(cpu_rq(i)); @@ -5906,7 +5923,11 @@ find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu) } } - return shallowest_idle_cpu != -1 ? shallowest_idle_cpu : least_loaded_cpu; + if (shallowest_idle_cpu != -1) + return shallowest_idle_cpu; + + return (shallowest_idle_cpu_backup != -1 ? + shallowest_idle_cpu_backup : least_loaded_cpu); } #ifdef CONFIG_SCHED_SMT -- 2.7.4
[PATCH v5 0/3] sched/fair: Introduce scaled capacity awareness in enqueue
Changelog: --- v1->v2: * Changed the dynamic threshold calculation as the having global state can be avoided. v2->v3: * Split up the patch for find_idlest_cpu and select_idle_sibling code paths. v3->v4: * Rebased it to peterz's tree (apologies for wrong tree for v3) v4->v5: * Changed the threshold to 768 from 819 for easier shifts * Changed the find_idlest_cpu code path to be simpler * Changed the select_idle_core code path to search for idlest+full_capacity core * Added scaled capacity awareness to wake_affine_idle code path --- During OLTP workload runs, threads can end up on CPUs with a lot of softIRQ activity, thus delaying progress. For more reliable and faster runs, if the system can spare it, these threads should be scheduled on CPUs with lower IRQ/RT activity. Currently, the scheduler takes into account the original capacity of CPUs when providing 'hints' for select_idle_sibling code path to return an idle CPU. However, the rest of the select_idle_* code paths remain capacity agnostic. Further, these code paths are only aware of the original capacity and not the capacity stolen by IRQ/RT activity. This patch introduces capacity awarness in scheduler (CAS) which avoids CPUs which might have their capacities reduced (due to IRQ/RT activity) when trying to schedule threads (on the push side) in the system. This awareness has been added into the fair scheduling class. It does so by, using the following algorithm: 1) As in rt_avg the scaled capacities are already calculated. 2) Any CPU which is running below 80% capacity is considered running low on capacity. 3) During idle CPU search if a CPU is found running low on capacity, it is skipped if better CPUs are available. 4) If none of the CPUs are better in terms of idleness and capacity, then the low-capacity CPU is considered to be the best available CPU. The performance numbers: --- CAS shows upto 1.5% improvement on x86 when running 'SELECT' database workload. For microbenchmark results, I used hackbench running with process along with, running ping on CPU 0,1 and 2 as: 'ping -l 1 -q -s 10 -f hostX' The results below should be read as: * 'Baseline without ping' is how the workload would've behaved if there was no IRQ activity. * Compare 'Baseline with ping' and 'Baseline without ping' to see the effect of ping * Compare 'Baseline with ping' and 'CAS with ping' to see the improvement CAS can give over baseline Following are the runtime(s) with hackbench and ping activity as described above (lower is better), on a 44 core 2 socket x86 machine: +---+--+++ |Num. |CAS |Baseline|Baseline| |Tasks |with |with|without | |(groups of 40) |ping |ping|ping| +---+--+++ | |Mean |Mean|Mean| +---+--+++ |1 | 0.55 | 0.59 | 0.53 | |2 | 0.66 | 0.81 | 0.51 | |4 | 0.99 | 1.16 | 0.95 | |8 | 1.92 | 1.93 | 1.88 | |16 | 3.24 | 3.26 | 3.15 | |32 | 5.93 | 5.98 | 5.68 | |64 | 11.55| 11.94 | 10.89 | +---+--+++ Rohit Jain (3): sched/fair: Introduce scaled capacity awareness in find_idlest_cpu code path sched/fair: Introduce scaled capacity awareness in select_idle_sibling code path sched/fair: Introduce scaled capacity awareness in wake_affine_idle code path kernel/sched/fair.c | 66 ++--- 1 file changed, 53 insertions(+), 13 deletions(-) -- 2.7.4
[PATCH v5 0/3] sched/fair: Introduce scaled capacity awareness in enqueue
Changelog: --- v1->v2: * Changed the dynamic threshold calculation as the having global state can be avoided. v2->v3: * Split up the patch for find_idlest_cpu and select_idle_sibling code paths. v3->v4: * Rebased it to peterz's tree (apologies for wrong tree for v3) v4->v5: * Changed the threshold to 768 from 819 for easier shifts * Changed the find_idlest_cpu code path to be simpler * Changed the select_idle_core code path to search for idlest+full_capacity core * Added scaled capacity awareness to wake_affine_idle code path --- During OLTP workload runs, threads can end up on CPUs with a lot of softIRQ activity, thus delaying progress. For more reliable and faster runs, if the system can spare it, these threads should be scheduled on CPUs with lower IRQ/RT activity. Currently, the scheduler takes into account the original capacity of CPUs when providing 'hints' for select_idle_sibling code path to return an idle CPU. However, the rest of the select_idle_* code paths remain capacity agnostic. Further, these code paths are only aware of the original capacity and not the capacity stolen by IRQ/RT activity. This patch introduces capacity awarness in scheduler (CAS) which avoids CPUs which might have their capacities reduced (due to IRQ/RT activity) when trying to schedule threads (on the push side) in the system. This awareness has been added into the fair scheduling class. It does so by, using the following algorithm: 1) As in rt_avg the scaled capacities are already calculated. 2) Any CPU which is running below 80% capacity is considered running low on capacity. 3) During idle CPU search if a CPU is found running low on capacity, it is skipped if better CPUs are available. 4) If none of the CPUs are better in terms of idleness and capacity, then the low-capacity CPU is considered to be the best available CPU. The performance numbers: --- CAS shows upto 1.5% improvement on x86 when running 'SELECT' database workload. For microbenchmark results, I used hackbench running with process along with, running ping on CPU 0,1 and 2 as: 'ping -l 1 -q -s 10 -f hostX' The results below should be read as: * 'Baseline without ping' is how the workload would've behaved if there was no IRQ activity. * Compare 'Baseline with ping' and 'Baseline without ping' to see the effect of ping * Compare 'Baseline with ping' and 'CAS with ping' to see the improvement CAS can give over baseline Following are the runtime(s) with hackbench and ping activity as described above (lower is better), on a 44 core 2 socket x86 machine: +---+--+++ |Num. |CAS |Baseline|Baseline| |Tasks |with |with|without | |(groups of 40) |ping |ping|ping| +---+--+++ | |Mean |Mean|Mean| +---+--+++ |1 | 0.55 | 0.59 | 0.53 | |2 | 0.66 | 0.81 | 0.51 | |4 | 0.99 | 1.16 | 0.95 | |8 | 1.92 | 1.93 | 1.88 | |16 | 3.24 | 3.26 | 3.15 | |32 | 5.93 | 5.98 | 5.68 | |64 | 11.55| 11.94 | 10.89 | +---+--+++ Rohit Jain (3): sched/fair: Introduce scaled capacity awareness in find_idlest_cpu code path sched/fair: Introduce scaled capacity awareness in select_idle_sibling code path sched/fair: Introduce scaled capacity awareness in wake_affine_idle code path kernel/sched/fair.c | 66 ++--- 1 file changed, 53 insertions(+), 13 deletions(-) -- 2.7.4
[PATCH review for 4.9 33/50] platform/x86: intel_mid_thermal: Fix module autoload
From: Javier Martinez Canillas[ Upstream commit a93151a72061e944a4915458b1b1d6d505c03bbf ] If the driver is built as a module, autoload won't work because the module alias information is not filled. So user-space can't match the registered device with the corresponding module. Export the module alias information using the MODULE_DEVICE_TABLE() macro. Before this patch: $ modinfo drivers/platform/x86/intel_mid_thermal.ko | grep alias $ After this patch: $ modinfo drivers/platform/x86/intel_mid_thermal.ko | grep alias alias: platform:msic_thermal Signed-off-by: Javier Martinez Canillas Signed-off-by: Andy Shevchenko Signed-off-by: Sasha Levin --- drivers/platform/x86/intel_mid_thermal.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/platform/x86/intel_mid_thermal.c b/drivers/platform/x86/intel_mid_thermal.c index 9f713b832ba3..5c768c4627d3 100644 --- a/drivers/platform/x86/intel_mid_thermal.c +++ b/drivers/platform/x86/intel_mid_thermal.c @@ -550,6 +550,7 @@ static const struct platform_device_id therm_id_table[] = { { "msic_thermal", 1 }, { } }; +MODULE_DEVICE_TABLE(platform, therm_id_table); static struct platform_driver mid_thermal_driver = { .driver = { -- 2.11.0
[PATCH review for 4.9 33/50] platform/x86: intel_mid_thermal: Fix module autoload
From: Javier Martinez Canillas [ Upstream commit a93151a72061e944a4915458b1b1d6d505c03bbf ] If the driver is built as a module, autoload won't work because the module alias information is not filled. So user-space can't match the registered device with the corresponding module. Export the module alias information using the MODULE_DEVICE_TABLE() macro. Before this patch: $ modinfo drivers/platform/x86/intel_mid_thermal.ko | grep alias $ After this patch: $ modinfo drivers/platform/x86/intel_mid_thermal.ko | grep alias alias: platform:msic_thermal Signed-off-by: Javier Martinez Canillas Signed-off-by: Andy Shevchenko Signed-off-by: Sasha Levin --- drivers/platform/x86/intel_mid_thermal.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/platform/x86/intel_mid_thermal.c b/drivers/platform/x86/intel_mid_thermal.c index 9f713b832ba3..5c768c4627d3 100644 --- a/drivers/platform/x86/intel_mid_thermal.c +++ b/drivers/platform/x86/intel_mid_thermal.c @@ -550,6 +550,7 @@ static const struct platform_device_id therm_id_table[] = { { "msic_thermal", 1 }, { } }; +MODULE_DEVICE_TABLE(platform, therm_id_table); static struct platform_driver mid_thermal_driver = { .driver = { -- 2.11.0
[PATCH review for 4.9 43/50] mei: return error on notification request to a disconnected client
From: Alexander Usyskin[ Upstream commit 7c47d2ca0feca767479329da23523ed798acb854 ] Request for a notification from a disconnected client will be ignored silently by the FW but the caller should know that the operation hasn't succeeded. Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/misc/mei/client.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index e2af61f7e3b6..451d417eb451 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -1320,6 +1320,9 @@ int mei_cl_notify_request(struct mei_cl *cl, return -EOPNOTSUPP; } + if (!mei_cl_is_connected(cl)) + return -ENODEV; + rets = pm_runtime_get(dev->dev); if (rets < 0 && rets != -EINPROGRESS) { pm_runtime_put_noidle(dev->dev); -- 2.11.0
[PATCH review for 4.9 38/50] brcmfmac: check brcmf_bus_get_memdump result for error
From: Rafał Miłecki[ Upstream commit f4737a62033d7f3e0db740c449fc62119da7ab8a ] This method may be unsupported (see: USB bus) or may just fail (see: SDIO bus). While at it rework logic in brcmf_sdio_bus_get_memdump function to avoid too many conditional code nesting levels. Signed-off-by: Rafał Miłecki Acked-by: Arend van Spriel Signed-off-by: Kalle Valo Signed-off-by: Sasha Levin --- .../wireless/broadcom/brcm80211/brcmfmac/debug.c | 23 +++--- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c index e64557c35553..6f8a4b074c31 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c @@ -32,16 +32,25 @@ static int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data, { void *dump; size_t ramsize; + int err; ramsize = brcmf_bus_get_ramsize(bus); - if (ramsize) { - dump = vzalloc(len + ramsize); - if (!dump) - return -ENOMEM; - memcpy(dump, data, len); - brcmf_bus_get_memdump(bus, dump + len, ramsize); - dev_coredumpv(bus->dev, dump, len + ramsize, GFP_KERNEL); + if (!ramsize) + return -ENOTSUPP; + + dump = vzalloc(len + ramsize); + if (!dump) + return -ENOMEM; + + memcpy(dump, data, len); + err = brcmf_bus_get_memdump(bus, dump + len, ramsize); + if (err) { + vfree(dump); + return err; } + + dev_coredumpv(bus->dev, dump, len + ramsize, GFP_KERNEL); + return 0; } -- 2.11.0
[PATCH review for 4.9 43/50] mei: return error on notification request to a disconnected client
From: Alexander Usyskin [ Upstream commit 7c47d2ca0feca767479329da23523ed798acb854 ] Request for a notification from a disconnected client will be ignored silently by the FW but the caller should know that the operation hasn't succeeded. Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/misc/mei/client.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index e2af61f7e3b6..451d417eb451 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -1320,6 +1320,9 @@ int mei_cl_notify_request(struct mei_cl *cl, return -EOPNOTSUPP; } + if (!mei_cl_is_connected(cl)) + return -ENODEV; + rets = pm_runtime_get(dev->dev); if (rets < 0 && rets != -EINPROGRESS) { pm_runtime_put_noidle(dev->dev); -- 2.11.0
[PATCH review for 4.9 38/50] brcmfmac: check brcmf_bus_get_memdump result for error
From: Rafał Miłecki [ Upstream commit f4737a62033d7f3e0db740c449fc62119da7ab8a ] This method may be unsupported (see: USB bus) or may just fail (see: SDIO bus). While at it rework logic in brcmf_sdio_bus_get_memdump function to avoid too many conditional code nesting levels. Signed-off-by: Rafał Miłecki Acked-by: Arend van Spriel Signed-off-by: Kalle Valo Signed-off-by: Sasha Levin --- .../wireless/broadcom/brcm80211/brcmfmac/debug.c | 23 +++--- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c index e64557c35553..6f8a4b074c31 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c @@ -32,16 +32,25 @@ static int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data, { void *dump; size_t ramsize; + int err; ramsize = brcmf_bus_get_ramsize(bus); - if (ramsize) { - dump = vzalloc(len + ramsize); - if (!dump) - return -ENOMEM; - memcpy(dump, data, len); - brcmf_bus_get_memdump(bus, dump + len, ramsize); - dev_coredumpv(bus->dev, dump, len + ramsize, GFP_KERNEL); + if (!ramsize) + return -ENOTSUPP; + + dump = vzalloc(len + ramsize); + if (!dump) + return -ENOMEM; + + memcpy(dump, data, len); + err = brcmf_bus_get_memdump(bus, dump + len, ramsize); + if (err) { + vfree(dump); + return err; } + + dev_coredumpv(bus->dev, dump, len + ramsize, GFP_KERNEL); + return 0; } -- 2.11.0
[PATCH review for 4.9 36/50] staging: lustre: ptlrpc: skip lock if export failed
From: Alexander Boyko[ Upstream commit 4c43c27ddc461d8473cedd70f2549614641dfbc7 ] This patch resolves IO vs eviction race. After eviction failed export stayed at stale list, a client had IO processing and reconnected during it. A client sent brw rpc with last lock cookie and new connection. The lock with failed export was found and assert was happened. (ost_handler.c:1812:ost_prolong_lock_one()) ASSERTION( lock->l_export == opd->opd_exp ) failed: 1. Skip the lock at ldlm_handle2lock if lock export failed. 2. Validation of lock for IO was added at hpreq_check(). The lock searching is based on granted interval tree. If server doesn`t have a valid lock, it reply to client with ESTALE. Signed-off-by: Alexander Boyko Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-7702 Seagate-bug-id: MRP-2787 Reviewed-on: http://review.whamcloud.com/18120 Reviewed-by: Fan Yong Reviewed-by: Vitaly Fertman Reviewed-by: Oleg Drokin Signed-off-by: James Simmons Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/staging/lustre/lustre/ldlm/ldlm_lock.c | 7 +++ drivers/staging/lustre/lustre/ptlrpc/service.c | 21 - 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c index 3c48b4fb96f1..d18ab3f28c70 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c @@ -546,6 +546,13 @@ struct ldlm_lock *__ldlm_handle2lock(const struct lustre_handle *handle, if (!lock) return NULL; + if (lock->l_export && lock->l_export->exp_failed) { + CDEBUG(D_INFO, "lock export failed: lock %p, exp %p\n", + lock, lock->l_export); + LDLM_LOCK_PUT(lock); + return NULL; + } + /* It's unlikely but possible that someone marked the lock as * destroyed after we did handle2object on it */ diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c b/drivers/staging/lustre/lustre/ptlrpc/service.c index 72f39308eebb..9d34848d5458 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/service.c +++ b/drivers/staging/lustre/lustre/ptlrpc/service.c @@ -1264,20 +1264,15 @@ static int ptlrpc_server_hpreq_init(struct ptlrpc_service_part *svcpt, */ if (req->rq_ops->hpreq_check) { rc = req->rq_ops->hpreq_check(req); - /** -* XXX: Out of all current -* ptlrpc_hpreq_ops::hpreq_check(), only -* ldlm_cancel_hpreq_check() can return an error code; -* other functions assert in similar places, which seems -* odd. What also does not seem right is that handlers -* for those RPCs do not assert on the same checks, but -* rather handle the error cases. e.g. see -* ost_rw_hpreq_check(), and ost_brw_read(), -* ost_brw_write(). + if (rc == -ESTALE) { + req->rq_status = rc; + ptlrpc_error(req); + } + /** can only return error, +* 0 for normal request, +* or 1 for high priority request */ - if (rc < 0) - return rc; - LASSERT(rc == 0 || rc == 1); + LASSERT(rc <= 1); } spin_lock_bh(>rq_export->exp_rpc_lock); -- 2.11.0
[PATCH review for 4.9 09/50] mfd: axp20x: Fix axp288 PEK_DBR and PEK_DBF irqs being swapped
From: Hans de Goede[ Upstream commit 1af468ebe45591651ec3bafc2e9ddc6fdef70ae0 ] The R in PEK_DBR stands for rising, so it should be mapped to AXP288_IRQ_POKP where the last P stands for positive edge. Likewise PEK_DBF should be mapped to the falling edge, aka the _N_egative edge, so it should be mapped to AXP288_IRQ_POKN. This fixes the inverted powerbutton status reporting by the axp20x-pek driver. Signed-off-by: Hans de Goede Acked-by: Chen-Yu Tsai Signed-off-by: Lee Jones Signed-off-by: Sasha Levin --- drivers/mfd/axp20x.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c index ba130be32e61..9617fc323e15 100644 --- a/drivers/mfd/axp20x.c +++ b/drivers/mfd/axp20x.c @@ -205,14 +205,14 @@ static struct resource axp22x_pek_resources[] = { static struct resource axp288_power_button_resources[] = { { .name = "PEK_DBR", - .start = AXP288_IRQ_POKN, - .end= AXP288_IRQ_POKN, + .start = AXP288_IRQ_POKP, + .end= AXP288_IRQ_POKP, .flags = IORESOURCE_IRQ, }, { .name = "PEK_DBF", - .start = AXP288_IRQ_POKP, - .end= AXP288_IRQ_POKP, + .start = AXP288_IRQ_POKN, + .end= AXP288_IRQ_POKN, .flags = IORESOURCE_IRQ, }, }; -- 2.11.0
[PATCH review for 4.9 45/50] s390/prng: Adjust generation of entropy to produce real 256 bits.
From: Harald Freudenberger[ Upstream commit d34b1acb78af41b8b8d5c60972b6555ea19f7564 ] The generate_entropy function used a sha256 for compacting together 256 bits of entropy into 32 bytes hash. However, it is questionable if a sha256 can really be used here, as potential collisions may reduce the max entropy fitting into a 32 byte hash value. So this batch introduces the use of sha512 instead and the required buffer adjustments for the calling functions. Further more the working buffer for the generate_entropy function has been widened from one page to two pages. So now 1024 stckf invocations are used to gather 256 bits of entropy. This has been done to be on the save side if the jitters of stckf values isn't as good as supposed. Signed-off-by: Harald Freudenberger Signed-off-by: Martin Schwidefsky Signed-off-by: Sasha Levin --- arch/s390/crypto/prng.c | 40 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/arch/s390/crypto/prng.c b/arch/s390/crypto/prng.c index 1113389d0a39..fe7368a41aa8 100644 --- a/arch/s390/crypto/prng.c +++ b/arch/s390/crypto/prng.c @@ -110,22 +110,30 @@ static const u8 initial_parm_block[32] __initconst = { /*** helper functions ***/ +/* + * generate_entropy: + * This algorithm produces 64 bytes of entropy data based on 1024 + * individual stckf() invocations assuming that each stckf() value + * contributes 0.25 bits of entropy. So the caller gets 256 bit + * entropy per 64 byte or 4 bits entropy per byte. + */ static int generate_entropy(u8 *ebuf, size_t nbytes) { int n, ret = 0; - u8 *pg, *h, hash[32]; + u8 *pg, *h, hash[64]; - pg = (u8 *) __get_free_page(GFP_KERNEL); + /* allocate 2 pages */ + pg = (u8 *) __get_free_pages(GFP_KERNEL, 1); if (!pg) { prng_errorflag = PRNG_GEN_ENTROPY_FAILED; return -ENOMEM; } while (nbytes) { - /* fill page with urandom bytes */ - get_random_bytes(pg, PAGE_SIZE); - /* exor page with stckf values */ - for (n = 0; n < PAGE_SIZE / sizeof(u64); n++) { + /* fill pages with urandom bytes */ + get_random_bytes(pg, 2*PAGE_SIZE); + /* exor pages with 1024 stckf values */ + for (n = 0; n < 2 * PAGE_SIZE / sizeof(u64); n++) { u64 *p = ((u64 *)pg) + n; *p ^= get_tod_clock_fast(); } @@ -134,8 +142,8 @@ static int generate_entropy(u8 *ebuf, size_t nbytes) h = hash; else h = ebuf; - /* generate sha256 from this page */ - cpacf_kimd(CPACF_KIMD_SHA_256, h, pg, PAGE_SIZE); + /* hash over the filled pages */ + cpacf_kimd(CPACF_KIMD_SHA_512, h, pg, 2*PAGE_SIZE); if (n < sizeof(hash)) memcpy(ebuf, hash, n); ret += n; @@ -143,7 +151,7 @@ static int generate_entropy(u8 *ebuf, size_t nbytes) nbytes -= n; } - free_page((unsigned long)pg); + free_pages((unsigned long)pg, 1); return ret; } @@ -334,7 +342,7 @@ static int __init prng_sha512_selftest(void) static int __init prng_sha512_instantiate(void) { int ret, datalen; - u8 seed[64]; + u8 seed[64 + 32 + 16]; pr_debug("prng runs in SHA-512 mode " "with chunksize=%d and reseed_limit=%u\n", @@ -357,12 +365,12 @@ static int __init prng_sha512_instantiate(void) if (ret) goto outfree; - /* generate initial seed bytestring, first 48 bytes of entropy */ - ret = generate_entropy(seed, 48); - if (ret != 48) + /* generate initial seed bytestring, with 256 + 128 bits entropy */ + ret = generate_entropy(seed, 64 + 32); + if (ret != 64 + 32) goto outfree; /* followed by 16 bytes of unique nonce */ - get_tod_clock_ext(seed + 48); + get_tod_clock_ext(seed + 64 + 32); /* initial seed of the ppno drng */ cpacf_ppno(CPACF_PPNO_SHA512_DRNG_SEED, @@ -395,9 +403,9 @@ static void prng_sha512_deinstantiate(void) static int prng_sha512_reseed(void) { int ret; - u8 seed[32]; + u8 seed[64]; - /* generate 32 bytes of fresh entropy */ + /* fetch 256 bits of fresh entropy */ ret = generate_entropy(seed, sizeof(seed)); if (ret != sizeof(seed)) return ret; -- 2.11.0
[PATCH review for 4.9 36/50] staging: lustre: ptlrpc: skip lock if export failed
From: Alexander Boyko [ Upstream commit 4c43c27ddc461d8473cedd70f2549614641dfbc7 ] This patch resolves IO vs eviction race. After eviction failed export stayed at stale list, a client had IO processing and reconnected during it. A client sent brw rpc with last lock cookie and new connection. The lock with failed export was found and assert was happened. (ost_handler.c:1812:ost_prolong_lock_one()) ASSERTION( lock->l_export == opd->opd_exp ) failed: 1. Skip the lock at ldlm_handle2lock if lock export failed. 2. Validation of lock for IO was added at hpreq_check(). The lock searching is based on granted interval tree. If server doesn`t have a valid lock, it reply to client with ESTALE. Signed-off-by: Alexander Boyko Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-7702 Seagate-bug-id: MRP-2787 Reviewed-on: http://review.whamcloud.com/18120 Reviewed-by: Fan Yong Reviewed-by: Vitaly Fertman Reviewed-by: Oleg Drokin Signed-off-by: James Simmons Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/staging/lustre/lustre/ldlm/ldlm_lock.c | 7 +++ drivers/staging/lustre/lustre/ptlrpc/service.c | 21 - 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c index 3c48b4fb96f1..d18ab3f28c70 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c @@ -546,6 +546,13 @@ struct ldlm_lock *__ldlm_handle2lock(const struct lustre_handle *handle, if (!lock) return NULL; + if (lock->l_export && lock->l_export->exp_failed) { + CDEBUG(D_INFO, "lock export failed: lock %p, exp %p\n", + lock, lock->l_export); + LDLM_LOCK_PUT(lock); + return NULL; + } + /* It's unlikely but possible that someone marked the lock as * destroyed after we did handle2object on it */ diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c b/drivers/staging/lustre/lustre/ptlrpc/service.c index 72f39308eebb..9d34848d5458 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/service.c +++ b/drivers/staging/lustre/lustre/ptlrpc/service.c @@ -1264,20 +1264,15 @@ static int ptlrpc_server_hpreq_init(struct ptlrpc_service_part *svcpt, */ if (req->rq_ops->hpreq_check) { rc = req->rq_ops->hpreq_check(req); - /** -* XXX: Out of all current -* ptlrpc_hpreq_ops::hpreq_check(), only -* ldlm_cancel_hpreq_check() can return an error code; -* other functions assert in similar places, which seems -* odd. What also does not seem right is that handlers -* for those RPCs do not assert on the same checks, but -* rather handle the error cases. e.g. see -* ost_rw_hpreq_check(), and ost_brw_read(), -* ost_brw_write(). + if (rc == -ESTALE) { + req->rq_status = rc; + ptlrpc_error(req); + } + /** can only return error, +* 0 for normal request, +* or 1 for high priority request */ - if (rc < 0) - return rc; - LASSERT(rc == 0 || rc == 1); + LASSERT(rc <= 1); } spin_lock_bh(>rq_export->exp_rpc_lock); -- 2.11.0
[PATCH review for 4.9 09/50] mfd: axp20x: Fix axp288 PEK_DBR and PEK_DBF irqs being swapped
From: Hans de Goede [ Upstream commit 1af468ebe45591651ec3bafc2e9ddc6fdef70ae0 ] The R in PEK_DBR stands for rising, so it should be mapped to AXP288_IRQ_POKP where the last P stands for positive edge. Likewise PEK_DBF should be mapped to the falling edge, aka the _N_egative edge, so it should be mapped to AXP288_IRQ_POKN. This fixes the inverted powerbutton status reporting by the axp20x-pek driver. Signed-off-by: Hans de Goede Acked-by: Chen-Yu Tsai Signed-off-by: Lee Jones Signed-off-by: Sasha Levin --- drivers/mfd/axp20x.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c index ba130be32e61..9617fc323e15 100644 --- a/drivers/mfd/axp20x.c +++ b/drivers/mfd/axp20x.c @@ -205,14 +205,14 @@ static struct resource axp22x_pek_resources[] = { static struct resource axp288_power_button_resources[] = { { .name = "PEK_DBR", - .start = AXP288_IRQ_POKN, - .end= AXP288_IRQ_POKN, + .start = AXP288_IRQ_POKP, + .end= AXP288_IRQ_POKP, .flags = IORESOURCE_IRQ, }, { .name = "PEK_DBF", - .start = AXP288_IRQ_POKP, - .end= AXP288_IRQ_POKP, + .start = AXP288_IRQ_POKN, + .end= AXP288_IRQ_POKN, .flags = IORESOURCE_IRQ, }, }; -- 2.11.0
[PATCH review for 4.9 45/50] s390/prng: Adjust generation of entropy to produce real 256 bits.
From: Harald Freudenberger [ Upstream commit d34b1acb78af41b8b8d5c60972b6555ea19f7564 ] The generate_entropy function used a sha256 for compacting together 256 bits of entropy into 32 bytes hash. However, it is questionable if a sha256 can really be used here, as potential collisions may reduce the max entropy fitting into a 32 byte hash value. So this batch introduces the use of sha512 instead and the required buffer adjustments for the calling functions. Further more the working buffer for the generate_entropy function has been widened from one page to two pages. So now 1024 stckf invocations are used to gather 256 bits of entropy. This has been done to be on the save side if the jitters of stckf values isn't as good as supposed. Signed-off-by: Harald Freudenberger Signed-off-by: Martin Schwidefsky Signed-off-by: Sasha Levin --- arch/s390/crypto/prng.c | 40 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/arch/s390/crypto/prng.c b/arch/s390/crypto/prng.c index 1113389d0a39..fe7368a41aa8 100644 --- a/arch/s390/crypto/prng.c +++ b/arch/s390/crypto/prng.c @@ -110,22 +110,30 @@ static const u8 initial_parm_block[32] __initconst = { /*** helper functions ***/ +/* + * generate_entropy: + * This algorithm produces 64 bytes of entropy data based on 1024 + * individual stckf() invocations assuming that each stckf() value + * contributes 0.25 bits of entropy. So the caller gets 256 bit + * entropy per 64 byte or 4 bits entropy per byte. + */ static int generate_entropy(u8 *ebuf, size_t nbytes) { int n, ret = 0; - u8 *pg, *h, hash[32]; + u8 *pg, *h, hash[64]; - pg = (u8 *) __get_free_page(GFP_KERNEL); + /* allocate 2 pages */ + pg = (u8 *) __get_free_pages(GFP_KERNEL, 1); if (!pg) { prng_errorflag = PRNG_GEN_ENTROPY_FAILED; return -ENOMEM; } while (nbytes) { - /* fill page with urandom bytes */ - get_random_bytes(pg, PAGE_SIZE); - /* exor page with stckf values */ - for (n = 0; n < PAGE_SIZE / sizeof(u64); n++) { + /* fill pages with urandom bytes */ + get_random_bytes(pg, 2*PAGE_SIZE); + /* exor pages with 1024 stckf values */ + for (n = 0; n < 2 * PAGE_SIZE / sizeof(u64); n++) { u64 *p = ((u64 *)pg) + n; *p ^= get_tod_clock_fast(); } @@ -134,8 +142,8 @@ static int generate_entropy(u8 *ebuf, size_t nbytes) h = hash; else h = ebuf; - /* generate sha256 from this page */ - cpacf_kimd(CPACF_KIMD_SHA_256, h, pg, PAGE_SIZE); + /* hash over the filled pages */ + cpacf_kimd(CPACF_KIMD_SHA_512, h, pg, 2*PAGE_SIZE); if (n < sizeof(hash)) memcpy(ebuf, hash, n); ret += n; @@ -143,7 +151,7 @@ static int generate_entropy(u8 *ebuf, size_t nbytes) nbytes -= n; } - free_page((unsigned long)pg); + free_pages((unsigned long)pg, 1); return ret; } @@ -334,7 +342,7 @@ static int __init prng_sha512_selftest(void) static int __init prng_sha512_instantiate(void) { int ret, datalen; - u8 seed[64]; + u8 seed[64 + 32 + 16]; pr_debug("prng runs in SHA-512 mode " "with chunksize=%d and reseed_limit=%u\n", @@ -357,12 +365,12 @@ static int __init prng_sha512_instantiate(void) if (ret) goto outfree; - /* generate initial seed bytestring, first 48 bytes of entropy */ - ret = generate_entropy(seed, 48); - if (ret != 48) + /* generate initial seed bytestring, with 256 + 128 bits entropy */ + ret = generate_entropy(seed, 64 + 32); + if (ret != 64 + 32) goto outfree; /* followed by 16 bytes of unique nonce */ - get_tod_clock_ext(seed + 48); + get_tod_clock_ext(seed + 64 + 32); /* initial seed of the ppno drng */ cpacf_ppno(CPACF_PPNO_SHA512_DRNG_SEED, @@ -395,9 +403,9 @@ static void prng_sha512_deinstantiate(void) static int prng_sha512_reseed(void) { int ret; - u8 seed[32]; + u8 seed[64]; - /* generate 32 bytes of fresh entropy */ + /* fetch 256 bits of fresh entropy */ ret = generate_entropy(seed, sizeof(seed)); if (ret != sizeof(seed)) return ret; -- 2.11.0
[PATCH review for 4.9 02/50] crypto: ccp - Set the AES size field for all modes
From: Gary R Hook[ Upstream commit f7cc02b3c3a33a10dd5bb9e5dfd22e47e09503a2 ] Ensure that the size field is correctly populated for all AES modes. Signed-off-by: Gary R Hook Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/crypto/ccp/ccp-dev-v5.c | 3 +-- drivers/crypto/ccp/ccp-dev.h| 1 + drivers/crypto/ccp/ccp-ops.c| 8 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/crypto/ccp/ccp-dev-v5.c b/drivers/crypto/ccp/ccp-dev-v5.c index 17b19a68e269..71980c41283b 100644 --- a/drivers/crypto/ccp/ccp-dev-v5.c +++ b/drivers/crypto/ccp/ccp-dev-v5.c @@ -278,8 +278,7 @@ static int ccp5_perform_aes(struct ccp_op *op) CCP_AES_ENCRYPT() = op->u.aes.action; CCP_AES_MODE() = op->u.aes.mode; CCP_AES_TYPE() = op->u.aes.type; - if (op->u.aes.mode == CCP_AES_MODE_CFB) - CCP_AES_SIZE() = 0x7f; + CCP_AES_SIZE() = op->u.aes.size; CCP5_CMD_FUNCTION() = function.raw; diff --git a/drivers/crypto/ccp/ccp-dev.h b/drivers/crypto/ccp/ccp-dev.h index e23c36c7691c..347b77108baa 100644 --- a/drivers/crypto/ccp/ccp-dev.h +++ b/drivers/crypto/ccp/ccp-dev.h @@ -470,6 +470,7 @@ struct ccp_aes_op { enum ccp_aes_type type; enum ccp_aes_mode mode; enum ccp_aes_action action; + unsigned int size; }; struct ccp_xts_aes_op { diff --git a/drivers/crypto/ccp/ccp-ops.c b/drivers/crypto/ccp/ccp-ops.c index 64deb006c3be..7d4cd518e602 100644 --- a/drivers/crypto/ccp/ccp-ops.c +++ b/drivers/crypto/ccp/ccp-ops.c @@ -692,6 +692,14 @@ static int ccp_run_aes_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd) goto e_ctx; } } + switch (aes->mode) { + case CCP_AES_MODE_CFB: /* CFB128 only */ + case CCP_AES_MODE_CTR: + op.u.aes.size = AES_BLOCK_SIZE * BITS_PER_BYTE - 1; + break; + default: + op.u.aes.size = 0; + } /* Prepare the input and output data workareas. For in-place * operations we need to set the dma direction to BIDIRECTIONAL -- 2.11.0
[PATCH review for 4.9 02/50] crypto: ccp - Set the AES size field for all modes
From: Gary R Hook [ Upstream commit f7cc02b3c3a33a10dd5bb9e5dfd22e47e09503a2 ] Ensure that the size field is correctly populated for all AES modes. Signed-off-by: Gary R Hook Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/crypto/ccp/ccp-dev-v5.c | 3 +-- drivers/crypto/ccp/ccp-dev.h| 1 + drivers/crypto/ccp/ccp-ops.c| 8 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/crypto/ccp/ccp-dev-v5.c b/drivers/crypto/ccp/ccp-dev-v5.c index 17b19a68e269..71980c41283b 100644 --- a/drivers/crypto/ccp/ccp-dev-v5.c +++ b/drivers/crypto/ccp/ccp-dev-v5.c @@ -278,8 +278,7 @@ static int ccp5_perform_aes(struct ccp_op *op) CCP_AES_ENCRYPT() = op->u.aes.action; CCP_AES_MODE() = op->u.aes.mode; CCP_AES_TYPE() = op->u.aes.type; - if (op->u.aes.mode == CCP_AES_MODE_CFB) - CCP_AES_SIZE() = 0x7f; + CCP_AES_SIZE() = op->u.aes.size; CCP5_CMD_FUNCTION() = function.raw; diff --git a/drivers/crypto/ccp/ccp-dev.h b/drivers/crypto/ccp/ccp-dev.h index e23c36c7691c..347b77108baa 100644 --- a/drivers/crypto/ccp/ccp-dev.h +++ b/drivers/crypto/ccp/ccp-dev.h @@ -470,6 +470,7 @@ struct ccp_aes_op { enum ccp_aes_type type; enum ccp_aes_mode mode; enum ccp_aes_action action; + unsigned int size; }; struct ccp_xts_aes_op { diff --git a/drivers/crypto/ccp/ccp-ops.c b/drivers/crypto/ccp/ccp-ops.c index 64deb006c3be..7d4cd518e602 100644 --- a/drivers/crypto/ccp/ccp-ops.c +++ b/drivers/crypto/ccp/ccp-ops.c @@ -692,6 +692,14 @@ static int ccp_run_aes_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd) goto e_ctx; } } + switch (aes->mode) { + case CCP_AES_MODE_CFB: /* CFB128 only */ + case CCP_AES_MODE_CTR: + op.u.aes.size = AES_BLOCK_SIZE * BITS_PER_BYTE - 1; + break; + default: + op.u.aes.size = 0; + } /* Prepare the input and output data workareas. For in-place * operations we need to set the dma direction to BIDIRECTIONAL -- 2.11.0
[PATCH review for 4.9 42/50] [media] exynos4-is: fimc-is: Unmap region obtained by of_iomap()
From: Arvind Yadav[ Upstream commit 4742575cde1f3cee0ea6b41af42781672315b04b ] Free memory mapping, if fimc_is_probe is not successful. Signed-off-by: Arvind Yadav Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/platform/exynos4-is/fimc-is.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c index 518ad34f80d7..7f92144a1de3 100644 --- a/drivers/media/platform/exynos4-is/fimc-is.c +++ b/drivers/media/platform/exynos4-is/fimc-is.c @@ -825,12 +825,13 @@ static int fimc_is_probe(struct platform_device *pdev) is->irq = irq_of_parse_and_map(dev->of_node, 0); if (!is->irq) { dev_err(dev, "no irq found\n"); - return -EINVAL; + ret = -EINVAL; + goto err_iounmap; } ret = fimc_is_get_clocks(is); if (ret < 0) - return ret; + goto err_iounmap; platform_set_drvdata(pdev, is); @@ -891,6 +892,8 @@ static int fimc_is_probe(struct platform_device *pdev) free_irq(is->irq, is); err_clk: fimc_is_put_clocks(is); +err_iounmap: + iounmap(is->pmu_regs); return ret; } @@ -947,6 +950,7 @@ static int fimc_is_remove(struct platform_device *pdev) fimc_is_unregister_subdevs(is); vb2_dma_contig_clear_max_seg_size(dev); fimc_is_put_clocks(is); + iounmap(is->pmu_regs); fimc_is_debugfs_remove(is); release_firmware(is->fw.f_w); fimc_is_free_cpu_memory(is); -- 2.11.0
[PATCH review for 4.9 42/50] [media] exynos4-is: fimc-is: Unmap region obtained by of_iomap()
From: Arvind Yadav [ Upstream commit 4742575cde1f3cee0ea6b41af42781672315b04b ] Free memory mapping, if fimc_is_probe is not successful. Signed-off-by: Arvind Yadav Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/platform/exynos4-is/fimc-is.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c index 518ad34f80d7..7f92144a1de3 100644 --- a/drivers/media/platform/exynos4-is/fimc-is.c +++ b/drivers/media/platform/exynos4-is/fimc-is.c @@ -825,12 +825,13 @@ static int fimc_is_probe(struct platform_device *pdev) is->irq = irq_of_parse_and_map(dev->of_node, 0); if (!is->irq) { dev_err(dev, "no irq found\n"); - return -EINVAL; + ret = -EINVAL; + goto err_iounmap; } ret = fimc_is_get_clocks(is); if (ret < 0) - return ret; + goto err_iounmap; platform_set_drvdata(pdev, is); @@ -891,6 +892,8 @@ static int fimc_is_probe(struct platform_device *pdev) free_irq(is->irq, is); err_clk: fimc_is_put_clocks(is); +err_iounmap: + iounmap(is->pmu_regs); return ret; } @@ -947,6 +950,7 @@ static int fimc_is_remove(struct platform_device *pdev) fimc_is_unregister_subdevs(is); vb2_dma_contig_clear_max_seg_size(dev); fimc_is_put_clocks(is); + iounmap(is->pmu_regs); fimc_is_debugfs_remove(is); release_firmware(is->fw.f_w); fimc_is_free_cpu_memory(is); -- 2.11.0
[PATCH review for 4.9 41/50] ASoC: Intel: boards: remove .pm_ops in all Atom/DPCM machine drivers
From: Pierre-Louis Bossart[ Upstream commit 3639ac1cd5177685a5c8abb7230096b680e1d497 ] This patch corrects an omission in bytcr_rt5640 and bytcr_rt5651. All existing machine drivers shall not use .pm_ops to avoid a double suspend, as initially implemented by 3f2dcbeaeb2b ("ASoC: Intel: Remove soc pm handling to allow platform driver handle it"). Reported-by: Shrirang Bagul Signed-off-by: Pierre-Louis Bossart Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/intel/boards/bytcr_rt5640.c | 1 - sound/soc/intel/boards/bytcr_rt5651.c | 1 - 2 files changed, 2 deletions(-) diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index bd19fad2d91b..c17f262f0834 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -807,7 +807,6 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) static struct platform_driver snd_byt_rt5640_mc_driver = { .driver = { .name = "bytcr_rt5640", - .pm = _soc_pm_ops, }, .probe = snd_byt_rt5640_mc_probe, }; diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c index eabff3a857d0..ae49f8199e45 100644 --- a/sound/soc/intel/boards/bytcr_rt5651.c +++ b/sound/soc/intel/boards/bytcr_rt5651.c @@ -317,7 +317,6 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev) static struct platform_driver snd_byt_rt5651_mc_driver = { .driver = { .name = "bytcr_rt5651", - .pm = _soc_pm_ops, }, .probe = snd_byt_rt5651_mc_probe, }; -- 2.11.0
[PATCH review for 4.9 44/50] s390/dasd: check for device error pointer within state change interrupts
From: Stefan Haberland[ Upstream commit 2202134e48a3b50320aeb9e3dd1186833e9d7e66 ] Check if the device pointer is valid. Just a sanity check since we already are in the int handler of the device. Signed-off-by: Stefan Haberland Signed-off-by: Martin Schwidefsky Signed-off-by: Sasha Levin --- drivers/s390/block/dasd.c | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 1de089019268..5ecd40884f01 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -1704,8 +1704,11 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, /* check for for attention message */ if (scsw_dstat(>scsw) & DEV_STAT_ATTENTION) { device = dasd_device_from_cdev_locked(cdev); - device->discipline->check_attention(device, irb->esw.esw1.lpum); - dasd_put_device(device); + if (!IS_ERR(device)) { + device->discipline->check_attention(device, + irb->esw.esw1.lpum); + dasd_put_device(device); + } } if (!cqr) -- 2.11.0
[PATCH review for 4.9 41/50] ASoC: Intel: boards: remove .pm_ops in all Atom/DPCM machine drivers
From: Pierre-Louis Bossart [ Upstream commit 3639ac1cd5177685a5c8abb7230096b680e1d497 ] This patch corrects an omission in bytcr_rt5640 and bytcr_rt5651. All existing machine drivers shall not use .pm_ops to avoid a double suspend, as initially implemented by 3f2dcbeaeb2b ("ASoC: Intel: Remove soc pm handling to allow platform driver handle it"). Reported-by: Shrirang Bagul Signed-off-by: Pierre-Louis Bossart Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/intel/boards/bytcr_rt5640.c | 1 - sound/soc/intel/boards/bytcr_rt5651.c | 1 - 2 files changed, 2 deletions(-) diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index bd19fad2d91b..c17f262f0834 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -807,7 +807,6 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) static struct platform_driver snd_byt_rt5640_mc_driver = { .driver = { .name = "bytcr_rt5640", - .pm = _soc_pm_ops, }, .probe = snd_byt_rt5640_mc_probe, }; diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c index eabff3a857d0..ae49f8199e45 100644 --- a/sound/soc/intel/boards/bytcr_rt5651.c +++ b/sound/soc/intel/boards/bytcr_rt5651.c @@ -317,7 +317,6 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev) static struct platform_driver snd_byt_rt5651_mc_driver = { .driver = { .name = "bytcr_rt5651", - .pm = _soc_pm_ops, }, .probe = snd_byt_rt5651_mc_probe, }; -- 2.11.0
[PATCH review for 4.9 44/50] s390/dasd: check for device error pointer within state change interrupts
From: Stefan Haberland [ Upstream commit 2202134e48a3b50320aeb9e3dd1186833e9d7e66 ] Check if the device pointer is valid. Just a sanity check since we already are in the int handler of the device. Signed-off-by: Stefan Haberland Signed-off-by: Martin Schwidefsky Signed-off-by: Sasha Levin --- drivers/s390/block/dasd.c | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 1de089019268..5ecd40884f01 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -1704,8 +1704,11 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, /* check for for attention message */ if (scsw_dstat(>scsw) & DEV_STAT_ATTENTION) { device = dasd_device_from_cdev_locked(cdev); - device->discipline->check_attention(device, irb->esw.esw1.lpum); - dasd_put_device(device); + if (!IS_ERR(device)) { + device->discipline->check_attention(device, + irb->esw.esw1.lpum); + dasd_put_device(device); + } } if (!cqr) -- 2.11.0
[PATCH review for 4.9 25/50] ath10k: fix reading sram contents for QCA4019
From: Ashok Raj Nagarajan[ Upstream commit 7f622593cc5add77a99cd39404e8a851be9de792 ] With QCA4019 platform, SRAM address can be accessed directly from host but currently, we are assuming sram addresses cannot be accessed directly and hence we convert the addresses. While there, clean up growing hw checks during conversion of target CPU address to CE address. Now we have function pointer pertaining to different chips. Signed-off-by: Ashok Raj Nagarajan Signed-off-by: Kalle Valo Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath10k/ahb.c | 23 drivers/net/wireless/ath/ath10k/pci.c | 51 ++- drivers/net/wireless/ath/ath10k/pci.h | 5 3 files changed, 60 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/ahb.c b/drivers/net/wireless/ath/ath10k/ahb.c index 766c63bf05c4..45226dbee5ce 100644 --- a/drivers/net/wireless/ath/ath10k/ahb.c +++ b/drivers/net/wireless/ath/ath10k/ahb.c @@ -33,6 +33,9 @@ static const struct of_device_id ath10k_ahb_of_match[] = { MODULE_DEVICE_TABLE(of, ath10k_ahb_of_match); +#define QCA4019_SRAM_ADDR 0x000C +#define QCA4019_SRAM_LEN 0x0004 /* 256 kb */ + static inline struct ath10k_ahb *ath10k_ahb_priv(struct ath10k *ar) { return &((struct ath10k_pci *)ar->drv_priv)->ahb[0]; @@ -699,6 +702,25 @@ static int ath10k_ahb_hif_power_up(struct ath10k *ar) return ret; } +static u32 ath10k_ahb_qca4019_targ_cpu_to_ce_addr(struct ath10k *ar, u32 addr) +{ + u32 val = 0, region = addr & 0xf; + + val = ath10k_pci_read32(ar, PCIE_BAR_REG_ADDRESS); + + if (region >= QCA4019_SRAM_ADDR && region <= + (QCA4019_SRAM_ADDR + QCA4019_SRAM_LEN)) { + /* SRAM contents for QCA4019 can be directly accessed and +* no conversions are required +*/ + val |= region; + } else { + val |= 0x10 | region; + } + + return val; +} + static const struct ath10k_hif_ops ath10k_ahb_hif_ops = { .tx_sg = ath10k_pci_hif_tx_sg, .diag_read = ath10k_pci_hif_diag_read, @@ -766,6 +788,7 @@ static int ath10k_ahb_probe(struct platform_device *pdev) ar_pci->mem_len = ar_ahb->mem_len; ar_pci->ar = ar; ar_pci->bus_ops = _ahb_bus_ops; + ar_pci->targ_cpu_to_ce_addr = ath10k_ahb_qca4019_targ_cpu_to_ce_addr; ret = ath10k_pci_setup_resource(ar); if (ret) { diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 410bcdaa9e87..25b8d501d437 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -840,31 +840,35 @@ void ath10k_pci_rx_replenish_retry(unsigned long ptr) ath10k_pci_rx_post(ar); } -static u32 ath10k_pci_targ_cpu_to_ce_addr(struct ath10k *ar, u32 addr) +static u32 ath10k_pci_qca988x_targ_cpu_to_ce_addr(struct ath10k *ar, u32 addr) { - u32 val = 0; + u32 val = 0, region = addr & 0xf; - switch (ar->hw_rev) { - case ATH10K_HW_QCA988X: - case ATH10K_HW_QCA9887: - case ATH10K_HW_QCA6174: - case ATH10K_HW_QCA9377: - val = (ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + - CORE_CTRL_ADDRESS) & - 0x7ff) << 21; - break; - case ATH10K_HW_QCA9888: - case ATH10K_HW_QCA99X0: - case ATH10K_HW_QCA9984: - case ATH10K_HW_QCA4019: - val = ath10k_pci_read32(ar, PCIE_BAR_REG_ADDRESS); - break; - } + val = (ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + CORE_CTRL_ADDRESS) +& 0x7ff) << 21; + val |= 0x10 | region; + return val; +} + +static u32 ath10k_pci_qca99x0_targ_cpu_to_ce_addr(struct ath10k *ar, u32 addr) +{ + u32 val = 0, region = addr & 0xf; - val |= 0x10 | (addr & 0xf); + val = ath10k_pci_read32(ar, PCIE_BAR_REG_ADDRESS); + val |= 0x10 | region; return val; } +static u32 ath10k_pci_targ_cpu_to_ce_addr(struct ath10k *ar, u32 addr) +{ + struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); + + if (WARN_ON_ONCE(!ar_pci->targ_cpu_to_ce_addr)) + return -ENOTSUPP; + + return ar_pci->targ_cpu_to_ce_addr(ar, addr); +} + /* * Diagnostic read/write access is provided for startup/config/debug usage. * Caller must guarantee proper alignment, when applicable, and single user @@ -3171,6 +3175,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev, bool pci_ps; int (*pci_soft_reset)(struct ath10k *ar); int (*pci_hard_reset)(struct ath10k *ar); + u32 (*targ_cpu_to_ce_addr)(struct ath10k *ar, u32 addr); switch (pci_dev->device) { case
[PATCH review for 4.9 25/50] ath10k: fix reading sram contents for QCA4019
From: Ashok Raj Nagarajan [ Upstream commit 7f622593cc5add77a99cd39404e8a851be9de792 ] With QCA4019 platform, SRAM address can be accessed directly from host but currently, we are assuming sram addresses cannot be accessed directly and hence we convert the addresses. While there, clean up growing hw checks during conversion of target CPU address to CE address. Now we have function pointer pertaining to different chips. Signed-off-by: Ashok Raj Nagarajan Signed-off-by: Kalle Valo Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath10k/ahb.c | 23 drivers/net/wireless/ath/ath10k/pci.c | 51 ++- drivers/net/wireless/ath/ath10k/pci.h | 5 3 files changed, 60 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/ahb.c b/drivers/net/wireless/ath/ath10k/ahb.c index 766c63bf05c4..45226dbee5ce 100644 --- a/drivers/net/wireless/ath/ath10k/ahb.c +++ b/drivers/net/wireless/ath/ath10k/ahb.c @@ -33,6 +33,9 @@ static const struct of_device_id ath10k_ahb_of_match[] = { MODULE_DEVICE_TABLE(of, ath10k_ahb_of_match); +#define QCA4019_SRAM_ADDR 0x000C +#define QCA4019_SRAM_LEN 0x0004 /* 256 kb */ + static inline struct ath10k_ahb *ath10k_ahb_priv(struct ath10k *ar) { return &((struct ath10k_pci *)ar->drv_priv)->ahb[0]; @@ -699,6 +702,25 @@ static int ath10k_ahb_hif_power_up(struct ath10k *ar) return ret; } +static u32 ath10k_ahb_qca4019_targ_cpu_to_ce_addr(struct ath10k *ar, u32 addr) +{ + u32 val = 0, region = addr & 0xf; + + val = ath10k_pci_read32(ar, PCIE_BAR_REG_ADDRESS); + + if (region >= QCA4019_SRAM_ADDR && region <= + (QCA4019_SRAM_ADDR + QCA4019_SRAM_LEN)) { + /* SRAM contents for QCA4019 can be directly accessed and +* no conversions are required +*/ + val |= region; + } else { + val |= 0x10 | region; + } + + return val; +} + static const struct ath10k_hif_ops ath10k_ahb_hif_ops = { .tx_sg = ath10k_pci_hif_tx_sg, .diag_read = ath10k_pci_hif_diag_read, @@ -766,6 +788,7 @@ static int ath10k_ahb_probe(struct platform_device *pdev) ar_pci->mem_len = ar_ahb->mem_len; ar_pci->ar = ar; ar_pci->bus_ops = _ahb_bus_ops; + ar_pci->targ_cpu_to_ce_addr = ath10k_ahb_qca4019_targ_cpu_to_ce_addr; ret = ath10k_pci_setup_resource(ar); if (ret) { diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 410bcdaa9e87..25b8d501d437 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -840,31 +840,35 @@ void ath10k_pci_rx_replenish_retry(unsigned long ptr) ath10k_pci_rx_post(ar); } -static u32 ath10k_pci_targ_cpu_to_ce_addr(struct ath10k *ar, u32 addr) +static u32 ath10k_pci_qca988x_targ_cpu_to_ce_addr(struct ath10k *ar, u32 addr) { - u32 val = 0; + u32 val = 0, region = addr & 0xf; - switch (ar->hw_rev) { - case ATH10K_HW_QCA988X: - case ATH10K_HW_QCA9887: - case ATH10K_HW_QCA6174: - case ATH10K_HW_QCA9377: - val = (ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + - CORE_CTRL_ADDRESS) & - 0x7ff) << 21; - break; - case ATH10K_HW_QCA9888: - case ATH10K_HW_QCA99X0: - case ATH10K_HW_QCA9984: - case ATH10K_HW_QCA4019: - val = ath10k_pci_read32(ar, PCIE_BAR_REG_ADDRESS); - break; - } + val = (ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + CORE_CTRL_ADDRESS) +& 0x7ff) << 21; + val |= 0x10 | region; + return val; +} + +static u32 ath10k_pci_qca99x0_targ_cpu_to_ce_addr(struct ath10k *ar, u32 addr) +{ + u32 val = 0, region = addr & 0xf; - val |= 0x10 | (addr & 0xf); + val = ath10k_pci_read32(ar, PCIE_BAR_REG_ADDRESS); + val |= 0x10 | region; return val; } +static u32 ath10k_pci_targ_cpu_to_ce_addr(struct ath10k *ar, u32 addr) +{ + struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); + + if (WARN_ON_ONCE(!ar_pci->targ_cpu_to_ce_addr)) + return -ENOTSUPP; + + return ar_pci->targ_cpu_to_ce_addr(ar, addr); +} + /* * Diagnostic read/write access is provided for startup/config/debug usage. * Caller must guarantee proper alignment, when applicable, and single user @@ -3171,6 +3175,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev, bool pci_ps; int (*pci_soft_reset)(struct ath10k *ar); int (*pci_hard_reset)(struct ath10k *ar); + u32 (*targ_cpu_to_ce_addr)(struct ath10k *ar, u32 addr); switch (pci_dev->device) { case QCA988X_2_0_DEVICE_ID: @@ -3178,12 +3183,14 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
[PATCH review for 4.9 46/50] s390/crypto: Extend key length check for AES-XTS in fips mode.
From: Harald Freudenberger[ Upstream commit a4f2779ecf2f42b0997fedef6fd20a931c40a3e3 ] In fips mode only xts keys with 128 bit or 125 bit are allowed. This fix extends the xts_aes_set_key function to check for these valid key lengths in fips mode. Signed-off-by: Harald Freudenberger Signed-off-by: Martin Schwidefsky Signed-off-by: Sasha Levin --- arch/s390/crypto/aes_s390.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c index 303d28eb03a2..591cbdf615af 100644 --- a/arch/s390/crypto/aes_s390.c +++ b/arch/s390/crypto/aes_s390.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -501,6 +502,12 @@ static int xts_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, if (err) return err; + /* In fips mode only 128 bit or 256 bit keys are valid */ + if (fips_enabled && key_len != 32 && key_len != 64) { + tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; + return -EINVAL; + } + /* Pick the correct function code based on the key length */ fc = (key_len == 32) ? CPACF_KM_XTS_128 : (key_len == 64) ? CPACF_KM_XTS_256 : 0; -- 2.11.0
[PATCH review for 4.9 46/50] s390/crypto: Extend key length check for AES-XTS in fips mode.
From: Harald Freudenberger [ Upstream commit a4f2779ecf2f42b0997fedef6fd20a931c40a3e3 ] In fips mode only xts keys with 128 bit or 125 bit are allowed. This fix extends the xts_aes_set_key function to check for these valid key lengths in fips mode. Signed-off-by: Harald Freudenberger Signed-off-by: Martin Schwidefsky Signed-off-by: Sasha Levin --- arch/s390/crypto/aes_s390.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c index 303d28eb03a2..591cbdf615af 100644 --- a/arch/s390/crypto/aes_s390.c +++ b/arch/s390/crypto/aes_s390.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -501,6 +502,12 @@ static int xts_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, if (err) return err; + /* In fips mode only 128 bit or 256 bit keys are valid */ + if (fips_enabled && key_len != 32 && key_len != 64) { + tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; + return -EINVAL; + } + /* Pick the correct function code based on the key length */ fc = (key_len == 32) ? CPACF_KM_XTS_128 : (key_len == 64) ? CPACF_KM_XTS_256 : 0; -- 2.11.0
[PATCH review for 4.4 10/24] drm/amdgpu: when dpm disabled, also need to stop/start vce.
From: Rex Zhu[ Upstream commit 28ed5504ab4b211a4e589e648e5ebd1e0caa7a6a ] Signed-off-by: Rex Zhu Reviewed-by: Alex Deucher Acked-by: Christian König Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | 9 + 1 file changed, 9 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c index bb0da76051a1..e5da6f19b9b8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c @@ -284,6 +284,10 @@ static void amdgpu_vce_idle_work_handler(struct work_struct *work) amdgpu_dpm_enable_vce(adev, false); } else { amdgpu_asic_set_vce_clocks(adev, 0, 0); + amdgpu_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCE, + AMD_PG_STATE_GATE); + amdgpu_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_VCE, + AMD_CG_STATE_GATE); } } else { schedule_delayed_work(>vce.idle_work, @@ -315,6 +319,11 @@ static void amdgpu_vce_note_usage(struct amdgpu_device *adev) amdgpu_dpm_enable_vce(adev, true); } else { amdgpu_asic_set_vce_clocks(adev, 53300, 4); + amdgpu_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_VCE, + AMD_CG_STATE_UNGATE); + amdgpu_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCE, + AMD_PG_STATE_UNGATE); + } } } -- 2.11.0
[PATCH review for 4.4 10/24] drm/amdgpu: when dpm disabled, also need to stop/start vce.
From: Rex Zhu [ Upstream commit 28ed5504ab4b211a4e589e648e5ebd1e0caa7a6a ] Signed-off-by: Rex Zhu Reviewed-by: Alex Deucher Acked-by: Christian König Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | 9 + 1 file changed, 9 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c index bb0da76051a1..e5da6f19b9b8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c @@ -284,6 +284,10 @@ static void amdgpu_vce_idle_work_handler(struct work_struct *work) amdgpu_dpm_enable_vce(adev, false); } else { amdgpu_asic_set_vce_clocks(adev, 0, 0); + amdgpu_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCE, + AMD_PG_STATE_GATE); + amdgpu_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_VCE, + AMD_CG_STATE_GATE); } } else { schedule_delayed_work(>vce.idle_work, @@ -315,6 +319,11 @@ static void amdgpu_vce_note_usage(struct amdgpu_device *adev) amdgpu_dpm_enable_vce(adev, true); } else { amdgpu_asic_set_vce_clocks(adev, 53300, 4); + amdgpu_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_VCE, + AMD_CG_STATE_UNGATE); + amdgpu_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCE, + AMD_PG_STATE_UNGATE); + } } } -- 2.11.0
[PATCH review for 4.4 05/24] mfd: axp20x: Fix axp288 PEK_DBR and PEK_DBF irqs being swapped
From: Hans de Goede[ Upstream commit 1af468ebe45591651ec3bafc2e9ddc6fdef70ae0 ] The R in PEK_DBR stands for rising, so it should be mapped to AXP288_IRQ_POKP where the last P stands for positive edge. Likewise PEK_DBF should be mapped to the falling edge, aka the _N_egative edge, so it should be mapped to AXP288_IRQ_POKN. This fixes the inverted powerbutton status reporting by the axp20x-pek driver. Signed-off-by: Hans de Goede Acked-by: Chen-Yu Tsai Signed-off-by: Lee Jones Signed-off-by: Sasha Levin --- drivers/mfd/axp20x.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c index 9842199e2e6c..89a2dd4d212a 100644 --- a/drivers/mfd/axp20x.c +++ b/drivers/mfd/axp20x.c @@ -164,14 +164,14 @@ static struct resource axp22x_pek_resources[] = { static struct resource axp288_power_button_resources[] = { { .name = "PEK_DBR", - .start = AXP288_IRQ_POKN, - .end= AXP288_IRQ_POKN, + .start = AXP288_IRQ_POKP, + .end= AXP288_IRQ_POKP, .flags = IORESOURCE_IRQ, }, { .name = "PEK_DBF", - .start = AXP288_IRQ_POKP, - .end= AXP288_IRQ_POKP, + .start = AXP288_IRQ_POKN, + .end= AXP288_IRQ_POKN, .flags = IORESOURCE_IRQ, }, }; -- 2.11.0
[PATCH review for 4.9 47/50] [media] bt8xx: fix memory leak
From: Sudip Mukherjee[ Upstream commit 6792eb0cf9310ec240b7e7c9bfa86dff4c758c68 ] If dvb_attach() fails then we were just printing an error message and exiting but the memory allocated to state was not released. Signed-off-by: Sudip Mukherjee Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/pci/bt8xx/dvb-bt8xx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/pci/bt8xx/dvb-bt8xx.c b/drivers/media/pci/bt8xx/dvb-bt8xx.c index e69d338ab9be..ae550a180364 100644 --- a/drivers/media/pci/bt8xx/dvb-bt8xx.c +++ b/drivers/media/pci/bt8xx/dvb-bt8xx.c @@ -680,6 +680,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) /* DST is not a frontend, attaching the ASIC */ if (dvb_attach(dst_attach, state, >dvb_adapter) == NULL) { pr_err("%s: Could not find a Twinhan DST\n", __func__); + kfree(state); break; } /* Attach other DST peripherals if any */ -- 2.11.0
[PATCH review for 4.9 08/50] mfd: ab8500-sysctrl: Handle probe deferral
From: Linus Walleij[ Upstream commit 7e9c40c63933a643908d686bd89dfc2315e8c70a ] In the current boot, clients making use of the AB8500 sysctrl may be probed before the ab8500-sysctrl driver. This gives them -EINVAL, but should rather give -EPROBE_DEFER. Before this, the abx500 clock driver didn't probe properly, and as a result the codec driver in turn using the clocks did not probe properly. After this patch, everything probes properly. Also add OF compatible-string probing. This driver is all device tree, so let's just make a drive-by-fix of that as well. Signed-off-by: Linus Walleij Signed-off-by: Lee Jones Signed-off-by: Sasha Levin --- drivers/mfd/ab8500-sysctrl.c | 14 +++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/mfd/ab8500-sysctrl.c b/drivers/mfd/ab8500-sysctrl.c index 207cc497958a..8062d37b4ba4 100644 --- a/drivers/mfd/ab8500-sysctrl.c +++ b/drivers/mfd/ab8500-sysctrl.c @@ -98,7 +98,7 @@ int ab8500_sysctrl_read(u16 reg, u8 *value) u8 bank; if (sysctrl_dev == NULL) - return -EINVAL; + return -EPROBE_DEFER; bank = (reg >> 8); if (!valid_bank(bank)) @@ -114,11 +114,13 @@ int ab8500_sysctrl_write(u16 reg, u8 mask, u8 value) u8 bank; if (sysctrl_dev == NULL) - return -EINVAL; + return -EPROBE_DEFER; bank = (reg >> 8); - if (!valid_bank(bank)) + if (!valid_bank(bank)) { + pr_err("invalid bank\n"); return -EINVAL; + } return abx500_mask_and_set_register_interruptible(sysctrl_dev, bank, (u8)(reg & 0xFF), mask, value); @@ -145,9 +147,15 @@ static int ab8500_sysctrl_remove(struct platform_device *pdev) return 0; } +static const struct of_device_id ab8500_sysctrl_match[] = { + { .compatible = "stericsson,ab8500-sysctrl", }, + {} +}; + static struct platform_driver ab8500_sysctrl_driver = { .driver = { .name = "ab8500-sysctrl", + .of_match_table = ab8500_sysctrl_match, }, .probe = ab8500_sysctrl_probe, .remove = ab8500_sysctrl_remove, -- 2.11.0
[PATCH review for 4.9 47/50] [media] bt8xx: fix memory leak
From: Sudip Mukherjee [ Upstream commit 6792eb0cf9310ec240b7e7c9bfa86dff4c758c68 ] If dvb_attach() fails then we were just printing an error message and exiting but the memory allocated to state was not released. Signed-off-by: Sudip Mukherjee Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/pci/bt8xx/dvb-bt8xx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/pci/bt8xx/dvb-bt8xx.c b/drivers/media/pci/bt8xx/dvb-bt8xx.c index e69d338ab9be..ae550a180364 100644 --- a/drivers/media/pci/bt8xx/dvb-bt8xx.c +++ b/drivers/media/pci/bt8xx/dvb-bt8xx.c @@ -680,6 +680,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) /* DST is not a frontend, attaching the ASIC */ if (dvb_attach(dst_attach, state, >dvb_adapter) == NULL) { pr_err("%s: Could not find a Twinhan DST\n", __func__); + kfree(state); break; } /* Attach other DST peripherals if any */ -- 2.11.0
[PATCH review for 4.9 08/50] mfd: ab8500-sysctrl: Handle probe deferral
From: Linus Walleij [ Upstream commit 7e9c40c63933a643908d686bd89dfc2315e8c70a ] In the current boot, clients making use of the AB8500 sysctrl may be probed before the ab8500-sysctrl driver. This gives them -EINVAL, but should rather give -EPROBE_DEFER. Before this, the abx500 clock driver didn't probe properly, and as a result the codec driver in turn using the clocks did not probe properly. After this patch, everything probes properly. Also add OF compatible-string probing. This driver is all device tree, so let's just make a drive-by-fix of that as well. Signed-off-by: Linus Walleij Signed-off-by: Lee Jones Signed-off-by: Sasha Levin --- drivers/mfd/ab8500-sysctrl.c | 14 +++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/mfd/ab8500-sysctrl.c b/drivers/mfd/ab8500-sysctrl.c index 207cc497958a..8062d37b4ba4 100644 --- a/drivers/mfd/ab8500-sysctrl.c +++ b/drivers/mfd/ab8500-sysctrl.c @@ -98,7 +98,7 @@ int ab8500_sysctrl_read(u16 reg, u8 *value) u8 bank; if (sysctrl_dev == NULL) - return -EINVAL; + return -EPROBE_DEFER; bank = (reg >> 8); if (!valid_bank(bank)) @@ -114,11 +114,13 @@ int ab8500_sysctrl_write(u16 reg, u8 mask, u8 value) u8 bank; if (sysctrl_dev == NULL) - return -EINVAL; + return -EPROBE_DEFER; bank = (reg >> 8); - if (!valid_bank(bank)) + if (!valid_bank(bank)) { + pr_err("invalid bank\n"); return -EINVAL; + } return abx500_mask_and_set_register_interruptible(sysctrl_dev, bank, (u8)(reg & 0xFF), mask, value); @@ -145,9 +147,15 @@ static int ab8500_sysctrl_remove(struct platform_device *pdev) return 0; } +static const struct of_device_id ab8500_sysctrl_match[] = { + { .compatible = "stericsson,ab8500-sysctrl", }, + {} +}; + static struct platform_driver ab8500_sysctrl_driver = { .driver = { .name = "ab8500-sysctrl", + .of_match_table = ab8500_sysctrl_match, }, .probe = ab8500_sysctrl_probe, .remove = ab8500_sysctrl_remove, -- 2.11.0
[PATCH review for 4.4 05/24] mfd: axp20x: Fix axp288 PEK_DBR and PEK_DBF irqs being swapped
From: Hans de Goede [ Upstream commit 1af468ebe45591651ec3bafc2e9ddc6fdef70ae0 ] The R in PEK_DBR stands for rising, so it should be mapped to AXP288_IRQ_POKP where the last P stands for positive edge. Likewise PEK_DBF should be mapped to the falling edge, aka the _N_egative edge, so it should be mapped to AXP288_IRQ_POKN. This fixes the inverted powerbutton status reporting by the axp20x-pek driver. Signed-off-by: Hans de Goede Acked-by: Chen-Yu Tsai Signed-off-by: Lee Jones Signed-off-by: Sasha Levin --- drivers/mfd/axp20x.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c index 9842199e2e6c..89a2dd4d212a 100644 --- a/drivers/mfd/axp20x.c +++ b/drivers/mfd/axp20x.c @@ -164,14 +164,14 @@ static struct resource axp22x_pek_resources[] = { static struct resource axp288_power_button_resources[] = { { .name = "PEK_DBR", - .start = AXP288_IRQ_POKN, - .end= AXP288_IRQ_POKN, + .start = AXP288_IRQ_POKP, + .end= AXP288_IRQ_POKP, .flags = IORESOURCE_IRQ, }, { .name = "PEK_DBF", - .start = AXP288_IRQ_POKP, - .end= AXP288_IRQ_POKP, + .start = AXP288_IRQ_POKN, + .end= AXP288_IRQ_POKN, .flags = IORESOURCE_IRQ, }, }; -- 2.11.0
[PATCH review for 4.4 02/24] mmc: s3cmci: include linux/interrupt.h for tasklet_struct
From: Arnd Bergmann[ Upstream commit e1c6ec26b853e9062f0b3daaf695c546d0702953 ] I got this new build error on today's linux-next drivers/mmc/host/s3cmci.h:69:24: error: field 'pio_tasklet' has incomplete type struct tasklet_struct pio_tasklet; drivers/mmc/host/s3cmci.c: In function 's3cmci_enable_irq': drivers/mmc/host/s3cmci.c:390:4: error: implicit declaration of function 'enable_irq';did you mean 'enable_imask'? [-Werror=implicit-function-declaration] While I haven't found out why this happened now and not earlier, the solution is obvious, we should include the header that defines the structure. Signed-off-by: Arnd Bergmann Signed-off-by: Ulf Hansson Signed-off-by: Sasha Levin --- drivers/mmc/host/s3cmci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 6291d5042ef2..6fed41bd016a 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include -- 2.11.0
[PATCH review for 4.4 02/24] mmc: s3cmci: include linux/interrupt.h for tasklet_struct
From: Arnd Bergmann [ Upstream commit e1c6ec26b853e9062f0b3daaf695c546d0702953 ] I got this new build error on today's linux-next drivers/mmc/host/s3cmci.h:69:24: error: field 'pio_tasklet' has incomplete type struct tasklet_struct pio_tasklet; drivers/mmc/host/s3cmci.c: In function 's3cmci_enable_irq': drivers/mmc/host/s3cmci.c:390:4: error: implicit declaration of function 'enable_irq';did you mean 'enable_imask'? [-Werror=implicit-function-declaration] While I haven't found out why this happened now and not earlier, the solution is obvious, we should include the header that defines the structure. Signed-off-by: Arnd Bergmann Signed-off-by: Ulf Hansson Signed-off-by: Sasha Levin --- drivers/mmc/host/s3cmci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 6291d5042ef2..6fed41bd016a 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include -- 2.11.0
[PATCH review for 4.9 50/50] PCI: Avoid possible deadlock on pci_lock and p->pi_lock
From: Bjorn Helgaas[ Upstream commit cdcb33f9824429a926b971bf041a6cec238f91ff ] pci_lock is an IRQ-safe spinlock that protects all accesses to PCI configuration space (see PCI_OP_READ() and PCI_OP_WRITE() in pci/access.c). The pci_cfg_access_unlock() path acquires pci_lock, then p->pi_lock (inside wake_up_all()). According to lockdep, there is a possible path involving snbep_uncore_pci_read_counter() that could acquire them in the reverse order: acquiring p->pi_lock, then pci_lock, which could result in a deadlock. Lockdep details are in the bugzilla below. Avoid the possible deadlock by dropping pci_lock before waking up any config access waiters. Link: https://bugzilla.kernel.org/show_bug.cgi?id=192901 Signed-off-by: Bjorn Helgaas Signed-off-by: Sasha Levin --- drivers/pci/access.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/pci/access.c b/drivers/pci/access.c index d11cdbb8fba3..7b5cf6d1181a 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c @@ -672,8 +672,9 @@ void pci_cfg_access_unlock(struct pci_dev *dev) WARN_ON(!dev->block_cfg_access); dev->block_cfg_access = 0; - wake_up_all(_cfg_wait); raw_spin_unlock_irqrestore(_lock, flags); + + wake_up_all(_cfg_wait); } EXPORT_SYMBOL_GPL(pci_cfg_access_unlock); -- 2.11.0
[PATCH review for 4.9 50/50] PCI: Avoid possible deadlock on pci_lock and p->pi_lock
From: Bjorn Helgaas [ Upstream commit cdcb33f9824429a926b971bf041a6cec238f91ff ] pci_lock is an IRQ-safe spinlock that protects all accesses to PCI configuration space (see PCI_OP_READ() and PCI_OP_WRITE() in pci/access.c). The pci_cfg_access_unlock() path acquires pci_lock, then p->pi_lock (inside wake_up_all()). According to lockdep, there is a possible path involving snbep_uncore_pci_read_counter() that could acquire them in the reverse order: acquiring p->pi_lock, then pci_lock, which could result in a deadlock. Lockdep details are in the bugzilla below. Avoid the possible deadlock by dropping pci_lock before waking up any config access waiters. Link: https://bugzilla.kernel.org/show_bug.cgi?id=192901 Signed-off-by: Bjorn Helgaas Signed-off-by: Sasha Levin --- drivers/pci/access.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/pci/access.c b/drivers/pci/access.c index d11cdbb8fba3..7b5cf6d1181a 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c @@ -672,8 +672,9 @@ void pci_cfg_access_unlock(struct pci_dev *dev) WARN_ON(!dev->block_cfg_access); dev->block_cfg_access = 0; - wake_up_all(_cfg_wait); raw_spin_unlock_irqrestore(_lock, flags); + + wake_up_all(_cfg_wait); } EXPORT_SYMBOL_GPL(pci_cfg_access_unlock); -- 2.11.0