Re: [PATCH] block: Remove judgement for rq_mergeable(rq) in func elv_rqhash_find.
On 2013-01-07 06:08, majianpeng wrote: > Because only mergeable rq can add rqhash.So it does not make sense to > judge rq_mergeable(rq) in func elv_rqhash_find. It does make sense. A request is always mergeable when it enters the hash, but it may not remain mergeable. This can happen if we merge it to its maximum size, for instance. -- Jens Axboe -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH V2 2/2] virtio-net: reset virtqueue affinity when doing cpu hotplug
On 01/07/2013 03:48 PM, Wanlong Gao wrote: > On 01/07/2013 03:28 PM, Jason Wang wrote: >> On 01/07/2013 03:15 PM, Wanlong Gao wrote: >>> Add a cpu notifier to virtio-net, so that we can reset the >>> virtqueue affinity if the cpu hotplug happens. It improve >>> the performance through enabling or disabling the virtqueue >>> affinity after doing cpu hotplug. >>> Adding the notifier block to virtnet_info is suggested by >>> Jason, thank you. >>> >>> Cc: Rusty Russell >>> Cc: "Michael S. Tsirkin" >>> Cc: Jason Wang >>> Cc: Eric Dumazet >>> Cc: virtualizat...@lists.linux-foundation.org >>> Cc: net...@vger.kernel.org >>> Signed-off-by: Wanlong Gao >>> --- >>> drivers/net/virtio_net.c | 30 ++ >>> 1 file changed, 30 insertions(+) >>> >>> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c >>> index b483fb5..9547b4c 100644 >>> --- a/drivers/net/virtio_net.c >>> +++ b/drivers/net/virtio_net.c >>> @@ -26,6 +26,7 @@ >>> #include >>> #include >>> #include >>> +#include >>> >>> static int napi_weight = 128; >>> module_param(napi_weight, int, 0444); >>> @@ -123,6 +124,9 @@ struct virtnet_info { >>> >>> /* Does the affinity hint is set for virtqueues? */ >>> bool affinity_hint_set; >>> + >>> + /* CPU hot plug notifier */ >>> + struct notifier_block nb; >>> }; >>> >>> struct skb_vnet_hdr { >>> @@ -1051,6 +1055,23 @@ static void virtnet_set_affinity(struct virtnet_info >>> *vi, bool set) >>> } >>> } >>> >>> +static int virtnet_cpu_callback(struct notifier_block *nfb, >>> + unsigned long action, void *hcpu) >>> +{ >>> + struct virtnet_info *vi = container_of(nfb, struct virtnet_info, nb); >>> + switch(action) { >>> + case CPU_ONLINE: >>> + case CPU_ONLINE_FROZEN: >>> + case CPU_DEAD: >>> + case CPU_DEAD_FROZEN: >>> + virtnet_set_affinity(vi, true); >>> + break; >>> + default: >>> + break; >>> + } >>> + return NOTIFY_OK; >>> +} >>> + >> I think you'd better fix the .ndo_select_queue() as well (as Michael >> said in your V1) since it currently uses smp processor id which may not >> work very well in this case also. > The bug is we can't get the right txq if the CPU IDs are not consecutive, > right? Do you have any good idea about fixing this? > > Thanks, > Wanlong Gao The point is make the virtqueue private to a specific cpu when the number of queue pairs is equal to the number of cpus. So after you bind the vq affinity to a specific cpu, you'd better use the reverse mapping of this affinity to do .ndo_select_queue(). One possible idea, as Michael suggested, is a per-cpu structure to record the preferable virtqueue and do both .ndo_select_queue() and affinity hint setting based on this. > >> Thanks >>> static void virtnet_get_ringparam(struct net_device *dev, >>> struct ethtool_ringparam *ring) >>> { >>> @@ -1509,6 +1530,13 @@ static int virtnet_probe(struct virtio_device *vdev) >>> } >>> } >>> >>> + vi->nb.notifier_call = _cpu_callback; >>> + err = register_hotcpu_notifier(>nb); >>> + if (err) { >>> + pr_debug("virtio_net: registering cpu notifier failed\n"); >>> + goto free_recv_bufs; >>> + } >>> + >>> /* Assume link up if device can't report link status, >>>otherwise get link status from config. */ >>> if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) { >>> @@ -1553,6 +1581,8 @@ static void virtnet_remove(struct virtio_device *vdev) >>> { >>> struct virtnet_info *vi = vdev->priv; >>> >>> + unregister_hotcpu_notifier(>nb); >>> + >>> /* Prevent config work handler from accessing the device. */ >>> mutex_lock(>config_lock); >>> vi->config_enable = false; >> -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] iommu: moving initialization earlier
The iommu_init() initializes IOMMU internal structures and data required for the IOMMU API as iommu_group_alloc(). It is registered as a subsys_initcall now. One of the IOMMU users is going to be a PCI subsystem on POWER. It discovers new IOMMU tables during the PCI scan so the logical place to call iommu_group_alloc() is the moment when a new group is discovered. However PCI scan is done from subsys_initcall hook as IOMMU does so PCI hook can be (and is) called before the IOMMU one. The patch moves IOMMU subsystem initialization one step earlier to make sure that IOMMU is initialized before PCI scan begins. Signed-off-by: Alexey Kardashevskiy --- drivers/iommu/iommu.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index ddbdaca..1065a1a 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -861,7 +861,7 @@ static int __init iommu_init(void) return 0; } -subsys_initcall(iommu_init); +arch_initcall(iommu_init); int iommu_domain_get_attr(struct iommu_domain *domain, enum iommu_attr attr, void *data) -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH V3 4/8] memcg: add per cgroup dirty pages accounting
(2013/01/07 5:02), Hugh Dickins wrote: On Sat, 5 Jan 2013, Sha Zhengju wrote: On Wed, Jan 2, 2013 at 6:44 PM, Michal Hocko wrote: Maybe I have missed some other locking which would prevent this from happening but the locking relations are really complicated in this area so if mem_cgroup_{begin,end}_update_page_stat might be called recursively then we need a fat comment which justifies that. Ohhh...good catching! I didn't notice there is a recursive call of mem_cgroup_{begin,end}_update_page_stat in page_remove_rmap(). The mem_cgroup_{begin,end}_update_page_stat() design has depressed me a lot recently as the lock granularity is a little bigger than I thought. Not only the resource but also some code logic is in the range of locking which may be deadlock prone. The problem still exists if we are trying to add stat account of other memcg page later, may I make bold to suggest that we dig into the lock again... Forgive me, I must confess I'm no more than skimming this thread, and don't like dumping unsigned-off patches on people; but thought that on balance it might be more helpful than not if I offer you a patch I worked on around 3.6-rc2 (but have updated to 3.8-rc2 below). I too was getting depressed by the constraints imposed by mem_cgroup_{begin,end}_update_page_stat (good job though Kamezawa-san did to minimize them), and wanted to replace by something freer, more RCU-like. In the end it seemed more effort than it was worth to go as far as I wanted, but I do think that this is some improvement over what we currently have, and should deal with your recursion issue. In what case does this improve performance ? But if this does appear useful to memcg people, then we really ought to get it checked over by locking/barrier experts before going further. I think myself that I've over-barriered it, and could use a little lighter; but they (Paul McKenney, Peter Zijlstra, Oleg Nesterov come to mind) will see more clearly, and may just hate the whole thing, as yet another peculiar lockdep-avoiding hand-crafted locking scheme. I've not wanted to waste their time on reviewing it, if it's not even going to be useful to memcg people. It may be easier to understand if you just apply the patch and look at the result in mm/memcontrol.c, where I tried to gather the pieces together in one place and describe them ("These functions mediate..."). Hugh Hi, this patch seems interesting but...doesn't this make move_account() very slow if the number of cpus increases because of scanning all cpus per a page ? And this looks like reader-can-block-writer percpu rwlock..it's too heavy to writers if there are many readers. Thanks, -Kame -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH V2 2/2] virtio-net: reset virtqueue affinity when doing cpu hotplug
On 01/07/2013 03:28 PM, Jason Wang wrote: > On 01/07/2013 03:15 PM, Wanlong Gao wrote: >> Add a cpu notifier to virtio-net, so that we can reset the >> virtqueue affinity if the cpu hotplug happens. It improve >> the performance through enabling or disabling the virtqueue >> affinity after doing cpu hotplug. >> Adding the notifier block to virtnet_info is suggested by >> Jason, thank you. >> >> Cc: Rusty Russell >> Cc: "Michael S. Tsirkin" >> Cc: Jason Wang >> Cc: Eric Dumazet >> Cc: virtualizat...@lists.linux-foundation.org >> Cc: net...@vger.kernel.org >> Signed-off-by: Wanlong Gao >> --- >> drivers/net/virtio_net.c | 30 ++ >> 1 file changed, 30 insertions(+) >> >> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c >> index b483fb5..9547b4c 100644 >> --- a/drivers/net/virtio_net.c >> +++ b/drivers/net/virtio_net.c >> @@ -26,6 +26,7 @@ >> #include >> #include >> #include >> +#include >> >> static int napi_weight = 128; >> module_param(napi_weight, int, 0444); >> @@ -123,6 +124,9 @@ struct virtnet_info { >> >> /* Does the affinity hint is set for virtqueues? */ >> bool affinity_hint_set; >> + >> +/* CPU hot plug notifier */ >> +struct notifier_block nb; >> }; >> >> struct skb_vnet_hdr { >> @@ -1051,6 +1055,23 @@ static void virtnet_set_affinity(struct virtnet_info >> *vi, bool set) >> } >> } >> >> +static int virtnet_cpu_callback(struct notifier_block *nfb, >> +unsigned long action, void *hcpu) >> +{ >> +struct virtnet_info *vi = container_of(nfb, struct virtnet_info, nb); >> +switch(action) { >> +case CPU_ONLINE: >> +case CPU_ONLINE_FROZEN: >> +case CPU_DEAD: >> +case CPU_DEAD_FROZEN: >> +virtnet_set_affinity(vi, true); >> +break; >> +default: >> +break; >> +} >> +return NOTIFY_OK; >> +} >> + > > I think you'd better fix the .ndo_select_queue() as well (as Michael > said in your V1) since it currently uses smp processor id which may not > work very well in this case also. The bug is we can't get the right txq if the CPU IDs are not consecutive, right? Do you have any good idea about fixing this? Thanks, Wanlong Gao > > Thanks >> static void virtnet_get_ringparam(struct net_device *dev, >> struct ethtool_ringparam *ring) >> { >> @@ -1509,6 +1530,13 @@ static int virtnet_probe(struct virtio_device *vdev) >> } >> } >> >> +vi->nb.notifier_call = _cpu_callback; >> +err = register_hotcpu_notifier(>nb); >> +if (err) { >> +pr_debug("virtio_net: registering cpu notifier failed\n"); >> +goto free_recv_bufs; >> +} >> + >> /* Assume link up if device can't report link status, >> otherwise get link status from config. */ >> if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) { >> @@ -1553,6 +1581,8 @@ static void virtnet_remove(struct virtio_device *vdev) >> { >> struct virtnet_info *vi = vdev->priv; >> >> +unregister_hotcpu_notifier(>nb); >> + >> /* Prevent config work handler from accessing the device. */ >> mutex_lock(>config_lock); >> vi->config_enable = false; > > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] SPI: SSP SPI Controller driver v3
On Mon, 2013-01-07 at 00:36 +0100, Linus Walleij wrote: > On Wed, Dec 19, 2012 at 10:56 AM, Mika Westerberg > wrote: > > On Tue, Dec 18, 2012 at 04:11:36PM +0800, chao bi wrote: > >> > >> This patch is to implement SSP SPI controller driver, which has been > >> applied and > >> validated on intel Moorestown & Medfield platform. The patch are > >> originated by > >> Ken Mills and Sylvain Centelles > >> , > >> migrating to lateset Linux mainline SPI framework by Channing > >> > >> and Chen Jun according to their integration & > >> validation > >> on Medfield platform. > > > > This is the same IP block as used in PXA, right? With few modifications > > here and there. Is there a reason not to use spi-pxa2xx.c? > > This needs to be investigated. Two drivers for the same or closely related > hardware block is never a good sign... > > Yours, > Linus Walleij Dear Linus ,Mika and Grant, Thanks for your remind. Frankly I'm currently not sure whether they share same IP.. per your reminds, I tried to find but get limited info about PXA SSP's IP, from the code, looks like they have part of registers the same. As far as I know, spi-pxa2xx.c is specific for SSP controller of PXA2XX/PXA3XX core, right? While Medfield platform is embedded with ATOM core, the SSP driver we upload is validated on SSP controller of ATOM. In my view, they're specific for different AP & Platforms, if compare the 2 files, there are still many difference in how they works, if to choose a driver for Intel Medfild/Moorestown platform, I believe spi-intel-mid-ssp.c driver could be a more mature solution. What do you think? please correct me if I'm mistaken. -chao -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: HSI subsystem status
On Mon, Jan 7, 2013 at 12:11 AM, Linus Walleij wrote: > Hi Carlos, > > what is the status on the HSI subsystem? We have based some patches for > HSI master on top of the OMAP HSI master patches, but these never seem > to reach the tree? Ping on the cch.devel address instead... Yours, Linus Walleij -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: sched: Consequences of integrating the Per Entity Load Tracking Metric into the Load Balancer
On Mon, 2013-01-07 at 10:59 +0530, Preeti U Murthy wrote: > Hi Mike, > Thank you very much for your inputs.Just a few thoughts so that we are > clear with the problems so far in the scheduler scalability and in what > direction we ought to move to correct them. > > 1. During fork or exec,the scheduler goes through find_idlest_group() > and find_idlest_cpu() in select_task_rq_fair() by iterating through all > domains.Why then was a similar approach not followed for wake up > balancing? What was so different about wake ups (except that the woken > up task had to remain close to the prev/waking cpu) that we had to > introduce select_idle_sibling() in the first place? Cost. select_idle_sibling() was introduced specifically to recoup overlap via placing wakee in a shared L2 where there is no pain really, it's all gain. L3 ain't the same deal, but it still does a good job, even for fast movers (on Intel) if you're not bouncing them all over the place. Breakeven depends on architecture, but critical for fast movers on all is no bounce allowed. Wakeup is a whole different thing than fork/exec balancing, there, you just want to spread to seed your future, and it doesn't matter much where you send wakees. With wakeup of fast movers, you lose on every migration, so buddies really really need to find each other fast, and stay put, so you really do recoup overlap instead of just paying again and again. My old Q6600 kicks the snot out of that 10 core Westmere CPU in a common desktop box cross core scheduling scenario. That's sick. > 2.To the best of my knowlege,the concept of buddy cpu was introduced in > select_idle_sibling() so as to avoid the entire package traversal and > restrict it to the buddy cpus alone.But even during fork or exec,we > iterate through all the sched domains,like I have mentioned above.Why > did not the buddy cpu solution come to the rescue here as well? I'm looking (well, pondering) fork/exec. It may be a common case win too, but I kinda doubt it'll matter. It's the 1:1 waker/wakee relation that suffers mightily. The buddy was introduced specifically to bind 1:1 sw buddies (common) in hw as well. They are one, make it so. It was the simplest solution I could think of to both kill the evil, and cut cost to restore select_idle_sibling() to the optimization it was intended to be vs the pessimization it has turned into on large L3 CPUs. I took it back to it's functional roots. Weld two modern cores together, create core2duo on steroids, optimization works again and is cheap again. That the current behavior has its upsides too is.. most unfortunate :) > 3.So the correct problem stands at avoid iterating through the entire > package at the cost of less aggression in finding the idle cpu or > iterate through the package with an intention of finding the idlest > cpu.To the best of my understanding the former is your approach or > commit 37407ea7,the latter is what I tried to do.But as you have rightly > pointed out my approach will have scaling issues.In this light,how does > your best_combined patch(below) look like? It doesn't exist anymore, morphed into ever less wonderful as the day went on. Integration needs to fiddle with find_* to cut some wasted cycles, and methinks reordered groups _may_ make it usable with no idle-buddy hint. Using the idle-buddy first looked promising, but bottom line is that at higher load, you use it for a modest fee, buddy was busy, so you then do the full scan paying a bigger fee on top of it, which of course crops the high end. Reorder should kill the low load horror, but you've still got the problem that as you approach saturation, the less value any search has. That, and the logic is not necessarily as light as it must be when targeting wakeups, where every scheduler cycle detracts substantially from fast/light task performance. > Do you introduce a cut off value on the loads to decide on which > approach to take? I fiddled with that, but then whacked it, because the result needs to be nice to 1:1 and 1:N which may need to spread at high frequency, so the cutoff would be harmful. Seems likely either a cutoff or 1:1 vs 1:N detection or _something_ will be needed to cut cost when it's flat not affordable. With 1:N pgbench (and ilk), there's no such thing as too expensive a search, but for fast/light network stuff there is. -Mike -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH V2 2/2] virtio-net: reset virtqueue affinity when doing cpu hotplug
On 01/07/2013 03:15 PM, Wanlong Gao wrote: > Add a cpu notifier to virtio-net, so that we can reset the > virtqueue affinity if the cpu hotplug happens. It improve > the performance through enabling or disabling the virtqueue > affinity after doing cpu hotplug. > Adding the notifier block to virtnet_info is suggested by > Jason, thank you. > > Cc: Rusty Russell > Cc: "Michael S. Tsirkin" > Cc: Jason Wang > Cc: Eric Dumazet > Cc: virtualizat...@lists.linux-foundation.org > Cc: net...@vger.kernel.org > Signed-off-by: Wanlong Gao > --- > drivers/net/virtio_net.c | 30 ++ > 1 file changed, 30 insertions(+) > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c > index b483fb5..9547b4c 100644 > --- a/drivers/net/virtio_net.c > +++ b/drivers/net/virtio_net.c > @@ -26,6 +26,7 @@ > #include > #include > #include > +#include > > static int napi_weight = 128; > module_param(napi_weight, int, 0444); > @@ -123,6 +124,9 @@ struct virtnet_info { > > /* Does the affinity hint is set for virtqueues? */ > bool affinity_hint_set; > + > + /* CPU hot plug notifier */ > + struct notifier_block nb; > }; > > struct skb_vnet_hdr { > @@ -1051,6 +1055,23 @@ static void virtnet_set_affinity(struct virtnet_info > *vi, bool set) > } > } > > +static int virtnet_cpu_callback(struct notifier_block *nfb, > + unsigned long action, void *hcpu) > +{ > + struct virtnet_info *vi = container_of(nfb, struct virtnet_info, nb); > + switch(action) { > + case CPU_ONLINE: > + case CPU_ONLINE_FROZEN: > + case CPU_DEAD: > + case CPU_DEAD_FROZEN: > + virtnet_set_affinity(vi, true); > + break; > + default: > + break; > + } > + return NOTIFY_OK; > +} > + I think you'd better fix the .ndo_select_queue() as well (as Michael said in your V1) since it currently uses smp processor id which may not work very well in this case also. Thanks > static void virtnet_get_ringparam(struct net_device *dev, > struct ethtool_ringparam *ring) > { > @@ -1509,6 +1530,13 @@ static int virtnet_probe(struct virtio_device *vdev) > } > } > > + vi->nb.notifier_call = _cpu_callback; > + err = register_hotcpu_notifier(>nb); > + if (err) { > + pr_debug("virtio_net: registering cpu notifier failed\n"); > + goto free_recv_bufs; > + } > + > /* Assume link up if device can't report link status, > otherwise get link status from config. */ > if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) { > @@ -1553,6 +1581,8 @@ static void virtnet_remove(struct virtio_device *vdev) > { > struct virtnet_info *vi = vdev->priv; > > + unregister_hotcpu_notifier(>nb); > + > /* Prevent config work handler from accessing the device. */ > mutex_lock(>config_lock); > vi->config_enable = false; -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH V3 4/8] memcg: add per cgroup dirty pages accounting
(2013/01/05 13:48), Sha Zhengju wrote: On Wed, Jan 2, 2013 at 6:44 PM, Michal Hocko wrote: On Wed 26-12-12 01:26:07, Sha Zhengju wrote: From: Sha Zhengju This patch adds memcg routines to count dirty pages, which allows memory controller to maintain an accurate view of the amount of its dirty memory and can provide some info for users while cgroup's direct reclaim is working. I guess you meant targeted resp. (hard/soft) limit reclaim here, right? It is true that this is direct reclaim but it is not clear to me Yes, I meant memcg hard/soft reclaim here which is triggered directly by allocation and is distinct from background kswapd reclaim (global). why the usefulnes should be limitted to the reclaim for users. I would understand this if the users was in fact in-kernel users. One of the reasons I'm trying to accounting the dirty pages is to get a more board overall view of memory usages because memcg hard/soft reclaim may have effect on response time of user application. Yeah, the beneficiary can be application administrator or kernel users. :P [...] To prevent AB/BA deadlock mentioned by Greg Thelen in previous version (https://lkml.org/lkml/2012/7/30/227), we adjust the lock order: ->private_lock --> mapping->tree_lock --> memcg->move_lock. So we need to make mapping->tree_lock ahead of TestSetPageDirty in __set_page_dirty() and __set_page_dirty_nobuffers(). But in order to avoiding useless spinlock contention, a prepare PageDirty() checking is added. But there is another AA deadlock here I believe. page_remove_rmap mem_cgroup_begin_update_page_stat <<< 1 set_page_dirty __set_page_dirty_buffers __set_page_dirty mem_cgroup_begin_update_page_stat <<< 2 move_lock_mem_cgroup spin_lock_irqsave(>move_lock, *flags); mem_cgroup_begin_update_page_stat is not recursive wrt. locking AFAICS because we might race with the moving charges: CPU0CPU1 page_remove_rmap mem_cgroup_can_attach mem_cgroup_begin_update_page_stat (1) rcu_read_lock mem_cgroup_start_move atomic_inc(_moving) atomic_inc(>moving_account) synchronize_rcu __mem_cgroup_begin_update_page_stat mem_cgroup_stolen <<< TRUE move_lock_mem_cgroup [...] mem_cgroup_begin_update_page_stat (2) __mem_cgroup_begin_update_page_stat mem_cgroup_stolen <<< still TRUE move_lock_mem_cgroup <<< DEADLOCK [...] mem_cgroup_end_update_page_stat rcu_unlock # wake up from synchronize_rcu [...] mem_cgroup_move_task mem_cgroup_move_charge walk_page_range mem_cgroup_move_account move_lock_mem_cgroup Maybe I have missed some other locking which would prevent this from happening but the locking relations are really complicated in this area so if mem_cgroup_{begin,end}_update_page_stat might be called recursively then we need a fat comment which justifies that. Ohhh...good catching! I didn't notice there is a recursive call of mem_cgroup_{begin,end}_update_page_stat in page_remove_rmap(). The mem_cgroup_{begin,end}_update_page_stat() design has depressed me a lot recently as the lock granularity is a little bigger than I thought. Not only the resource but also some code logic is in the range of locking which may be deadlock prone. The problem still exists if we are trying to add stat account of other memcg page later, may I make bold to suggest that we dig into the lock again... But with regard to the current lock implementation, I doubt if we can we can account MEM_CGROUP_STAT_FILE_{MAPPED, DIRTY} in one breath and just try to get move_lock once in the beginning. IMHO we can make mem_cgroup_{begin,end}_update_page_stat() to recursive aware and what I'm thinking now is changing memcg->move_lock to rw-spinlock from the original spinlock: mem_cgroup_{begin,end}_update_page_stat() try to get the read lock which make it reenterable and memcg moving task side try to get the write spinlock. Then the race may be following: CPU0CPU1 page_remove_rmap mem_cgroup_can_attach mem_cgroup_begin_update_page_stat (1) rcu_read_lock mem_cgroup_start_move
[PATCH 2/9] Thermal: Create zone level APIs
This patch adds a new thermal_zone structure to thermal.h. Also, adds zone level APIs to the thermal framework. A thermal zone is a hot spot on the platform, which can have one or more sensors and cooling devices attached to it. These sensors can be mapped to a set of cooling devices, which when throttled, can help to bring down the temperature of the hot spot. Signed-off-by: Durgadoss R --- drivers/thermal/thermal_sys.c | 196 + include/linux/thermal.h | 22 + 2 files changed, 218 insertions(+) diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c index b2becb9..513b0fc 100644 --- a/drivers/thermal/thermal_sys.c +++ b/drivers/thermal/thermal_sys.c @@ -44,19 +44,46 @@ MODULE_DESCRIPTION("Generic thermal management sysfs support"); MODULE_LICENSE("GPL"); static DEFINE_IDR(thermal_tz_idr); +static DEFINE_IDR(thermal_zone_idr); static DEFINE_IDR(thermal_cdev_idr); static DEFINE_IDR(thermal_sensor_idr); static DEFINE_MUTEX(thermal_idr_lock); static LIST_HEAD(thermal_tz_list); static LIST_HEAD(thermal_sensor_list); +static LIST_HEAD(thermal_zone_list); static LIST_HEAD(thermal_cdev_list); static LIST_HEAD(thermal_governor_list); static DEFINE_MUTEX(thermal_list_lock); static DEFINE_MUTEX(sensor_list_lock); +static DEFINE_MUTEX(zone_list_lock); static DEFINE_MUTEX(thermal_governor_lock); +#define for_each_thermal_sensor(pos) \ + list_for_each_entry(pos, _sensor_list, node) + +#define for_each_thermal_zone(pos) \ + list_for_each_entry(pos, _zone_list, node) + +#define GET_INDEX(tz, ptr, type) \ +({ \ + int i, ret = -EINVAL; \ + do {\ + if (!tz || !ptr)\ + break; \ + mutex_lock(##_list_lock); \ + for (i = 0; i < tz->type##_indx; i++) { \ + if (tz->type##s[i] == ptr) {\ + ret = i;\ + break; \ + } \ + } \ + mutex_unlock(##_list_lock);\ + } while (0);\ + ret;\ +}) + static struct thermal_governor *__find_governor(const char *name) { struct thermal_governor *pos; @@ -419,15 +446,44 @@ static void thermal_zone_device_check(struct work_struct *work) thermal_zone_device_update(tz); } +static void remove_sensor_from_zone(struct thermal_zone *tz, + struct thermal_sensor *ts) +{ + int j, indx; + + indx = GET_INDEX(tz, ts, sensor); + if (indx < 0) + return; + + sysfs_remove_link(>device.kobj, kobject_name(>device.kobj)); + + /* Shift the entries in the tz->sensors array */ + for (j = indx; j < MAX_SENSORS_PER_ZONE - 1; j++) + tz->sensors[j] = tz->sensors[j + 1]; + + tz->sensor_indx--; +} + /* sys I/F for thermal zone */ #define to_thermal_zone(_dev) \ container_of(_dev, struct thermal_zone_device, device) +#define to_zone(_dev) \ + container_of(_dev, struct thermal_zone, device) + #define to_thermal_sensor(_dev) \ container_of(_dev, struct thermal_sensor, device) static ssize_t +zone_name_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct thermal_zone *tz = to_zone(dev); + + return sprintf(buf, "%s\n", tz->name); +} + +static ssize_t sensor_name_show(struct device *dev, struct device_attribute *attr, char *buf) { struct thermal_sensor *ts = to_thermal_sensor(dev); @@ -809,6 +865,8 @@ static DEVICE_ATTR(policy, S_IRUGO | S_IWUSR, policy_show, policy_store); static DEVICE_ATTR(sensor_name, 0444, sensor_name_show, NULL); static DEVICE_ATTR(temp_input, 0444, sensor_temp_show, NULL); +static DEVICE_ATTR(zone_name, 0444, zone_name_show, NULL); + /* sys I/F for cooling device */ #define to_cooling_device(_dev)\ container_of(_dev, struct thermal_cooling_device, device) @@ -1654,6 +1712,136 @@ static int enable_sensor_thresholds(struct thermal_sensor *ts, int count) return 0; } +struct thermal_zone *create_thermal_zone(const char *name, void *devdata) +{ + struct thermal_zone *tz; + int ret; + + if (!name || (name && strlen(name) >= THERMAL_NAME_LENGTH)) + return ERR_PTR(-EINVAL); + + tz = kzalloc(sizeof(*tz), GFP_KERNEL); + if (!tz) + return ERR_PTR(-ENOMEM); + + idr_init(>idr); + ret = get_idr(_zone_idr, _idr_lock, >id); + if (ret) + goto exit_free; + + strcpy(tz->name, name); +
[PATCH 4/9] Thermal: Add trip point sysfs nodes for sensor
This patch adds a trip point related sysfs nodes for each sensor under a zone in /sys/class/thermal/zoneX/. The nodes will be named, sensorX_trip_active, sensorX_trip_passive, sensorX_trip_hot, sensorX_trip_critical for active, passive, hot and critical trip points respectively for sensorX. Signed-off-by: Durgadoss R --- drivers/thermal/thermal_sys.c | 211 - include/linux/thermal.h | 38 +++- 2 files changed, 246 insertions(+), 3 deletions(-) diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c index 332bd61..1958bb8 100644 --- a/drivers/thermal/thermal_sys.c +++ b/drivers/thermal/thermal_sys.c @@ -450,6 +450,22 @@ static void thermal_zone_device_check(struct work_struct *work) thermal_zone_device_update(tz); } +static int get_sensor_indx_by_kobj(struct thermal_zone *tz, const char *name) +{ + int i, indx = -EINVAL; + + mutex_lock(_list_lock); + for (i = 0; i < tz->sensor_indx; i++) { + if (!strnicmp(name, kobject_name(>sensors[i]->device.kobj), + THERMAL_NAME_LENGTH)) { + indx = i; + break; + } + } + mutex_unlock(_list_lock); + return indx; +} + static void remove_sensor_from_zone(struct thermal_zone *tz, struct thermal_sensor *ts) { @@ -461,9 +477,16 @@ static void remove_sensor_from_zone(struct thermal_zone *tz, sysfs_remove_link(>device.kobj, kobject_name(>device.kobj)); + /* Remove trip point attributes associated with this sensor */ + kfree(tz->trip_attr[indx]); + tz->trip_attr[indx] = NULL; + /* Shift the entries in the tz->sensors array */ - for (j = indx; j < MAX_SENSORS_PER_ZONE - 1; j++) + for (j = indx; j < MAX_SENSORS_PER_ZONE - 1; j++) { tz->sensors[j] = tz->sensors[j + 1]; + tz->sensor_trip[j] = tz->sensor_trip[j + 1]; + tz->trip_attr[j] = tz->trip_attr[j + 1]; + } tz->sensor_indx--; } @@ -877,6 +900,99 @@ policy_show(struct device *dev, struct device_attribute *devattr, char *buf) return sprintf(buf, "%s\n", tz->governor->name); } +static ssize_t +active_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int i, indx, ret = 0; + char kobj_name[THERMAL_NAME_LENGTH]; + struct thermal_zone *tz = to_zone(dev); + + if (!sscanf(attr->attr.name, "sensor%d_trip_active", )) + return -EINVAL; + + snprintf(kobj_name, THERMAL_NAME_LENGTH, "sensor%d", i); + indx = get_sensor_indx_by_kobj(tz, kobj_name); + if (indx < 0) + return indx; + + if (tz->sensor_trip[indx]->num_active_trips <= 0) + return sprintf(buf, "\n"); + + ret += sprintf(buf, "0x%x", tz->sensor_trip[indx]->active_trip_mask); + for (i = 0; i < tz->sensor_trip[indx]->num_active_trips; i++) { + ret += sprintf(buf + ret, " %d", + tz->sensor_trip[indx]->active_trips[i]); + } + + ret += sprintf(buf + ret, "\n"); + return ret; +} + +static ssize_t +ptrip_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int i, indx, ret = 0; + char kobj_name[THERMAL_NAME_LENGTH]; + struct thermal_zone *tz = to_zone(dev); + + if (!sscanf(attr->attr.name, "sensor%d_trip_passive", )) + return -EINVAL; + + snprintf(kobj_name, THERMAL_NAME_LENGTH, "sensor%d", i); + indx = get_sensor_indx_by_kobj(tz, kobj_name); + if (indx < 0) + return indx; + + if (tz->sensor_trip[indx]->num_passive_trips <= 0) + return sprintf(buf, "\n"); + + for (i = 0; i < tz->sensor_trip[indx]->num_passive_trips; i++) { + ret += sprintf(buf + ret, "%d ", + tz->sensor_trip[indx]->passive_trips[i]); + } + + ret += sprintf(buf + ret, "\n"); + return ret; +} + +static ssize_t +hot_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int indx; + char kobj_name[THERMAL_NAME_LENGTH]; + struct thermal_zone *tz = to_zone(dev); + + if (!sscanf(attr->attr.name, "sensor%d_trip_hot", )) + return -EINVAL; + + snprintf(kobj_name, THERMAL_NAME_LENGTH, "sensor%d", indx); + + indx = get_sensor_indx_by_kobj(tz, kobj_name); + if (indx < 0) + return indx; + + return sprintf(buf, "%d\n", tz->sensor_trip[indx]->hot); +} + +static ssize_t +critical_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int indx; + char kobj_name[THERMAL_NAME_LENGTH]; + struct thermal_zone *tz = to_zone(dev); + + if (!sscanf(attr->attr.name, "sensor%d_trip_hot", )) + return -EINVAL; + + snprintf(kobj_name, THERMAL_NAME_LENGTH, "sensor%d", indx); + +
[PATCHv2 0/9] Thermal Framework Enhancements
This patch set is a v2 of the previous versions submitted here: [v1]: https://lkml.org/lkml/2012/12/18/108 [RFC]: https://patchwork.kernel.org/patch/1758921/ This patch set is based on Rui's -thermal tree, and is tested on a Core-i5 and an Atom netbook. Changes Since v1: * Removed kobject creation for thermal_trip and thermal_map nodes as per Greg-KH's comments. * Added ABI Documentation under 'testing'. * Modified the GET_INDEX macro to be more linux-like, thanks to Joe Perches. * Added get_[sensor/cdev]_by_name APIs to thermal.h This series contains 9 patches: Patch 1/9: Creates new sensor level APIs Patch 2/9: Creates new zone level APIs. The existing tzd structure is kept as such for clarity and compatibility purposes. Patch 3/9: Creates functions to add/remove a cdev to/from a zone. The existing tcd structure need not be modified. Patch 4/9: Adds sensorX_trip_[active/passive/hot/critical] sysfs nodes, under /sys/class/thermal/zoneY/. This exposes various trip points for sensorX present in zoneY. Patch 5/9: Adds mapX sysfs node. It is a compact representation of the binding relationship between a sensor and a cdev, within a zone. Patch 6/9: Creates Documentation for the new APIs. A new file is created for clarity. Final goal is to merge with the existing file or refactor the files, as whatever seems appropriate. Patch 7/9: Make PER ZONE values configurable through Kconfig Patch 8/9: Add ABI documentation for sysfs interfaces introduced in this patch. Patch 9/9: A dummy driver that can be used for testing. This is not for merge. Thanks to Greg-KH, Hongbo Zhang and Joe Perches for their comments on v1. Durgadoss R (9): Thermal: Create sensor level APIs Thermal: Create zone level APIs Thermal: Add APIs to bind cdev to new zone structure Thermal: Add trip point sysfs nodes for sensor Thermal: Create 'mapX' sysfs node for a zone Thermal: Add Documentation to new APIs Thermal: Make PER_ZONE values configurable Thermal: Add ABI Documentation for sysfs interfaces Thermal: Dummy driver used for testing Documentation/ABI/testing/sysfs-class-thermal | 93 +++ Documentation/thermal/sysfs-api2.txt | 248 +++ drivers/thermal/Kconfig | 19 + drivers/thermal/Makefile |3 + drivers/thermal/thermal_sys.c | 881 + drivers/thermal/thermal_test.c| 315 + include/linux/thermal.h | 117 +++- 7 files changed, 1675 insertions(+), 1 deletion(-) create mode 100644 Documentation/ABI/testing/sysfs-class-thermal create mode 100644 Documentation/thermal/sysfs-api2.txt create mode 100644 drivers/thermal/thermal_test.c -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 7/9] Thermal: Make PER_ZONE values configurable
This patch makes MAX_SENSORS_PER_ZONE and MAX_CDEVS_PER_ZONE values configurable. The default value is 1, and range is 1-12. Signed-off-by: Durgadoss R --- drivers/thermal/Kconfig | 14 ++ include/linux/thermal.h |6 +++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index d96da07..c5ba3340 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -15,6 +15,20 @@ menuconfig THERMAL if THERMAL +config THERMAL_MAX_SENSORS_PER_ZONE + int "Maximum number of sensors allowed per thermal zone" + default 1 + range 1 12 + ---help--- + Specify the number of sensors allowed per zone + +config THERMAL_MAX_CDEVS_PER_ZONE + int "Maximum number of cooling devices allowed per thermal zone" + default 1 + range 1 12 + ---help--- + Specify the number of cooling devices allowed per zone + config THERMAL_HWMON bool depends on HWMON=y || HWMON=THERMAL diff --git a/include/linux/thermal.h b/include/linux/thermal.h index 187fadb..cf19fba 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -50,9 +50,9 @@ /* Default Thermal Governor: Does Linear Throttling */ #define DEFAULT_THERMAL_GOVERNOR "step_wise" -#define MAX_SENSORS_PER_ZONE 5 - -#define MAX_CDEVS_PER_ZONE 5 +/* Maximum number of sensors/cdevs per zone, defined through Kconfig */ +#define MAX_SENSORS_PER_ZONE CONFIG_THERMAL_MAX_SENSORS_PER_ZONE +#define MAX_CDEVS_PER_ZONE CONFIG_THERMAL_MAX_CDEVS_PER_ZONE /* If we map each sensor with every possible cdev for a zone */ #define MAX_MAPS_PER_ZONE (MAX_SENSORS_PER_ZONE * MAX_CDEVS_PER_ZONE) -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 9/9] Thermal: Dummy driver used for testing
This patch has a dummy driver that can be used for testing purposes. This patch is not for merge. Signed-off-by: Durgadoss R --- drivers/thermal/Kconfig|5 + drivers/thermal/Makefile |3 + drivers/thermal/thermal_test.c | 329 3 files changed, 337 insertions(+) create mode 100644 drivers/thermal/thermal_test.c diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index c5ba3340..3b92a76 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -136,4 +136,9 @@ config DB8500_CPUFREQ_COOLING bound cpufreq cooling device turns active to set CPU frequency low to cool down the CPU. +config THERMAL_TEST + tristate "test driver" + help + Enable this to test the thermal framework. + endif diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile index d8da683..02c3edb 100644 --- a/drivers/thermal/Makefile +++ b/drivers/thermal/Makefile @@ -18,3 +18,6 @@ obj-$(CONFIG_RCAR_THERMAL)+= rcar_thermal.o obj-$(CONFIG_EXYNOS_THERMAL) += exynos_thermal.o obj-$(CONFIG_DB8500_THERMAL) += db8500_thermal.o obj-$(CONFIG_DB8500_CPUFREQ_COOLING) += db8500_cpufreq_cooling.o + +# dummy driver for testing +obj-$(CONFIG_THERMAL_TEST) += thermal_test.o diff --git a/drivers/thermal/thermal_test.c b/drivers/thermal/thermal_test.c new file mode 100644 index 000..137b562 --- /dev/null +++ b/drivers/thermal/thermal_test.c @@ -0,0 +1,329 @@ +/* + * thermal_test.c - This driver can be used to test Thermal + *Framework changes. Not specific to any + *platform. Fills the log buffer generously ;) + * + * Copyright (C) 2012 Intel Corporation + * + * ~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * ~~ + * Author: Durgadoss R + */ + +#define pr_fmt(fmt) "thermal_test: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_THERMAL_ZONES 2 +#define MAX_THERMAL_SENSORS2 +#define MAX_COOLING_DEVS 4 +#define NUM_THRESHOLDS 3 + +static struct ts_data { + int curr_temp; + int flag; +} ts_data; + +int active_trips[10] = {100, 90, 80, 70, 60, 50, 40, 30, 20, 10}; +int passive_trips[5] = {100, 90, 60, 50, 40}; +int wts[5] = {50, 50, 50, 50, 40}; + +static struct platform_device *pdev; +static unsigned long cur_cdev_state = 2; +static struct thermal_sensor *ts, *ts1; +static struct thermal_zone *tz; +static struct thermal_cooling_device *cdev; + +static long thermal_thresholds[NUM_THRESHOLDS] = {3, 4, 5}; + +static struct thermal_trip_point trip = { + .hot = 90, + .crit = 100, + .num_passive_trips = 5, + .passive_trips = passive_trips, + .num_active_trips = 10, + .active_trips = active_trips, + .active_trip_mask = 0xCFF, +}; + +static struct thermal_trip_point trip1 = { + .hot = 95, + .crit = 125, + .num_passive_trips = 0, + .passive_trips = passive_trips, + .num_active_trips = 6, + .active_trips = active_trips, + .active_trip_mask = 0xFF, +}; + +static struct thermal_map map = { + .trip_type = THERMAL_TRIP_PASSIVE, + .sensor_name = "ts", + .cdev_name = "cdev", + .num_weights = 5, + .trip_mask = 0x0F, + .weights = wts, +}; + +static int read_cur_state(struct thermal_cooling_device *cdev, + unsigned long *state) +{ + *state = cur_cdev_state; + return 0; +} + +static int write_cur_state(struct thermal_cooling_device *cdev, + unsigned long state) +{ + cur_cdev_state = state; + return 0; +} + +static int read_max_state(struct thermal_cooling_device *cdev, + unsigned long *state) +{ + *state = 5; + return 0; +} + +static int read_curr_temp(struct thermal_sensor *ts, long *temp) +{ + *temp = ts_data.curr_temp; + return 0; +} + +static ssize_t +flag_show(struct device *dev, struct device_attribute *devattr, char *buf) +{ + return sprintf(buf, "%d\n", ts_data.flag); +} + +static ssize_t +flag_store(struct device *dev, struct
[PATCH 8/9] Thermal: Add ABI Documentation for sysfs interfaces
This patch adds Documentation for ABI's introduced for thermal subsystem (under /sys/class/thermal/). Signed-off-by: Durgadoss R --- Documentation/ABI/testing/sysfs-class-thermal | 93 + 1 file changed, 93 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-class-thermal diff --git a/Documentation/ABI/testing/sysfs-class-thermal b/Documentation/ABI/testing/sysfs-class-thermal new file mode 100644 index 000..d1a450e --- /dev/null +++ b/Documentation/ABI/testing/sysfs-class-thermal @@ -0,0 +1,93 @@ +What: /sys/class/thermal/sensorX/temp +Date: January 2013 +KernelVersion: 3.8 +Contact: Linux PM Mailing list +Description: + Exposes 'temperature' of a thermal sensor in mC +Users: Kernel/User space thermal governors + +What: /sys/class/thermal/sensorX/name +Date: January 2013 +KernelVersion: 3.8 +Contact: Linux PM Mailing list +Description: + Name of the thermal sensor +Users: Kernel/User space thermal governors + +What: /sys/class/thermal/sensorX/thresholdY +Date: January 2013 +KernelVersion: 3.8 +Contact: Linux PM Mailing list +Description: + Programmable threshold (in terms of mC). On reaching + this, the thermal governors may take action to control + temperature. +Users: Kernel/User space thermal governors + +What: /sys/class/thermal/zoneX/name +Date: January 2013 +KernelVersion: 3.8 +Contact: Linux PM Mailing list +Description: + Name of the thermal zone. +Users: Kernel/User space thermal governors + +What: /sys/class/thermal/zoneX/sensorY +Date: January 2013 +KernelVersion: 3.8 +Contact: Linux PM Mailing list +Description: + Symlink to a sensor associated with this zone. +Users: User space thermal governors or applications + +What: /sys/class/thermal/zoneX/cooling_deviceY +Date: January 2013 +KernelVersion: 3.8 +Contact: Linux PM Mailing list +Description: + Symlink to a cooling device associated with this zone. +Users: User space thermal governors or applications + +What: /sys/class/thermal/zoneX/sensorY_trip_active +Date: January 2013 +KernelVersion: 3.8 +Contact: Linux PM Mailing list +Description: + Space separated list of active trip points for 'sensorY' + in 'zoneX' (in mC). +Users: Kernel/User space thermal governors + +What: /sys/class/thermal/zoneX/sensorY_trip_passive +Date: January 2013 +KernelVersion: 3.8 +Contact: Linux PM Mailing list +Description: + Space separated list of passive trip points for 'sensorY' + in 'zoneX' (in mC). +Users: Kernel/User space thermal governors + +What: /sys/class/thermal/zoneX/sensorY_trip_hot +Date: January 2013 +KernelVersion: 3.8 +Contact: Linux PM Mailing list +Description: + Hot trip point for 'sensorY' in 'zoneX' (in mC). +Users: Kernel/User space thermal governors + +What: /sys/class/thermal/zoneX/sensorY_trip_critical +Date: January 2013 +KernelVersion: 3.8 +Contact: Linux PM Mailing list +Description: + Critical trip point for 'sensorY' in 'zoneX' (in mC). +Users: Kernel/User space thermal governors + +What: /sys/class/thermal/zoneX/mapY +Date: January 2013 +KernelVersion: 3.8 +Contact: Linux PM Mailing list +Description: + Mapping information between a sensor and a cooling device + in 'zoneX'. See Documentation/thermal/sysfs-api2.txt for more + information on this interface. +Users: Kernel/User space thermal governors -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 6/9] Thermal: Add Documentation to new APIs
This patch adds Documentation for the new APIs introduced in this patch set. The documentation also has a model sysfs structure for reference. Signed-off-by: Durgadoss R --- Documentation/thermal/sysfs-api2.txt | 248 ++ 1 file changed, 248 insertions(+) create mode 100644 Documentation/thermal/sysfs-api2.txt diff --git a/Documentation/thermal/sysfs-api2.txt b/Documentation/thermal/sysfs-api2.txt new file mode 100644 index 000..ffd0402 --- /dev/null +++ b/Documentation/thermal/sysfs-api2.txt @@ -0,0 +1,248 @@ +Thermal Framework +- + +Written by Durgadoss R +Copyright (c) 2012 Intel Corporation + +Created on: 4 November 2012 +Updated on: 18 December 2012 + +0. Introduction +--- +The Linux thermal framework provides a set of interfaces for thermal +sensors and thermal cooling devices (fan, processor...) to register +with the thermal management solution and to be a part of it. + +This document focuses on how to enable new thermal sensors and cooling +devices to participate in thermal management. This solution is intended +to be 'light-weight' and platform/architecture independent. Any thermal +sensor/cooling device should be able to use the infrastructure easily. + +The goal of thermal framework is to expose the thermal sensor/zone and +cooling device attributes in a consistent way. This will help the +thermal governors to make use of the information to manage platform +thermals efficiently. + +The thermal sensor source file can be generic (can be any sensor driver, +in any subsystem). This driver will use the sensor APIs and register with +thermal framework to participate in platform Thermal management. This +does not (and should not) know about which zone it belongs to, or any +other information about platform thermals. A sensor driver is a standalone +piece of code, which can optionally register with thermal framework. + +However, for any platform, there should be a platformX_thermal.c file, +which will know about the platform thermal characteristics (like how many +sensors, zones, cooling devices, etc.. And how they are related to each other +i.e the mapping information). Only in this file, the zone level APIs should +be used, in which case the file will have all information required to attach +various sensors to a particular zone. + +This way, we can have one platform level thermal file, which can support +multiple platforms (may be)using the same set of sensors (but)binded in +a different way. This file can get the platform thermal information +through Firmware, ACPI tables, device tree etc. + +Unfortunately, today we don't have many drivers that can be clearly +differentiated as 'sensor_file.c' and 'platform_thermal_file.c'. +But very soon we will need/have. The reason I am saying this is because +we are seeing a lot of chip drivers, starting to use thermal framework, +and we should keep it really light-weight for them to do so. + +An Example: drivers/hwmon/emc1403.c - a generic thermal chip driver +In one platform this sensor can belong to 'ZoneA' and in another the +same can belong to 'ZoneB'. But, emc1403.c does not really care about +where does it belong. It just reports temperature. + +1. Terminology +-- +This section describes the terminology used in the rest of this +document as well as the thermal framework code. + +thermal_sensor: Hardware that can report temperature of a particular + spot in the platform, where it is placed. The temperature + reported by the sensor is the 'real' temperature reported + by the hardware. +thermal_zone: A virtual area on the device, that gets heated up. It may + have one or more thermal sensors attached to it. +cooling_device:Any component that can help in reducing the temperature of + a 'hot spot' either by reducing its performance (passive + cooling) or by other means(Active cooling E.g. Fan) + +trip_points: Various temperature levels for each sensor. As of now, we + have four levels namely active, passive, hot and critical. + Hot and critical trip point support only one value whereas + active and passive can have any number of values. These + temperature values can come from platform data, and are + exposed through sysfs in a consistent manner. Stand-alone + thermal sensor drivers are not expected to know these values. + These values are RO. +thresholds:These are programmable temperature limits, on reaching which + the thermal sensor generates an interrupt. The framework is + notified about this interrupt to take appropriate action. + There can be as many number of thresholds as that of the + hardware supports. These values are RW. + +thermal_map: This provides the mapping (aka binding) information between +
[PATCH 5/9] Thermal: Create 'mapX' sysfs node for a zone
This patch creates a thermal map sysfs node under /sys/class/thermal/zoneX/. This contains entries named map0, map1 .. mapN. Each map has the following space separated values: trip_type sensor_name cdev_name trip_mask weights Signed-off-by: Durgadoss R --- drivers/thermal/thermal_sys.c | 122 - include/linux/thermal.h | 19 +++ 2 files changed, 139 insertions(+), 2 deletions(-) diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c index 1958bb8..5f806d1 100644 --- a/drivers/thermal/thermal_sys.c +++ b/drivers/thermal/thermal_sys.c @@ -509,6 +509,39 @@ static void remove_cdev_from_zone(struct thermal_zone *tz, tz->cdev_indx--; } +static inline void __clean_map_entry(struct thermal_zone *tz, int i) +{ + device_remove_file(>device, >map_attr[i]->attr); + kfree(tz->map_attr[i]); + tz->map[i] = NULL; +} + +static void remove_sensor_map_entry(struct thermal_zone *tz, + struct thermal_sensor *ts) +{ + int i; + + for (i = 0; i < MAX_MAPS_PER_ZONE; i++) { + if (tz->map[i] && !strnicmp(ts->name, tz->map[i]->sensor_name, + THERMAL_NAME_LENGTH)) { + __clean_map_entry(tz, i); + } + } +} + +static void remove_cdev_map_entry(struct thermal_zone *tz, + struct thermal_cooling_device *cdev) +{ + int i; + + for (i = 0; i < MAX_MAPS_PER_ZONE; i++) { + if (tz->map[i] && !strnicmp(cdev->type, tz->map[i]->cdev_name, + THERMAL_NAME_LENGTH)) { + __clean_map_entry(tz, i); + } + } +} + /* sys I/F for thermal zone */ #define to_thermal_zone(_dev) \ @@ -901,6 +934,39 @@ policy_show(struct device *dev, struct device_attribute *devattr, char *buf) } static ssize_t +map_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + char *trip; + int i, indx, ret = 0; + struct thermal_map *map; + struct thermal_zone *tz = to_zone(dev); + + if (!sscanf(attr->attr.name, "map%d", )) + return -EINVAL; + + if (indx < 0 || indx >= MAX_MAPS_PER_ZONE) + return -EINVAL; + + if (!tz->map[indx]) + return sprintf(buf, "\n"); + + map = tz->map[indx]; + + trip = (map->trip_type == THERMAL_TRIP_ACTIVE) ? + "active" : "passive"; + ret += sprintf(buf, "%s", trip); + ret += sprintf(buf + ret, " %s", map->sensor_name); + ret += sprintf(buf + ret, " %s", map->cdev_name); + ret += sprintf(buf + ret, " 0x%x", map->trip_mask); + + for (i = 0; i < map->num_weights; i++) + ret += sprintf(buf + ret, " %d", map->weights[i]); + + ret += sprintf(buf + ret, "\n"); + return ret; +} + +static ssize_t active_show(struct device *dev, struct device_attribute *attr, char *buf) { int i, indx, ret = 0; @@ -1639,8 +1705,10 @@ void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev) mutex_lock(_list_lock); - for_each_thermal_zone(tmp_tz) + for_each_thermal_zone(tmp_tz) { remove_cdev_from_zone(tmp_tz, cdev); + remove_cdev_map_entry(tmp_tz, cdev); + } mutex_unlock(_list_lock); @@ -1978,6 +2046,9 @@ void remove_thermal_zone(struct thermal_zone *tz) kobject_name(>cdevs[i]->device.kobj)); } + for (i = 0; i < MAX_MAPS_PER_ZONE; i++) + __clean_map_entry(tz, i); + release_idr(_zone_idr, _idr_lock, tz->id); idr_destroy(>idr); @@ -2023,6 +2094,51 @@ struct thermal_sensor *get_sensor_by_name(const char *name) } EXPORT_SYMBOL(get_sensor_by_name); +int add_map_entry(struct thermal_zone *tz, struct thermal_map *map) +{ + int ret, indx; + + if (!tz || !map) + return -EINVAL; + + mutex_lock(_list_lock); + + for (indx = 0; indx < MAX_MAPS_PER_ZONE; indx++) { + if (tz->map[indx] == NULL) + break; + } + + if (indx >= MAX_MAPS_PER_ZONE) { + ret = -EINVAL; + goto exit; + } + + tz->map_attr[indx] = kzalloc(sizeof(struct thermal_attr), GFP_KERNEL); + if (!tz->map_attr[indx]) { + ret = -ENOMEM; + goto exit; + } + + sprintf(tz->map_attr[indx]->name, "map%d", indx); + + tz->map_attr[indx]->attr.attr.name = tz->map_attr[indx]->name; + tz->map_attr[indx]->attr.attr.mode = S_IRUGO; + tz->map_attr[indx]->attr.show = map_show; + + sysfs_attr_init(>map_attr[indx]->attr.attr); + ret = device_create_file(>device, >map_attr[indx]->attr); + if (ret) { + kfree(tz->map_attr[indx]); + goto exit; + } + +
[PATCH 3/9] Thermal: Add APIs to bind cdev to new zone structure
This patch creates new APIs to add/remove a cdev to/from a zone. This patch does not change the old cooling device implementation. Signed-off-by: Durgadoss R --- drivers/thermal/thermal_sys.c | 80 + include/linux/thermal.h |9 + 2 files changed, 89 insertions(+) diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c index 513b0fc..332bd61 100644 --- a/drivers/thermal/thermal_sys.c +++ b/drivers/thermal/thermal_sys.c @@ -58,6 +58,7 @@ static LIST_HEAD(thermal_governor_list); static DEFINE_MUTEX(thermal_list_lock); static DEFINE_MUTEX(sensor_list_lock); static DEFINE_MUTEX(zone_list_lock); +static DEFINE_MUTEX(cdev_list_lock); static DEFINE_MUTEX(thermal_governor_lock); #define for_each_thermal_sensor(pos) \ @@ -84,6 +85,9 @@ static DEFINE_MUTEX(thermal_governor_lock); ret;\ }) +#define for_each_cdev(pos) \ + list_for_each_entry(pos, _cdev_list, node) + static struct thermal_governor *__find_governor(const char *name) { struct thermal_governor *pos; @@ -464,6 +468,24 @@ static void remove_sensor_from_zone(struct thermal_zone *tz, tz->sensor_indx--; } +static void remove_cdev_from_zone(struct thermal_zone *tz, + struct thermal_cooling_device *cdev) +{ + int j, indx; + + indx = GET_INDEX(tz, cdev, cdev); + if (indx < 0) + return; + + sysfs_remove_link(>device.kobj, kobject_name(>device.kobj)); + + /* Shift the entries in the tz->cdevs array */ + for (j = indx; j < MAX_CDEVS_PER_ZONE - 1; j++) + tz->cdevs[j] = tz->cdevs[j + 1]; + + tz->cdev_indx--; +} + /* sys I/F for thermal zone */ #define to_thermal_zone(_dev) \ @@ -1460,6 +1482,7 @@ void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev) int i; const struct thermal_zone_params *tzp; struct thermal_zone_device *tz; + struct thermal_zone *tmp_tz; struct thermal_cooling_device *pos = NULL; if (!cdev) @@ -1497,6 +1520,13 @@ void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev) mutex_unlock(_list_lock); + mutex_lock(_list_lock); + + for_each_thermal_zone(tmp_tz) + remove_cdev_from_zone(tmp_tz, cdev); + + mutex_unlock(_list_lock); + if (cdev->type[0]) device_remove_file(>device, _attr_cdev_type); device_remove_file(>device, _attr_max_state); @@ -1792,6 +1822,23 @@ exit: } EXPORT_SYMBOL(remove_thermal_zone); +struct thermal_cooling_device *get_cdev_by_name(const char *name) +{ + struct thermal_cooling_device *pos; + struct thermal_cooling_device *cdev = NULL; + + mutex_lock(_list_lock); + for_each_cdev(pos) { + if (!strnicmp(pos->type, name, THERMAL_NAME_LENGTH)) { + cdev = pos; + break; + } + } + mutex_unlock(_list_lock); + return cdev; +} +EXPORT_SYMBOL(get_cdev_by_name); + struct thermal_sensor *get_sensor_by_name(const char *name) { struct thermal_sensor *pos; @@ -1842,6 +1889,39 @@ exit_zone: } EXPORT_SYMBOL(add_sensor_to_zone); +int add_cdev_to_zone(struct thermal_zone *tz, + struct thermal_cooling_device *cdev) +{ + int ret; + + if (!tz || !cdev) + return -EINVAL; + + mutex_lock(_list_lock); + + /* Ensure we are not adding the same cdev again!! */ + ret = GET_INDEX(tz, cdev, cdev); + if (ret >= 0) { + ret = -EEXIST; + goto exit_zone; + } + + mutex_lock(_list_lock); + ret = sysfs_create_link(>device.kobj, >device.kobj, + kobject_name(>device.kobj)); + if (ret) + goto exit_cdev; + + tz->cdevs[tz->cdev_indx++] = cdev; + +exit_cdev: + mutex_unlock(_list_lock); +exit_zone: + mutex_unlock(_list_lock); + return ret; +} +EXPORT_SYMBOL(add_cdev_to_zone); + /** * thermal_sensor_register - register a new thermal sensor * @name: name of the thermal sensor diff --git a/include/linux/thermal.h b/include/linux/thermal.h index f5b9540..12cc953 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -51,6 +51,8 @@ #define MAX_SENSORS_PER_ZONE 5 +#define MAX_CDEVS_PER_ZONE 5 + struct thermal_sensor; struct thermal_zone_device; struct thermal_cooling_device; @@ -209,6 +211,10 @@ struct thermal_zone { /* Sensor level information */ int sensor_indx; /* index into 'sensors' array */ struct thermal_sensor *sensors[MAX_SENSORS_PER_ZONE]; + + /* cdev level information */ + int cdev_indx; /* index into 'cdevs' array */ + struct thermal_cooling_device *cdevs[MAX_CDEVS_PER_ZONE]; }; /* Structure that holds thermal governor
[PATCH 1/9] Thermal: Create sensor level APIs
This patch creates sensor level APIs, in the generic thermal framework. A Thermal sensor is a piece of hardware that can report temperature of the spot in which it is placed. A thermal sensor driver reads the temperature from this sensor and reports it out. This kind of driver can be in any subsystem. If the sensor needs to participate in platform thermal management, the corresponding driver can use the APIs introduced in this patch, to register(or unregister) with the thermal framework. Signed-off-by: Durgadoss R --- drivers/thermal/thermal_sys.c | 280 + include/linux/thermal.h | 29 + 2 files changed, 309 insertions(+) diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c index 8f0f37b..b2becb9 100644 --- a/drivers/thermal/thermal_sys.c +++ b/drivers/thermal/thermal_sys.c @@ -45,13 +45,16 @@ MODULE_LICENSE("GPL"); static DEFINE_IDR(thermal_tz_idr); static DEFINE_IDR(thermal_cdev_idr); +static DEFINE_IDR(thermal_sensor_idr); static DEFINE_MUTEX(thermal_idr_lock); static LIST_HEAD(thermal_tz_list); +static LIST_HEAD(thermal_sensor_list); static LIST_HEAD(thermal_cdev_list); static LIST_HEAD(thermal_governor_list); static DEFINE_MUTEX(thermal_list_lock); +static DEFINE_MUTEX(sensor_list_lock); static DEFINE_MUTEX(thermal_governor_lock); static struct thermal_governor *__find_governor(const char *name) @@ -421,6 +424,103 @@ static void thermal_zone_device_check(struct work_struct *work) #define to_thermal_zone(_dev) \ container_of(_dev, struct thermal_zone_device, device) +#define to_thermal_sensor(_dev) \ + container_of(_dev, struct thermal_sensor, device) + +static ssize_t +sensor_name_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct thermal_sensor *ts = to_thermal_sensor(dev); + + return sprintf(buf, "%s\n", ts->name); +} + +static ssize_t +sensor_temp_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int ret; + long val; + struct thermal_sensor *ts = to_thermal_sensor(dev); + + ret = ts->ops->get_temp(ts, ); + + return ret ? ret : sprintf(buf, "%ld\n", val); +} + +static ssize_t +hyst_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int indx, ret; + long val; + struct thermal_sensor *ts = to_thermal_sensor(dev); + + if (!sscanf(attr->attr.name, "threshold%d_hyst", )) + return -EINVAL; + + ret = ts->ops->get_hyst(ts, indx, ); + + return ret ? ret : sprintf(buf, "%ld\n", val); +} + +static ssize_t +hyst_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + int indx, ret; + long val; + struct thermal_sensor *ts = to_thermal_sensor(dev); + + if (!ts->ops->set_hyst) + return -EPERM; + + if (!sscanf(attr->attr.name, "threshold%d_hyst", )) + return -EINVAL; + + if (kstrtol(buf, 10, )) + return -EINVAL; + + ret = ts->ops->set_hyst(ts, indx, val); + + return ret ? ret : count; +} + +static ssize_t +threshold_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int indx, ret; + long val; + struct thermal_sensor *ts = to_thermal_sensor(dev); + + if (!sscanf(attr->attr.name, "threshold%d", )) + return -EINVAL; + + ret = ts->ops->get_threshold(ts, indx, ); + + return ret ? ret : sprintf(buf, "%ld\n", val); +} + +static ssize_t +threshold_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + int indx, ret; + long val; + struct thermal_sensor *ts = to_thermal_sensor(dev); + + if (!ts->ops->set_threshold) + return -EPERM; + + if (!sscanf(attr->attr.name, "threshold%d", )) + return -EINVAL; + + if (kstrtol(buf, 10, )) + return -EINVAL; + + ret = ts->ops->set_threshold(ts, indx, val); + + return ret ? ret : count; +} + static ssize_t type_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -705,6 +805,10 @@ static DEVICE_ATTR(mode, 0644, mode_show, mode_store); static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show, passive_store); static DEVICE_ATTR(policy, S_IRUGO | S_IWUSR, policy_show, policy_store); +/* Thermal sensor attributes */ +static DEVICE_ATTR(sensor_name, 0444, sensor_name_show, NULL); +static DEVICE_ATTR(temp_input, 0444, sensor_temp_show, NULL); + /* sys I/F for cooling device */ #define to_cooling_device(_dev)\ container_of(_dev, struct thermal_cooling_device, device) @@ -1491,6 +1595,182 @@ static void remove_trip_attrs(struct thermal_zone_device *tz) } /** + * enable_sensor_thresholds - create sysfs nodes for thresholdX + * @ts:the thermal sensor + * @count:
RE: [Xen-devel] [PATCH] xen/swiotlb: Exchange to contiguous memory for map_sg hook
> -Original Message- > From: Jan Beulich [mailto:jbeul...@suse.com] > Sent: Thursday, December 20, 2012 4:56 PM > To: Xu, Dongxiao > Cc: xen-de...@lists.xen.org; Konrad Rzeszutek Wilk; > linux-kernel@vger.kernel.org > Subject: RE: [Xen-devel] [PATCH] xen/swiotlb: Exchange to contiguous memory > for map_sg hook > > >>> On 20.12.12 at 02:23, "Xu, Dongxiao" wrote: > > Sorry, maybe I am still not describing this issue clearly. > > No, at least I understood you the way you re-describe below. > > > Take the libata case as an example, the static DMA buffer locates > > (dev->link->ap->sector_buf , here we use Data Structure B in the graph) in > > the following structure: > > > > -Page boundary > > > > > > -Page boundary > > > > > > -Page boundary > > > > Where Structure B is our DMA target. > > > > For Data Structure B, we didn't care about the simultaneous access, either > > lock or sync function will take care of it. > > What we are not sure is "read/write of A and C from other processor". As we > > will have memory copy for the pages, and at the same time, other CPU may > > access A/C. > > The question is whether what libata does here is valid in the first > place - fill an SG list entry with something that crosses a page > boundary and is not a compound page. Sorry for the late response about this thread. To make sure I understand you correctly, so do you mean the correct fix should be applied to libata driver, and make sure it DMA from/to correct place (for example, some memory allocated by DMA API), but not such certain field in a static structure? If we fix it in device driver side, then we may not need to modify the xen-swiotlb part. Thanks, Dongxiao > > Jan -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH V2 2/2] virtio-net: reset virtqueue affinity when doing cpu hotplug
Add a cpu notifier to virtio-net, so that we can reset the virtqueue affinity if the cpu hotplug happens. It improve the performance through enabling or disabling the virtqueue affinity after doing cpu hotplug. Adding the notifier block to virtnet_info is suggested by Jason, thank you. Cc: Rusty Russell Cc: "Michael S. Tsirkin" Cc: Jason Wang Cc: Eric Dumazet Cc: virtualizat...@lists.linux-foundation.org Cc: net...@vger.kernel.org Signed-off-by: Wanlong Gao --- drivers/net/virtio_net.c | 30 ++ 1 file changed, 30 insertions(+) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index b483fb5..9547b4c 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -26,6 +26,7 @@ #include #include #include +#include static int napi_weight = 128; module_param(napi_weight, int, 0444); @@ -123,6 +124,9 @@ struct virtnet_info { /* Does the affinity hint is set for virtqueues? */ bool affinity_hint_set; + + /* CPU hot plug notifier */ + struct notifier_block nb; }; struct skb_vnet_hdr { @@ -1051,6 +1055,23 @@ static void virtnet_set_affinity(struct virtnet_info *vi, bool set) } } +static int virtnet_cpu_callback(struct notifier_block *nfb, + unsigned long action, void *hcpu) +{ + struct virtnet_info *vi = container_of(nfb, struct virtnet_info, nb); + switch(action) { + case CPU_ONLINE: + case CPU_ONLINE_FROZEN: + case CPU_DEAD: + case CPU_DEAD_FROZEN: + virtnet_set_affinity(vi, true); + break; + default: + break; + } + return NOTIFY_OK; +} + static void virtnet_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring) { @@ -1509,6 +1530,13 @@ static int virtnet_probe(struct virtio_device *vdev) } } + vi->nb.notifier_call = _cpu_callback; + err = register_hotcpu_notifier(>nb); + if (err) { + pr_debug("virtio_net: registering cpu notifier failed\n"); + goto free_recv_bufs; + } + /* Assume link up if device can't report link status, otherwise get link status from config. */ if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) { @@ -1553,6 +1581,8 @@ static void virtnet_remove(struct virtio_device *vdev) { struct virtnet_info *vi = vdev->priv; + unregister_hotcpu_notifier(>nb); + /* Prevent config work handler from accessing the device. */ mutex_lock(>config_lock); vi->config_enable = false; -- 1.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH V2 1/2] virtio-net: fix the set affinity bug when CPU IDs are not consecutive
As M.S.T mentioned, set affinity will not work very well when CPU IDs are not consecutive, this can happen with hot unplug. Fix this bug by traversal the online CPUs. Cc: Rusty Russell Cc: "Michael S. Tsirkin" Cc: Jason Wang Cc: Eric Dumazet Cc: virtualizat...@lists.linux-foundation.org Cc: net...@vger.kernel.org Signed-off-by: Wanlong Gao --- drivers/net/virtio_net.c | 24 +--- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index a6fcf15..b483fb5 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -1016,6 +1016,7 @@ static int virtnet_vlan_rx_kill_vid(struct net_device *dev, u16 vid) static void virtnet_set_affinity(struct virtnet_info *vi, bool set) { int i; + int cpu; /* In multiqueue mode, when the number of cpu is equal to the number of * queue pairs, we let the queue pairs to be private to one cpu by @@ -1029,16 +1030,25 @@ static void virtnet_set_affinity(struct virtnet_info *vi, bool set) return; } - for (i = 0; i < vi->max_queue_pairs; i++) { - int cpu = set ? i : -1; - virtqueue_set_affinity(vi->rq[i].vq, cpu); - virtqueue_set_affinity(vi->sq[i].vq, cpu); - } + if (set) { + i = 0; + for_each_online_cpu(cpu) { + virtqueue_set_affinity(vi->rq[i].vq, cpu); + virtqueue_set_affinity(vi->sq[i].vq, cpu); + i++; + if (i >= vi->max_queue_pairs) + break; + } - if (set) vi->affinity_hint_set = true; - else + } else { + for(i = 0; i < vi->max_queue_pairs; i++) { + virtqueue_set_affinity(vi->rq[i].vq, -1); + virtqueue_set_affinity(vi->sq[i].vq, -1); + } + vi->affinity_hint_set = false; + } } static void virtnet_get_ringparam(struct net_device *dev, -- 1.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] drivers/power/88pm860x_battery.c: eliminate possible references to released resources
On Sun, Jan 06, 2013 at 10:53:21PM -0800, Anton Vorontsov wrote: > On Mon, Jan 07, 2013 at 09:42:23AM +0300, Dan Carpenter wrote: > > On Sun, Jan 06, 2013 at 01:16:50PM -0800, Anton Vorontsov wrote: > > > The patch is whitespace-damaged (for some reason there are two spaces in > > > the beginning of each non-change line). I repeated changes manually, but > > > you might want to fix your mail/patch setup anyway. :) > > > > > > > It may be something on your end, the patch applies fine for me. > > I just looked into Julia's email headers, and it says: > > Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed > > flowed? for the patch? :) That's not right. > > Documentation/email-clients.txt says: > > Don't send patches with "format=flowed". This can cause unexpected > and unwanted line breaks. > > :-P > > As for why it applied fine for you, your mailer probably automatically > decodes the content, but I apply mbox file directly. (If I '-C' the > email in mutt, then it also applies for me, but I normally don't do that.) Ah. You're right, of course. I'm also using mutt but I have in my macros like you say. macro index,pager ap "rm -f tmp/patchtmp/patch~/progs/kernel/apply_patch.sh ~/var/mail/tmp/patch" When I pipe to scripts it uses the undecoded copy. I wish I knew how to use the decoded version there as well... regards, dan carpenter -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] drivers/power/88pm860x_battery.c: eliminate possible references to released resources
On Mon, Jan 07, 2013 at 09:42:23AM +0300, Dan Carpenter wrote: > On Sun, Jan 06, 2013 at 01:16:50PM -0800, Anton Vorontsov wrote: > > The patch is whitespace-damaged (for some reason there are two spaces in > > the beginning of each non-change line). I repeated changes manually, but > > you might want to fix your mail/patch setup anyway. :) > > > > It may be something on your end, the patch applies fine for me. I just looked into Julia's email headers, and it says: Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed flowed? for the patch? :) That's not right. Documentation/email-clients.txt says: Don't send patches with "format=flowed". This can cause unexpected and unwanted line breaks. :-P As for why it applied fine for you, your mailer probably automatically decodes the content, but I apply mbox file directly. (If I '-C' the email in mutt, then it also applies for me, but I normally don't do that.) Anton -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v3 09/22] sched: compute runnable load avg in cpu_load and cpu_avg_load_per_task
Hi everyone, On 01/07/2013 12:01 AM, Linus Torvalds wrote: > On Sat, Jan 5, 2013 at 11:54 PM, Alex Shi wrote: >> >> I just looked into the aim9 benchmark, in this case it forks 2000 tasks, >> after all tasks ready, aim9 give a signal than all tasks burst waking up >> and run until all finished. >> Since each of tasks are finished very quickly, a imbalanced empty cpu >> may goes to sleep till a regular balancing give it some new tasks. That >> causes the performance dropping. cause more idle entering. > > Sounds like for AIM (and possibly for other really bursty loads), we > might want to do some load-balancing at wakeup time by *just* looking > at the number of running tasks, rather than at the load average. Hmm? During wake ups,the load average is not even queried,is it? wake_affine() is called to see in the affinity of which cpu(prev/waking),the task should go.But after that select_idle_sibling() simply sees if there is an idle cpu to offload the task to. Looks like only in the periodic load balancing we can correct this scenario as of now, as pointed below. > > The load average is fundamentally always going to run behind a bit, > and while you want to use it for long-term balancing, a short-term you > might want to do just a "if we have a huge amount of runnable > processes, do a load balancing *now*". Where "huge amount" should > probably be relative to the long-term load balancing (ie comparing the > number of runnable processes on this CPU right *now* with the load > average over the last second or so would show a clear spike, and a > reason for quick action). > >Linus > Earlier I had posted a patch,to address this. https://lkml.org/lkml/2012/10/25/156 update_sd_pick_busiest() checks whether a sched group has too many running tasks to be offloaded. --START_PATCH- The scenario which led to this patch is shown below: Consider Task1 and Task2 to be a long running task and Tasks 3,4,5,6 to be short running tasks Task3 Task4 Task1 Task5 Task2 Task6 -- -- SCHED_GRP1 SCHED_GRP2 Normal load calculator would qualify SCHED_GRP2 as the candidate for sd->busiest due to the following loads that it calculates. SCHED_GRP1:2048 SCHED_GRP2:4096 Load calculator would probably qualify SCHED_GRP1 as the candidate for sd->busiest due to the following loads that it calculates SCHED_GRP1:3200 SCHED_GRP2:1156 This patch aims to strike a balance between the loads of the group and the number of tasks running on the group to decide the busiest group in the sched_domain. This means we will need to use the PJT's metrics but with an additional constraint. Signed-off-by: Preeti U Murthy --- kernel/sched/fair.c | 25 ++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index e02dad4..aafa3c1 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -165,7 +165,8 @@ void sched_init_granularity(void) #else # define WMULT_CONST (1UL << 32) #endif - +#define NR_THRESHOLD 2 +#define LOAD_THRESHOLD 1 #define WMULT_SHIFT32 /* @@ -4169,6 +4170,7 @@ struct sd_lb_stats { /* Statistics of the busiest group */ unsigned int busiest_idle_cpus; unsigned long max_load; + u64 max_sg_load; /* Equivalent of max_load but calculated using pjt's metric*/ unsigned long busiest_load_per_task; unsigned long busiest_nr_running; unsigned long busiest_group_capacity; @@ -4628,8 +4630,24 @@ static bool update_sd_pick_busiest(struct lb_env *env, struct sched_group *sg, struct sg_lb_stats *sgs) { - if (sgs->avg_load <= sds->max_load) - return false; + /* Use PJT's metrics to qualify a sched_group as busy +* +* But a low load sched group may be queueing up many tasks +* So before dismissing a sched group with lesser load,ensure +* that the number of processes on it is checked if it is +* not too less loaded than the max load so far +* +* But as of now as LOAD_THRESHOLD is 1,this check is a nop. +* But we could vary LOAD_THRESHOLD suitably to bring in this check +*/ + if (sgs->avg_cfs_runnable_load <= sds->max_sg_load) { + if (sgs->avg_cfs_runnable_load > LOAD_THRESHOLD * sds->max_sg_load) { + if (sgs->sum_nr_running <= (NR_THRESHOLD + sds->busiest_nr_running)) + return false; + } else { + return false; + } + } if (sgs->sum_nr_running > sgs->group_capacity) return true; @@ -4708,6 +4726,7 @@ static inline void update_sd_lb_stats(struct lb_env *env,
Re: [PATCH] drivers/power/88pm860x_battery.c: eliminate possible references to released resources
On Mon, 7 Jan 2013, Dan Carpenter wrote: > On Sun, Jan 06, 2013 at 01:16:50PM -0800, Anton Vorontsov wrote: > > The patch is whitespace-damaged (for some reason there are two spaces in > > the beginning of each non-change line). I repeated changes manually, but > > you might want to fix your mail/patch setup anyway. :) > > > > It may be something on your end, the patch applies fine for me. There was a problem on my end and I fixed it. thanks, julia -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] drivers/power/88pm860x_battery.c: eliminate possible references to released resources
On Sun, Jan 06, 2013 at 01:16:50PM -0800, Anton Vorontsov wrote: > The patch is whitespace-damaged (for some reason there are two spaces in > the beginning of each non-change line). I repeated changes manually, but > you might want to fix your mail/patch setup anyway. :) > It may be something on your end, the patch applies fine for me. regards, dan carpenter -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 1/2] power_supply: Add charge control struct in power supply class
On Mon, Jan 07, 2013 at 05:43:58AM +, Pallala, Ramakrishna wrote: > > > > > +struct power_supply_charger_control { > > > > > + const char *name; > > > > > + /* get charging status */ > > > > > + int (*is_charging_enabled)(void); > > > > > + int (*is_charger_enabled)(void); [...] > > The similar functionalities are exposed by patch > > https://lkml.org/lkml/2012/10/18/219. > > As per Anton's review comments on this patch, I'll be moving the macros to > > power_supply.h. > > Wouldn't that be enough ? > > Though the macros seem to be fine but I would still think that call back way > of interfaces would be > More flexible and straightforward. We have properties mechanism deployed already, so I'd rather keep it consistent. p.s. We had 'properties vs. callbacks' debates before, there are pros and cons of each approach. Unless there are some unresolvable issues, let's stick with the original approach. :) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v3 4/7] memcg: remove memcg from the reclaim iterators
(2013/01/04 2:54), Michal Hocko wrote: > Now that per-node-zone-priority iterator caches memory cgroups rather > than their css ids we have to be careful and remove them from the > iterator when they are on the way out otherwise they might hang for > unbounded amount of time (until the global/targeted reclaim triggers the > zone under priority to find out the group is dead and let it to find the > final rest). > > This is solved by hooking into mem_cgroup_css_offline and checking all > per-node-zone-priority iterators up the way to the root cgroup. If the > current memcg is found in the respective iter->last_visited then it is > replaced by the previous one in the same sub-hierarchy. > > This guarantees that no group gets more reclaiming than necessary and > the next iteration will continue without noticing that the removed group > has disappeared. > > Spotted-by: Ying Han > Signed-off-by: Michal Hocko Acked-by: KAMEZAWA Hiroyuki -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
RE: [PATCH 1/2] power_supply: Add charge control struct in power supply class
> > > > > +struct power_supply_charger_control { > > > > > + const char *name; > > > > > + /* get charging status */ > > > > > + int (*is_charging_enabled)(void); > > > > > + int (*is_charger_enabled)(void); > > > > > + > > > > > + /* set charging parameters */ > > > > > + int (*set_in_current_limit)(int uA); > > > > > + int (*set_charge_current)(int uA); > > > > > + int (*set_charge_voltage)(int uV); > > > > > + > > > > > + /* control battery charging */ > > > > > + int (*enable_charging)(void); > > > > > + int (*disable_charging)(void); > > > > > + > > > > > + /* control VSYS or system supply */ > > > > > + int (*turnon_charger)(void); > > > > > + int (*turnoff_charger)(void); > > > > > +}; > > > > > + > > > > > > > > I'm all for this patch, but why do you need to place it into > > > > power_supply.h and power_supply_core.c? :) I see nothing generic > > > > here, it's pure charger-manager stuff. So, place everything into > > > > charger- > > > manager.{c,h}. > > > > > > Hi Anton, > > > > > > The main reason for keeping this stuff in power_supply.h and > > > power_supply_core.c is to make these interfaces uniform Across > > > multiple charger frameworks and to avoid each charger framework > > > define it's own interfaces. If there is need for new callback They > > > can add to the existing struct defined above and it will available > > > to all the frameworks. Also the work required to support a new > > > Framework will be reduced if the driver already support any one of the > existing frameworks. > > > > > > > Rama, > > > > The similar functionalities are exposed by patch > https://lkml.org/lkml/2012/10/18/219. > > As per Anton's review comments on this patch, I'll be moving the macros to > power_supply.h. > > Wouldn't that be enough ? > > Btw, how do these two sets relate to each other? Both seem to control chargers > in some way... But yours approach uses properties, which I like more. > > I guess you should coordinate on this? Sure Anton we will sync up on this and get back to you. N�r��yb�X��ǧv�^�){.n�+{zX����ܨ}���Ơz�:+v���zZ+��+zf���h���~i���z��w���?�&�)ߢf��^jǫy�m��@A�a��� 0��h���i
Re: [PATCH] backlight: l4f00242t03: Convert to devm_regulator_get
On Monday, January 07, 2013 2:17 PM, Axel Lin wrote > > Signed-off-by: Axel Lin It looks good. Acked-by: Jingoo Han Best regards, Jingoo Han > --- > drivers/video/backlight/l4f00242t03.c | 24 +--- > 1 file changed, 5 insertions(+), 19 deletions(-) > > diff --git a/drivers/video/backlight/l4f00242t03.c > b/drivers/video/backlight/l4f00242t03.c > index 9bef9cf..fb61557 100644 > --- a/drivers/video/backlight/l4f00242t03.c > +++ b/drivers/video/backlight/l4f00242t03.c > @@ -190,27 +190,24 @@ static int l4f00242t03_probe(struct spi_device *spi) > return ret; > } > > - priv->io_reg = regulator_get(>dev, "vdd"); > + priv->io_reg = devm_regulator_get(>dev, "vdd"); > if (IS_ERR(priv->io_reg)) { > dev_err(>dev, "%s: Unable to get the IO regulator\n", > __func__); > return PTR_ERR(priv->io_reg); > } > > - priv->core_reg = regulator_get(>dev, "vcore"); > + priv->core_reg = devm_regulator_get(>dev, "vcore"); > if (IS_ERR(priv->core_reg)) { > - ret = PTR_ERR(priv->core_reg); > dev_err(>dev, "%s: Unable to get the core regulator\n", > __func__); > - goto err1; > + return PTR_ERR(priv->core_reg); > } > > priv->ld = lcd_device_register("l4f00242t03", > >dev, priv, _ops); > - if (IS_ERR(priv->ld)) { > - ret = PTR_ERR(priv->ld); > - goto err2; > - } > + if (IS_ERR(priv->ld)) > + return PTR_ERR(priv->ld); > > /* Init the LCD */ > l4f00242t03_lcd_init(spi); > @@ -220,13 +217,6 @@ static int l4f00242t03_probe(struct spi_device *spi) > dev_info(>dev, "Epson l4f00242t03 lcd probed.\n"); > > return 0; > - > -err2: > - regulator_put(priv->core_reg); > -err1: > - regulator_put(priv->io_reg); > - > - return ret; > } > > static int l4f00242t03_remove(struct spi_device *spi) > @@ -235,12 +225,8 @@ static int l4f00242t03_remove(struct spi_device *spi) > > l4f00242t03_lcd_power_set(priv->ld, FB_BLANK_POWERDOWN); > lcd_device_unregister(priv->ld); > - > spi_set_drvdata(spi, NULL); > > - regulator_put(priv->io_reg); > - regulator_put(priv->core_reg); > - > return 0; > } > > -- > 1.7.9.5 > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
RE: [PATCH 1/2] power_supply: Add charge control struct in power supply class
> > > > +struct power_supply_charger_control { > > > > + const char *name; > > > > + /* get charging status */ > > > > + int (*is_charging_enabled)(void); > > > > + int (*is_charger_enabled)(void); > > > > + > > > > + /* set charging parameters */ > > > > + int (*set_in_current_limit)(int uA); > > > > + int (*set_charge_current)(int uA); > > > > + int (*set_charge_voltage)(int uV); > > > > + > > > > + /* control battery charging */ > > > > + int (*enable_charging)(void); > > > > + int (*disable_charging)(void); > > > > + > > > > + /* control VSYS or system supply */ > > > > + int (*turnon_charger)(void); > > > > + int (*turnoff_charger)(void); > > > > +}; > > > > + > > > > > > I'm all for this patch, but why do you need to place it into > > > power_supply.h and power_supply_core.c? :) I see nothing generic > > > here, it's pure charger-manager stuff. So, place everything into > > > charger- > > manager.{c,h}. > > > > Hi Anton, > > > > The main reason for keeping this stuff in power_supply.h and > > power_supply_core.c is to make these interfaces uniform Across > > multiple charger frameworks and to avoid each charger framework define > > it's own interfaces. If there is need for new callback They can add to > > the existing struct defined above and it will available to all the > > frameworks. Also the work required to support a new Framework will be > > reduced if the driver already support any one of the existing frameworks. > > > > Rama, > > The similar functionalities are exposed by patch > https://lkml.org/lkml/2012/10/18/219. > As per Anton's review comments on this patch, I'll be moving the macros to > power_supply.h. > Wouldn't that be enough ? Though the macros seem to be fine but I would still think that call back way of interfaces would be More flexible and straightforward. Thanks, Ram
Re: [PATCH 1/2] power_supply: Add charge control struct in power supply class
On Mon, Jan 07, 2013 at 05:23:36AM +, Tc, Jenny wrote: > > > > > > +struct power_supply_charger_control { > > > > + const char *name; > > > > + /* get charging status */ > > > > + int (*is_charging_enabled)(void); > > > > + int (*is_charger_enabled)(void); > > > > + > > > > + /* set charging parameters */ > > > > + int (*set_in_current_limit)(int uA); > > > > + int (*set_charge_current)(int uA); > > > > + int (*set_charge_voltage)(int uV); > > > > + > > > > + /* control battery charging */ > > > > + int (*enable_charging)(void); > > > > + int (*disable_charging)(void); > > > > + > > > > + /* control VSYS or system supply */ > > > > + int (*turnon_charger)(void); > > > > + int (*turnoff_charger)(void); > > > > +}; > > > > + > > > > > > I'm all for this patch, but why do you need to place it into > > > power_supply.h and power_supply_core.c? :) I see nothing generic here, > > > it's pure charger-manager stuff. So, place everything into charger- > > manager.{c,h}. > > > > Hi Anton, > > > > The main reason for keeping this stuff in power_supply.h and > > power_supply_core.c is to make these interfaces uniform Across multiple > > charger frameworks and to avoid each charger framework define it's own > > interfaces. If there is need for new callback They can add to the existing > > struct > > defined above and it will available to all the frameworks. Also the work > > required to support a new Framework will be reduced if the driver already > > support any one of the existing frameworks. > > > > Rama, > > The similar functionalities are exposed by patch > https://lkml.org/lkml/2012/10/18/219. > As per Anton's review comments on this patch, I'll be moving the macros to > power_supply.h. > Wouldn't that be enough ? Btw, how do these two sets relate to each other? Both seem to control chargers in some way... But yours approach uses properties, which I like more. I guess you should coordinate on this? Thanks, Anton -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v5 14/14] memory-hotplug: free node_data when a node is offlined
(2012/12/30 15:02), Wen Congyang wrote: > At 12/28/2012 08:28 AM, Kamezawa Hiroyuki Wrote: >> (2012/12/27 21:16), Wen Congyang wrote: >>> At 12/26/2012 11:55 AM, Kamezawa Hiroyuki Wrote: (2012/12/24 21:09), Tang Chen wrote: > From: Wen Congyang > > We call hotadd_new_pgdat() to allocate memory to store node_data. So we > should free it when removing a node. > > Signed-off-by: Wen Congyang I'm sorry but is it safe to remove pgdat ? All zone cache and zonelists are properly cleared/rebuilded in synchronous way ? and No threads are visinting zone in vmscan.c ? >>> >>> We have rebuilt zonelists when a zone has no memory after offlining some >>> pages. >>> >> >> How do you guarantee that the address of pgdat/zone is not on stack of any >> kernel >> threads or other kernel objects without reference counting or other syncing >> method ? > > No way to guarentee this. But, the kernel should not use the address of > pgdat/zone when > it is offlined. > > Hmm, what about this: reuse the memory when the node is onlined again? > That's the only way which we can go now. Please don't free it. Thanks, -Kame -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: sched: Consequences of integrating the Per Entity Load Tracking Metric into the Load Balancer
Hi Mike, Thank you very much for your inputs.Just a few thoughts so that we are clear with the problems so far in the scheduler scalability and in what direction we ought to move to correct them. 1. During fork or exec,the scheduler goes through find_idlest_group() and find_idlest_cpu() in select_task_rq_fair() by iterating through all domains.Why then was a similar approach not followed for wake up balancing? What was so different about wake ups (except that the woken up task had to remain close to the prev/waking cpu) that we had to introduce select_idle_sibling() in the first place? 2.To the best of my knowlege,the concept of buddy cpu was introduced in select_idle_sibling() so as to avoid the entire package traversal and restrict it to the buddy cpus alone.But even during fork or exec,we iterate through all the sched domains,like I have mentioned above.Why did not the buddy cpu solution come to the rescue here as well? 3.So the correct problem stands at avoid iterating through the entire package at the cost of less aggression in finding the idle cpu or iterate through the package with an intention of finding the idlest cpu.To the best of my understanding the former is your approach or commit 37407ea7,the latter is what I tried to do.But as you have rightly pointed out my approach will have scaling issues.In this light,how does your best_combined patch(below) look like? Do you introduce a cut off value on the loads to decide on which approach to take? Meanwhile I will also try to run tbench and a few other benchmarks to find out why the results are like below.Will update you very soon on this. Thank you Regards Preeti U Murthy On 01/06/2013 10:02 PM, Mike Galbraith wrote: > On Sat, 2013-01-05 at 09:13 +0100, Mike Galbraith wrote: > >> I still have a 2.6-rt problem I need to find time to squabble with, but >> maybe I'll soonish see if what you did plus what I did combined works >> out on that 4x10 core box where current is _so_ unbelievably horrible. >> Heck, it can't get any worse, and the restricted wake balance alone >> kinda sorta worked. > > Actually, I flunked copy/paste 101. Below (preeti) shows the real deal. > > tbench, 3 runs, 30 secs/run > revert = 37407ea7 reverted > clients 1 5 1020 40 >80 > 3.6.0.virgin27.83 139.501488.76 4172.936983.71 > 8301.73 > 29.23 139.981500.22 4162.926907.16 > 8231.13 > 30.00 141.431500.09 3975.506847.24 > 7983.98 > > 3.6.0+revert 281.081404.762802.44 5019.497080.97 > 8592.80 >282.381375.702747.23 4823.957052.15 > 8508.45 >270.691375.532736.29 5243.057058.75 > 8806.72 > > 3.6.0+preeti26.43 126.621027.23 3350.067004.22 > 7561.83 > 26.67 128.66 922.57 3341.737045.05 > 7662.18 > 25.54 129.201015.02 3337.606591.32 > 7634.33 > > 3.6.0+best_combined280.481382.072730.27 4786.206477.28 > 7980.07 >276.881392.502708.23 4741.256590.99 > 7992.11 >278.921368.552735.49 4614.996573.38 > 7921.75 > > 3.0.51-0.7.9-default 286.441415.372794.41 5284.397282.57 > 13670.80 > > Something is either wrong with 3.6 itself, or the config I'm using, as > max throughput is nowhere near where it should be (see default). On the > bright side, integrating the two does show some promise. > > -Mike > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
RE: [PATCH 1/2] power_supply: Add charge control struct in power supply class
> > > > +struct power_supply_charger_control { > > > + const char *name; > > > + /* get charging status */ > > > + int (*is_charging_enabled)(void); > > > + int (*is_charger_enabled)(void); > > > + > > > + /* set charging parameters */ > > > + int (*set_in_current_limit)(int uA); > > > + int (*set_charge_current)(int uA); > > > + int (*set_charge_voltage)(int uV); > > > + > > > + /* control battery charging */ > > > + int (*enable_charging)(void); > > > + int (*disable_charging)(void); > > > + > > > + /* control VSYS or system supply */ > > > + int (*turnon_charger)(void); > > > + int (*turnoff_charger)(void); > > > +}; > > > + > > > > I'm all for this patch, but why do you need to place it into > > power_supply.h and power_supply_core.c? :) I see nothing generic here, > > it's pure charger-manager stuff. So, place everything into charger- > manager.{c,h}. > > Hi Anton, > > The main reason for keeping this stuff in power_supply.h and > power_supply_core.c is to make these interfaces uniform Across multiple > charger frameworks and to avoid each charger framework define it's own > interfaces. If there is need for new callback They can add to the existing > struct > defined above and it will available to all the frameworks. Also the work > required to support a new Framework will be reduced if the driver already > support any one of the existing frameworks. > Rama, The similar functionalities are exposed by patch https://lkml.org/lkml/2012/10/18/219. As per Anton's review comments on this patch, I'll be moving the macros to power_supply.h. Wouldn't that be enough ?
[PATCH 3/5] ARM: dts: AM33XX: Add am335x-evm lcdc pincontrol info
Update pin mux information for lcd panel on AM335X-EVM Signed-off-by: Afzal Mohammed --- arch/arm/boot/dts/am335x-evm.dts | 35 ++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts index a4229aa..25ebfc2 100644 --- a/arch/arm/boot/dts/am335x-evm.dts +++ b/arch/arm/boot/dts/am335x-evm.dts @@ -26,7 +26,7 @@ am33xx_pinmux: pinmux@44e10800 { pinctrl-names = "default"; - pinctrl-0 = <_keypad_s0 _keys_s0>; + pinctrl-0 = <_keypad_s0 _keys_s0 _pins_s0>; matrix_keypad_s0: matrix_keypad_s0 { pinctrl-single,pins = < @@ -44,6 +44,39 @@ 0x154 0x27 /* spi0_d0.gpio0_3, INPUT | MODE7 */ >; }; + + lcd_pins_s0: lcd_pins_s0 { + pinctrl-single,pins = < + 0x20 0x01 + 0x24 0x01 + 0x28 0x01 + 0x2c 0x01 + 0x30 0x01 + 0x34 0x01 + 0x38 0x01 + 0x3c 0x01 + 0xa0 0x08 + 0xa4 0x08 + 0xa8 0x08 + 0xac 0x08 + 0xb0 0x08 + 0xb4 0x08 + 0xb8 0x08 + 0xbc 0x08 + 0xc0 0x08 + 0xc4 0x08 + 0xc8 0x08 + 0xcc 0x08 + 0xd0 0x08 + 0xd4 0x08 + 0xd8 0x08 + 0xdc 0x08 + 0xe0 0x00 + 0xe4 0x00 + 0xe8 0x00 + 0xec 0x00 + >; + }; }; ocp { -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 0/5] ARM: dts: AM33XX: lcdc support
Hi, This series add DT sources for AM335x SoC as well as AM335x based boards. As pinmux is an SoC specific detail rather than IP specific one, addition of pin control has been done in a separate patch from the one in which display timings are added. Also it may aid in debugging in case of any issues. This has been tested on AM335x based boards like AM335x EVM and AM335x EVM-SK. This series is based on v3.8-rc2. This series has a dependency on, 1. Series v16 "of: add display helper" by, Steffen Trumtrar 2. Series v2 "video: da8xx-fb: runtime timing configuration" by, me (Afzal Mohammed ) 3. Series "video: da8xx-fb: DT support" by, me (Afzal Mohammed ) To test on AM335x, in addition to the above, following changes, 1. Patch "da8xx: Allow use by am33xx based devices" by, Pantelis Antoniou 3. Series "HWMOD fixes for AM33xx PWM submodules and device tree nodes" by, Philip, Avinash would be required A tree with all above for testing is available @git://gitorious.org/x0148406-public/linux-kernel.git da8xx-fb-dt Regards Afzal Afzal Mohammed (5): ARM: dts: AM33XX: Add lcdc node ARM: dts: AM33XX: Add am335x-evm lcdc panel timings ARM: dts: AM33XX: Add am335x-evm lcdc pincontrol info ARM: dts: AM33XX: Add am335x-evmsk lcdc panel timings ARM: dts: AM33XX: Add am335x-evmsk lcdc pincontrol info arch/arm/boot/dts/am335x-evm.dts | 55 +++- arch/arm/boot/dts/am335x-evmsk.dts | 55 +++- arch/arm/boot/dts/am33xx.dtsi |8 ++ 3 files changed, 116 insertions(+), 2 deletions(-) -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 5/5] ARM: dts: AM33XX: Add am335x-evmsk lcdc pincontrol info
Update pin mux information for lcd panel on AM335X-EVMSK. Signed-off-by: Afzal Mohammed --- arch/arm/boot/dts/am335x-evmsk.dts | 35 ++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/am335x-evmsk.dts b/arch/arm/boot/dts/am335x-evmsk.dts index a7e017b..6275a50 100644 --- a/arch/arm/boot/dts/am335x-evmsk.dts +++ b/arch/arm/boot/dts/am335x-evmsk.dts @@ -32,7 +32,7 @@ am33xx_pinmux: pinmux@44e10800 { pinctrl-names = "default"; - pinctrl-0 = <_leds_s0 _keys_s0>; + pinctrl-0 = <_leds_s0 _keys_s0 _pins_s0>; user_leds_s0: user_leds_s0 { pinctrl-single,pins = < @@ -51,6 +51,39 @@ 0x9c 0x27 /* gpmc_ben0_cle.gpio2_5, INPUT | MODE7 */ >; }; + + lcd_pins_s0: lcd_pins_s0 { + pinctrl-single,pins = < + 0x20 0x01 + 0x24 0x01 + 0x28 0x01 + 0x2c 0x01 + 0x30 0x01 + 0x34 0x01 + 0x38 0x01 + 0x3c 0x01 + 0xa0 0x08 + 0xa4 0x08 + 0xa8 0x08 + 0xac 0x08 + 0xb0 0x08 + 0xb4 0x08 + 0xb8 0x08 + 0xbc 0x08 + 0xc0 0x08 + 0xc4 0x08 + 0xc8 0x08 + 0xcc 0x08 + 0xd0 0x08 + 0xd4 0x08 + 0xd8 0x08 + 0xdc 0x08 + 0xe0 0x00 + 0xe4 0x00 + 0xe8 0x00 + 0xec 0x00 + >; + }; }; ocp { -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 4/5] ARM: dts: AM33XX: Add am335x-evmsk lcdc panel timings
Update lcdc node with panel timings (typical) for AM335X-EVMSK. Signed-off-by: Afzal Mohammed --- arch/arm/boot/dts/am335x-evmsk.dts | 20 1 file changed, 20 insertions(+) diff --git a/arch/arm/boot/dts/am335x-evmsk.dts b/arch/arm/boot/dts/am335x-evmsk.dts index f5a6162..a7e017b 100644 --- a/arch/arm/boot/dts/am335x-evmsk.dts +++ b/arch/arm/boot/dts/am335x-evmsk.dts @@ -248,3 +248,23 @@ }; }; }; + + { + status = "okay"; + + display-timings { + 480x272p57 { + clock-frequency = <900>; + hactive = <480>; + vactive = <272>; + hfront-porch = <8>; + hback-porch = <43>; + hsync-len = <4>; + vback-porch = <12>; + vfront-porch = <4>; + vsync-len = <10>; + hsync-active = <1>; + vsync-active = <1>; + }; + }; +}; -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/5] ARM: dts: AM33XX: Add am335x-evm lcdc panel timings
Update lcdc node with panel timings (typical) for AM335X-EVM. Signed-off-by: Afzal Mohammed --- arch/arm/boot/dts/am335x-evm.dts | 20 1 file changed, 20 insertions(+) diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts index d649644..a4229aa 100644 --- a/arch/arm/boot/dts/am335x-evm.dts +++ b/arch/arm/boot/dts/am335x-evm.dts @@ -244,3 +244,23 @@ _emac1 { phy_id = <_mdio>, <1>; }; + + { + status = "okay"; + + display-timings { + 800x480p62 { + clock-frequency = <3000>; + hactive = <800>; + vactive = <480>; + hfront-porch = <39>; + hback-porch = <39>; + hsync-len = <47>; + vback-porch = <29>; + vfront-porch = <13>; + vsync-len = <2>; + hsync-active = <1>; + vsync-active = <1>; + }; + }; +}; -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 1/5] ARM: dts: AM33XX: Add lcdc node
Add lcdc node. Signed-off-by: Afzal Mohammed --- arch/arm/boot/dts/am33xx.dtsi |8 1 file changed, 8 insertions(+) diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index c2f14e8..432d4bb8 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -385,5 +385,13 @@ mac-address = [ 00 00 00 00 00 00 ]; }; }; + + lcdc: lcdc@4830e000 { + compatible = "ti,am3352-lcdc", "ti,da830-lcdc"; + reg = <0x4830e000 0x1000>; + interrupts = <36>; + status = "disabled"; + ti,hwmods = "lcdc"; + }; }; }; -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] ARM: DTS: exynos4210-origen: Add MAX8997 node entry
On 01/04/2013 10:51 PM, Thomas Abraham wrote: > On 4 January 2013 00:23, Tushar Behera wrote: >> The node entry is added as per documentation and legacy board file. >> >> Signed-off-by: Tushar Behera >> --- >> The patch is rebased on v3.8-rc1. >> >> arch/arm/boot/dts/exynos4210-origen.dts | 150 >> +++ >> 1 files changed, 150 insertions(+), 0 deletions(-) Please ignore this patch. > > This patch has already been posted. Here is the link: > https://patchwork.kernel.org/patch/1794501/ > Sorry, had missed that patch. I have added a 'Tested-by' to the original patch. -- Tushar Behera -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] backlight: l4f00242t03: Convert to devm_regulator_get
Signed-off-by: Axel Lin --- drivers/video/backlight/l4f00242t03.c | 24 +--- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/drivers/video/backlight/l4f00242t03.c b/drivers/video/backlight/l4f00242t03.c index 9bef9cf..fb61557 100644 --- a/drivers/video/backlight/l4f00242t03.c +++ b/drivers/video/backlight/l4f00242t03.c @@ -190,27 +190,24 @@ static int l4f00242t03_probe(struct spi_device *spi) return ret; } - priv->io_reg = regulator_get(>dev, "vdd"); + priv->io_reg = devm_regulator_get(>dev, "vdd"); if (IS_ERR(priv->io_reg)) { dev_err(>dev, "%s: Unable to get the IO regulator\n", __func__); return PTR_ERR(priv->io_reg); } - priv->core_reg = regulator_get(>dev, "vcore"); + priv->core_reg = devm_regulator_get(>dev, "vcore"); if (IS_ERR(priv->core_reg)) { - ret = PTR_ERR(priv->core_reg); dev_err(>dev, "%s: Unable to get the core regulator\n", __func__); - goto err1; + return PTR_ERR(priv->core_reg); } priv->ld = lcd_device_register("l4f00242t03", >dev, priv, _ops); - if (IS_ERR(priv->ld)) { - ret = PTR_ERR(priv->ld); - goto err2; - } + if (IS_ERR(priv->ld)) + return PTR_ERR(priv->ld); /* Init the LCD */ l4f00242t03_lcd_init(spi); @@ -220,13 +217,6 @@ static int l4f00242t03_probe(struct spi_device *spi) dev_info(>dev, "Epson l4f00242t03 lcd probed.\n"); return 0; - -err2: - regulator_put(priv->core_reg); -err1: - regulator_put(priv->io_reg); - - return ret; } static int l4f00242t03_remove(struct spi_device *spi) @@ -235,12 +225,8 @@ static int l4f00242t03_remove(struct spi_device *spi) l4f00242t03_lcd_power_set(priv->ld, FB_BLANK_POWERDOWN); lcd_device_unregister(priv->ld); - spi_set_drvdata(spi, NULL); - regulator_put(priv->io_reg); - regulator_put(priv->core_reg); - return 0; } -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 07/10] video: da8xx-fb: invoke platform callback safely
Ensure that platform data is present before checking whether platform callback is present (the one used to control backlight). So far this was not an issue as driver was purely non-DT triggered, but now DT support has been added. Signed-off-by: Afzal Mohammed --- drivers/video/da8xx-fb.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index d10479f..68ae925 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c @@ -1351,7 +1351,7 @@ static int __devinit fb_probe(struct platform_device *device) par->dev = >dev; par->lcdc_clk = fb_clk; par->lcd_fck_rate = clk_get_rate(fb_clk); - if (fb_pdata->panel_power_ctrl) { + if (fb_pdata && fb_pdata->panel_power_ctrl) { par->panel_power_ctrl = fb_pdata->panel_power_ctrl; par->panel_power_ctrl(1); } -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 06/10] video: da8xx-fb: minimal dt support
Driver is provided a means to have the probe triggered by DT. Signed-off-by: Afzal Mohammed --- .../devicetree/bindings/video/fb-da8xx.txt | 16 drivers/video/da8xx-fb.c |7 +++ 2 files changed, 23 insertions(+) create mode 100644 Documentation/devicetree/bindings/video/fb-da8xx.txt diff --git a/Documentation/devicetree/bindings/video/fb-da8xx.txt b/Documentation/devicetree/bindings/video/fb-da8xx.txt new file mode 100644 index 000..581e014 --- /dev/null +++ b/Documentation/devicetree/bindings/video/fb-da8xx.txt @@ -0,0 +1,16 @@ +TI LCD Controller on DA830/DA850/AM335x SoC's + +Required properties: +- compatible: + DA830 - "ti,da830-lcdc" + AM335x SoC's - "ti,am3352-lcdc", "ti,da830-lcdc" +- reg: Address range of lcdc register set +- interrupts: lcdc interrupt + +Example: + +lcdc@4830e000 { + compatible = "ti,am3352-lcdc", "ti,da830-lcdc"; + reg = <0x4830e000 0x1000>; + interrupts = <36>; +}; diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index 991d9e3..d10479f 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c @@ -1599,6 +1599,12 @@ static int fb_resume(struct platform_device *dev) #define fb_resume NULL #endif +static const struct of_device_id da8xx_fb_of_match[] = { + {.compatible = "ti,da830-lcdc", }, + {}, +}; +MODULE_DEVICE_TABLE(of, da8xx_fb_of_match); + static struct platform_driver da8xx_fb_driver = { .probe = fb_probe, .remove = __devexit_p(fb_remove), @@ -1607,6 +1613,7 @@ static struct platform_driver da8xx_fb_driver = { .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, + .of_match_table = of_match_ptr(da8xx_fb_of_match), }, }; -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 09/10] video: da8xx-fb: ensure pdata only for non-dt
This driver is DT probe-able, hence ensure presence of platform data only for non-DT boot. Signed-off-by: Afzal Mohammed --- drivers/video/da8xx-fb.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index 94add01..3e590d4 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c @@ -1306,7 +1306,7 @@ static int __devinit fb_probe(struct platform_device *device) int ret; unsigned long ulcm; - if (fb_pdata == NULL) { + if (fb_pdata == NULL && !device->dev.of_node) { dev_err(>dev, "Can not get platform data\n"); return -ENOENT; } -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 10/10] video: da8xx-fb: setup struct lcd_ctrl_config for dt
strcut lcd_ctrl_config information required for driver is currently obtained via platform data. To handle DT probing, create lcd_ctrl_config and populate it with default values, these values are sufficient for the panels so far used with this controller to work. Signed-off-by: Afzal Mohammed --- drivers/video/da8xx-fb.c | 34 +- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index 3e590d4..4a4b4dc 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c @@ -1257,6 +1257,35 @@ static struct fb_ops da8xx_fb_ops = { .fb_blank = cfb_blank, }; +static struct lcd_ctrl_config *da8xx_fb_create_cfg(struct platform_device *dev) +{ + struct lcd_ctrl_config *cfg; + + cfg = devm_kzalloc(>dev, sizeof(struct fb_videomode), GFP_KERNEL); + if (!cfg) { + dev_err(>dev, "memory allocation failed\n"); + return NULL; + } + + /* default values */ + + if (lcd_revision == LCD_VERSION_1) + cfg->bpp = 16; + else + cfg->bpp = 32; + + /* +* For panels so far used with this LCDC, below statement is sufficient. +* For new panels, if required, struct lcd_ctrl_cfg fields to be updated +* with additional/modified values. Those values would have to be then +* obtained from dt(requiring new dt bindings). +*/ + + cfg->panel_shade = COLOR_ACTIVE; + + return cfg; +} + static struct fb_videomode *da8xx_fb_get_videomode(struct platform_device *dev) { struct da8xx_lcdc_platform_data *fb_pdata = dev->dev.platform_data; @@ -1348,7 +1377,10 @@ static int __devinit fb_probe(struct platform_device *device) break; } - lcd_cfg = (struct lcd_ctrl_config *)fb_pdata->controller_data; + if (device->dev.of_node) + lcd_cfg = da8xx_fb_create_cfg(device); + else + lcd_cfg = (struct lcd_ctrl_config *)fb_pdata->controller_data; if (!lcd_cfg) { ret = -EINVAL; -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 08/10] video: da8xx-fb: obtain fb_videomode info from dt
Obtain fb_videomode details for the connected lcd panel using the display timing details present in DT. Signed-off-by: Afzal Mohammed --- .../devicetree/bindings/video/fb-da8xx.txt | 20 drivers/video/da8xx-fb.c | 16 2 files changed, 36 insertions(+) diff --git a/Documentation/devicetree/bindings/video/fb-da8xx.txt b/Documentation/devicetree/bindings/video/fb-da8xx.txt index 581e014..eeb935b 100644 --- a/Documentation/devicetree/bindings/video/fb-da8xx.txt +++ b/Documentation/devicetree/bindings/video/fb-da8xx.txt @@ -6,6 +6,11 @@ Required properties: AM335x SoC's - "ti,am3352-lcdc", "ti,da830-lcdc" - reg: Address range of lcdc register set - interrupts: lcdc interrupt +- display-timings: list of different videomodes supported by the lcd + panel, represented as childs, can have multiple modes supported, if + only one, then it is considered native mode, if multiple modes are + provided, native mode can be set explicitly, more details available + @Documentation/devicetree/bindings/video/display-timing.txt Example: @@ -13,4 +18,19 @@ lcdc@4830e000 { compatible = "ti,am3352-lcdc", "ti,da830-lcdc"; reg = <0x4830e000 0x1000>; interrupts = <36>; + display-timings { + 800x480p62 { + clock-frequency = <3000>; + hactive = <800>; + vactive = <480>; + hfront-porch = <39>; + hback-porch = <39>; + hsync-len = <47>; + vback-porch = <29>; + vfront-porch = <13>; + vsync-len = <2>; + hsync-active = <1>; + vsync-active = <1>; + }; + }; }; diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index 68ae925..94add01 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c @@ -1261,8 +1261,24 @@ static struct fb_videomode *da8xx_fb_get_videomode(struct platform_device *dev) { struct da8xx_lcdc_platform_data *fb_pdata = dev->dev.platform_data; struct fb_videomode *lcdc_info; + struct device_node *np = dev->dev.of_node; int i; + if (np) { + lcdc_info = devm_kzalloc(>dev, +sizeof(struct fb_videomode), +GFP_KERNEL); + if (!lcdc_info) { + dev_err(>dev, "memory allocation failed\n"); + return NULL; + } + if (of_get_fb_videomode(np, lcdc_info, 0)) { + dev_err(>dev, "timings not available in DT\n"); + return NULL; + } + return lcdc_info; + } + for (i = 0, lcdc_info = known_lcd_panels; i < ARRAY_SIZE(known_lcd_panels); i++, lcdc_info++) { if (strcmp(fb_pdata->type, lcdc_info->name) == 0) -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 04/10] video: da8xx-fb: ensure non-null cfg in pdata
Ensure that platform data contains pointer for lcd_ctrl_config. Signed-off-by: Afzal Mohammed --- drivers/video/da8xx-fb.c |5 + 1 file changed, 5 insertions(+) diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index e119ec8..32ce385 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c @@ -1324,6 +1324,11 @@ static int __devinit fb_probe(struct platform_device *device) lcd_cfg = (struct lcd_ctrl_config *)fb_pdata->controller_data; + if (!lcd_cfg) { + ret = -EINVAL; + goto err_pm_runtime_disable; + } + da8xx_fb_info = framebuffer_alloc(sizeof(struct da8xx_fb_par), >dev); if (!da8xx_fb_info) { -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 05/10] video: da8xx-fb: reorganize panel detection
Move panel detection to a separate function, this helps in readability as well as makes DT support cleaner. Signed-off-by: Afzal Mohammed --- drivers/video/da8xx-fb.c | 42 ++ 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index 32ce385..991d9e3 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c @@ -1257,6 +1257,27 @@ static struct fb_ops da8xx_fb_ops = { .fb_blank = cfb_blank, }; +static struct fb_videomode *da8xx_fb_get_videomode(struct platform_device *dev) +{ + struct da8xx_lcdc_platform_data *fb_pdata = dev->dev.platform_data; + struct fb_videomode *lcdc_info; + int i; + + for (i = 0, lcdc_info = known_lcd_panels; + i < ARRAY_SIZE(known_lcd_panels); i++, lcdc_info++) { + if (strcmp(fb_pdata->type, lcdc_info->name) == 0) + break; + } + + if (i == ARRAY_SIZE(known_lcd_panels)) { + dev_err(>dev, "no panel found\n"); + return NULL; + } + dev_info(>dev, "found %s panel\n", lcdc_info->name); + + return lcdc_info; +} + static int __devinit fb_probe(struct platform_device *device) { struct da8xx_lcdc_platform_data *fb_pdata = @@ -1266,7 +1287,7 @@ static int __devinit fb_probe(struct platform_device *device) struct fb_info *da8xx_fb_info; struct clk *fb_clk = NULL; struct da8xx_fb_par *par; - int ret, i; + int ret; unsigned long ulcm; if (fb_pdata == NULL) { @@ -1274,6 +1295,10 @@ static int __devinit fb_probe(struct platform_device *device) return -ENOENT; } + lcdc_info = da8xx_fb_get_videomode(device); + if (lcdc_info == NULL) + return -ENODEV; + lcdc_regs = platform_get_resource(device, IORESOURCE_MEM, 0); da8xx_fb_reg_base = devm_request_and_ioremap(>dev, lcdc_regs); if (!da8xx_fb_reg_base) { @@ -1307,21 +1332,6 @@ static int __devinit fb_probe(struct platform_device *device) break; } - for (i = 0, lcdc_info = known_lcd_panels; - i < ARRAY_SIZE(known_lcd_panels); - i++, lcdc_info++) { - if (strcmp(fb_pdata->type, lcdc_info->name) == 0) - break; - } - - if (i == ARRAY_SIZE(known_lcd_panels)) { - dev_err(>dev, "GLCD: No valid panel found\n"); - ret = -ENODEV; - goto err_pm_runtime_disable; - } else - dev_info(>dev, "GLCD: Found %s panel\n", - fb_pdata->type); - lcd_cfg = (struct lcd_ctrl_config *)fb_pdata->controller_data; if (!lcd_cfg) { -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 03/10] video: da8xx-fb: use devres
Replace existing resource handling in the driver with managed device resource. Signed-off-by: Afzal Mohammed --- drivers/video/da8xx-fb.c | 35 ++- 1 file changed, 6 insertions(+), 29 deletions(-) diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index 4f92028..e119ec8 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c @@ -1040,12 +1040,9 @@ static int __devexit fb_remove(struct platform_device *dev) par->p_palette_base); dma_free_coherent(NULL, par->vram_size, par->vram_virt, par->vram_phys); - free_irq(par->irq, par); pm_runtime_put_sync(>dev); pm_runtime_disable(>dev); framebuffer_release(info); - iounmap(da8xx_fb_reg_base); - release_mem_region(lcdc_regs->start, resource_size(lcdc_regs)); } return 0; @@ -1269,7 +1266,6 @@ static int __devinit fb_probe(struct platform_device *device) struct fb_info *da8xx_fb_info; struct clk *fb_clk = NULL; struct da8xx_fb_par *par; - resource_size_t len; int ret, i; unsigned long ulcm; @@ -1279,29 +1275,16 @@ static int __devinit fb_probe(struct platform_device *device) } lcdc_regs = platform_get_resource(device, IORESOURCE_MEM, 0); - if (!lcdc_regs) { - dev_err(>dev, - "Can not get memory resource for LCD controller\n"); - return -ENOENT; - } - - len = resource_size(lcdc_regs); - - lcdc_regs = request_mem_region(lcdc_regs->start, len, lcdc_regs->name); - if (!lcdc_regs) - return -EBUSY; - - da8xx_fb_reg_base = ioremap(lcdc_regs->start, len); + da8xx_fb_reg_base = devm_request_and_ioremap(>dev, lcdc_regs); if (!da8xx_fb_reg_base) { - ret = -EBUSY; - goto err_request_mem; + dev_err(>dev, "memory resource setup failed\n"); + return -EADDRNOTAVAIL; } - fb_clk = clk_get(>dev, "fck"); + fb_clk = devm_clk_get(>dev, "fck"); if (IS_ERR(fb_clk)) { dev_err(>dev, "Can not get device clock\n"); - ret = -ENODEV; - goto err_ioremap; + return -ENODEV; } pm_runtime_enable(>dev); @@ -1462,7 +1445,7 @@ static int __devinit fb_probe(struct platform_device *device) lcdc_irq_handler = lcdc_irq_handler_rev02; } - ret = request_irq(par->irq, lcdc_irq_handler, 0, + ret = devm_request_irq(>dev, par->irq, lcdc_irq_handler, 0, DRIVER_NAME, par); if (ret) goto irq_freq; @@ -1492,12 +1475,6 @@ err_pm_runtime_disable: pm_runtime_put_sync(>dev); pm_runtime_disable(>dev); -err_ioremap: - iounmap(da8xx_fb_reg_base); - -err_request_mem: - release_mem_region(lcdc_regs->start, len); - return ret; } -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 02/10] video: da8xx-fb: enable sync lost intr for v2 ip
interrupt handler is checking for sync lost interrupt, but it was not enabled, enable it. Signed-off-by: Afzal Mohammed --- drivers/video/da8xx-fb.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index cd73b87..4f92028 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c @@ -322,7 +322,7 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par) reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) | LCD_V2_END_OF_FRAME0_INT_ENA | LCD_V2_END_OF_FRAME1_INT_ENA | - LCD_FRAME_DONE; + LCD_FRAME_DONE | LCD_SYNC_LOST; lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG); } reg_dma |= LCD_DUAL_FRAME_BUFFER_ENABLE; -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 01/10] video: da8xx-fb: fix 24bpp raster configuration
From: "Manjunathappa, Prakash" Set only LCD_V2_TFT_24BPP_MODE bit for 24bpp and LCD_V2_TFT_24BPP_UNPACK bit along with LCD_V2_TFT_24BPP_MODE for 32bpp configuration. Patch is tested on am335x-evm for 24bpp and da850-evm for 16bpp configurations. Signed-off-by: Manjunathappa, Prakash Signed-off-by: Afzal Mohammed --- drivers/video/da8xx-fb.c |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index 240eac7..cd73b87 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c @@ -554,10 +554,10 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height, case 4: case 16: break; - case 24: - reg |= LCD_V2_TFT_24BPP_MODE; case 32: reg |= LCD_V2_TFT_24BPP_UNPACK; + case 24: + reg |= LCD_V2_TFT_24BPP_MODE; break; case 8: -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 00/10] video: da8xx-fb: DT support
Hi, This series adds DT support to da8xx-fb driver (device found on DaVinci and AM335x SoC's). It does certain cleanup's in the process. This makes use of Steffen Trumtrar's v16 of display timing DT support. Testing has been done on AM335x SoC based boards like AM335x EVM and AM335x EVM-SK. It has also been verified that display on DA850 EVM (non-DT boot) works as earlier. Another series that adds DT nodes for AM335x SoC/board would follow this. This series is based on v3.8-rc2, and is dependent on, 1. Series v16 "of: add display helper" by, Steffen Trumtrar 2. Patch "da8xx: Allow use by am33xx based devices" by, Pantelis Antoniou 3. Series v2 "video: da8xx-fb: runtime timing configuration" by, me (Afzal Mohammed ) To test this series on AM335x based boards, 1. Series "ARM: dts: AM33XX: lcdc support" by, me (Afzal Mohammed ), as well as, 2. Series "HWMOD fixes for AM33xx PWM submodules and device tree nodes" by, Philip, Avinash would be needed. A tree with all above dependencies (and below mentioned hack) is available @git://gitorious.org/x0148406-public/linux-kernel.git da8xx-fb-dt In the case of AM335x, in addition to this series, display PLL has to be locked to required frequency. Unless bootloader configures it properly, a hack would required in the Kernel. This is also present in the above mentioned branch of the tree. A solution in the Kernel is being worked upon and would be posted at the earliest. Regards Afzal Afzal Mohammed (9): video: da8xx-fb: enable sync lost intr for v2 ip video: da8xx-fb: use devres video: da8xx-fb: ensure non-null cfg in pdata video: da8xx-fb: reorganize panel detection video: da8xx-fb: minimal dt support video: da8xx-fb: invoke platform callback safely video: da8xx-fb: obtain fb_videomode info from dt video: da8xx-fb: ensure pdata only for non-dt video: da8xx-fb: setup struct lcd_ctrl_config for dt Manjunathappa, Prakash (1): video: da8xx-fb: fix 24bpp raster configuration .../devicetree/bindings/video/fb-da8xx.txt | 36 + drivers/video/da8xx-fb.c | 145 +--- 2 files changed, 132 insertions(+), 49 deletions(-) create mode 100644 Documentation/devicetree/bindings/video/fb-da8xx.txt -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
RE: [PATCH 1/2] power_supply: Add charge control struct in power supply class
> > +struct power_supply_charger_control { > > + const char *name; > > + /* get charging status */ > > + int (*is_charging_enabled)(void); > > + int (*is_charger_enabled)(void); > > + > > + /* set charging parameters */ > > + int (*set_in_current_limit)(int uA); > > + int (*set_charge_current)(int uA); > > + int (*set_charge_voltage)(int uV); > > + > > + /* control battery charging */ > > + int (*enable_charging)(void); > > + int (*disable_charging)(void); > > + > > + /* control VSYS or system supply */ > > + int (*turnon_charger)(void); > > + int (*turnoff_charger)(void); > > +}; > > + > > I'm all for this patch, but why do you need to place it into power_supply.h > and > power_supply_core.c? :) I see nothing generic here, it's pure charger-manager > stuff. So, place everything into charger-manager.{c,h}. Hi Anton, The main reason for keeping this stuff in power_supply.h and power_supply_core.c is to make these interfaces uniform Across multiple charger frameworks and to avoid each charger framework define it's own interfaces. If there is need for new callback They can add to the existing struct defined above and it will available to all the frameworks. Also the work required to support a new Framework will be reduced if the driver already support any one of the existing frameworks. Thanks, Ram
[PATCH] block: Remove judgement for rq_mergeable(rq) in func elv_rqhash_find.
Because only mergeable rq can add rqhash.So it does not make sense to judge rq_mergeable(rq) in func elv_rqhash_find. Signed-off-by: Jianpeng Ma --- block/elevator.c |5 - 1 file changed, 5 deletions(-) diff --git a/block/elevator.c b/block/elevator.c index 9edba1b..d5901a4 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -273,11 +273,6 @@ static struct request *elv_rqhash_find(struct request_queue *q, sector_t offset) hlist_for_each_entry_safe(rq, entry, next, hash_list, hash) { BUG_ON(!ELV_ON_HASH(rq)); - if (unlikely(!rq_mergeable(rq))) { - __elv_rqhash_del(rq); - continue; - } - if (rq_hash_key(rq) == offset) return rq; } -- 1.7.9.5
Re: HSI subsystem status
On 01/06/13 15:15, Linus Walleij wrote: > On Mon, Jan 7, 2013 at 12:11 AM, Linus Walleij > wrote: > >> Hi Carlos, >> >> what is the status on the HSI subsystem? We have based some patches for >> HSI master on top of the OMAP HSI master patches, but these never seem >> to reach the tree? > > Mail server replied: > > Delivery to the following recipient failed permanently: > > carlos.chi...@nokia.com > > Hm, maybe that answers the question. > > Does anyone know Carlos' current whereabouts? > There was one message posted by him from cch.devel @ gmail.com on lkml: http://marc.info/?l=linux-kernel=19872920118=2 so you could try that. -- ~Randy -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 09/10] video: da8xx-fb: report correct pixclock
Update "var" pixclock with the value that is configurable in hardware. This lets user know the actual pixclock. Signed-off-by: Afzal Mohammed --- drivers/video/da8xx-fb.c | 11 +++ 1 file changed, 11 insertions(+) diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index 663b3c5..c7393f1 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c @@ -690,6 +690,15 @@ static inline unsigned da8xx_fb_calc_clk_divider(struct da8xx_fb_par *par, return par->lcd_fck_rate / (PICOS2KHZ(pixclock) * 1000); } +static inline unsigned da8xx_fb_round_clk(struct da8xx_fb_par *par, + unsigned pixclock) +{ + unsigned div; + + div = da8xx_fb_calc_clk_divider(par, pixclock); + return KHZ2PICOS(par->lcd_fck_rate / (1000 * div)); +} + static inline void da8xx_fb_config_clk_divider(unsigned div) { /* Configure the LCD clock divisor. */ @@ -966,6 +975,8 @@ static int fb_check_var(struct fb_var_screeninfo *var, if (var->yres + var->yoffset > var->yres_virtual) var->yoffset = var->yres_virtual - var->yres; + var->pixclock = da8xx_fb_round_clk(par, var->pixclock); + return err; } -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 10/10] video: da8xx-fb: fb_set_par support
fb_set_par helps in runtime configuration of lcd controller like changing resolution, pixel clock etc. (eg. using fbset utility) Reconfigure lcd controller based on information passed by framework. Enable raster back if it was already enabled. As fb_set_par would get invoked indirectly from probe via fb_set_var, remove existing lcdc initialization in probe and do lcdc reset in probe so that reset happens only at the begining. Signed-off-by: Afzal Mohammed --- v2: disable raster in fb_set_par properly as required, without this there would be no issue on DA850, but it will cause problem on AM335X drivers/video/da8xx-fb.c | 60 +- 1 file changed, 49 insertions(+), 11 deletions(-) diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index c7393f1..240eac7 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c @@ -247,6 +247,11 @@ static struct fb_videomode known_lcd_panels[] = { }, }; +static inline bool da8xx_fb_is_raster_enabled(void) +{ + return !!(lcdc_read(LCD_RASTER_CTRL_REG) & LCD_RASTER_ENABLE); +} + /* Enable the Raster Engine of the LCD Controller */ static inline void lcd_enable_raster(void) { @@ -669,9 +674,6 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green, static void da8xx_fb_lcd_reset(void) { - /* Disable the Raster if previously Enabled */ - lcd_disable_raster(false); - /* DMA has to be disabled */ lcdc_write(0, LCD_DMA_CTRL_REG); lcdc_write(0, LCD_RASTER_CTRL_REG); @@ -724,8 +726,6 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg, u32 bpp; int ret = 0; - da8xx_fb_lcd_reset(); - da8xx_fb_calc_config_clk_divider(par, panel); if (panel->sync & FB_SYNC_CLK_INVERT) @@ -1205,9 +1205,52 @@ static int da8xx_pan_display(struct fb_var_screeninfo *var, return ret; } +static int da8xxfb_set_par(struct fb_info *info) +{ + struct da8xx_fb_par *par = info->par; + int ret; + bool raster = da8xx_fb_is_raster_enabled(); + + if (raster) + lcd_disable_raster(true); + else + lcd_disable_raster(false); + + fb_var_to_videomode(>mode, >var); + + par->cfg.bpp = info->var.bits_per_pixel; + + info->fix.visual = (par->cfg.bpp <= 8) ? + FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; + info->fix.line_length = (par->mode.xres * par->cfg.bpp) / 8; + + ret = lcd_init(par, >cfg, >mode); + if (ret < 0) { + dev_err(par->dev, "lcd init failed\n"); + return ret; + } + + par->dma_start = info->fix.smem_start + +info->var.yoffset * info->fix.line_length + +info->var.xoffset * info->var.bits_per_pixel / 8; + par->dma_end = par->dma_start + +info->var.yres * info->fix.line_length - 1; + + lcdc_write(par->dma_start, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG); + lcdc_write(par->dma_end, LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG); + lcdc_write(par->dma_start, LCD_DMA_FRM_BUF_BASE_ADDR_1_REG); + lcdc_write(par->dma_end, LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG); + + if (raster) + lcd_enable_raster(); + + return 0; +} + static struct fb_ops da8xx_fb_ops = { .owner = THIS_MODULE, .fb_check_var = fb_check_var, + .fb_set_par = da8xxfb_set_par, .fb_setcolreg = fb_setcolreg, .fb_pan_display = da8xx_pan_display, .fb_ioctl = fb_ioctl, @@ -1316,14 +1359,9 @@ static int __devinit fb_probe(struct platform_device *device) } fb_videomode_to_var(_fb_var, lcdc_info); - fb_var_to_videomode(>mode, _fb_var); par->cfg = *lcd_cfg; - if (lcd_init(par, lcd_cfg, lcdc_info) < 0) { - dev_err(>dev, "lcd_init failed\n"); - ret = -EFAULT; - goto err_release_fb; - } + da8xx_fb_lcd_reset(); /* allocate frame buffer */ par->vram_size = lcdc_info->xres * lcdc_info->yres * lcd_cfg->bpp; -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 08/10] video: da8xx-fb: store struct device *
store struct device pointer so that dev_dbg/err can be used outside of probe. Signed-off-by: Afzal Mohammed --- drivers/video/da8xx-fb.c |2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index 19ee560..663b3c5 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c @@ -154,6 +154,7 @@ static inline void lcdc_write(unsigned int val, unsigned int addr) } struct da8xx_fb_par { + struct device *dev; resource_size_t p_palette_base; unsigned char *v_palette_base; dma_addr_t vram_phys; @@ -1295,6 +1296,7 @@ static int __devinit fb_probe(struct platform_device *device) } par = da8xx_fb_info->par; + par->dev = >dev; par->lcdc_clk = fb_clk; par->lcd_fck_rate = clk_get_rate(fb_clk); if (fb_pdata->panel_power_ctrl) { -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 07/10] video: da8xx-fb: pix clk and clk div handling cleanup
Use the new modedb field to store pix clk. Reorganize existing clock divider functions with names now corresponding to what they do, add common function prefix. Fix existing panel modedb pixclock to be in ps instead of Hz. This needed a change in the way clock divider is calculated. As modedb pixclock information is now in ps, override on "var" pixclock over modedb to var conversion is removed. Signed-off-by: Afzal Mohammed --- drivers/video/da8xx-fb.c | 48 +- 1 file changed, 18 insertions(+), 30 deletions(-) diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index e858438..19ee560 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c @@ -164,7 +164,6 @@ struct da8xx_fb_par { struct clk *lcdc_clk; int irq; unsigned int palette_sz; - unsigned int pxl_clk; int blank; wait_queue_head_t vsync_wait; int vsync_flag; @@ -205,7 +204,7 @@ static struct fb_videomode known_lcd_panels[] = { .name = "Sharp_LCD035Q3DG01", .xres = 320, .yres = 240, - .pixclock = 4608000, + .pixclock = 217014, .left_margin= 6, .right_margin = 8, .upper_margin = 2, @@ -220,7 +219,7 @@ static struct fb_videomode known_lcd_panels[] = { .name = "Sharp_LK043T1DG01", .xres = 480, .yres = 272, - .pixclock = 7833600, + .pixclock = 127655, .left_margin= 2, .right_margin = 2, .upper_margin = 2, @@ -235,7 +234,7 @@ static struct fb_videomode known_lcd_panels[] = { .name = "SP10Q010", .xres = 320, .yres = 240, - .pixclock = 7833600, + .pixclock = 127655, .left_margin= 10, .right_margin = 10, .upper_margin = 10, @@ -684,13 +683,14 @@ static void da8xx_fb_lcd_reset(void) } } -static void lcd_calc_clk_divider(struct da8xx_fb_par *par) +static inline unsigned da8xx_fb_calc_clk_divider(struct da8xx_fb_par *par, +unsigned pixclock) { - unsigned int lcd_clk, div; - - lcd_clk = clk_get_rate(par->lcdc_clk); - div = lcd_clk / par->pxl_clk; + return par->lcd_fck_rate / (PICOS2KHZ(pixclock) * 1000); +} +static inline void da8xx_fb_config_clk_divider(unsigned div) +{ /* Configure the LCD clock divisor. */ lcdc_write(LCD_CLK_DIVISOR(div) | (LCD_RASTER_MODE & 0x1), LCD_CTRL_REG); @@ -698,7 +698,14 @@ static void lcd_calc_clk_divider(struct da8xx_fb_par *par) if (lcd_revision == LCD_VERSION_2) lcdc_write(LCD_V2_DMA_CLK_EN | LCD_V2_LIDD_CLK_EN | LCD_V2_CORE_CLK_EN, LCD_CLK_ENABLE_REG); +} + +static inline void da8xx_fb_calc_config_clk_divider(struct da8xx_fb_par *par, + struct fb_videomode *mode) +{ + unsigned div = da8xx_fb_calc_clk_divider(par, mode->pixclock); + da8xx_fb_config_clk_divider(div); } static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg, @@ -709,8 +716,7 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg, da8xx_fb_lcd_reset(); - /* Calculate the divider */ - lcd_calc_clk_divider(par); + da8xx_fb_calc_config_clk_divider(par, panel); if (panel->sync & FB_SYNC_CLK_INVERT) lcdc_write((lcdc_read(LCD_RASTER_TIMING_2_REG) | @@ -973,7 +979,7 @@ static int lcd_da8xx_cpufreq_transition(struct notifier_block *nb, if (par->lcd_fck_rate != clk_get_rate(par->lcdc_clk)) { par->lcd_fck_rate = clk_get_rate(par->lcdc_clk); lcd_disable_raster(true); - lcd_calc_clk_divider(par); + da8xx_fb_calc_config_clk_divider(par, >mode); if (par->blank == FB_BLANK_UNBLANK) lcd_enable_raster(); } @@ -1199,22 +1205,6 @@ static struct fb_ops da8xx_fb_ops = { .fb_blank = cfb_blank, }; -/* Calculate and return pixel clock period in pico seconds */ -static unsigned int da8xxfb_pixel_clk_period(struct da8xx_fb_par *par) -{ - unsigned int lcd_clk, div; - unsigned int configured_pix_clk; - unsigned long long pix_clk_period_picosec = 1ULL; - - lcd_clk = clk_get_rate(par->lcdc_clk); - div = lcd_clk / par->pxl_clk; - configured_pix_clk = (lcd_clk / div); - - do_div(pix_clk_period_picosec, configured_pix_clk); - -
[PATCH v2 06/10] video: da8xx-fb: store clk rate even if !CPUFREQ
store lcd clk rate always, i.e. irrespective of whether CPUFREQ is enabled or not. This can be used to get clk rate directly instead of enquiring with clock framework with clk handle every time. Signed-off-by: Afzal Mohammed --- drivers/video/da8xx-fb.c |4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index 072074d..e858438 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c @@ -178,8 +178,8 @@ struct da8xx_fb_par { unsigned intwhich_dma_channel_done; #ifdef CONFIG_CPU_FREQ struct notifier_block freq_transition; - unsigned intlcd_fck_rate; #endif + unsigned intlcd_fck_rate; void (*panel_power_ctrl)(int); u32 pseudo_palette[16]; struct fb_videomode mode; @@ -1306,9 +1306,7 @@ static int __devinit fb_probe(struct platform_device *device) par = da8xx_fb_info->par; par->lcdc_clk = fb_clk; -#ifdef CONFIG_CPU_FREQ par->lcd_fck_rate = clk_get_rate(fb_clk); -#endif par->pxl_clk = lcdc_info->pixclock; if (fb_pdata->panel_power_ctrl) { par->panel_power_ctrl = fb_pdata->panel_power_ctrl; -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 05/10] video: da8xx-fb: store current display information
store current videomode and controller data so that reconfiguring can be done easily. Reconfiguring would be required in fb_set_par, which is going to be added soon. If these details are not stored, the work probe does to retrieve these information would have to repeated at the place of reconfiguring and modifying platform data would be necessary to handle controller data changes like bpp. Signed-off-by: Afzal Mohammed --- drivers/video/da8xx-fb.c |4 1 file changed, 4 insertions(+) diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index 79862ff..072074d 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c @@ -182,6 +182,8 @@ struct da8xx_fb_par { #endif void (*panel_power_ctrl)(int); u32 pseudo_palette[16]; + struct fb_videomode mode; + struct lcd_ctrl_config cfg; }; static struct fb_var_screeninfo da8xx_fb_var; @@ -1314,6 +1316,8 @@ static int __devinit fb_probe(struct platform_device *device) } fb_videomode_to_var(_fb_var, lcdc_info); + fb_var_to_videomode(>mode, _fb_var); + par->cfg = *lcd_cfg; if (lcd_init(par, lcd_cfg, lcdc_info) < 0) { dev_err(>dev, "lcd_init failed\n"); -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 04/10] video: da8xx-fb: remove unneeded "var" initialization
modedb helper now updates "var" information based on the detected panel, remove the unnecessary initialization. Signed-off-by: Afzal Mohammed --- drivers/video/da8xx-fb.c | 18 +- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index 0c404ed..79862ff 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c @@ -184,23 +184,7 @@ struct da8xx_fb_par { u32 pseudo_palette[16]; }; -/* Variable Screen Information */ -static struct fb_var_screeninfo da8xx_fb_var __devinitdata = { - .xoffset = 0, - .yoffset = 0, - .transp = {0, 0, 0}, - .nonstd = 0, - .activate = 0, - .height = -1, - .width = -1, - .accel_flags = 0, - .left_margin = LEFT_MARGIN, - .right_margin = RIGHT_MARGIN, - .upper_margin = UPPER_MARGIN, - .lower_margin = LOWER_MARGIN, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED -}; +static struct fb_var_screeninfo da8xx_fb_var; static struct fb_fix_screeninfo da8xx_fb_fix __devinitdata = { .id = "DA8xx FB Drv", -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 03/10] video: da8xx-fb: use modedb helper to update var
modedb structure is now used to store panel information, run modedb helper over it for initial update of "var" information instead of equating each fields. While at it, remove redundant update of bits_per_pixel. Note: pixclock is overridden with proper value using an existing code as currently modedb is having it in Hz instead of ps, this would be fixed in a later change and this overide would be removed. Signed-off-by: Afzal Mohammed --- drivers/video/da8xx-fb.c | 18 ++ 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index c8e97de..0c404ed 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c @@ -1329,6 +1329,8 @@ static int __devinit fb_probe(struct platform_device *device) par->panel_power_ctrl(1); } + fb_videomode_to_var(_fb_var, lcdc_info); + if (lcd_init(par, lcd_cfg, lcdc_info) < 0) { dev_err(>dev, "lcd_init failed\n"); ret = -EFAULT; @@ -1381,25 +1383,9 @@ static int __devinit fb_probe(struct platform_device *device) goto err_release_pl_mem; } - /* Initialize par */ - da8xx_fb_info->var.bits_per_pixel = lcd_cfg->bpp; - - da8xx_fb_var.xres = lcdc_info->xres; - da8xx_fb_var.xres_virtual = lcdc_info->xres; - - da8xx_fb_var.yres = lcdc_info->yres; - da8xx_fb_var.yres_virtual = lcdc_info->yres * LCD_NUM_BUFFERS; - da8xx_fb_var.grayscale = lcd_cfg->panel_shade == MONOCHROME ? 1 : 0; da8xx_fb_var.bits_per_pixel = lcd_cfg->bpp; - - da8xx_fb_var.hsync_len = lcdc_info->hsync_len; - da8xx_fb_var.vsync_len = lcdc_info->vsync_len; - da8xx_fb_var.right_margin = lcdc_info->right_margin; - da8xx_fb_var.left_margin = lcdc_info->left_margin; - da8xx_fb_var.lower_margin = lcdc_info->lower_margin; - da8xx_fb_var.upper_margin = lcdc_info->upper_margin; da8xx_fb_var.pixclock = da8xxfb_pixel_clk_period(par); /* Initialize fbinfo */ -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 02/10] video: da8xx-fb: simplify lcd_reset
lcd_reset function doesn't require any arguement, remove it. Signed-off-by: Afzal Mohammed --- drivers/video/da8xx-fb.c |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index 89446aa..c8e97de 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c @@ -681,7 +681,7 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green, } #undef CNVT_TOHW -static void lcd_reset(struct da8xx_fb_par *par) +static void da8xx_fb_lcd_reset(void) { /* Disable the Raster if previously Enabled */ lcd_disable_raster(false); @@ -721,7 +721,7 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg, u32 bpp; int ret = 0; - lcd_reset(par); + da8xx_fb_lcd_reset(); /* Calculate the divider */ lcd_calc_clk_divider(par); -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 01/10] video: da8xx-fb: fb_check_var enhancement
Check whether "struct fb_var_screeninfo" fields are sane, if not update it to be within allowed limits. If user sends down buggy "var" values, this will bring those within allowable limits. And fb_set_par is not supposed to change "var" values, fb_check_var has to ensure that values are proper. Signed-off-by: Afzal Mohammed --- drivers/video/da8xx-fb.c | 18 ++ 1 file changed, 18 insertions(+) diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index 46534e0..89446aa 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c @@ -888,6 +888,9 @@ static int fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { int err = 0; + struct da8xx_fb_par *par = info->par; + int bpp = var->bits_per_pixel >> 3; + unsigned long line_size = var->xres_virtual * bpp; if (var->bits_per_pixel > 16 && lcd_revision == LCD_VERSION_1) return -EINVAL; @@ -955,6 +958,21 @@ static int fb_check_var(struct fb_var_screeninfo *var, var->green.msb_right = 0; var->blue.msb_right = 0; var->transp.msb_right = 0; + + if (line_size * var->yres_virtual > par->vram_size) + var->yres_virtual = par->vram_size / line_size; + + if (var->yres > var->yres_virtual) + var->yres = var->yres_virtual; + + if (var->xres > var->xres_virtual) + var->xres = var->xres_virtual; + + if (var->xres + var->xoffset > var->xres_virtual) + var->xoffset = var->xres_virtual - var->xres; + if (var->yres + var->yoffset > var->yres_virtual) + var->yoffset = var->yres_virtual - var->yres; + return err; } -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 00/10] video: da8xx-fb: runtime timing configuration
Hi, This series makes da8xx-fb driver (device found on DaVinci and AM335x) capable of handling runtime timing configuration by adding fb_set_par. The last change adds actual fb_set_par support. Other preceeding changes makes the way clear for it as well as does certain cleanup's on the way. This has been tested on da850 evm as is. This was also tested on am335x-evm & am335x-evmsk with a series that adds DT support which follows shortly. This is based on v3.8-rc2 Regards Afzal v2: disable raster in fb_set_par properly Afzal Mohammed (10): video: da8xx-fb: fb_check_var enhancement video: da8xx-fb: simplify lcd_reset video: da8xx-fb: use modedb helper to update var video: da8xx-fb: remove unneeded "var" initialization video: da8xx-fb: store current display information video: da8xx-fb: store clk rate even if !CPUFREQ video: da8xx-fb: pix clk and clk div handling cleanup video: da8xx-fb: store struct device * video: da8xx-fb: report correct pixclock video: da8xx-fb: fb_set_par support drivers/video/da8xx-fb.c | 181 +++--- 1 file changed, 105 insertions(+), 76 deletions(-) -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] tcp: fix MSG_SENDPAGE_NOTLAST logic
From: Eric Dumazet Date: Sun, 06 Jan 2013 20:21:49 -0800 > From: Eric Dumazet > > commit 35f9c09fe9c72e (tcp: tcp_sendpages() should call tcp_push() once) > added an internal flag : MSG_SENDPAGE_NOTLAST meant to be set on all > frags but the last one for a splice() call. > > The condition used to set the flag in pipe_to_sendpage() relied on > splice() user passing the exact number of bytes present in the pipe, > or a smaller one. > > But some programs pass an arbitrary high value, and the test fails. > > The effect of this bug is a lack of tcp_push() at the end of a > splice(pipe -> socket) call, and possibly very slow or erratic TCP > sessions. > > We should both test sd->total_len and fact that another fragment > is in the pipe (pipe->nrbufs > 1) > > Many thanks to Willy for providing very clear bug report, bisection > and test programs. > > Reported-by: Willy Tarreau > Bisected-by: Willy Tarreau > Tested-by: Willy Tarreau > Signed-off-by: Eric Dumazet Applied and queued up for -stable, thanks everyone. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH V3 2/2] vhost: handle polling errors
On 01/06/2013 09:22 PM, Michael S. Tsirkin wrote: > On Sun, Jan 06, 2013 at 03:18:38PM +0800, Jason Wang wrote: >> Polling errors were ignored by vhost/vhost_net, this may lead to crash when >> trying to remove vhost from waitqueue when after the polling is failed. Solve >> this problem by: >> >> - checking the poll->wqh before trying to remove from waitqueue >> - report an error when poll() returns a POLLERR in vhost_start_poll() >> - report an error when vhost_start_poll() fails in >> vhost_vring_ioctl()/vhost_net_set_backend() which is used to notify the >> failure to userspace. >> - report an error in the data path in vhost_net when meet polling errors. >> >> After those changes, we can safely drop the tx polling state in vhost_net >> since >> it was replaced by the checking of poll->wqh. >> >> Signed-off-by: Jason Wang >> --- >> drivers/vhost/net.c | 74 >> >> drivers/vhost/vhost.c | 31 +++- >> drivers/vhost/vhost.h |2 +- >> 3 files changed, 49 insertions(+), 58 deletions(-) >> >> diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c >> index d10ad6f..125c1e5 100644 >> --- a/drivers/vhost/net.c >> +++ b/drivers/vhost/net.c >> @@ -64,20 +64,10 @@ enum { >> VHOST_NET_VQ_MAX = 2, >> }; >> >> -enum vhost_net_poll_state { >> -VHOST_NET_POLL_DISABLED = 0, >> -VHOST_NET_POLL_STARTED = 1, >> -VHOST_NET_POLL_STOPPED = 2, >> -}; >> - >> struct vhost_net { >> struct vhost_dev dev; >> struct vhost_virtqueue vqs[VHOST_NET_VQ_MAX]; >> struct vhost_poll poll[VHOST_NET_VQ_MAX]; >> -/* Tells us whether we are polling a socket for TX. >> - * We only do this when socket buffer fills up. >> - * Protected by tx vq lock. */ >> -enum vhost_net_poll_state tx_poll_state; >> /* Number of TX recently submitted. >> * Protected by tx vq lock. */ >> unsigned tx_packets; >> @@ -155,24 +145,6 @@ static void copy_iovec_hdr(const struct iovec *from, >> struct iovec *to, >> } >> } >> >> -/* Caller must have TX VQ lock */ >> -static void tx_poll_stop(struct vhost_net *net) >> -{ >> -if (likely(net->tx_poll_state != VHOST_NET_POLL_STARTED)) >> -return; >> -vhost_poll_stop(net->poll + VHOST_NET_VQ_TX); >> -net->tx_poll_state = VHOST_NET_POLL_STOPPED; >> -} >> - >> -/* Caller must have TX VQ lock */ >> -static void tx_poll_start(struct vhost_net *net, struct socket *sock) >> -{ >> -if (unlikely(net->tx_poll_state != VHOST_NET_POLL_STOPPED)) >> -return; >> -vhost_poll_start(net->poll + VHOST_NET_VQ_TX, sock->file); >> -net->tx_poll_state = VHOST_NET_POLL_STARTED; >> -} >> - >> /* In case of DMA done not in order in lower device driver for some reason. >> * upend_idx is used to track end of used idx, done_idx is used to track >> head >> * of used idx. Once lower device DMA done contiguously, we will signal KVM >> @@ -227,6 +199,7 @@ static void vhost_zerocopy_callback(struct ubuf_info >> *ubuf, bool success) >> static void handle_tx(struct vhost_net *net) >> { >> struct vhost_virtqueue *vq = >dev.vqs[VHOST_NET_VQ_TX]; >> +struct vhost_poll *poll = net->poll + VHOST_NET_VQ_TX; >> unsigned out, in, s; >> int head; >> struct msghdr msg = { >> @@ -252,7 +225,8 @@ static void handle_tx(struct vhost_net *net) >> wmem = atomic_read(>sk->sk_wmem_alloc); >> if (wmem >= sock->sk->sk_sndbuf) { >> mutex_lock(>mutex); >> -tx_poll_start(net, sock); >> +if (vhost_poll_start(poll, sock->file)) >> +vq_err(vq, "Fail to start TX polling\n"); > s/Fail/Failed/ > > A question though: how can this happen? Could you clarify please? > Maybe we can find a way to prevent this error? Two conditions I think this can happen: 1) a buggy userspace disable a queue through TUNSETQUEUE 2) the net device were gone For 1, looks like we can delay the disabling until the refcnt goes to zero. For 2 may needs more changes. Not sure it's worth to do this work, maybe a warning is enough just like other failure. > >> mutex_unlock(>mutex); >> return; >> } >> @@ -261,7 +235,7 @@ static void handle_tx(struct vhost_net *net) >> vhost_disable_notify(>dev, vq); >> >> if (wmem < sock->sk->sk_sndbuf / 2) >> -tx_poll_stop(net); >> +vhost_poll_stop(poll); >> hdr_size = vq->vhost_hlen; >> zcopy = vq->ubufs; >> >> @@ -283,8 +257,10 @@ static void handle_tx(struct vhost_net *net) >> >> wmem = atomic_read(>sk->sk_wmem_alloc); >> if (wmem >= sock->sk->sk_sndbuf * 3 / 4) { >> -tx_poll_start(net, sock); >> -set_bit(SOCK_ASYNC_NOSPACE, >flags); >> +if (vhost_poll_start(poll, sock->file)) >> +vq_err(vq, "Fail to start TX >> polling\n"); >> +
Re: [PATCH] block: delete super ancient PC-XT driver for 1980's hardware
On 01/04/2013 07:27 PM, Paul Gortmaker wrote: This driver was for the 8 bit ISA cards that were installed in the PC-XT machines of 1980 vintage. They supported the dual ribbon cable MFM drives of 10-20MB capacity, and ran at a 3:1 interleave, giving performance on the order of 128kB/s. By the introduction of the PC-AT (286) these controllers were already scrapped in favour of 16 bit controllers with some onboard RAM that could support a 1:1 interleave. The git history doesn't show any evidence of runtime fixes that would reflect active usage; instead just the usual tree-wide API type changes/cleanups. Going back to in-source changelogs, the last "runtime" fix that is evident is something I did over a dozen years ago[1] -- and even back then, the hardware was long since unavailable, so that ancient fix was also not runtime tested. The time is long overdue for this to get flushed, so lets get rid of it before anyone wastes more time doing builds and sparse checks etc. on long since dead code. Although this hardware is obviously long obsolete, it's conceivable that someone could still drag out an old MFM/RLL controller and run it on a non-completely-ancient PC with ISA slots in order to recover data from an old drive or something. Given that the code doesn't have wide-ranging effects beyond a couple of files, I'd lean towards keeping it unless there's some reason to believe it's hopelessly broken. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] tcp: fix MSG_SENDPAGE_NOTLAST logic
From: Eric Dumazet commit 35f9c09fe9c72e (tcp: tcp_sendpages() should call tcp_push() once) added an internal flag : MSG_SENDPAGE_NOTLAST meant to be set on all frags but the last one for a splice() call. The condition used to set the flag in pipe_to_sendpage() relied on splice() user passing the exact number of bytes present in the pipe, or a smaller one. But some programs pass an arbitrary high value, and the test fails. The effect of this bug is a lack of tcp_push() at the end of a splice(pipe -> socket) call, and possibly very slow or erratic TCP sessions. We should both test sd->total_len and fact that another fragment is in the pipe (pipe->nrbufs > 1) Many thanks to Willy for providing very clear bug report, bisection and test programs. Reported-by: Willy Tarreau Bisected-by: Willy Tarreau Tested-by: Willy Tarreau Signed-off-by: Eric Dumazet --- fs/splice.c |4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/splice.c b/fs/splice.c index 8890604..6909d89 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -696,8 +696,10 @@ static int pipe_to_sendpage(struct pipe_inode_info *pipe, return -EINVAL; more = (sd->flags & SPLICE_F_MORE) ? MSG_MORE : 0; - if (sd->len < sd->total_len) + + if (sd->len < sd->total_len && pipe->nrbufs > 1) more |= MSG_SENDPAGE_NOTLAST; + return file->f_op->sendpage(file, buf->page, buf->offset, sd->len, , more); } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: PEBS (in perf) stopped working from 3.6 -> 3.7
On 1/4/13 6:05 PM, Steinar H. Gunderson wrote: On Fri, Jan 04, 2013 at 05:16:27PM -0700, David Ahern wrote: Known problem. Pick one of: update perf to 3.7, add H to the command (-e cycles:ppH) or apply this patch: https://lkml.org/lkml/2012/12/28/384 I spoke too soon. This works for cycles, but not for branch-misses: pannekake:~> sudo perf record -e branch-misses:ppH -a Error: sys_perf_event_open() syscall returned with 95 (Operation not supported) for event branch-misses:ppH. /bin/dmesg may provide additional information. No hardware sampling interrupt available. No APIC? If so then you can boot the kernel with the "lapic" boot parameter to force-enable it. Why would the two be different? I will make a guess that is processor dependent. On an E5540 with 3.4.11-1.fc16.x86_64, 3.6.10-2.fc16.x86_64, and 3.8 I get the same failure message. But on a E5620, it works fine with 3.4 and 3.7 (no intermediate kernels on that box). David -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2] mm: memblock: fix wrong memmove size in memblock_merge_regions()
The memmove span covers from (next+1) to the end of the array, and the index of next is (i+1), so the index of (next+1) is (i+2). So the size of remaining array elements is (type->cnt - (i + 2)). Cc: Tejun Heo Reviewed-by: Wanpeng Li Signed-off-by: Lin Feng --- ChangeLog v1->v2: - Add a comment pointed out by Tejun. --- mm/memblock.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mm/memblock.c b/mm/memblock.c index 6259055..88adc8a 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -314,7 +314,8 @@ static void __init_memblock memblock_merge_regions(struct memblock_type *type) } this->size += next->size; - memmove(next, next + 1, (type->cnt - (i + 1)) * sizeof(*next)); + /* move forward from next + 1, index of which is i + 2 */ + memmove(next, next + 1, (type->cnt - (i + 2)) * sizeof(*next)); type->cnt--; } } -- 1.7.11.7 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: oops in copy_page_rep()
On Sun, 6 Jan 2013, Dave Jones wrote: > > investigating the huge page theory a little further I'm a bit confused. > The kernel on that machine has THP enabled, and the cpu supports it (an old > amd64), but.. > > $ cat /sys/kernel/mm/hugepages/hugepages-2048kB/* > 0 > 0 > 0 > 0 > 0 > 0 > > I was expecting at least one of those to be non-zero. > > /sys/kernel/mm/transparent_hugepage/khugepaged/full_scans and pages_collapsed > are both non-zero, so it's been busy doing _something_. > > Is this expected behaviour ? Yes. /sys/kernel/mm/hugepages/ is all about those dusty old opaque hugepages you might have got from fs/hugetlbfs and mm/hugetlb.c; whereas the splitting issue we suspect is peculiar to the dazzling new transparent hugepages you get from mm/huge_memory.c. Hugh -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
linux-next: Tree for Jan 7
Hi all, Changes since 20130104: Undropped tree: pekey The slave-dma tree gained a build failure so I used the version from next-20130104. The pekey tree lost its build failure. I have created today's linux-next tree at git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git (patches at http://www.kernel.org/pub/linux/kernel/next/ ). If you are tracking the linux-next tree using git, you should not use "git pull" to do so as that will try to merge the new linux-next release with the old one. You should use "git fetch" as mentioned in the FAQ on the wiki (see below). You can see which trees have been included by looking in the Next/Trees file in the source. There are also quilt-import.log and merge.log files in the Next directory. Between each merge, the tree was built with a ppc64_defconfig for powerpc and an allmodconfig for x86_64. After the final fixups (if any), it is also built with powerpc allnoconfig (32 and 64 bit), ppc44x_defconfig and allyesconfig (minus CONFIG_PROFILE_ALL_BRANCHES - this fails its final link) and i386, sparc, sparc64 and arm defconfig. These builds also have CONFIG_ENABLE_WARN_DEPRECATED, CONFIG_ENABLE_MUST_CHECK and CONFIG_DEBUG_INFO disabled when necessary. Below is a summary of the state of the merge. We are up to 214 trees (counting Linus' and 28 trees of patches pending for Linus' tree), more are welcome (even if they are currently empty). Thanks to those who have contributed, and to those who haven't, please do. Status of my local build tests will be at http://kisskb.ellerman.id.au/linux-next . If maintainers want to give advice about cross compilers/configs that work, we are always open to add more builds. Thanks to Randy Dunlap for doing many randconfig builds. And to Paul Gortmaker for triage and bug fixes. There is a wiki covering stuff to do with linux-next at http://linux.f-seidel.de/linux-next/pmwiki/ . Thanks to Frank Seidel. -- Cheers, Stephen Rothwells...@canb.auug.org.au $ git checkout master $ git reset --hard stable Merging origin/master (5f243b9 Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/cmarinas/linux-aarch64) Merging fixes/master (3b095f2 disable the SB105X driver) Merging kbuild-current/rc-fixes (bad9955 menuconfig: Replace CIRCLEQ by list_head-style lists.) Merging arm-current/fixes (5ced33b ARM: 7611/1: VIC: fix bug in VIC irqdomain code) Merging m68k-current/for-linus (e7e29b4 m68k: Wire up finit_module) Merging powerpc-merge/merge (e6449c9 powerpc: Add missing NULL terminator to avoid boot panic on PPC40x) Merging sparc/master (4e4d78f sparc: Hook up finit_module syscall.) Merging net/master (3b09adc ip-sysctl: fix spelling errors) Merging sound-current/for-linus (dc30a43 sound: oss/pas2: Fix possible access out of array) Merging pci-current/for-linus (812089e PCI: Reduce Ricoh 0xe822 SD card reader base clock frequency to 50MHz) Merging wireless/master (2be7d22 wireless: add new wil6210 802.11ad 60GHz driver) Merging driver-core.current/driver-core-linus (4956964 Merge tag 'driver-core-3.8-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core) Merging tty.current/tty-linus (d1c3ed6 Linux 3.8-rc2) Merging usb.current/usb-linus (d1c3ed6 Linux 3.8-rc2) Merging staging.current/staging-linus (d1c3ed6 Linux 3.8-rc2) Merging char-misc.current/char-misc-linus (d1c3ed6 Linux 3.8-rc2) Merging input-current/for-linus (bec7a4b Input: lm8323 - fix checking PWM interrupt status) Merging md-current/for-linus (a9add5d md/raid5: add blktrace calls) Merging audit-current/for-linus (c158a35 audit: no leading space in audit_log_d_path prefix) Merging crypto-current/master (a2c0911 crypto: caam - Updated SEC-4.0 device tree binding for ERA information.) Merging ide/master (9974e43 ide: fix generic_ide_suspend/resume Oops) Merging dwmw2/master (084a0ec x86: add CONFIG_X86_MOVBE option) CONFLICT (content): Merge conflict in arch/x86/Kconfig Merging sh-current/sh-fixes-for-linus (4403310 SH: Convert out[bwl] macros to inline functions) Merging irqdomain-current/irqdomain/merge (a0d271c Linux 3.6) Merging devicetree-current/devicetree/merge (ab28698 of: define struct device in of_platform.h if !OF_DEVICE and !OF_ADDRESS) Merging spi-current/spi/merge (d3601e5 spi/sh-hspi: fix return value check in hspi_probe().) Merging gpio-current/gpio/merge (bc1008c gpio/mvebu-gpio: Make mvebu-gpio depend on OF_CONFIG) Merging rr-fixes/fixes (52441fa module: prevent warning when finit_module a 0 sized file) Merging asm-generic/master (fb9de7e xtensa: Use generic asm/mmu.h for nommu) Merging arm/for-next (5ced33b ARM: 7611/1: VIC: fix bug in VIC irqdomain code) Merging arm-perf/for-next/perf (3d70f8c Linux 3.7-rc4) Merging davinci/davinci-next (fe0d422 Linux 3.0-rc6) Merging xilinx/arm-next (a3607ea serial: xilinx_uartps: fix return value check in xuartps_probe()) Merging arm64/upstream (25c92a3
Re: [PATCH] drivers/net/wireless/mwl8k.c: avoid use-after-free
On Sun, Jan 06, 2013 at 10:02:14PM -0500, Nickolai Zeldovich wrote: > > Good catch, but the patch would be better titled "mwl8k.c: avoid > > having a working driver", as the station_id return code _is_ needed > > by the caller in case of success. > > I'm not quite sure what you mean -- is there something subtle going on > here? I believe my patch preserves the semantics of the original > code: it returns the value of p->station_id if mwl8k_post_cmd() > returned 0, but it just does so by reading p->station_id first before > calling kfree(cmd). Oops! You're right. Sorry about that. /me goes to order some crow for dinner -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] drivers/net/wireless/mwl8k.c: avoid use-after-free
Hi Lennert, On Mon, Jan 7, 2013 at 1:48 PM, Lennert Buytenhek wrote: > On Sun, Jan 06, 2013 at 08:27:22PM -0500, Nickolai Zeldovich wrote: > >> Do not dereference p->station_id after kfree(cmd) because p >> points into the cmd data structure. > > Good catch, but the patch would be better titled "mwl8k.c: avoid > having a working driver", as the station_id return code _is_ needed > by the caller in case of success. Are you sure? >> diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c >> index f221b95..83564d3 100644 >> --- a/drivers/net/wireless/mwl8k.c >> +++ b/drivers/net/wireless/mwl8k.c >> @@ -4250,9 +4250,11 @@ static int mwl8k_cmd_update_stadb_add(struct >> ieee80211_hw *hw, >> p->amsdu_enabled = 0; >> >> rc = mwl8k_post_cmd(hw, >header); >> + if (!rc) >> + rc = p->station_id; >> kfree(cmd); >> >> - return rc ? rc : p->station_id; If I'm reading this right, the removed line is equivalent to: if( rc ) return rc; else return p->station_id; which is equivalent to: if( !rc ) rc = p->station_id; return rc; Thanks, -- Julian Calaby Email: julian.cal...@gmail.com Profile: http://www.google.com/profiles/julian.calaby/ .Plan: http://sites.google.com/site/juliancalaby/ -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] drivers/net/wireless/mwl8k.c: avoid use-after-free
On Sun, Jan 6, 2013 at 9:48 PM, Lennert Buytenhek wrote: > Good catch, but the patch would be better titled "mwl8k.c: avoid > having a working driver", as the station_id return code _is_ needed > by the caller in case of success. I'm not quite sure what you mean -- is there something subtle going on here? I believe my patch preserves the semantics of the original code: it returns the value of p->station_id if mwl8k_post_cmd() returned 0, but it just does so by reading p->station_id first before calling kfree(cmd). Nickolai. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] drivers/net/wireless/mwl8k.c: avoid use-after-free
On Sun, Jan 06, 2013 at 08:27:22PM -0500, Nickolai Zeldovich wrote: > Do not dereference p->station_id after kfree(cmd) because p > points into the cmd data structure. Good catch, but the patch would be better titled "mwl8k.c: avoid having a working driver", as the station_id return code _is_ needed by the caller in case of success. > Signed-off-by: Nickolai Zeldovich > --- > drivers/net/wireless/mwl8k.c |4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > > diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c > index f221b95..83564d3 100644 > --- a/drivers/net/wireless/mwl8k.c > +++ b/drivers/net/wireless/mwl8k.c > @@ -4250,9 +4250,11 @@ static int mwl8k_cmd_update_stadb_add(struct > ieee80211_hw *hw, > p->amsdu_enabled = 0; > > rc = mwl8k_post_cmd(hw, >header); > + if (!rc) > + rc = p->station_id; > kfree(cmd); > > - return rc ? rc : p->station_id; > + return rc; > } > > static int mwl8k_cmd_update_stadb_del(struct ieee80211_hw *hw, > -- > 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] block: Remove judgement for rq_mergeable(rq) in func elv_rqhash_find.
Because only mergeable rq can add rqhash.So it does not make sense to judge rq_mergeable(rq) in func elv_rqhash_find. Signed-off-by: Jianpeng Ma --- block/elevator.c |5 - 1 file changed, 5 deletions(-) diff --git a/block/elevator.c b/block/elevator.c index 9edba1b..d5901a4 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -273,11 +273,6 @@ static struct request *elv_rqhash_find(struct request_queue *q, sector_t offset) hlist_for_each_entry_safe(rq, entry, next, hash_list, hash) { BUG_ON(!ELV_ON_HASH(rq)); - if (unlikely(!rq_mergeable(rq))) { - __elv_rqhash_del(rq); - continue; - } - if (rq_hash_key(rq) == offset) return rq; } -- 1.7.9.5 N�Р骒r��yb�X�肚�v�^�)藓{.n�+�伐�{��赙zXФ�≤�}��财�z�:+v�����赙zZ+��+zf"�h���~i���z��wア�?�ㄨ��&�)撷f��^j谦y�m��@A�a囤� 0鹅h���i
[PATCH] regulator: lp8755: Remove enum bucks
We already have enum lp8755_bucks in lp8755.h, so it looks pointless adding enum bucks in lp8755.c. Signed-off-by: Axel Lin --- drivers/regulator/lp8755.c | 50 +++- 1 file changed, 17 insertions(+), 33 deletions(-) diff --git a/drivers/regulator/lp8755.c b/drivers/regulator/lp8755.c index dbc4d12..29a1f81 100644 --- a/drivers/regulator/lp8755.c +++ b/drivers/regulator/lp8755.c @@ -37,15 +37,6 @@ #define LP8755_BUCK_LINEAR_OUT_MAX 0x76 #define LP8755_BUCK_VOUT_M 0x7F -enum bucks { - BUCK0 = 0, - BUCK1, - BUCK2, - BUCK3, - BUCK4, - BUCK5, -}; - struct lp8755_mphase { int nreg; int buck_num[LP8755_BUCK_MAX]; @@ -262,33 +253,26 @@ static struct regulator_ops lp8755_buck_ops = { } static struct regulator_init_data lp8755_reg_default[LP8755_BUCK_MAX] = { - [BUCK0] = lp8755_buck_init(0), - [BUCK1] = lp8755_buck_init(1), - [BUCK2] = lp8755_buck_init(2), - [BUCK3] = lp8755_buck_init(3), - [BUCK4] = lp8755_buck_init(4), - [BUCK5] = lp8755_buck_init(5), + [LP8755_BUCK0] = lp8755_buck_init(0), + [LP8755_BUCK1] = lp8755_buck_init(1), + [LP8755_BUCK2] = lp8755_buck_init(2), + [LP8755_BUCK3] = lp8755_buck_init(3), + [LP8755_BUCK4] = lp8755_buck_init(4), + [LP8755_BUCK5] = lp8755_buck_init(5), }; static const struct lp8755_mphase mphase_buck[MPHASE_CONF_MAX] = { - {3, {BUCK0, BUCK3, BUCK5} -}, - {6, {BUCK0, BUCK1, BUCK2, BUCK3, BUCK4, BUCK5} -}, - {5, {BUCK0, BUCK2, BUCK3, BUCK4, BUCK5} -}, - {4, {BUCK0, BUCK3, BUCK4, BUCK5} -}, - {3, {BUCK0, BUCK4, BUCK5} -}, - {2, {BUCK0, BUCK5} -}, - {1, {BUCK0} -}, - {2, {BUCK0, BUCK3} -}, - {4, {BUCK0, BUCK2, BUCK3, BUCK5} -}, + { 3, { LP8755_BUCK0, LP8755_BUCK3, LP8755_BUCK5 } }, + { 6, { LP8755_BUCK0, LP8755_BUCK1, LP8755_BUCK2, LP8755_BUCK3, + LP8755_BUCK4, LP8755_BUCK5 } }, + { 5, { LP8755_BUCK0, LP8755_BUCK2, LP8755_BUCK3, LP8755_BUCK4, + LP8755_BUCK5} }, + { 4, { LP8755_BUCK0, LP8755_BUCK3, LP8755_BUCK4, LP8755_BUCK5} }, + { 3, { LP8755_BUCK0, LP8755_BUCK4, LP8755_BUCK5} }, + { 2, { LP8755_BUCK0, LP8755_BUCK5} }, + { 1, { LP8755_BUCK0} }, + { 2, { LP8755_BUCK0, LP8755_BUCK3} }, + { 4, { LP8755_BUCK0, LP8755_BUCK2, LP8755_BUCK3, LP8755_BUCK5} }, }; static int lp8755_init_data(struct lp8755_chip *pchip) -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [v3 PATCH 06/12] spi/atmel_spi: add dmaengine support
On Mon, 2013-01-07 at 09:50 +0800, Wenyou Yang wrote: > From: Nicolas Ferre [] > diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c [] > +static inline bool atmel_spi_use_dma(struct atmel_spi *as, > + struct spi_transfer *xfer) > +{ > + if ((as->use_dma) && (xfer->len >= DMA_MIN_BYTES)) > + return true; > + else > + return false; > +} Same unnecessary form. return as->use_dma && xfer->len >= DMA_MIN_BYTES; > +static inline bool atmel_spi_use_pdc(struct atmel_spi *as) > +{ > + if (as->use_pdc) > + return true; > + else > + return false; > +} Does this function really need to exist at all? -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2] media: cx18, ivtv: eliminate unnecessary array index checks
Nickolai Zeldovich wrote: >The idx values passed to cx18_i2c_register() and ivtv_i2c_register() >by cx18_init_subdevs() and ivtv_load_and_init_modules() respectively >are always in-range, based on how the hw_all bitmask is populated. >Previously, the checks were already ineffective because arrays were >being dereferenced using the index before the check. > >Signed-off-by: Nickolai Zeldovich >--- >Thanks to Andy Walls for suggesting that instead of moving the checks >before array dereference, a better fix is to remove the checks >altogether, >since they are superfluous. > > drivers/media/pci/cx18/cx18-i2c.c |3 --- > drivers/media/pci/ivtv/ivtv-i2c.c |2 -- > 2 files changed, 5 deletions(-) > >diff --git a/drivers/media/pci/cx18/cx18-i2c.c >b/drivers/media/pci/cx18/cx18-i2c.c >index 4908eb7..ccb1d15 100644 >--- a/drivers/media/pci/cx18/cx18-i2c.c >+++ b/drivers/media/pci/cx18/cx18-i2c.c >@@ -116,9 +116,6 @@ int cx18_i2c_register(struct cx18 *cx, unsigned >idx) > const char *type = hw_devicenames[idx]; > u32 hw = 1 << idx; > >- if (idx >= ARRAY_SIZE(hw_addrs)) >- return -1; >- > if (hw == CX18_HW_TUNER) { > /* special tuner group handling */ > sd = v4l2_i2c_new_subdev(>v4l2_dev, >diff --git a/drivers/media/pci/ivtv/ivtv-i2c.c >b/drivers/media/pci/ivtv/ivtv-i2c.c >index 46e262b..bc984af 100644 >--- a/drivers/media/pci/ivtv/ivtv-i2c.c >+++ b/drivers/media/pci/ivtv/ivtv-i2c.c >@@ -267,8 +267,6 @@ int ivtv_i2c_register(struct ivtv *itv, unsigned >idx) > const char *type = hw_devicenames[idx]; > u32 hw = 1 << idx; > >- if (idx >= ARRAY_SIZE(hw_addrs)) >- return -1; > if (hw == IVTV_HW_TUNER) { > /* special tuner handling */ > sd = v4l2_i2c_new_subdev(>v4l2_dev, adap, type, 0, >-- >1.7.10.4 Acked-by: Andy Walls -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [v3 PATCH 05/12] spi/atmel_spi: update the dt support
On Mon, 2013-01-07 at 09:50 +0800, Wenyou Yang wrote: > To meet the different spi IP version of atmel SoC, > add more compatible "atmel,at91rm9200-spi", "atmel,at91sam9260-spi" > "atmel,at91sam9g45-spi", "atmel,at91sam9x5-spi" with different > config and devtype. trivial comment: > diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c [] > @@ -230,11 +302,15 @@ struct atmel_spi_device { > * register, but I haven't checked that it exists on all chips, and > * this is cheaper anyway. > */ > -static bool atmel_spi_is_v2(void) > +static bool atmel_spi_is_v2(struct atmel_spi *as) There's a comment that needs updating above this now > { > - return !cpu_is_at91rm9200(); > + if (as->pdata->version == 2) > + return true; > + else > + return false; return as->pdata->version == 2; is rather more readable to me -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT] Fix for regression in integrity subsystem
Please pull for 3.8. Description from Tetsuo: Commit fdf90729 "ima: support new kernel module syscall" by error modified init_module() to return INTEGRITY_UNKNOWN (which is 4) to user space if kernel was built with CONFIG_IMA_APPRAISE=y. As a result, user space can no longer load kernel modules using init_module(). This commit fixes this regression. The following changes since commit 5f243b9b46a22e5790dbbc36f574c2417af49a41: Linus Torvalds (1): Merge tag 'arm64-fixes' of git://git.kernel.org/.../cmarinas/linux-aarch64 are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security.git for-linus James Morris (1): Merge branch 'for-Linus' of git://git.kernel.org/.../zohar/linux-integrity into for-linus Mimi Zohar (1): ima: fallback to MODULE_SIG_ENFORCE for existing kernel module syscall security/integrity/ima/ima.h|1 + security/integrity/ima/ima_main.c | 12 security/integrity/ima/ima_policy.c |3 ++- 3 files changed, 11 insertions(+), 5 deletions(-) --- commit a7f2a366f62319dfebf8d4dfe8b211f631c78457 Author: Mimi Zohar Date: Fri Dec 21 08:34:21 2012 -0500 ima: fallback to MODULE_SIG_ENFORCE for existing kernel module syscall The new kernel module syscall appraises kernel modules based on policy. If the IMA policy requires kernel module checking, fallback to module signature enforcing for the existing syscall. Without CONFIG_MODULE_SIG_FORCE enabled, the kernel module's integrity is unknown, return -EACCES. Changelog v1: - Fix ima_module_check() return result (Tetsuo Handa) Reported-by: Tetsuo Handa Reviewed-by: Tetsuo Handa Signed-off-by: Mimi Zohar diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 3b2adb7..079a85d 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -139,6 +139,7 @@ void ima_delete_rules(void); /* Appraise integrity measurements */ #define IMA_APPRAISE_ENFORCE 0x01 #define IMA_APPRAISE_FIX 0x02 +#define IMA_APPRAISE_MODULES 0x04 #ifdef CONFIG_IMA_APPRAISE int ima_appraise_measurement(struct integrity_iint_cache *iint, diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 45de18e..dba965d 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -291,11 +291,15 @@ EXPORT_SYMBOL_GPL(ima_file_check); */ int ima_module_check(struct file *file) { - int rc; + int rc = 0; - if (!file) - rc = INTEGRITY_UNKNOWN; - else + if (!file) { + if (ima_appraise & IMA_APPRAISE_MODULES) { +#ifndef CONFIG_MODULE_SIG_FORCE + rc = -EACCES; /* INTEGRITY_UNKNOWN */ +#endif + } + } else rc = process_measurement(file, file->f_dentry->d_name.name, MAY_EXEC, MODULE_CHECK); return (ima_appraise & IMA_APPRAISE_ENFORCE) ? rc : 0; diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index af7d182..479fca9 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -523,7 +523,8 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) } if (!result && (entry->action == UNKNOWN)) result = -EINVAL; - + else if (entry->func == MODULE_CHECK) + ima_appraise |= IMA_APPRAISE_MODULES; audit_log_format(ab, "res=%d", !result); audit_log_end(ab); return result; -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 01/17] ARM: shmobile: fix memory size for kota2_defconfig
On Fri, Nov 30, 2012 at 02:10:47PM -0800, Olof Johansson wrote: > Hi, > > On Thu, Oct 4, 2012 at 1:58 AM, Simon Horman wrote: > > On Thu, Oct 04, 2012 at 08:34:54AM +, Arnd Bergmann wrote: > >> On Wednesday 03 October 2012, Simon Horman wrote: > >> > I looked through my fines and found a config that I believe > >> > worked with a derivative of 2.6.35.7. > >> > > >> > It has CONFIG_MEMORY_SIZE=0x1e80. > >> > > >> > So what I suspect has happened is that an extra zero has crept into > >> > arch/arm/configs/kota2_defconfig and the intended value is: > >> > > >> > CONFIG_MEMORY_SIZE=0x1e00 > >> > > >> > Unfortunately I do not have access to a board to test this, > >> > nor am I aware of anyone who does. > >> > >> Ok, I'll drop this patch for now then, so we keep the warning around > >> to remind us of the problem. > > > > Thanks. I have subsequently located a Kota2 board, > > however it may be a little while before I get my hands on it. > > Gentle ping. I just came across this warning again so I figured I'd check. Hi, I have my kota2 board up and running now and I believe that the correct value is 0x1e00. I will apply a patch to my defconfigs branch accordingly. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[v3 PATCH 03/12] spi/atmel_spi: status information passed through controller data
From: Nicolas Ferre The status of transfer is stored in controller data structure so that it can be used not only by atmel_spi_msg_done() function. This will be useful for upcoming dmaengine enabled driver. Signed-off-by: Nicolas Ferre Cc: grant.lik...@secretlab.ca Cc: spi-devel-gene...@lists.sourceforge.net --- drivers/spi/spi-atmel.c | 13 - 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index 9782206..687075e 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -202,6 +202,7 @@ struct atmel_spi { unsigned long current_remaining_bytes; struct spi_transfer *next_transfer; unsigned long next_remaining_bytes; + int done_status; void*buffer; dma_addr_t buffer_dma; @@ -545,15 +546,15 @@ static void atmel_spi_dma_unmap_xfer(struct spi_master *master, static void atmel_spi_msg_done(struct spi_master *master, struct atmel_spi *as, - struct spi_message *msg, int status, int stay) + struct spi_message *msg, int stay) { - if (!stay || status < 0) + if (!stay || as->done_status < 0) cs_deactivate(as, msg->spi); else as->stay = msg->spi; list_del(>queue); - msg->status = status; + msg->status = as->done_status; dev_dbg(master->dev.parent, "xfer complete: %u bytes transferred\n", @@ -565,6 +566,7 @@ atmel_spi_msg_done(struct spi_master *master, struct atmel_spi *as, as->current_transfer = NULL; as->next_transfer = NULL; + as->done_status = 0; /* continue if needed */ if (list_empty(>queue) || as->stopping) @@ -642,7 +644,8 @@ atmel_spi_interrupt(int irq, void *dev_id) /* Clear any overrun happening while cleaning up */ spi_readl(as, SR); - atmel_spi_msg_done(master, as, msg, -EIO, 0); + as->done_status = -EIO; + atmel_spi_msg_done(master, as, msg, 0); } else if (pending & (SPI_BIT(RXBUFF) | SPI_BIT(ENDRX))) { ret = IRQ_HANDLED; @@ -660,7 +663,7 @@ atmel_spi_interrupt(int irq, void *dev_id) if (atmel_spi_xfer_is_last(msg, xfer)) { /* report completed message */ - atmel_spi_msg_done(master, as, msg, 0, + atmel_spi_msg_done(master, as, msg, xfer->cs_change); } else { if (xfer->cs_change) { -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[v3 PATCH 09/12] spi/atmel_spi: correct 16 bits transfer with DMA
From: Richard Genoud Signed-off-by: Richard Genoud Cc: grant.lik...@secretlab.ca Cc: spi-devel-gene...@lists.sourceforge.net --- drivers/spi/spi-atmel.c | 17 +++-- 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index 5abb276..dd070cd 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -466,12 +466,18 @@ static inline int atmel_spi_xfer_can_be_chained(struct spi_transfer *xfer) } static int atmel_spi_dma_slave_config(struct atmel_spi *as, - struct dma_slave_config *slave_config) + struct dma_slave_config *slave_config, + u8 bits_per_word) { int err = 0; - slave_config->dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; - slave_config->src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; + if (bits_per_word > 8) { + slave_config->dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; + slave_config->src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; + } else { + slave_config->dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; + slave_config->src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; + } slave_config->dst_addr = (dma_addr_t)as->phybase + SPI_TDR; slave_config->src_addr = (dma_addr_t)as->phybase + SPI_RDR; @@ -533,7 +539,7 @@ static int __devinit atmel_spi_configure_dma(struct atmel_spi *as) goto error; } - err = atmel_spi_dma_slave_config(as, _config); + err = atmel_spi_dma_slave_config(as, _config, 8); if (err) goto error; @@ -667,10 +673,9 @@ static int atmel_spi_next_xfer_dma_submit(struct spi_master *master, *plen = len; - if (atmel_spi_dma_slave_config(as, _config)) + if (atmel_spi_dma_slave_config(as, _config, 8)) goto err_exit; - /* Send both scatterlists */ rxdesc = rxchan->device->device_prep_slave_sg(rxchan, >dma.sgrx, -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[v3 PATCH 01/12] spi/atmel_spi: add physical base address
From: Nicolas Ferre Needed for future use with dmaengine enabled driver. Signed-off-by: Nicolas Ferre Cc: grant.lik...@secretlab.ca Cc: spi-devel-gene...@lists.sourceforge.net --- drivers/spi/spi-atmel.c |2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index ab34497..4516839 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -189,6 +189,7 @@ struct atmel_spi { spinlock_t lock; + resource_size_t phybase; void __iomem*regs; int irq; struct clk *clk; @@ -967,6 +968,7 @@ static int atmel_spi_probe(struct platform_device *pdev) as->regs = ioremap(regs->start, resource_size(regs)); if (!as->regs) goto out_free_buffer; + as->phybase = regs->start; as->irq = irq; as->clk = clk; -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[v3 PATCH 08/12] spi/atmel_spi: correct 16 bits transfers using PIO
From: Richard Genoud Signed-off-by: Richard Genoud Cc: grant.lik...@secretlab.ca Cc: spi-devel-gene...@lists.sourceforge.net --- drivers/spi/spi-atmel.c | 46 +- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index 8131aa1..5abb276 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -599,13 +599,17 @@ static void atmel_spi_next_xfer_pio(struct spi_master *master, } if (xfer->tx_buf) - spi_writel(as, TDR, *(u8 *)(xfer->tx_buf)); + if (xfer->bits_per_word > 8) + spi_writel(as, TDR, *(u16 *)(xfer->tx_buf)); + else + spi_writel(as, TDR, *(u8 *)(xfer->tx_buf)); else spi_writel(as, TDR, 0); dev_dbg(master->dev.parent, - " start pio xfer %p: len %u tx %p rx %p\n", - xfer, xfer->len, xfer->tx_buf, xfer->rx_buf); + " start pio xfer %p: len %u tx %p rx %p bitpw %d\n", + xfer, xfer->len, xfer->tx_buf, xfer->rx_buf, + xfer->bits_per_word); /* Enable relevant interrupts */ spi_writel(as, IER, SPI_BIT(RDRF) | SPI_BIT(OVRES)); @@ -1023,21 +1027,39 @@ atmel_spi_pump_pio_data(struct atmel_spi *as, struct spi_transfer *xfer) { u8 *txp; u8 *rxp; + u16 *txp16; + u16 *rxp16; unsigned long xfer_pos = xfer->len - as->current_remaining_bytes; if (xfer->rx_buf) { - rxp = ((u8 *)xfer->rx_buf) + xfer_pos; - *rxp = spi_readl(as, RDR); + if (xfer->bits_per_word > 8) { + rxp16 = (u16 *)(((u8 *)xfer->rx_buf) + xfer_pos); + *rxp16 = spi_readl(as, RDR); + } else { + rxp = ((u8 *)xfer->rx_buf) + xfer_pos; + *rxp = spi_readl(as, RDR); + } } else { spi_readl(as, RDR); } - - as->current_remaining_bytes--; + if (xfer->bits_per_word > 8) { + as->current_remaining_bytes -= 2; + if (as->current_remaining_bytes < 0) + as->current_remaining_bytes = 0; + } else { + as->current_remaining_bytes--; + } if (as->current_remaining_bytes) { if (xfer->tx_buf) { - txp = ((u8 *)xfer->tx_buf) + xfer_pos + 1; - spi_writel(as, TDR, *txp); + if (xfer->bits_per_word > 8) { + txp16 = (u16 *)(((u8 *)xfer->tx_buf) + + xfer_pos + 2); + spi_writel(as, TDR, *txp16); + } else { + txp = ((u8 *)xfer->tx_buf) + xfer_pos + 1; + spi_writel(as, TDR, *txp); + } } else { spi_writel(as, TDR, 0); } @@ -1459,6 +1481,12 @@ static int atmel_spi_transfer(struct spi_device *spi, struct spi_message *msg) return -ENOPROTOOPT; } } + if (xfer->bits_per_word > 8) { + if (xfer->len % 2) { + dev_dbg(>dev, "buffer len should be 16 bits aligned\n"); + return -EINVAL; + } + } /* FIXME implement these protocol options!! */ if (xfer->speed_hz) { -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[v3 PATCH 07/12] spi/atmel_spi: fix spi-atmel driver to adapt to slave_config changes
From: Richard Genoud This is the following of the patch e2b35f3dbfc080f15b72834d08f04f0269dbe9be Signed-off-by: Richard Genoud [wenyou.y...@atmel.com: fix DMA: when enable both spi0 and spi1, spi0 doesn't work] Signed-off-by: Wenyou Yang Cc: grant.lik...@secretlab.ca Cc: spi-devel-gene...@lists.sourceforge.net --- drivers/spi/spi-atmel.c | 61 +++ 1 file changed, 51 insertions(+), 10 deletions(-) diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index 68ac8e2..8131aa1 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -465,6 +465,37 @@ static inline int atmel_spi_xfer_can_be_chained(struct spi_transfer *xfer) return xfer->delay_usecs == 0 && !xfer->cs_change; } +static int atmel_spi_dma_slave_config(struct atmel_spi *as, + struct dma_slave_config *slave_config) +{ + int err = 0; + + slave_config->dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; + slave_config->src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; + + slave_config->dst_addr = (dma_addr_t)as->phybase + SPI_TDR; + slave_config->src_addr = (dma_addr_t)as->phybase + SPI_RDR; + slave_config->src_maxburst = 1; + slave_config->dst_maxburst = 1; + slave_config->device_fc = false; + + slave_config->direction = DMA_MEM_TO_DEV; + if (dmaengine_slave_config(as->dma.chan_tx, slave_config)) { + dev_err(>pdev->dev, + "failed to configure tx dma channel\n"); + err = -EINVAL; + } + + slave_config->direction = DMA_DEV_TO_MEM; + if (dmaengine_slave_config(as->dma.chan_rx, slave_config)) { + dev_err(>pdev->dev, + "failed to configure rx dma channel\n"); + err = -EINVAL; + } + + return err; +} + static bool filter(struct dma_chan *chan, void *slave) { struct at_dma_slave *sl = slave; @@ -481,14 +512,12 @@ static int __devinit atmel_spi_configure_dma(struct atmel_spi *as) { struct at_dma_slave *sdata = (struct at_dma_slave *)>pdata->dma_slave; + struct dma_slave_config slave_config; + int err; if (sdata && sdata->dma_dev) { dma_cap_mask_t mask; - /* setup DMA addresses */ - sdata->rx_reg = (dma_addr_t)as->phybase + SPI_RDR; - sdata->tx_reg = (dma_addr_t)as->phybase + SPI_TDR; - /* Try to grab two DMA channels */ dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); @@ -498,21 +527,27 @@ static int __devinit atmel_spi_configure_dma(struct atmel_spi *as) dma_request_channel(mask, filter, sdata); } if (!as->dma.chan_rx || !as->dma.chan_tx) { - if (as->dma.chan_rx) - dma_release_channel(as->dma.chan_rx); - if (as->dma.chan_tx) - dma_release_channel(as->dma.chan_tx); dev_err(>pdev->dev, "DMA channel not available, unable to use SPI\n"); - return -EBUSY; + err = -EBUSY; + goto error; } + err = atmel_spi_dma_slave_config(as, _config); + if (err) + goto error; + dev_info(>pdev->dev, "Using %s (tx) and %s (rx) for DMA transfers\n", dma_chan_name(as->dma.chan_tx), dma_chan_name(as->dma.chan_rx)); - return 0; +error: + if (as->dma.chan_rx) + dma_release_channel(as->dma.chan_rx); + if (as->dma.chan_tx) + dma_release_channel(as->dma.chan_tx); + return err; } static void atmel_spi_stop_dma(struct atmel_spi *as) @@ -589,6 +624,7 @@ static int atmel_spi_next_xfer_dma_submit(struct spi_master *master, struct dma_chan *txchan = as->dma.chan_tx; struct dma_async_tx_descriptor *rxdesc; struct dma_async_tx_descriptor *txdesc; + struct dma_slave_config slave_config; dma_cookie_tcookie; u32 len = *plen; @@ -627,6 +663,10 @@ static int atmel_spi_next_xfer_dma_submit(struct spi_master *master, *plen = len; + if (atmel_spi_dma_slave_config(as, _config)) + goto err_exit; + + /* Send both scatterlists */ rxdesc = rxchan->device->device_prep_slave_sg(rxchan, >dma.sgrx, @@ -675,6 +715,7 @@ static int atmel_spi_next_xfer_dma_submit(struct spi_master *master, err_dma: spi_writel(as, IDR, SPI_BIT(OVRES)); atmel_spi_stop_dma(as); +err_exit: atmel_spi_lock(as); return -ENOMEM; } -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at
[v3 PATCH 11/12] ARM: dts: add spi nodes for atmel SoC
From: Richard Genoud Signed-off-by: Richard Genoud [wenyou.y...@atmel.com: add spi nodes for sam9260, sam9263, sam9g45 and sam9n12] [wenyou.y...@atmel.com: remove spi property "cs-gpios" to the board dts files] Signed-off-by: Wenyou Yang Cc: li...@arm.linux.org.uk --- arch/arm/boot/dts/at91sam9260.dtsi | 18 ++ arch/arm/boot/dts/at91sam9263.dtsi | 18 ++ arch/arm/boot/dts/at91sam9g45.dtsi | 18 ++ arch/arm/boot/dts/at91sam9n12.dtsi | 18 ++ arch/arm/boot/dts/at91sam9x5.dtsi | 18 ++ 5 files changed, 90 insertions(+) diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi index 68bccf4..9586fe1 100644 --- a/arch/arm/boot/dts/at91sam9260.dtsi +++ b/arch/arm/boot/dts/at91sam9260.dtsi @@ -453,6 +453,24 @@ status = "disabled"; }; + spi0: spi@fffc8000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "atmel,at91sam9260-spi"; + reg = <0xfffc8000 0x200>; + interrupts = <12 4 3>; + status = "disabled"; + }; + + spi1: spi@fffcc000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "atmel,at91sam9260-spi"; + reg = <0xfffcc000 0x200>; + interrupts = <13 4 3>; + status = "disabled"; + }; + adc0: adc@fffe { compatible = "atmel,at91sam9260-adc"; reg = <0xfffe 0x100>; diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi index 32ec62c..636b882 100644 --- a/arch/arm/boot/dts/at91sam9263.dtsi +++ b/arch/arm/boot/dts/at91sam9263.dtsi @@ -426,6 +426,24 @@ reg = <0xfd40 0x10>; status = "disabled"; }; + + spi0: spi@fffa4000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "atmel,at91sam9260-spi"; + reg = <0xfffa4000 0x200>; + interrupts = <14 4 3>; + status = "disabled"; + }; + + spi1: spi@fffa8000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "atmel,at91sam9260-spi"; + reg = <0xfffa8000 0x200>; + interrupts = <15 4 3>; + status = "disabled"; + }; }; nand0: nand@4000 { diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi index 231858f..0100b80 100644 --- a/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/arch/arm/boot/dts/at91sam9g45.dtsi @@ -495,6 +495,24 @@ reg = <0xfd40 0x10>; status = "disabled"; }; + + spi0: spi@fffa4000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "atmel,at91sam9g45-spi"; + reg = <0xfffa4000 0x200>; + interrupts = <14 4 3>; + status = "disabled"; + }; + + spi1: spi@fffa8000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "atmel,at91sam9g45-spi"; + reg = <0xfffa8000 0x200>; + interrupts = <15 4 3>; + status = "disabled"; + }; }; nand0: nand@4000 { diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi index e9efb34..86d5357 100644 --- a/arch/arm/boot/dts/at91sam9n12.dtsi +++ b/arch/arm/boot/dts/at91sam9n12.dtsi @@ -355,6 +355,24 @@ #size-cells = <0>; status = "disabled"; }; + + spi0: spi@f000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "atmel,at91sam9x5-spi"; +
[v3 PATCH 02/12] spi/atmel_spi: call unmapping on transfers buffers
From: Nicolas Ferre Signed-off-by: Nicolas Ferre Cc: grant.lik...@secretlab.ca Cc: spi-devel-gene...@lists.sourceforge.net --- drivers/spi/spi-atmel.c |8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index 4516839..9782206 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -1016,6 +1016,7 @@ static int atmel_spi_remove(struct platform_device *pdev) struct spi_master *master = platform_get_drvdata(pdev); struct atmel_spi*as = spi_master_get_devdata(master); struct spi_message *msg; + struct spi_transfer *xfer; /* reset the hardware and block queue progress */ spin_lock_irq(>lock); @@ -1027,9 +1028,10 @@ static int atmel_spi_remove(struct platform_device *pdev) /* Terminate remaining queued transfers */ list_for_each_entry(msg, >queue, queue) { - /* REVISIT unmapping the dma is a NOP on ARM and AVR32 -* but we shouldn't depend on that... -*/ + list_for_each_entry(xfer, >transfers, transfer_list) { + if (!msg->is_dma_mapped) + atmel_spi_dma_unmap_xfer(master, xfer); + } msg->status = -ESHUTDOWN; msg->complete(msg->context); } -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 12/12] ARM: dts: add spi nodes for the atmel boards
From: Richard Genoud Signed-off-by: Richard Genoud [wenyou.y...@atmel.com: added spi nodes for the sam9263ek, sam9g20ek, sam9m10g45ek and sam9n12ek boards] Signed-off-by: Wenyou Yang Cc: li...@arm.linux.org.uk --- arch/arm/boot/dts/at91sam9263ek.dts | 14 ++ arch/arm/boot/dts/at91sam9g20ek_common.dtsi | 14 ++ arch/arm/boot/dts/at91sam9m10g45ek.dts | 14 ++ arch/arm/boot/dts/at91sam9n12ek.dts | 14 ++ arch/arm/boot/dts/at91sam9x5ek.dtsi | 14 ++ 5 files changed, 70 insertions(+) diff --git a/arch/arm/boot/dts/at91sam9263ek.dts b/arch/arm/boot/dts/at91sam9263ek.dts index 1eb0872..63ba57b 100644 --- a/arch/arm/boot/dts/at91sam9263ek.dts +++ b/arch/arm/boot/dts/at91sam9263ek.dts @@ -79,6 +79,20 @@ }; }; }; + + spi0: spi@fffa4000 { + status = "okay"; + cs-gpios = < 5 0 +3 0 +4 0 +11 0 + >; + mtd_dataflash@0 { + compatible = "atmel,at45", "atmel,dataflash"; + spi-max-frequency = <5000>; + reg = <0>; + }; + }; }; nand0: nand@4000 { diff --git a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi index da15e83..49ad49e 100644 --- a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi +++ b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi @@ -96,6 +96,20 @@ status = "okay"; pinctrl-0 = <_ssc0_tx>; }; + + spi0: spi@fffc8000 { + status = "okay"; + cs-gpios = < 3 0 +11 0 +16 0 +17 0 + >; + mtd_dataflash@0 { + compatible = "atmel,at45", "atmel,dataflash"; + spi-max-frequency = <5000>; + reg = <1>; + }; + }; }; nand0: nand@4000 { diff --git a/arch/arm/boot/dts/at91sam9m10g45ek.dts b/arch/arm/boot/dts/at91sam9m10g45ek.dts index 20c3191..275f22d 100644 --- a/arch/arm/boot/dts/at91sam9m10g45ek.dts +++ b/arch/arm/boot/dts/at91sam9m10g45ek.dts @@ -102,6 +102,20 @@ }; }; }; + + spi0: spi@fffa4000{ + status = "okay"; + cs-gpios = < 3 0 +18 0 +19 0 +27 0 + >; + mtd_dataflash@0 { + compatible = "atmel,at45", "atmel,dataflash"; + spi-max-frequency = <1300>; + reg = <0>; + }; + }; }; nand0: nand@4000 { diff --git a/arch/arm/boot/dts/at91sam9n12ek.dts b/arch/arm/boot/dts/at91sam9n12ek.dts index 0376bf4..4eeca7b 100644 --- a/arch/arm/boot/dts/at91sam9n12ek.dts +++ b/arch/arm/boot/dts/at91sam9n12ek.dts @@ -67,6 +67,20 @@ }; }; }; + + spi0: spi@f000 { + status = "okay"; + cs-gpios = < 14 0 +7 0 +1 0 +3 0 + >; + m25p80@0 { + compatible = "atmel,at25df321a"; + spi-max-frequency = <5000>; + reg = <0>; + }; + }; }; nand0: nand@4000 { diff --git a/arch/arm/boot/dts/at91sam9x5ek.dtsi b/arch/arm/boot/dts/at91sam9x5ek.dtsi index 8a7cf1d..ca0a056 100644 --- a/arch/arm/boot/dts/at91sam9x5ek.dtsi +++
[v3 PATCH 06/12] spi/atmel_spi: add dmaengine support
From: Nicolas Ferre Add dmaengine support. For different SoC, the "has_dma_support" is used to select the transfer mode: dmaengine or PDC. For the dmaengine transfer mode, if it fails to config dmaengine, or if the message len less than 16 bytes, it will use the PIO transfer mode. Signed-off-by: Nicolas Ferre [wenyou.y...@atmel.com: using "has_dma_support" to select DMA as the spi xfer mode] [wenyou.y...@atmel.com: add support NPCS1,2,3 chip select other than NPCS0] [wenyou.y...@atmel.com: fix DMA: OOPS if buffer > 4096 bytes] Signed-off-by: Wenyou Yang Cc: grant.lik...@secretlab.ca Cc: spi-devel-gene...@lists.sourceforge.net Cc: richard.gen...@gmail.com --- This patch is based on the original patch from Nicolas [PATCH] spi/atmel_spi: add dmaengine support and merge the patches from Richard Genoud [PATCH] spi-atmel: update with dmaengine interface [PATCH] spi-atmel: fix __init/__devinit sections mismatch and Wenyou Yang add the code to support selecting the spi transfer mode, add support NPCS1,2,3 chip select other than NPCS0. fix DMA: OOPS if buffer > 4096 bytes. Hi, Richard, Could you sign your signature in this patch? Best Regards, Wenyou Yang drivers/spi/spi-atmel.c | 566 --- 1 file changed, 532 insertions(+), 34 deletions(-) diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index 43374ca..68ac8e2 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -15,11 +15,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include @@ -182,6 +184,19 @@ #define spi_writel(port,reg,value) \ __raw_writel((value), (port)->regs + SPI_##reg) +/* use PIO for small transfers, avoiding DMA setup/teardown overhead and + * cache operations; better heuristics consider wordsize and bitrate. + */ +#define DMA_MIN_BYTES 16 + +struct atmel_spi_dma { + struct dma_chan *chan_rx; + struct dma_chan *chan_tx; + struct scatterlist sgrx; + struct scatterlist sgtx; + struct dma_async_tx_descriptor *data_desc_rx; + struct dma_async_tx_descriptor *data_desc_tx; +}; /* * The core SPI transfer engine just talks to a register bank to set up @@ -192,6 +207,7 @@ struct atmel_spi_pdata { u8 version; boolhas_dma_support; boolhas_wdrbt; + struct at_dma_slave dma_slave; }; struct atmel_spi { @@ -207,6 +223,7 @@ struct atmel_spi { u8 stopping; struct list_headqueue; + struct tasklet_struct tasklet; struct spi_transfer *current_transfer; unsigned long current_remaining_bytes; struct spi_transfer *next_transfer; @@ -214,8 +231,15 @@ struct atmel_spi { int done_status; struct atmel_spi_pdata *pdata; + booluse_dma; + booluse_pdc; + + /* scratch buffer */ void*buffer; dma_addr_t buffer_dma; + + /* dmaengine data */ + struct atmel_spi_dmadma; }; /* Controller-specific per-slave state */ @@ -331,9 +355,7 @@ static bool atmel_spi_is_v2(struct atmel_spi *as) * and (c) will trigger that first erratum in some cases. * * TODO: Test if the atmel_spi_is_v2() branch below works on - * AT91RM9200 if we use some other register than CSR0. However, don't - * do this unconditionally since AP7000 has an errata where the BITS - * field in CSR0 overrides all other CSRs. + * AT91RM9200 if we use some other register than CSR0. */ static void cs_activate(struct atmel_spi *as, struct spi_device *spi) @@ -343,18 +365,16 @@ static void cs_activate(struct atmel_spi *as, struct spi_device *spi) u32 mr; if (atmel_spi_is_v2(as)) { - /* -* Always use CSR0. This ensures that the clock -* switches to the correct idle polarity before we -* toggle the CS. -*/ - spi_writel(as, CSR0, asd->csr); + spi_writel(as, CSR0 + 4 * spi->chip_select, asd->csr); if (as->pdata->has_wdrbt) - spi_writel(as, MR, SPI_BF(PCS, 0x0e) | SPI_BIT(MSTR) - | SPI_BIT(MODFDIS) | SPI_BIT(WDRBT)); + spi_writel(as, MR, + SPI_BF(PCS, ~(0x01 << spi->chip_select)) + | SPI_BIT(MSTR) | SPI_BIT(MODFDIS) + | SPI_BIT(WDRBT)); else - spi_writel(as, MR, SPI_BF(PCS, 0x0e) + spi_writel(as, MR, + SPI_BF(PCS, ~(0x01 << spi->chip_select))
[v3 PATCH 10/12] ARM: at91: add clocks for spi dt entries
From: Richard Genoud Signed-off-by: Richard Genoud [ Cc: li...@arm.linux.org.uk Cc: plagn...@jcrosoft.com Cc: li...@maxim.org.za --- arch/arm/mach-at91/at91sam9260.c |2 ++ arch/arm/mach-at91/at91sam9g45.c |2 ++ arch/arm/mach-at91/at91sam9n12.c |2 ++ arch/arm/mach-at91/at91sam9x5.c |2 ++ 4 files changed, 8 insertions(+) diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index b67cd53..44199bc 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c @@ -232,6 +232,8 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("t2_clk", "fffdc000.timer", _clk), CLKDEV_CON_DEV_ID("hclk", "50.ohci", _clk), CLKDEV_CON_DEV_ID("mci_clk", "fffa8000.mmc", _clk), + CLKDEV_CON_DEV_ID("spi_clk", "fffc8000.spi", _clk), + CLKDEV_CON_DEV_ID("spi_clk", "fffcc000.spi", _clk), /* fake hclk clock */ CLKDEV_CON_DEV_ID("hclk", "at91_ohci", _clk), CLKDEV_CON_ID("pioA", _clk), diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index d3addee..2ec5efe 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -262,6 +262,8 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("mci_clk", "fffd.mmc", _clk), CLKDEV_CON_DEV_ID(NULL, "fff84000.i2c", _clk), CLKDEV_CON_DEV_ID(NULL, "fff88000.i2c", _clk), + CLKDEV_CON_DEV_ID("spi_clk", "fffa4000.spi", _clk), + CLKDEV_CON_DEV_ID("spi_clk", "fffa8000.spi", _clk), /* fake hclk clock */ CLKDEV_CON_DEV_ID("hclk", "at91_ohci", _clk), CLKDEV_CON_DEV_ID(NULL, "f200.gpio", _clk), diff --git a/arch/arm/mach-at91/at91sam9n12.c b/arch/arm/mach-at91/at91sam9n12.c index 5dfc8fd..ccd0783 100644 --- a/arch/arm/mach-at91/at91sam9n12.c +++ b/arch/arm/mach-at91/at91sam9n12.c @@ -172,6 +172,8 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("dma_clk", "ec00.dma-controller", _clk), CLKDEV_CON_DEV_ID(NULL, "f801.i2c", _clk), CLKDEV_CON_DEV_ID(NULL, "f8014000.i2c", _clk), + CLKDEV_CON_DEV_ID("spi_clk", "f000.spi", _clk), + CLKDEV_CON_DEV_ID("spi_clk", "f0004000.spi", _clk), CLKDEV_CON_DEV_ID(NULL, "f400.gpio", _clk), CLKDEV_CON_DEV_ID(NULL, "f600.gpio", _clk), CLKDEV_CON_DEV_ID(NULL, "f800.gpio", _clk), diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c index 44a9a62..a200d8a 100644 --- a/arch/arm/mach-at91/at91sam9x5.c +++ b/arch/arm/mach-at91/at91sam9x5.c @@ -237,6 +237,8 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID(NULL, "f801.i2c", _clk), CLKDEV_CON_DEV_ID(NULL, "f8014000.i2c", _clk), CLKDEV_CON_DEV_ID(NULL, "f8018000.i2c", _clk), + CLKDEV_CON_DEV_ID("spi_clk", "f000.spi", _clk), + CLKDEV_CON_DEV_ID("spi_clk", "f0004000.spi", _clk), CLKDEV_CON_DEV_ID(NULL, "f400.gpio", _clk), CLKDEV_CON_DEV_ID(NULL, "f600.gpio", _clk), CLKDEV_CON_DEV_ID(NULL, "f800.gpio", _clk), -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[v3 PATCH 05/12] spi/atmel_spi: update the dt support
To meet the different spi IP version of atmel SoC, add more compatible "atmel,at91rm9200-spi", "atmel,at91sam9260-spi" "atmel,at91sam9g45-spi", "atmel,at91sam9x5-spi" with different config and devtype. The "has_dma_support" is used to select the dma engine transfer mode. The "has_wdrbt" indicate if there is the "WDRBT" bit in the Mode Register, WDRBT (Wait Data Read Before Transfer),if WDRBT is set, a transfer can start only if the Receive Data Register is empty,i.e. does not contain any unread data, to prevent overrun error in reception Signed-off-by: Wenyou Yang --- drivers/spi/spi-atmel.c | 137 --- 1 file changed, 118 insertions(+), 19 deletions(-) diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index 8f6f0a0..43374ca 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -71,6 +71,8 @@ #define SPI_FDIV_SIZE 1 #define SPI_MODFDIS_OFFSET 4 #define SPI_MODFDIS_SIZE 1 +#define SPI_WDRBT_OFFSET 5 +#define SPI_WDRBT_SIZE 1 #define SPI_LLB_OFFSET 7 #define SPI_LLB_SIZE 1 #define SPI_PCS_OFFSET 16 @@ -186,6 +188,12 @@ * DMA transfers; transfer queue progress is driven by IRQs. The clock * framework provides the base clock, subdivided for each spi_device. */ +struct atmel_spi_pdata { + u8 version; + boolhas_dma_support; + boolhas_wdrbt; +}; + struct atmel_spi { spinlock_t lock; unsigned long flags; @@ -204,6 +212,7 @@ struct atmel_spi { struct spi_transfer *next_transfer; unsigned long next_remaining_bytes; int done_status; + struct atmel_spi_pdata *pdata; void*buffer; dma_addr_t buffer_dma; @@ -218,6 +227,69 @@ struct atmel_spi_device { #define BUFFER_SIZEPAGE_SIZE #define INVALID_DMA_ADDRESS0x +static struct atmel_spi_pdata at91rm9200_config = { + .version = 1, + .has_dma_support = false, + .has_wdrbt = false, +}; + +static struct atmel_spi_pdata at91sam9260_config = { + .version = 2, + .has_dma_support = false, + .has_wdrbt = false, +}; + +static struct atmel_spi_pdata at91sam9g45_config = { + .version = 2, + .has_dma_support = false, + .has_wdrbt = true, +}; + +static struct atmel_spi_pdata at91sam9x5_config = { + .version = 2, + .has_dma_support = true, + .has_wdrbt = true, +}; + +static const struct platform_device_id atmel_spi_devtypes[] = { + { + .name = "spi-at91rm9200", + .driver_data = (unsigned long) _config, + }, { + .name = "spi-at91sam9260", + .driver_data = (unsigned long) _config, + }, { + .name = "spi-at91sam9g45", + .driver_data = (unsigned long) _config, + }, { + .name = "spi-at91sam9x5", + .driver_data = (unsigned long) _config, + }, { + /* sentinel */ + } +}; + +#if defined(CONFIG_OF) +static const struct of_device_id atmel_spi_dt_ids[] = { + { + .compatible = "atmel,at91rm9200-spi", + .data = _config, + } , { + .compatible = "atmel,at91sam9260-spi", + .data = _config, + } , { + .compatible = "atmel,at91sam9g45-spi", + .data = _config, + } , { + .compatible = "atmel,at91sam9x5-spi", + .data = _config, + }, { + /* sentinel */ + } +}; +MODULE_DEVICE_TABLE(of, atmel_spi_dt_ids); +#endif + /* * Version 2 of the SPI controller has * - CR.LASTXFER @@ -230,11 +302,15 @@ struct atmel_spi_device { * register, but I haven't checked that it exists on all chips, and * this is cheaper anyway. */ -static bool atmel_spi_is_v2(void) +static bool atmel_spi_is_v2(struct atmel_spi *as) { - return !cpu_is_at91rm9200(); + if (as->pdata->version == 2) + return true; + else + return false; } + /* * Earlier SPI controllers (e.g. on at91rm9200) have a design bug whereby * they assume that spi slave device state will not change on deselect, so @@ -266,15 +342,21 @@ static void cs_activate(struct atmel_spi *as, struct spi_device *spi) unsigned active = spi->mode & SPI_CS_HIGH; u32 mr; - if (atmel_spi_is_v2()) { + if (atmel_spi_is_v2(as)) { /* * Always use CSR0. This ensures that the clock * switches to the correct idle polarity before we * toggle the CS. */ spi_writel(as, CSR0, asd->csr); - spi_writel(as, MR, SPI_BF(PCS, 0x0e) |